version 1.2, 2006/03/24 23:08:33
|
version 1.4, 2008/12/04 12:17:13
|
Line 1
|
Line 1
|
/**************************************************************************** |
/**************************************************************************** |
* |
* |
* Copyright(c) 2002-2006, John Forkosh Associates, Inc. All rights reserved. |
* Copyright(c) 2002-2008, John Forkosh Associates, Inc. All rights reserved. |
|
* http://www.forkosh.com mailto: john@forkosh.com |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* 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, |
* version 2 or later, as published by the Free Software Foundation. |
* version 3 or later, as published by the Free Software Foundation. |
* MimeTeX is distributed in the hope that it will be useful, but |
* MimeTeX is distributed in the hope that it will be useful, but |
* WITHOUT ANY WARRANTY, not even the implied warranty of MERCHANTABILITY. |
* WITHOUT ANY WARRANTY, not even the implied warranty of MERCHANTABILITY. |
* See the GNU General Public License for specific details. |
* See the GNU General Public License for specific details. |
Line 12
|
Line 13
|
* agreed to these terms and conditions, and that you possess the legal |
* agreed to these terms and conditions, and that you possess the legal |
* right and ability to enter into this agreement and to use mimeTeX |
* right and ability to enter into this agreement and to use mimeTeX |
* in accordance with it. |
* in accordance with it. |
* Your mimeTeX distribution should contain a copy of the GNU General |
* Your mimetex.zip distribution file should contain the file COPYING, |
* Public License. If not, write to the Free Software Foundation, Inc., |
* an ascii text copy of the GNU General Public License, version 3. |
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, |
* If not, point your browser to http://www.gnu.org/licenses/ |
* or point your browser to http://www.gnu.org/licenses/gpl.html |
* or write to the Free Software Foundation, Inc., |
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* |
* |
* Purpose: o MimeTeX, licensed under the gpl, lets you easily embed |
* Purpose: o MimeTeX, licensed under the gpl, lets you easily embed |
Line 25
|
Line 27
|
* entirely separate little program that doesn't use TeX or |
* entirely separate little program that doesn't use TeX or |
* its fonts in any way. It's just one cgi that you put in |
* its fonts in any way. It's just one cgi that you put in |
* your site's cgi-bin/ directory, with no other dependencies. |
* your site's cgi-bin/ directory, with no other dependencies. |
* So mimeTeX is very easy to install. And it's equally easy |
* So mimeTeX is very easy to install. And it's equally |
* to use. Just place an html <img> tag in your document |
* easy to use. Just place an html <img> tag in your document |
* wherever you want to see the corresponding LaTeX expression. |
* wherever you want to see the corresponding LaTeX expression. |
* For example, |
* For example, |
* <img src="../cgi-bin/mimetex.cgi?\int_{-\infty}^xe^{-t^2}dt" |
* <img src="../cgi-bin/mimetex.cgi?\int_{-\infty}^xe^{-t^2}dt" |
* alt="" border=0 align=middle> |
* alt="" border=0 align=middle> |
* immediately generates the corresponding gif image on-the-fly, |
* immediately generates the corresponding gif image on-the-fly, |
* displaying the rendered expression wherever you put that |
* displaying the rendered expression wherever you put that |
* <img> tag. MimeTeX doesn't need intermediate dvi-to-gif |
* <img> tag. |
* conversion, and it doesn't clutter up your filesystem with |
* MimeTeX doesn't need intermediate dvi-to-gif conversion, |
* separate little gif files for each converted expression. |
* and it doesn't clutter up your filesystem with separate |
|
* little gif files for each converted expression. |
|
* But image caching is available by using mimeTeX's |
|
* -DCACHEPATH=\"path/\" compile option (see below). |
* There's also no inherent need to repeatedly write the |
* There's also no inherent need to repeatedly write the |
* cumbersome <img> tag illustrated above. You can write |
* cumbersome <img> tag illustrated above. You can write |
* your own custom tags, or write a wrapper script around |
* your own custom tags, or write a wrapper script around |
* mimeTeX to simplify the necessary notation. |
* mimeTeX to simplify the notation. |
|
* Further discussion about mimeTeX's features and |
|
* usage is available on its homepage, |
|
* http://www.forkosh.com/mimetex.html |
|
* and similarly in mimetex.html included with your mimetex.zip |
|
* distribution file. |
* |
* |
* Functions: ===================== Raster Functions ====================== |
* Functions: ===================== Raster Functions ====================== |
* PART2 --- raster constructor functions --- |
* PART2 --- raster constructor functions --- |
Line 53
|
Line 63
|
* rastcpy(rp) allocate new copy of rp |
* rastcpy(rp) allocate new copy of rp |
* subrastcpy(sp) allocate new copy of sp |
* subrastcpy(sp) allocate new copy of sp |
* rastrot(rp) new raster rotated right 90 degrees to rp |
* rastrot(rp) new raster rotated right 90 degrees to rp |
|
* rastref(rp,axis) new raster reflected (axis 1=horz,2=vert) |
* rastput(target,source,top,left,isopaque) overlay src on trgt |
* rastput(target,source,top,left,isopaque) overlay src on trgt |
* rastcompose(sp1,sp2,offset2,isalign,isfree) sp2 on top of sp1 |
* rastcompose(sp1,sp2,offset2,isalign,isfree) sp2 on top of sp1 |
* 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 |
* rastsmash(sp1,sp2,xmin,ymin) calc #smash pixels sp1||sp2 |
* rastsmash(sp1,sp2,xmin,ymin) calc #smash pixels sp1||sp2 |
|
* rastsmashcheck(term) check if term is "safe" to smash |
* --- 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 70
|
Line 82
|
* circle_recurse(rp,row0,col0,row1,col1,thickness,theta0,theta1) |
* circle_recurse(rp,row0,col0,row1,col1,thickness,theta0,theta1) |
* bezier_raster(rp,r0,c0,r1,c1,rt,ct) draw bezier recursively |
* bezier_raster(rp,r0,c0,r1,c1,rt,ct) draw bezier recursively |
* border_raster(rp,ntop,nbot,isline,isfree)put border around rp |
* border_raster(rp,ntop,nbot,isline,isfree)put border around rp |
|
* backspace_raster(rp,nback,pback,minspace,isfree) neg space |
* --- raster (and chardef) output functions --- |
* --- raster (and chardef) output functions --- |
* 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 |
Line 83
|
Line 96
|
* gftobitmap(rp) convert .gf-like pixmap to bitmap image |
* 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) return mathchardef for symbol |
* get_chardef(symdef,size) returns chardef for symdef,size |
* get_ligature(expr,family) return symtable index for ligature |
|
* get_chardef(symdef,size) return 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 |
* get_symsubraster(symbol,size) returns subraster for symbol |
* --- ancillary font functions --- |
* --- ancillary font functions --- |
Line 102
|
Line 116
|
* mimeprep(expression) preprocessor converts \left( to \(, etc. |
* mimeprep(expression) preprocessor converts \left( to \(, etc. |
* strchange(nfirst,from,to) change nfirst chars of from to to |
* strchange(nfirst,from,to) change nfirst chars of from to to |
* strreplace(string,from,to,nreplace) change from to to in str |
* strreplace(string,from,to,nreplace) change from to to in str |
|
* strwstr(string,substr,white,sublen) find substr in string |
* strtexchr(string,texchr) find texchr in string |
* strtexchr(string,texchr) find texchr in string |
* findbraces(expression,command) find opening { or closing } |
* findbraces(expression,command) find opening { or closing } |
* PART3 =========== Rasterize an Expression (recursively) =========== |
* PART3 =========== Rasterize an Expression (recursively) =========== |
Line 132
|
Line 147
|
* rastarray(expression,size,basesp,arg1,arg2,arg3) \array |
* rastarray(expression,size,basesp,arg1,arg2,arg3) \array |
* rastpicture(expression,size,basesp,arg1,arg2,arg3) \picture |
* rastpicture(expression,size,basesp,arg1,arg2,arg3) \picture |
* rastline(expression,size,basesp,arg1,arg2,arg3) \line |
* rastline(expression,size,basesp,arg1,arg2,arg3) \line |
|
* rastrule(expression,size,basesp,arg1,arg2,arg3) \rule |
* rastcircle(expression,size,basesp,arg1,arg2,arg3) \circle |
* rastcircle(expression,size,basesp,arg1,arg2,arg3) \circle |
* rastbezier(expression,size,basesp,arg1,arg2,arg3) \bezier |
* rastbezier(expression,size,basesp,arg1,arg2,arg3) \bezier |
* rastraise(expression,size,basesp,arg1,arg2,arg3) \raisebox |
* rastraise(expression,size,basesp,arg1,arg2,arg3) \raisebox |
* rastrotate(expression,size,basesp,arg1,arg2,arg3) \rotatebox |
* rastrotate(expression,size,basesp,arg1,arg2,arg3) \rotatebox |
|
* rastreflect(expression,size,basesp,arg1,arg2,arg3)\reflectbox |
* 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 |
Line 155
|
Line 172
|
* === 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 |
|
* aapnmlookup(rp,bytemap,grayscale) aapnm based on aagridnum() |
|
* aapatterns(rp,irow,icol,gridnum,patternum,grayscale) call 19, |
|
* aapattern1124(rp,irow,icol,gridnum,grayscale)antialias pattrn |
|
* aapattern19(rp,irow,icol,gridnum,grayscale) antialias pattern |
|
* aapattern20(rp,irow,icol,gridnum,grayscale) antialias pattern |
|
* aapattern39(rp,irow,icol,gridnum,grayscale) antialias pattern |
|
* aafollowline(rp,irow,icol,direction) looks for a "turn" |
|
* aagridnum(rp,irow,icol) calculates gridnum, 0-511 |
|
* aapatternnum(gridnum) looks up pattern#, 1-51, for gridnum |
|
* aalookup(gridnum) table lookup for all possible 3x3 grids |
|
* aalowpasslookup(rp,bytemap,grayscale) driver for aalookup() |
* aasupsamp(rp,aa,sf,grayscale) or by supersampling |
* aasupsamp(rp,aa,sf,grayscale) or by supersampling |
* aacolormap(bytemap,nbytes,colors,colormap)make colors,colormap |
* aacolormap(bytemap,nbytes,colors,colormap)make colors,colormap |
* aaweights(width,height) builds "canonical" weight matrix |
* aaweights(width,height) builds "canonical" weight matrix |
* aawtpixel(image,ipixel,weights,rotate) weight image at ipixel |
* aawtpixel(image,ipixel,weights,rotate) weight image at ipixel |
|
* === miscellaneous === |
|
* mimetexsetmsg(newmsglevel,newmsgfp) set msglevel and msgfp |
* 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 |
* CreateGifFromEq(expression,gifFileName) entry pt for win dll |
Line 166
|
Line 196
|
* 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,maxage,isbuffer) emit cachefile to stdout |
* emitcache(cachefile,maxage,valign,isbuffer) emit cachefile |
* readcachefile(cachefile,buffer) read cachefile into buffer |
* 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 |
* |
* |
* Source: mimetex.c (needs mimetex.h and texfonts.h to compile, |
* Source: mimetex.c (needs mimetex.h and texfonts.h to compile, |
* and also needs gifsave.c if compiled with -DAA or -DGIF) |
* and also needs gifsave.c when compiled with -DAA or -DGIF) |
* |
* |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Notes o See bottom of file for main() driver (and "friends"), |
* Notes o See bottom of file for main() driver (and "friends"), |
Line 189
|
Line 219
|
* and with -DAA or -DGIF you'll also need gifsave.c |
* and with -DAA or -DGIF you'll also need gifsave.c |
* o For gif images, the gifsave.c library by Sverre H. Huseby |
* o For gif images, the gifsave.c library by Sverre H. Huseby |
* <http://shh.thathost.com> slightly modified by me to allow |
* <http://shh.thathost.com> slightly modified by me to allow |
* (a)sending output to stdout and (b)specifying a transparent |
* (a)sending output to stdout or returning it in memory, |
* background color index, is included with mimeTeX, |
* and (b)specifying a transparent background color index, |
* and it's documented in mimetex.html#gifsave . |
* is included with mimeTeX, and it's documented in |
|
* mimetex.html#gifsave . |
* o Optional compile-line -D defined symbols are documented |
* o Optional compile-line -D defined symbols are documented |
* in mimetex.html#options . They include... |
* in mimetex.html#options . They include (additional -D |
|
* switches are discussed in mimetex.html#options)... |
* -DAA |
* -DAA |
* Turns on gif anti-aliasing with default values |
* Turns on gif anti-aliasing with default values |
* (CENTERWT=32, ADJACENTWT=3, CORNERWT=1) |
* (CENTERWT=32, ADJACENTWT=3, CORNERWT=1) |
Line 205
|
Line 237
|
* algorithm for anti-aliasing, which is applied to the |
* algorithm for anti-aliasing, which is applied to the |
* existing set of bitmap fonts. This lowpass filter |
* existing set of bitmap fonts. This lowpass filter |
* applies default weights |
* applies default weights |
* 1 3 1 |
* 1 2 1 |
* 3 32 3 |
* 2 8 2 |
* 1 3 1 |
* 1 2 1 |
* to neighboring pixels. The defaults weights are |
* to neighboring pixels. The defaults weights are |
* CENTERWT=32, ADJACENTWT=3 and CORNERWT=1, |
* CENTERWT=8, ADJACENTWT=2 and CORNERWT=1, |
* which you can adjust to control anti-aliasing. |
* which you can adjust to control anti-aliasing. |
* Lower CENTERWT values will blur/spread out lines |
* Lower CENTERWT values will blur/spread out lines |
* while higher values will tend to sharpen lines. |
* while higher values will tend to sharpen lines. |
Line 308
|
Line 340
|
* 02/01/04 J.Forkosh Version 1.40 released. |
* 02/01/04 J.Forkosh Version 1.40 released. |
* 10/02/04 J.Forkosh Version 1.50 released. |
* 10/02/04 J.Forkosh Version 1.50 released. |
* 11/30/04 J.Forkosh Version 1.60 released. |
* 11/30/04 J.Forkosh Version 1.60 released. |
|
* 10/11/05 J.Forkosh Version 1.64 released. |
|
* 11/30/06 J.Forkosh Version 1.65 released. |
|
* 09/06/08 J.Forkosh Version 1.70 released. |
* |
* |
****************************************************************************/ |
****************************************************************************/ |
|
|
Line 368 header files and macros
|
Line 403 header files and macros
|
#else |
#else |
#define ISSUPERSAMPLING 0 |
#define ISSUPERSAMPLING 0 |
#ifndef AAALGORITHM |
#ifndef AAALGORITHM |
#define AAALGORITHM 2 /* default lowpass algorithm */ |
#define AAALGORITHM 3 /*2*/ /* default lowpass algorithm */ |
#endif |
#endif |
#endif |
#endif |
|
#ifndef MAXFOLLOW |
|
#define MAXFOLLOW 8 /* aafollowline() maxturn default */ |
|
#endif |
|
|
/* --- set aa (and default gif) if any anti-aliasing options specified --- */ |
/* --- set aa (and default gif) if any anti-aliasing options specified --- */ |
#if defined(AA) || defined(GIF) || defined(PNG) \ |
#if defined(AA) || defined(GIF) || defined(PNG) \ |
Line 408 header files and macros
|
Line 446 header files and macros
|
#define NOREFMAXLEN 9999 /* default to any length query */ |
#define NOREFMAXLEN 9999 /* default to any length query */ |
#endif |
#endif |
#else |
#else |
#define NOTEXFONTS /* texfonts not required */ |
#ifndef TEXFONTS |
|
#define NOTEXFONTS /* texfonts not required */ |
|
#endif |
#endif |
#endif |
|
|
/* --- application headers --- */ |
/* --- application headers --- */ |
Line 423 header files and macros
|
Line 463 header files and macros
|
#else /* or just set dummy values */ |
#else /* or just set dummy values */ |
static int gifSize=0, maxgifSize=0; |
static int gifSize=0, maxgifSize=0; |
#endif |
#endif |
|
/* --- gamma correction --- */ |
|
#ifndef GAMMA |
|
#define GAMMA 1.25 /*1.75*/ /*2.2*/ |
|
#endif |
|
#ifndef REVERSEGAMMA |
|
#define REVERSEGAMMA 0.5 /* for \reverse white-on-black */ |
|
#endif |
|
/* --- opaque background (default to transparent) --- */ |
|
#ifndef OPAQUE |
|
#define ISTRANSPARENT 1 |
|
#else |
|
#define ISTRANSPARENT 0 |
|
#endif |
|
/* --- internal buffer sizes --- */ |
|
#if !defined(MAXEXPRSZ) |
|
#define MAXEXPRSZ (32768-1) /*max #bytes in input tex expression*/ |
|
#endif |
|
#if !defined(MAXSUBXSZ) |
|
#define MAXSUBXSZ (((MAXEXPRSZ+1)/2)-1)/*max #bytes in input subexpression*/ |
|
#endif |
|
#if !defined(MAXTOKNSZ) |
|
#define MAXTOKNSZ (((MAXSUBXSZ+1)/4)-1) /* max #bytes in input token */ |
|
#endif |
|
#if !defined(MAXFILESZ) |
|
#define MAXFILESZ (65536-1) /*max #bytes in input (output) file*/ |
|
#endif |
|
#if !defined(MAXLINESZ) |
|
#define MAXLINESZ (4096-1) /* max #chars in line from file */ |
|
#endif |
|
#if !defined(MAXGIFSZ) |
|
#define MAXGIFSZ 131072 /* max #bytes in output GIF image */ |
|
#endif |
|
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
adjustable default values |
adjustable default values |
Line 454 GLOBAL(int,minadjacent,MINADJACENT); /*
|
Line 526 GLOBAL(int,minadjacent,MINADJACENT); /*
|
GLOBAL(int,maxadjacent,MAXADJACENT); /* darken if<=adjacent pts black */ |
GLOBAL(int,maxadjacent,MAXADJACENT); /* darken if<=adjacent pts black */ |
GLOBAL(int,weightnum,1); /* font wt, */ |
GLOBAL(int,weightnum,1); /* font wt, */ |
GLOBAL(int,maxaaparams,4); /* #entries in table */ |
GLOBAL(int,maxaaparams,4); /* #entries in table */ |
/* --- parameter values by font weight --- */ |
/* --- anti-aliasing parameter values by font weight --- */ |
#define aaparameters struct aaparameters_struct /* typedef */ |
#define aaparameters struct aaparameters_struct /* typedef */ |
aaparameters |
aaparameters |
{ int centerwt; /* lowpass matrix center pixel wt*/ |
{ int centerwt; /* lowpass matrix center pixel wt*/ |
Line 476 STATIC aaparameters aaparams[] /* set p
|
Line 548 STATIC aaparameters aaparams[] /* set p
|
} /* --- end-of-aaparams[] --- */ |
} /* --- end-of-aaparams[] --- */ |
#endif |
#endif |
; |
; |
|
/* --- anti-aliasing diagnostics (to help improve algorithm) --- */ |
|
STATIC int patternnumcount0[99], patternnumcount1[99], /*aalookup() counts*/ |
|
ispatternnumcount = 1; /* true to accumulate counts */ |
|
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
other variables |
other variables |
Line 507 other variables
|
Line 582 other variables
|
#define SMASHMARGIN 3 |
#define SMASHMARGIN 3 |
#endif |
#endif |
#endif |
#endif |
|
#ifndef SMASHCHECK |
|
#define SMASHCHECK 0 |
|
#endif |
/* --- textwidth --- */ |
/* --- textwidth --- */ |
#ifndef TEXTWIDTH |
#ifndef TEXTWIDTH |
#define TEXTWIDTH (400) |
#define TEXTWIDTH (400) |
Line 552 other variables
|
Line 630 other variables
|
#ifndef TZDELTA |
#ifndef TZDELTA |
#define TZDELTA 0 |
#define TZDELTA 0 |
#endif |
#endif |
|
/* --- treat +'s in query string as blanks? --- */ |
|
#ifdef PLUSBLANK /* + always interpreted as blank */ |
|
#define ISPLUSBLANK 1 |
|
#else |
|
#ifdef PLUSNOTBLANK /* + never interpreted as blank */ |
|
#define ISPLUSBLANK 0 |
|
#else /* program tries to determine */ |
|
#define ISPLUSBLANK (-1) |
|
#endif |
|
#endif |
|
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
debugging and logging / error reporting |
debugging and logging / error reporting |
Line 586 control flags and values
|
Line 674 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,isstring,0); /*pixmap is ascii string, not raster*/ |
GLOBAL(int,isstring,0); /*pixmap is ascii string, not raster*/ |
|
GLOBAL(int,isligature,0); /* true if ligature found */ |
|
GLOBAL(char,*subexprptr,(char *)NULL); /* ptr within expression to subexpr*/ |
/*SHARED(int,imageformat,1);*/ /* image is 1=bitmap, 2=.gf-like */ |
/*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 $$...$$ */ |
Line 595 GLOBAL(int,displaysize,DISPLAYSIZE); /*
|
Line 685 GLOBAL(int,displaysize,DISPLAYSIZE); /*
|
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,iscatspace,1); /* true to add space in rastcat() */ |
GLOBAL(int,isnocatspace,0); /* >0 to not add space in rastcat()*/ |
GLOBAL(int,smashmargin,SMASHMARGIN); /* minimum "smash" margin */ |
GLOBAL(int,smashmargin,SMASHMARGIN); /* minimum "smash" margin */ |
|
GLOBAL(int,mathsmashmargin,SMASHMARGIN); /* needed for \text{if $n-m$ even}*/ |
GLOBAL(int,issmashdelta,1); /* true if smashmargin is a delta */ |
GLOBAL(int,issmashdelta,1); /* true if smashmargin is a delta */ |
GLOBAL(int,blanksignal,(-991234)); /*rastsmash signal right-hand blank*/ |
GLOBAL(int,isexplicitsmash,0); /* true if \smash explicitly given */ |
GLOBAL(int,istransparent,1); /*true to set background transparent*/ |
GLOBAL(int,smashcheck,SMASHCHECK); /* check if terms safe to smash */ |
|
GLOBAL(int,isscripted,0); /* is (lefthand) term text-scripted*/ |
|
GLOBAL(int,isdelimscript,0); /* is \right delim text-scripted */ |
|
GLOBAL(int,issmashokay,0); /*is leading char okay for smashing*/ |
|
#define BLANKSIGNAL (-991234) /*rastsmash signal right-hand blank*/ |
|
GLOBAL(int,blanksignal,BLANKSIGNAL); /*rastsmash signal right-hand blank*/ |
|
GLOBAL(int,blanksymspace,0); /* extra (or too much) space wanted*/ |
|
GLOBAL(int,istransparent,ISTRANSPARENT);/* true sets background transparent*/ |
GLOBAL(int,fgred,FGRED); |
GLOBAL(int,fgred,FGRED); |
GLOBAL(int,fggreen,FGGREEN); |
GLOBAL(int,fggreen,FGGREEN); |
GLOBAL(int,fgblue,FGBLUE); /* fg r,g,b */ |
GLOBAL(int,fgblue,FGBLUE); /* fg r,g,b */ |
GLOBAL(int,bgred,BGRED); |
GLOBAL(int,bgred,BGRED); |
GLOBAL(int,bggreen,BGGREEN); |
GLOBAL(int,bggreen,BGGREEN); |
GLOBAL(int,bgblue,BGBLUE); /* bg r,g,b */ |
GLOBAL(int,bgblue,BGBLUE); /* bg r,g,b */ |
|
GLOBAL(double,gammacorrection,GAMMA); /* gamma correction */ |
|
GLOBAL(int,isplusblank,ISPLUSBLANK); /*interpret +'s in query as blanks?*/ |
GLOBAL(int,isblackonwhite,ISBLACKONWHITE); /*1=black on white,0=reverse*/ |
GLOBAL(int,isblackonwhite,ISBLACKONWHITE); /*1=black on white,0=reverse*/ |
GLOBAL(char,exprprefix[256],PREFIX); /* prefix prepended to expressions */ |
GLOBAL(char,exprprefix[256],PREFIX); /* prefix prepended to expressions */ |
GLOBAL(int,aaalgorithm,AAALGORITHM); /* for lp, 1=aalowpass, 2 =aapnm */ |
GLOBAL(int,aaalgorithm,AAALGORITHM); /* for lp, 1=aalowpass, 2 =aapnm */ |
|
GLOBAL(int,maxfollow,MAXFOLLOW); /* aafollowline() maxturn parameter*/ |
GLOBAL(int,fgalias,1); |
GLOBAL(int,fgalias,1); |
GLOBAL(int,fgonly,0); |
GLOBAL(int,fgonly,0); |
GLOBAL(int,bgalias,0); |
GLOBAL(int,bgalias,0); |
Line 620 GLOBAL(subraster,*workingbox,(subraster
|
Line 721 GLOBAL(subraster,*workingbox,(subraster
|
GLOBAL(int,isreplaceleft,0); /* true to replace leftexpression */ |
GLOBAL(int,isreplaceleft,0); /* true to replace leftexpression */ |
GLOBAL(subraster,*leftexpression,(subraster *)NULL); /*rasterized so far*/ |
GLOBAL(subraster,*leftexpression,(subraster *)NULL); /*rasterized so far*/ |
GLOBAL(mathchardef,*leftsymdef,NULL); /* mathchardef for preceding symbol*/ |
GLOBAL(mathchardef,*leftsymdef,NULL); /* mathchardef for preceding symbol*/ |
|
GLOBAL(int,fraccenterline,NOVALUE); /* baseline for punct. after \frac */ |
|
/*GLOBAL(int,currentcharclass,NOVALUE);*/ /*primarily to check for PUNCTION*/ |
GLOBAL(int,iscaching,ISCACHING); /* true if caching images */ |
GLOBAL(int,iscaching,ISCACHING); /* true if caching images */ |
GLOBAL(char,cachepath[256],CACHEPATH); /* relative path to cached files */ |
GLOBAL(char,cachepath[256],CACHEPATH); /* relative path to cached files */ |
|
GLOBAL(int,isemitcontenttype,1); /* true to emit mime content-type */ |
|
int iscachecontenttype = 0; /* true to cache mime content-type */ |
|
char contenttype[2048] = "\000"; /* content-type:, etc buffer */ |
GLOBAL(char,pathprefix[256],PATHPREFIX); /*prefix for \input,\counter paths*/ |
GLOBAL(char,pathprefix[256],PATHPREFIX); /*prefix for \input,\counter paths*/ |
/*GLOBAL(int,iswindows,ISWINDOWS);*/ /* true if compiled for ms windows */ |
/*GLOBAL(int,iswindows,ISWINDOWS);*/ /* true if compiled for ms windows */ |
|
|
Line 639 miscellaneous macros
|
Line 745 miscellaneous macros
|
{ char *p; while((p=strchr((s),(c)))!=NULL) strcpy(p,p+1); } else |
{ char *p; while((p=strchr((s),(c)))!=NULL) strcpy(p,p+1); } else |
#define slower(s) if ((s)!=NULL) /* lowercase all chars in s */ \ |
#define slower(s) if ((s)!=NULL) /* lowercase all chars in s */ \ |
{ char *p=(s); while(*p!='\000'){*p=tolower(*p); p++;} } else |
{ char *p=(s); while(*p!='\000'){*p=tolower(*p); p++;} } else |
|
/*subraster *subrastcpy();*/ /* need global module declaration */ |
|
/*#define spnosmash(sp) if (sp->type==CHARASTER) sp=subrastcpy(sp); \*/ |
|
/* sp->type=blanksignal*/ |
|
|
/* --- |
/* --- |
* PART2 |
* PART2 |
Line 982 newsp->image = newrp; /* new raster im
|
Line 1091 newsp->image = newrp; /* new raster im
|
switch ( sp->type ) /* set new raster image type */ |
switch ( sp->type ) /* set new raster image type */ |
{ case STRINGRASTER: case CHARASTER: newsp->type = STRINGRASTER; break; |
{ case STRINGRASTER: case CHARASTER: newsp->type = STRINGRASTER; break; |
case ASCIISTRING: newsp->type = ASCIISTRING; break; |
case ASCIISTRING: newsp->type = ASCIISTRING; break; |
|
case FRACRASTER: newsp->type = FRACRASTER; break; |
|
case BLANKSIGNAL: newsp->type = blanksignal; break; |
case IMAGERASTER: default: newsp->type = IMAGERASTER; break; } |
case IMAGERASTER: default: newsp->type = IMAGERASTER; break; } |
/* --- return copy of sp to caller --- */ |
/* --- return copy of sp to caller --- */ |
end_of_job: |
end_of_job: |
Line 995 end_of_job:
|
Line 1106 end_of_job:
|
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: rp (I) ptr to raster struct to be rotated |
* Arguments: rp (I) ptr to raster struct to be rotated |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( raster * ) ptr to new raster rotated ralative to rp, |
* Returns: ( raster * ) ptr to new raster rotated relative to rp, |
* or NULL for any error. |
* or NULL for any error. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Notes: o An underbrace is } rotated 90 degrees clockwise, |
* Notes: o An underbrace is } rotated 90 degrees clockwise, |
Line 1028 return ( rotated ); /* return rotated
|
Line 1139 return ( rotated ); /* return rotated
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rastref ( rp, axis ) |
|
* Purpose: reflects rp, horizontally about y-axis |_ becomes _| if axis=1 |
|
* or vertically about x-axis M becomes W if axis=2. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) ptr to raster struct to be reflected |
|
* axis (I) int containing 1 for horizontal reflection, |
|
* or 2 for vertical |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( raster * ) ptr to new raster reflected relative to rp, |
|
* or NULL for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
raster *rastref ( raster *rp, int axis ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
raster *new_raster(), *reflected=NULL; /* reflected raster back to caller */ |
|
int height = rp->height, irow, /* height, row index */ |
|
width = rp->width, icol, /* width, column index */ |
|
pixsz = rp->pixsz; /* #bits per pixel */ |
|
/* ------------------------------------------------------------------------- |
|
allocate reflected raster and fill it |
|
-------------------------------------------------------------------------- */ |
|
/* --- allocate reflected raster with same width, height --- */ |
|
if ( axis==1 || axis==2 ) /* first validate axis arg */ |
|
if ( (reflected = new_raster(width,height,pixsz)) /* same width, height */ |
|
!= NULL ) /* check that allocation succeeded */ |
|
/* --- fill reflected raster --- */ |
|
for ( irow=0; irow<height; irow++ ) /* for each row of rp */ |
|
for ( icol=0; icol<width; icol++ ) { /* and each column of rp */ |
|
int value = getpixel(rp,irow,icol); |
|
if ( axis == 1 ) { setpixel(reflected,irow,width-1-icol,value); } |
|
if ( axis == 2 ) { setpixel(reflected,height-1-irow,icol,value); } } |
|
return ( reflected ); /*return reflected raster to caller*/ |
|
} /* --- end-of-function rastref() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: rastput ( target, source, top, left, isopaque ) |
* Function: rastput ( target, source, top, left, isopaque ) |
* Purpose: Overlays source onto target, |
* Purpose: Overlays source onto target, |
* with the 0,0-bit of source onto the top,left-bit of target. |
* with the 0,0-bit of source onto the top,left-bit of target. |
Line 1081 else
|
Line 1233 else
|
if ( isfatal ) goto end_of_job; /* abort if error is fatal */ |
if ( isfatal ) goto end_of_job; /* abort if error is fatal */ |
else break; } /*or just go on to next row*/ |
else break; } /*or just go on to next row*/ |
if ( tpix >= 0 ) /* bounds check okay */ |
if ( tpix >= 0 ) /* bounds check okay */ |
if ( svalue!=0 || isopaque ) /*got dark or opaque source*/ |
if ( svalue!=0 || isopaque ) { /*got dark or opaque source*/ |
setpixel(target,irow+top,icol+left,svalue); /*overlay source on target*/ |
setpixel(target,irow+top,icol+left,svalue); }/*overlay source on targ*/ |
} /* --- end-of-for(icol) --- */ |
} /* --- end-of-for(icol) --- */ |
} /* --- end-of-for(irow) --- */ |
} /* --- end-of-for(irow) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 1228 int height=0, width=0, pixsz=0, base=0;
|
Line 1380 int height=0, width=0, pixsz=0, base=0;
|
int issmash = (smashmargin!=0?1:0), /* true to "squash" sp1||sp2 */ |
int issmash = (smashmargin!=0?1:0), /* true to "squash" sp1||sp2 */ |
isopaque = (issmash?0:1), /* not oppaque if smashing */ |
isopaque = (issmash?0:1), /* not oppaque if smashing */ |
rastsmash(), isblank=0, nsmash=0, /* #cols to smash */ |
rastsmash(), isblank=0, nsmash=0, /* #cols to smash */ |
oldsmashmargin = smashmargin; /* save original smashmargin */ |
oldsmashmargin = smashmargin, /* save original smashmargin */ |
|
oldblanksymspace = blanksymspace, /* save original blanksymspace */ |
|
oldnocatspace = isnocatspace; /* save original isnocatspace */ |
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 1238 int class1 = (symdef1==NULL?ORDINARY:sym
|
Line 1392 int class1 = (symdef1==NULL?ORDINARY:sym
|
smash2 = (symdef2!=NULL)&&(class2==ORDINARY||class2==VARIABLE|| |
smash2 = (symdef2!=NULL)&&(class2==ORDINARY||class2==VARIABLE|| |
class2==OPENING||class2==CLOSING||class2==PUNCTION), |
class2==OPENING||class2==CLOSING||class2==PUNCTION), |
space = fontsize/2+1; /* #cols between sp1 and sp2 */ |
space = fontsize/2+1; /* #cols between sp1 and sp2 */ |
|
int isfrac = (type1 == FRACRASTER /* sp1 is a \frac */ |
|
&& class2 == PUNCTION); /* and sp2 is punctuation */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Initialization |
Initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 1245 Initialization
|
Line 1401 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 */ |
if ( !iscatspace ) space=0; /* spacing explicitly turned off */ |
if ( isnocatspace > 0 ) { /* spacing explicitly turned off */ |
|
space = 0; /* reset space */ |
|
isnocatspace--; } /* and decrement isnocatspace flag */ |
|
if ( 0 && sp1->type == BLANKSIGNAL ) space=0; /*implicitly turn off spacing*/ |
|
if ( sp1->type==BLANKSIGNAL && sp2->type==BLANKSIGNAL ) /* both blank */ |
|
space = 0; /* no extra space between spaces */ |
|
if ( sp2->type != BLANKSIGNAL ) /* not a blank space signal */ |
|
if ( blanksymspace != 0 ) { /* and we have a space adjustment */ |
|
space = max2(0,space+blanksymspace); /* adjust as much as possible */ |
|
blanksymspace = 0; } /* and reset adjustment */ |
|
if ( msgfp!=NULL && msglevel>=999 ) /* display space results */ |
|
{ fprintf(msgfp,"rastcat> space=%d, blanksymspace=%d, isnocatspace=%d\n", |
|
space,oldblanksymspace,oldnocatspace); fflush(msgfp); } |
/* --- determine smash --- */ |
/* --- determine smash --- */ |
if ( !isstring ) /* don't smash strings */ |
if ( !isstring && !isfrac ) /* don't smash strings or \frac's */ |
if ( issmash ) { /* raster smash wanted */ |
if ( issmash ) { /* raster smash wanted */ |
int maxsmash = rastsmash(sp1,sp2), /* calculate max smash space */ |
int maxsmash = rastsmash(sp1,sp2), /* calculate max smash space */ |
margin = smashmargin; /* init margin without delta */ |
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 |
|
&& type1!=FRACRASTER && type2!=FRACRASTER ) ) |
/*maxsmash = 0;*/ /* turn off smash */ |
/*maxsmash = 0;*/ /* turn off smash */ |
margin = max2(space-1,0); /* force small smashmargin */ |
margin = max2(space-1,0); /* force small smashmargin */ |
else /* adjust for delta if images */ |
else /* adjust for delta if images */ |
Line 1309 if ( (sp=new_subraster(width,height,pixs
|
Line 1478 if ( (sp=new_subraster(width,height,pixs
|
/* 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);*/ |
sp->type = /*type2;*//*(type1==type2?type2:IMAGERASTER);*/ |
(type2!=CHARASTER? type2 : (type1!=CHARASTER?type1:STRINGRASTER)); |
(type2!=CHARASTER? type2 : |
|
(type1!=CHARASTER&&type1!=BLANKSIGNAL |
|
&&type1!=FRACRASTER?type1:IMAGERASTER)); |
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 1334 if ( msgfp!=NULL && msglevel>=9999 )
|
Line 1505 if ( msgfp!=NULL && msglevel>=9999 )
|
{ type_raster(sp->image,msgfp); /* display composite raster */ |
{ type_raster(sp->image,msgfp); /* display composite raster */ |
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
if ( !isstring ) |
if ( !isstring ) |
rastput (rp, sp2->image, base-base2, /* overlay right-hand */ |
{ int fracbase = ( isfrac? /* baseline for punc after \frac */ |
max2(0,width1+space-nsmash), isopaque); /* minus any smashed space */ |
max2(fraccenterline,base2):base ); /*adjust baseline or use original*/ |
|
rastput (rp, sp2->image, fracbase-base2, /* overlay right-hand */ |
|
max2(0,width1+space-nsmash), isopaque); /* minus any smashed space */ |
|
if ( 1 && type1 == FRACRASTER /* we're done with \frac image */ |
|
&& type2 != FRACRASTER ) /* unless we have \frac\frac */ |
|
fraccenterline = NOVALUE; /* so reset centerline signal */ |
|
if ( fraccenterline != NOVALUE ) /* sp2 is a fraction */ |
|
fraccenterline += (base-base2); } /* so adjust its centerline */ |
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 1597 find minimum separation
|
Line 1775 find minimum separation
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
for ( irow2=top2; irow2<=bot2; irow2++ ) { /* check each row inside sp2 */ |
for ( irow2=top2; irow2<=bot2; irow2++ ) { /* check each row inside sp2 */ |
int margin1, margin2=firstcol2[irow2]; /* #cols to first set pixel */ |
int margin1, margin2=firstcol2[irow2]; /* #cols to first set pixel */ |
if ( margin2 != blanksignal ) /* irow2 not an empty/blank row */ |
if ( margin2 != blanksignal ) { /* irow2 not an empty/blank row */ |
for ( irow1=max2(irow2-smin,top1); ; irow1++ ) |
for ( irow1=max2(irow2-smin,top1); ; irow1++ ) |
if ( irow1 > min2(irow2+smin,bot1) ) break; /* upper bound check */ |
if ( irow1 > min2(irow2+smin,bot1) ) break; /* upper bound check */ |
else |
else |
Line 1607 for ( irow2=top2; irow2<=bot2; irow2++ )
|
Line 1785 for ( irow2=top2; irow2<=bot2; irow2++ )
|
if ( dy>smashmargin && 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) --- */ |
|
} /* --- end-of-if(margin2!=blanksignal) --- */ |
if ( smin<2 ) goto end_of_job; /* can't smash */ |
if ( smin<2 ) goto end_of_job; /* can't smash */ |
} /* --- end-of-for(irow2) --- */ |
} /* --- end-of-for(irow2) --- */ |
/*nsmash = min2(xmin,width2);*/ /* permissible smash */ |
/*nsmash = min2(xmin,width2);*/ /* permissible smash */ |
Line 1630 end_of_job:
|
Line 1809 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rastsmashcheck ( term ) |
|
* Purpose: Check an exponent term to see if its leading symbol |
|
* would make smashing dangerous |
|
* -------------------------------------------------------------------------- |
|
* Arguments: term (I) char * to null-terminated string |
|
* containing right-hand exponent term about to |
|
* be smashed against existing left-hand. |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 1 if it's okay to smash term, or |
|
* 0 if smash is dangerous. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int rastsmashcheck ( char *term ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int isokay = 0; /* 1 to signal okay to caller */ |
|
static char nosmashchars[64] = "-.,="; /* don't smash these leading chars */ |
|
static char *nosmashstrs[64] = { "\\frac", NULL }; /* or leading strings */ |
|
static char *grayspace[64] = { "\\tiny", "\\small", "\\normalsize", |
|
"\\large", "\\Large", "\\LARGE", "\\huge", "\\Huge", NULL }; |
|
char *expression = term; /* local ptr to beginning of expression */ |
|
char *token = NULL; int i; /* token = nosmashstrs[i] or grayspace[i] */ |
|
/* ------------------------------------------------------------------------- |
|
see if smash check enabled |
|
-------------------------------------------------------------------------- */ |
|
if ( smashcheck < 1 ) { /* no smash checking wanted */ |
|
if ( smashcheck >= 0 ) /* -1 means check should always fail */ |
|
isokay = 1; /* otherwise (if 0), signal okay to smash */ |
|
goto end_of_job; } /* return to caller */ |
|
/* ------------------------------------------------------------------------- |
|
skip leading white and gray space |
|
-------------------------------------------------------------------------- */ |
|
/* --- first check input --- */ |
|
if ( term == NULL ) goto end_of_job; /* no input so return 0 to caller */ |
|
if ( *term == '\000' ) goto end_of_job; /* ditto for empty string */ |
|
/* --- skip leading white space --- */ |
|
skipwhite(term); /* skip leading white sapce */ |
|
if ( *term == '\000' ) goto end_of_job; /* nothing but white space */ |
|
/* --- skip leading gray space --- */ |
|
skipgray: |
|
for ( i=0; (token=grayspace[i]) != NULL; i++ ) /* check each grayspace */ |
|
if ( strncmp(term,token,strlen(token)) == 0 ) { /* found grayspace */ |
|
term += strlen(token); /* skip past this grayspace token */ |
|
if ( *term == '\000' ) { /* nothing left so quit */ |
|
if ( msgfp!=NULL && msglevel >= 99 ) /* display for debugging */ |
|
fprintf(msgfp,"rastsmashcheck> only grayspace in %.32s\n",expression); |
|
goto end_of_job; } |
|
goto skipgray; } /* restart grayspace check from beginning */ |
|
/* ------------------------------------------------------------------------- |
|
check for leading no-smash single char |
|
-------------------------------------------------------------------------- */ |
|
/* --- don't smash if term begins with a "nosmash" char --- */ |
|
if ( (token=strchr(nosmashchars,*term)) != NULL ) { |
|
if ( msgfp!=NULL && msglevel >= 99 ) /* display for debugging */ |
|
fprintf(msgfp,"rastsmashcheck> char %.1s found in %.32s\n",token,term); |
|
goto end_of_job; } |
|
/* ------------------------------------------------------------------------- |
|
check for leading no-smash token |
|
-------------------------------------------------------------------------- */ |
|
for ( i=0; (token=nosmashstrs[i]) != NULL; i++ ) /* check each nosmashstr */ |
|
if ( strncmp(term,token,strlen(token)) == 0 ) { /* found a nosmashstr */ |
|
if ( msgfp!=NULL && msglevel >= 99 ) /* display for debugging */ |
|
fprintf(msgfp,"rastsmashcheck> token %s found in %.32s\n",token,term); |
|
goto end_of_job; } /* so don't smash term */ |
|
/* ------------------------------------------------------------------------- |
|
back to caller |
|
-------------------------------------------------------------------------- */ |
|
isokay = 1; /* no problem, so signal okay to smash */ |
|
end_of_job: |
|
if ( msgfp!=NULL && msglevel >= 999 ) /* display for debugging */ |
|
fprintf(msgfp,"rastsmashcheck> returning isokay=%d for \"%.32s\"\n", |
|
isokay,(expression==NULL?"<no input>":expression)); |
|
return ( isokay ); /* back to caller with 1 if okay to smash */ |
|
} /* --- end-of-function rastsmashcheck() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: accent_subraster ( accent, width, height, pixsz ) |
* Function: accent_subraster ( accent, width, height, pixsz ) |
* Purpose: Allocate a new subraster of width x height |
* Purpose: Allocate a new subraster of width x height |
* (or maybe different dimensions, depending on accent), |
* (or maybe different dimensions, depending on accent), |
Line 1779 switch ( accent )
|
Line 2039 switch ( accent )
|
if we constructed accent raster okay, embed it in a subraster and return it |
if we constructed accent raster okay, embed it in a subraster and return it |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- if all okay, allocate subraster to contain constructed raster --- */ |
/* --- if all okay, allocate subraster to contain constructed raster --- */ |
if ( rp != NULL ) /* accent raster constructed okay */ |
if ( rp != NULL ) { /* accent raster constructed okay */ |
if ( (sp=new_subraster(0,0,0)) /* allocate subraster "envelope" */ |
if ( (sp=new_subraster(0,0,0)) /* allocate subraster "envelope" */ |
== NULL ) /* and if we fail to allocate */ |
== NULL ) /* and if we fail to allocate */ |
delete_raster(rp); /* free now-unneeded raster */ |
delete_raster(rp); /* free now-unneeded raster */ |
Line 1789 if ( rp != NULL ) /* accent raster con
|
Line 2049 if ( rp != NULL ) /* accent raster con
|
sp->image = rp; /* raster we just constructed */ |
sp->image = rp; /* raster we just constructed */ |
sp->size = (-1); /* can't set font size here */ |
sp->size = (-1); /* can't set font size here */ |
sp->baseline = 0; } /* can't set baseline here */ |
sp->baseline = 0; } /* can't set baseline here */ |
|
} /* --- end-of-if(rp!=NULL) --- */ |
/* --- return subraster containing desired accent to caller --- */ |
/* --- return subraster containing desired accent to caller --- */ |
return ( sp ); /* return accent or NULL to caller */ |
return ( sp ); /* return accent or NULL to caller */ |
} /* --- end-of-function accent_subraster() --- */ |
} /* --- end-of-function accent_subraster() --- */ |
Line 1848 for ( irow=0; irow<height; irow++ ) /*
|
Line 2109 for ( irow=0; irow<height; irow++ ) /*
|
if ( drctn >= 0 ) /* right arrowhead wanted */ |
if ( drctn >= 0 ) /* right arrowhead wanted */ |
for ( icol=0; icol<thickness; icol++ ) /* for arrowhead thickness */ |
for ( icol=0; icol<thickness; icol++ ) /* for arrowhead thickness */ |
{ ipix = ((irow+1)*width - 1) - delta - icol; /* rightmost-delta-icol */ |
{ ipix = ((irow+1)*width - 1) - delta - icol; /* rightmost-delta-icol */ |
if ( ipix >= 0 ) /* bounds check */ |
if ( ipix >= 0 ) { /* bounds check */ |
if ( pixsz == 1 ) /* have a bitmap */ |
if ( pixsz == 1 ) /* have a bitmap */ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
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*/ |
/* --- left arrowhead (same as right except for ipix calculation) --- */ |
/* --- left arrowhead (same as right except for ipix calculation) --- */ |
if ( drctn <= 0 ) /* left arrowhead wanted */ |
if ( drctn <= 0 ) /* left arrowhead wanted */ |
for ( icol=0; icol<thickness; icol++ ) /* for arrowhead thickness */ |
for ( icol=0; icol<thickness; icol++ ) /* for arrowhead thickness */ |
{ ipix = irow*width + delta + icol; /* leftmost bit+delta+icol */ |
{ ipix = irow*width + delta + icol; /* leftmost bit+delta+icol */ |
if ( ipix < npix ) /* bounds check */ |
if ( ipix < npix ) { /* bounds check */ |
if ( pixsz == 1 ) /* have a bitmap */ |
if ( pixsz == 1 ) /* have a bitmap */ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
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(irow) --- */ |
end_of_job: |
end_of_job: |
return ( arrowsp ); /*back to caller with arrow or NULL*/ |
return ( arrowsp ); /*back to caller with arrow or NULL*/ |
Line 1924 for ( icol=0; icol<width; icol++ ) /* f
|
Line 2185 for ( icol=0; icol<width; icol++ ) /* f
|
if ( drctn >= 0 ) /* up arrowhead wanted */ |
if ( drctn >= 0 ) /* up arrowhead wanted */ |
for ( irow=0; irow<thickness; irow++ ) /* for arrowhead thickness */ |
for ( irow=0; irow<thickness; irow++ ) /* for arrowhead thickness */ |
{ ipix = (irow+delta)*width + icol; /* leftmost+icol */ |
{ ipix = (irow+delta)*width + icol; /* leftmost+icol */ |
if ( ipix < npix ) /* bounds check */ |
if ( ipix < npix ) { /* bounds check */ |
if ( pixsz == 1 ) /* have a bitmap */ |
if ( pixsz == 1 ) /* have a bitmap */ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
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*/ |
/* --- down arrowhead (same as up except for ipix calculation) --- */ |
/* --- down arrowhead (same as up except for ipix calculation) --- */ |
if ( drctn <= 0 ) /* down arrowhead wanted */ |
if ( drctn <= 0 ) /* down arrowhead wanted */ |
for ( irow=0; irow<thickness; irow++ ) /* for arrowhead thickness */ |
for ( irow=0; irow<thickness; irow++ ) /* for arrowhead thickness */ |
{ ipix = (height-1-delta-irow)*width + icol; /* leftmost + icol */ |
{ ipix = (height-1-delta-irow)*width + icol; /* leftmost + icol */ |
if ( ipix > 0 ) /* bounds check */ |
if ( ipix > 0 ) { /* bounds check */ |
if ( pixsz == 1 ) /* have a bitmap */ |
if ( pixsz == 1 ) /* have a bitmap */ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
setlongbit((arrowsp->image)->pixmap,ipix);/*turn on arrowhead bit*/ |
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(icol) --- */ |
} /* --- 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*/ |
Line 1961 end_of_job:
|
Line 2222 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 |
* 3 for solid rule with corners removed (bevel) |
|
* 4 for strut (nothing drawn) |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* 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 1981 int irow=0, icol=0; /* indexes over rp
|
Line 2243 int irow=0, icol=0; /* indexes over rp
|
int ipix = 0, /* 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 */ |
|
bevel=99/*3*/, strut=4; /* type for bevel (turned off), strut */ |
int dashlen=3, spacelen=2, /* #pixels for dash followed by space */ |
int dashlen=3, spacelen=2, /* #pixels for dash followed by space */ |
isdraw=1; /* true when drawing dash (init for solid) */ |
isdraw=1; /* true when drawing dash (init for solid) */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Check args |
Check args |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( rp == (raster *)NULL ) /* no raster arg supplied */ |
if ( rp == (raster *)NULL ) { /* no raster arg supplied */ |
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 ( type == bevel ) /* remove corners of solid box */ |
if ( width<3 || height<3 ) type=0; /* too small to remove corners */ |
if ( width<3 || height<3 ) type=0; /* too small to remove corners */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Fill line/box |
Fill line/box |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
for ( irow=top; irow<top+height; irow++ ) /*each scan line*/ |
if ( width > 0 ) /* zero width implies strut*/ |
|
for ( irow=top; irow<top+height; irow++ ) /* for each scan line */ |
{ |
{ |
|
if ( type == strut ) isdraw = 0; /* draw nothing for strut */ |
if ( type == vdash ) /*set isdraw for vert dash*/ |
if ( type == vdash ) /*set isdraw for vert dash*/ |
isdraw = (((irow-top)%(dashlen+spacelen)) < dashlen); |
isdraw = (((irow-top)%(dashlen+spacelen)) < dashlen); |
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 ( type == bevel ) { /* remove corners of box */ |
if ( (irow==top && icol==left) /* top-left corner */ |
if ( (irow==top && icol==left) /* top-left corner */ |
|| (irow==top && icol>=left+width-1) /* top-right 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) /* bottom-left corner */ |
|| (irow>=top+height-1 && icol>=left+width-1) ) /* bottom-right */ |
|| (irow>=top+height-1 && icol>=left+width-1) ) /* bottom-right */ |
isdraw = 0; else isdraw = 1; /*set isdraw to skip corner*/ |
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 */ |
if ( isfatal ) goto end_of_job; /* abort if error is fatal */ |
if ( isfatal ) goto end_of_job; /* abort if error is fatal */ |
else break; /*or just go on to next row*/ |
else break; /*or just go on to next row*/ |
else /*ibit is within rp bounds*/ |
else /*ibit is within rp bounds*/ |
if ( isdraw ) /*and we're drawing this bit*/ |
if ( isdraw ) { /*and we're drawing this bit*/ |
if ( rp->pixsz == 1 ) /* have a bitmap */ |
if ( rp->pixsz == 1 ) /* have a bitmap */ |
setlongbit(rp->pixmap,ipix); /* so turn on bit in line */ |
setlongbit(rp->pixmap,ipix); /* so turn on bit in line */ |
else /* should have a bytemap */ |
else /* should have a bytemap */ |
if ( rp->pixsz == 8 ) /* check pixsz for bytemap */ |
if ( rp->pixsz == 8 ) /* check pixsz for bytemap */ |
((unsigned char *)(rp->pixmap))[ipix] = 255; /* set black byte */ |
((unsigned char *)(rp->pixmap))[ipix] = 255; } /* set black byte */ |
} /* --- end-of-for(icol) --- */ |
} /* --- end-of-for(icol) --- */ |
} /* --- end-of-for(irow) --- */ |
} /* --- end-of-for(irow) --- */ |
end_of_job: |
end_of_job: |
Line 2085 int line_recurse(), isrecurse=1; /* true
|
Line 2350 int line_recurse(), isrecurse=1; /* true
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Check args |
Check args |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( rp == (raster *)NULL ) /* no raster arg supplied */ |
if ( rp == (raster *)NULL ) { /* no raster arg supplied */ |
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 */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Initialization |
Initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( msgfp!=NULL && msglevel>=29 ) /* debugging */ |
if ( msgfp!=NULL && msglevel>=29 ) { /* debugging */ |
fprintf(msgfp,"line_raster> row,col0=%d,%d row,col1=%d,%d, thickness=%d\n" |
fprintf(msgfp,"line_raster> row,col0=%d,%d row,col1=%d,%d, thickness=%d\n" |
"\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); fflush(msgfp); } |
/* --- check for recursive line drawing --- */ |
/* --- check for recursive line drawing --- */ |
if ( isrecurse ) { /* drawing lines recursively */ |
if ( isrecurse ) { /* drawing lines recursively */ |
for ( irow=0; irow<thickness; irow++ ) /* each line 1 pixel thick */ |
for ( irow=0; irow<thickness; irow++ ) /* each line 1 pixel thick */ |
Line 2563 Allocations and Declarations
|
Line 2828 Allocations and Declarations
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
raster *new_raster(), *bp=(raster *)NULL; /*raster back to caller*/ |
raster *new_raster(), *bp=(raster *)NULL; /*raster back to caller*/ |
int rastput(); /* overlay rp in new bordered raster */ |
int rastput(); /* overlay rp in new bordered raster */ |
int width = (rp==NULL?0:rp->width), /* height of raster */ |
int width = (rp==NULL?0:rp->width), /* width of raster */ |
height = (rp==NULL?0:rp->height), /* width of raster */ |
height = (rp==NULL?0:rp->height), /* height of raster */ |
istopneg=0, isbotneg=0, /* true if ntop or nbot negative */ |
istopneg=0, isbotneg=0, /* true if ntop or nbot negative */ |
leftmargin = 0; /* adjust width to whole number of bytes */ |
leftmargin = 0; /* adjust width to whole number of bytes */ |
int delete_raster(); /* to free input rp if isdelete is true */ |
int delete_raster(); /* free input rp if isfree is true */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Initialization |
Initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 2627 end_of_job:
|
Line 2892 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: backspace_raster ( rp, nback, pback, minspace, isfree ) |
|
* Purpose: Allocate a new raster containing a copy of input rp, |
|
* but with trailing nback columns removed. |
|
* If minspace>=0 then (at least) that many columns |
|
* of whitespace will be left in place, regardless of nback. |
|
* If minspace<0 then existing black pixels will be deleted |
|
* as required. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster on which a border |
|
* is to be placed |
|
* nback (I) int containing number of columns to |
|
* backspace (>=0) |
|
* pback (O) ptr to int returning #pixels actually |
|
* backspaced (or NULL to not use) |
|
* minspace (I) int containing number of columns |
|
* of whitespace to be left in place |
|
* isfree (I) int containing true to free rp before return |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( raster * ) ptr to backspaced raster, |
|
* or NULL for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o For \! negative space, for \hspace{-10}, etc. |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
raster *backspace_raster ( raster *rp, int nback, int *pback, int minspace, |
|
int isfree ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
raster *new_raster(), *bp=(raster *)NULL; /* raster returned to caller */ |
|
int delete_raster(); /* free input rp if isfree is true */ |
|
int width = (rp==NULL?0:rp->width), /* original width of raster */ |
|
height = (rp==NULL?0:rp->height), /* height of raster */ |
|
mback = nback, /* nback adjusted for minspace */ |
|
newwidth = width, /* adjusted width after backspace */ |
|
icol=0, irow=0; /* col,row index */ |
|
if ( rp == NULL ) goto end_of_job; /* no input given */ |
|
/* ------------------------------------------------------------------------- |
|
locate rightmost column of rp containing ink, and determine backspaced width |
|
-------------------------------------------------------------------------- */ |
|
/* --- locate rightmost column of rp containing ink --- */ |
|
if ( minspace >= 0 ) /* only needed if given minspace */ |
|
for ( icol=width-1; icol>=0; icol-- ) /* find first non-empty col in row */ |
|
for ( irow=0; irow<height; irow++ ) /* for each row inside rp */ |
|
if ( getpixel(rp,irow,icol) != 0 ) { /* found a set pixel */ |
|
int whitecols = (width-1) - icol; /* #cols containing white space */ |
|
mback = min2(nback,max2(0,whitecols-minspace)); /*leave minspace cols*/ |
|
goto gotright; } /* no need to look further */ |
|
/* --- determine width of new backspaced raster --- */ |
|
gotright: /* found col with ink (or rp empty)*/ |
|
if ( mback > width ) mback = width; /* can't backspace before beginning*/ |
|
newwidth = max2(1,width-mback); /* #cols in backspaced raster */ |
|
if ( pback != NULL ) *pback = width-newwidth; /* caller wants #pixels */ |
|
/* ------------------------------------------------------------------------- |
|
allocate new raster and fill it with leftmost cols of rp |
|
-------------------------------------------------------------------------- */ |
|
/* --- allocate backspaced raster --- */ |
|
if ( (bp=new_raster(newwidth,height,rp->pixsz)) /*allocate backspaced raster*/ |
|
== (raster *)NULL ) goto end_of_job; /* and quit if failed */ |
|
/* --- fill new raster --- */ |
|
if ( width-nback > 0 ) /* don't fill 1-pixel wide empty bp*/ |
|
for ( icol=0; icol<newwidth; icol++ ) /* find first non-empty col in row */ |
|
for ( irow=0; irow<height; irow++ ) /* for each row inside rp */ |
|
{ int value = getpixel(rp,irow,icol); /* original pixel at irow,icol */ |
|
setpixel(bp,irow,icol,value); } /* saved in backspaced raster */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with backspaced raster (or null for any error) |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( msgfp!=NULL && msglevel>=999 ) { fprintf(msgfp, /* diagnostics */ |
|
"backspace_raster> nback=%d,minspace=%d,mback=%d, width:old=%d,new=%d\n", |
|
nback,minspace,mback,width,newwidth); fflush(msgfp); } |
|
if ( isfree && bp!=NULL ) delete_raster(rp); /* free original raster */ |
|
return ( bp ); /* back with backspaced or null ptr*/ |
|
} /* --- end-of-function backspace_raster() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: type_raster ( rp, fp ) |
* Function: type_raster ( rp, fp ) |
* Purpose: Emit an ascii dump representing rp, on fp. |
* Purpose: Emit an ascii dump representing rp, on fp. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 2659 initialization
|
Line 3003 initialization
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- redirect null fp --- */ |
/* --- redirect null fp --- */ |
if ( fp == (FILE *)NULL ) fp = stdout; /* default fp to stdout if null */ |
if ( fp == (FILE *)NULL ) fp = stdout; /* default fp to stdout if null */ |
|
if ( msglevel >= 999 ) { fprintf(fp, /* debugging diagnostics */ |
|
"type_raster> width=%d height=%d ...\n", |
|
rp->width,rp->height); fflush(fp); } |
/* --- check for ascii string --- */ |
/* --- check for ascii string --- */ |
if ( isstring /* pixmap has string, not raster */ |
if ( isstring /* pixmap has string, not raster */ |
|| (0 && rp->height==1) ) /* infer input rp is a string */ |
|| (0 && rp->height==1) ) /* infer input rp is a string */ |
Line 3131 for ( ibyte=0; ibyte<nbytes; ibyte++ ) /
|
Line 3478 for ( ibyte=0; ibyte<nbytes; ibyte++ ) /
|
if ( ibyte < nbytes-1) /* not the last byte yet */ |
if ( ibyte < nbytes-1) /* not the last byte yet */ |
{ |
{ |
if ( !isstr ) fprintf(fp,","); /* follow hex number with comma */ |
if ( !isstr ) fprintf(fp,","); /* follow hex number with comma */ |
if ( (ibyte+1)%ncols==0 ) /* need new line after every ncols */ |
if ( (ibyte+1)%ncols==0 ) { /* need new line after every ncols */ |
if ( !isstr ) /* for hex numbers format ... */ |
if ( !isstr ) /* for hex numbers format ... */ |
fprintf(fp,"\n%.*s",col1,stub); /* ...just need newline and stub */ |
fprintf(fp,"\n%.*s",col1,stub); /* ...just need newline and stub */ |
else /* for string format... */ |
else /* for string format... */ |
fprintf(fp,"\"\n%.*s\"",col1,stub); /* ...need closing, opening "s */ |
fprintf(fp,"\"\n%.*s\"",col1,stub); } /*...need closing, opening "s*/ |
} /* --- end-of-if(ibyte<nbytes-1) --- */ |
} /* --- end-of-if(ibyte<nbytes-1) --- */ |
} /* --- end-of-for(ibyte) --- */ |
} /* --- end-of-for(ibyte) --- */ |
if ( isstr ) fprintf(fp,"\""); /* closing " after last line */ |
if ( isstr ) fprintf(fp,"\""); /* closing " after last line */ |
Line 3254 for ( icount=0,bitval=0; icount<ncounts;
|
Line 3601 for ( icount=0,bitval=0; icount<ncounts;
|
{ |
{ |
int nbits = (int)(getbyfmt(format,gf->pixmap,icount)); /*#bits to set*/ |
int nbits = (int)(getbyfmt(format,gf->pixmap,icount)); /*#bits to set*/ |
if ( isrepeat /* we're proxessing repeat counts */ |
if ( isrepeat /* we're proxessing repeat counts */ |
&& nbits == repeatcmds[format-2] ) /* and repeat opcode found */ |
&& nbits == repeatcmds[format-2] ) { /* and repeat opcode found */ |
if ( nrepeats == 0 ) /* recursive repeat is error */ |
if ( nrepeats == 0 ) /* recursive repeat is error */ |
{ nrepeats = (int)(getbyfmt(format,gf->pixmap,icount+1));/*repeat count*/ |
{ nrepeats = (int)(getbyfmt(format,gf->pixmap,icount+1));/*repeat count*/ |
nbits = (int)(getbyfmt(format,gf->pixmap,icount+2)); /*#bits to set*/ |
nbits = (int)(getbyfmt(format,gf->pixmap,icount+2)); /*#bits to set*/ |
icount += 2; } /* bump byte/nibble count */ |
icount += 2; } /* bump byte/nibble count */ |
else /* some internal error occurred */ |
else /* some internal error occurred */ |
if ( msgfp!=NULL && msglevel>=1 ) /* report error */ |
if ( msgfp!=NULL && msglevel>=1 ) /* report error */ |
fprintf(msgfp,"gftobitmap> found embedded repeat command\n"); |
fprintf(msgfp,"gftobitmap> found embedded repeat command\n"); } |
if ( 0 ) |
if ( 0 ) |
fprintf(stdout, |
fprintf(stdout, |
"gftobitmap> icount=%d bitval=%d nbits=%d ibit=%d totbits=%d\n", |
"gftobitmap> icount=%d bitval=%d nbits=%d ibit=%d totbits=%d\n", |
Line 3313 mathchardef *get_symdef ( char *symbol )
|
Line 3660 mathchardef *get_symdef ( char *symbol )
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
mathchardef *symdefs = symtable; /* table of mathchardefs */ |
mathchardef *symdefs = symtable; /* table of mathchardefs */ |
|
int ligdef=0, get_ligature(); /* or we may have a ligature */ |
int idef = 0, /* symdefs[] index */ |
int idef = 0, /* symdefs[] index */ |
bestdef = (-9999); /*index of shortest matching symdef*/ |
bestdef = (-9999); /*index of shortest matching symdef*/ |
int symlen = strlen(symbol), /* length of input symbol */ |
int symlen = strlen(symbol), /* length of input symbol */ |
Line 3342 static char *displaysyms[][2] = { /*xlat
|
Line 3690 static char *displaysyms[][2] = { /*xlat
|
{"\\bigvee", "\\Bigvee"}, |
{"\\bigvee", "\\Bigvee"}, |
{NULL, NULL} }; |
{NULL, NULL} }; |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
|
First check for ligature |
|
-------------------------------------------------------------------------- */ |
|
isligature = 0; /* init signal for no ligature */ |
|
if ( family == CYR10 ) /*only check for cyrillic ligatures*/ |
|
if ( (ligdef=get_ligature(subexprptr,family)) /* check for ligature */ |
|
>= 0 ) /* found a ligature */ |
|
{ bestdef = ligdef; /* set bestdef for ligature */ |
|
isligature = 1; /* signal we found a ligature */ |
|
goto end_of_job; } /* so just give it to caller */ |
|
/* ------------------------------------------------------------------------- |
If in \displaystyle mode, first xlate int to Bigint, etc. |
If in \displaystyle mode, first xlate int to Bigint, etc. |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( isdisplaystyle > 1 ) /* we're in \displaystyle mode */ |
if ( isdisplaystyle > 1 ) /* we're in \displaystyle mode */ |
Line 3364 for ( idef=0; ;idef++ ) /* until trail
|
Line 3722 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 (fontnum==0 /* mathmode, so check every match */ |
if ( (fontnum==0||family==CYR10) /* mathmode, so check every match */ |
|| (0 && istextmode && (!alphasym /* text mode and not alpha symbol */ |
|| (0 && istextmode && (!alphasym /* text mode and not alpha symbol */ |
|| symdefs[idef].handler!=NULL)) /* or text mode and directive */ |
|| symdefs[idef].handler!=NULL)) /* or text mode and directive */ |
|| (symdefs[idef].family==family /* have correct family */ |
|| (symdefs[idef].family==family /* have correct family */ |
Line 3389 if ( bestdef < 0 ) /* failed to look u
|
Line 3747 if ( bestdef < 0 ) /* failed to look u
|
symdef = get_symdef(symbol); /* repeat lookup with fontnum=0 */ |
symdef = get_symdef(symbol); /* repeat lookup with fontnum=0 */ |
fontnum = oldfontnum; /* reset font family */ |
fontnum = oldfontnum; /* reset font family */ |
return symdef; } /* caller gets fontnum=0 lookup */ |
return symdef; } /* caller gets fontnum=0 lookup */ |
if ( msgfp!=NULL && msglevel>=999 ) /* debugging output */ |
end_of_job: |
{ fprintf(msgfp,"get_symdef> symbol=%s matches symtable[%d]=%s\n", |
if ( msgfp!=NULL && msglevel>=999 ) /* debugging output */ |
symbol,bestdef,(bestdef<0?"NotFound":symdefs[bestdef].symbol)); |
{ fprintf(msgfp, |
|
"get_symdef> symbol=%s matches symtable[%d]=%s (isligature=%d)\n", |
|
symbol,bestdef,(bestdef<0?"NotFound":symdefs[bestdef].symbol),isligature); |
fflush(msgfp); } |
fflush(msgfp); } |
return ( (bestdef<0? NULL : &(symdefs[bestdef])) ); /*NULL or best symdef[]*/ |
return ( (bestdef<0? NULL : &(symdefs[bestdef])) );/*NULL or best symdef[]*/ |
} /* --- end-of-function get_symdef() --- */ |
} /* --- end-of-function get_symdef() --- */ |
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: get_ligature ( expression, family ) |
|
* Purpose: returns symtable[] index for ligature |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I) char * containing ligature |
|
* whose corresponding mathchardef is wanted |
|
* family (I) int containing NOVALUE for any family, |
|
* or, e.g., CYR10 for cyrillic, etc. |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) symtable[] index defining ligature, |
|
* or -9999 if no ligature found or for any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int get_ligature ( char *expression, int family ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
mathchardef *symdefs = symtable; /* table of mathchardefs */ |
|
char *ligature = expression /*- 1*/, /* expression ptr */ |
|
*symbol = NULL; /* symdefs[idef].symbol */ |
|
int liglen = strlen(ligature); /* #chars remaining in expression */ |
|
int iscyrfam = (family==CYR10); /* true for cyrillic families */ |
|
int idef = 0, /* symdefs[] index */ |
|
bestdef = (-9999), /*index of longest matching symdef*/ |
|
maxlen=(-9999); /*length of longest matching symdef*/ |
|
/* ------------------------------------------------------------------------- |
|
search symdefs[] in order for first occurrence of symbol |
|
-------------------------------------------------------------------------- */ |
|
if ( !isstring ) { /* no ligatures in "string" mode */ |
|
for ( idef=0; ;idef++ ) /* until trailer record found */ |
|
if ( (symbol=symdefs[idef].symbol) == NULL ) break; /* end-of-table */ |
|
else { /* check against caller's ligature */ |
|
int symlen = strlen(symbol); /* #chars in symbol */ |
|
if ( ( symlen>1 || iscyrfam ) /*ligature >1 char long or cyrillic*/ |
|
&& symlen <= liglen /* and enough remaining chars */ |
|
&& ( *symbol!='\\' || iscyrfam ) /* not escaped or cyrillic */ |
|
&& symdefs[idef].handler == NULL ) /* and not a handler */ |
|
if ( strncmp(ligature,symbol,symlen) == 0 ) /* found match */ |
|
if ( family < 0 /* no family specifies */ |
|
|| symdefs[idef].family == family ) /* or have correct family */ |
|
if ( symlen > maxlen ) /* new longest ligature */ |
|
{ bestdef = idef; /* save index of new best match */ |
|
maxlen = symlen; } /* and save its len for next test */ |
|
} /* --- end-of-if/else(symbol==NULL) --- */ |
|
if ( msgfp!=NULL && msglevel>=999 ) /* debugging output */ |
|
{ fprintf(msgfp,"get_ligature> ligature=%.4s matches symtable[%d]=%s\n", |
|
ligature,bestdef,(bestdef<0?"NotFound":symdefs[bestdef].symbol)); |
|
fflush(msgfp); } |
|
} /* --- end-of-if(!isstring) --- */ |
|
return ( bestdef ); /* -9999 or index of best symdef[] */ |
|
} /* --- end-of-function get_ligature --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: get_chardef ( symdef, size ) |
* Function: get_chardef ( symdef, size ) |
* Purpose: returns chardef ptr containing data for symdef at given size |
* Purpose: returns chardef ptr containing data for symdef at given size |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 3430 char *symptr = NULL; /* look for 1st a
|
Line 3846 char *symptr = NULL; /* look for 1st a
|
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- check symdef --- */ |
/* --- check symdef --- */ |
if ( symdef == NULL ) return ( NULL ); /* get_symdef() probably failed */ |
if ( symdef == NULL ) goto end_of_job; /* get_symdef() probably failed */ |
/* --- get local copy of indexes from symdef --- */ |
/* --- get local copy of indexes from symdef --- */ |
family = symdef->family; /* font family containing symbol */ |
family = symdef->family; /* font family containing symbol */ |
charnum = symdef->charnum; /* char# of symbol within font */ |
charnum = symdef->charnum; /* char# of symbol within font */ |
Line 3462 find font family in table of fonts[]
|
Line 3878 find font family in table of fonts[]
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- look up font family --- */ |
/* --- look up font family --- */ |
for ( ifont=0; ;ifont++ ) /* until trailer record found */ |
for ( ifont=0; ;ifont++ ) /* until trailer record found */ |
if ( fonts[ifont].family < 0 ) return ( NULL ); /* error, no such family */ |
if ( fonts[ifont].family < 0 ) { /* error, no such family */ |
|
if ( msgfp!=NULL && msglevel>=99 ) { /* emit error */ |
|
fprintf(msgfp,"get_chardef> failed to find font family %d\n", |
|
family); fflush(msgfp); } |
|
goto end_of_job; } /* quit if can't find font family*/ |
else if ( fonts[ifont].family == family ) break; /* found font family */ |
else if ( fonts[ifont].family == family ) break; /* found font family */ |
/* --- get local copy of table for this family by size --- */ |
/* --- get local copy of table for this family by size --- */ |
fontdef = fonts[ifont].fontdef; /* font by size */ |
fontdef = fonts[ifont].fontdef; /* font by size */ |
Line 3474 while ( 1 ) /* find size or closest a
|
Line 3894 while ( 1 ) /* find size or closest a
|
if ( fontdef[size] != NULL ) break; /* found available size */ |
if ( fontdef[size] != NULL ) break; /* found available size */ |
else /* adjust size closer to normal */ |
else /* adjust size closer to normal */ |
if ( size == NORMALSIZE /* already normal so no more sizes,*/ |
if ( size == NORMALSIZE /* already normal so no more sizes,*/ |
|| sizeinc == 0 ) return ( NULL); /* or must be supersampling */ |
|| sizeinc == 0 ) { /* or must be supersampling */ |
|
if ( msgfp!=NULL && msglevel>=99 ) { /* emit error */ |
|
fprintf(msgfp,"get_chardef> failed to find font size %d\n", |
|
size); fflush(msgfp); } |
|
goto end_of_job; } /* quit if can't find desired size */ |
else /*bump size 1 closer to NORMALSIZE*/ |
else /*bump size 1 closer to NORMALSIZE*/ |
size += sizeinc; /* see if adjusted size available */ |
size += sizeinc; /* see if adjusted size available */ |
/* --- ptr to chardef struct --- */ |
/* --- ptr to chardef struct --- */ |
Line 3489 if ( family == CMEX10 ) /* cmex10 need
|
Line 3913 if ( family == CMEX10 ) /* cmex10 need
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
return subraster containing chardef data for symbol in requested size |
return subraster containing chardef data for symbol in requested size |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
return ( gfdata ); /*ptr to chardef for symbol in size*/ |
end_of_job: |
|
if ( msgfp!=NULL && msglevel>=999 ) |
|
{ if (symdef == NULL) fprintf(msgfp,"get_chardef> input symdef==NULL\n"); |
|
else |
|
fprintf(msgfp,"get_chardef> requested symbol=\"%s\" size=%d %s\n", |
|
symdef->symbol,size,(gfdata==NULL?"FAILED":"Succeeded")); |
|
fflush(msgfp); } |
|
return ( gfdata ); /*ptr to chardef for symbol in size*/ |
} /* --- end-of-function get_chardef() --- */ |
} /* --- end-of-function get_chardef() --- */ |
|
|
|
|
Line 3562 if ( (gfdata=get_chardef(symdef,size)) /
|
Line 3993 if ( (gfdata=get_chardef(symdef,size)) /
|
} /* --- end-of-if(sp!=NULL) --- */ |
} /* --- end-of-if(sp!=NULL) --- */ |
end_of_job: |
end_of_job: |
if ( msgfp!=NULL && msglevel>=999 ) |
if ( msgfp!=NULL && msglevel>=999 ) |
{ fprintf(msgfp,"get_charsubraster> requested symbol=\"%s\" baseline=%d\n", |
{ fprintf(msgfp,"get_charsubraster> requested symbol=\"%s\" baseline=%d" |
symdef->symbol, (sp==NULL?0:sp->baseline)); fflush(msgfp); } |
" %s %s\n", symdef->symbol, (sp==NULL?0:sp->baseline), |
|
(sp==NULL?"FAILED":"Succeeded"), (gfdata==NULL?"(gfdata=NULL)":" ")); |
|
fflush(msgfp); } |
return ( sp ); /* back to caller */ |
return ( sp ); /* back to caller */ |
} /* --- end-of-function get_charsubraster() --- */ |
} /* --- end-of-function get_charsubraster() --- */ |
|
|
Line 3683 int defheight, bestheight=9999, /* heigh
|
Line 4116 int defheight, bestheight=9999, /* heigh
|
int iswidth = 0; /* true if best-fit width desired */ |
int iswidth = 0; /* true if best-fit width desired */ |
int isunesc = 0, /* true if leading escape removed */ |
int isunesc = 0, /* true if leading escape removed */ |
issq=0, isoint=0; /* true for \sqcup,etc, \oint,etc */ |
issq=0, isoint=0; /* true for \sqcup,etc, \oint,etc */ |
|
int iscurly = 0; /* true for StMary's curly symbols */ |
char *bigint="bigint", *bigoint="bigoint"; /* substitutes for int, oint */ |
char *bigint="bigint", *bigoint="bigoint"; /* substitutes for int, oint */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
determine if searching height or width, and search symdefs[] for best-fit |
determine if searching height or width, and search symdefs[] for best-fit |
Line 3690 determine if searching height or width,
|
Line 4124 determine if searching height or width,
|
/* --- arg checks --- */ |
/* --- arg checks --- */ |
if ( symlen < 1 ) return (sp); /* no input symbol suplied */ |
if ( symlen < 1 ) return (sp); /* no input symbol suplied */ |
if ( strcmp(symbol,"e") == 0 ) return(sp); /* e causes segfault??? */ |
if ( strcmp(symbol,"e") == 0 ) return(sp); /* e causes segfault??? */ |
|
if ( strstr(symbol,"curly") != NULL ) iscurly=1; /* user wants curly delim */ |
/* --- ignore leading escapes for CMEX10 --- */ |
/* --- ignore leading escapes for CMEX10 --- */ |
if ( 1 ) /* ignore leading escape */ |
if ( 1 ) /* ignore leading escape */ |
if ( (family==CMEX10 || family==CMSYEX) ) { /* for CMEX10 or CMSYEX */ |
if ( (family==CMEX10 || family==CMSYEX) ) { /* for CMEX10 or CMSYEX */ |
Line 3731 for ( idef=0; ;idef++ ) /* until trail
|
Line 4166 for ( idef=0; ;idef++ ) /* until trail
|
if ((symptr=strstr(lcsymbol,unescsymbol)) != NULL) /*found caller's sym*/ |
if ((symptr=strstr(lcsymbol,unescsymbol)) != NULL) /*found caller's sym*/ |
if ( (isoint || strstr(lcsymbol,"oint")==NULL) /* skip unwanted "oint"*/ |
if ( (isoint || strstr(lcsymbol,"oint")==NULL) /* skip unwanted "oint"*/ |
&& (issq || strstr(lcsymbol,"sq")==NULL) ) /* skip unwanted "sq" */ |
&& (issq || strstr(lcsymbol,"sq")==NULL) ) /* skip unwanted "sq" */ |
if ( (deffam == CMSY10 ? /* CMSY10 or not CMSY10 */ |
if ( ( deffam == CMSY10 ? /* CMSY10 or not CMSY10 */ |
symptr == lcsymbol /* caller's sym is a prefix */ |
symptr == lcsymbol /* caller's sym is a prefix */ |
&& deflen == symlen: /* and same length */ |
&& deflen == symlen: /* and same length */ |
symptr == lcsymbol /* caller's sym is a prefix */ |
(iscurly || strstr(lcsymbol,"curly")==NULL) &&/*not unwanted curly*/ |
|| symptr == lcsymbol+deflen-symlen) ) /* or a suffix */ |
(symptr == lcsymbol /* caller's sym is a prefix */ |
|
|| symptr == lcsymbol+deflen-symlen) ) ) /* or a suffix */ |
for ( size=0; size<=LARGESTSIZE; size++ ) /* check all font sizes */ |
for ( size=0; size<=LARGESTSIZE; size++ ) /* check all font sizes */ |
if ( (gfdata=get_chardef(&(symdefs[idef]),size)) != NULL ) /*got one*/ |
if ( (gfdata=get_chardef(&(symdefs[idef]),size)) != NULL ) /*got one*/ |
{ defheight = gfdata->image.height; /* height of this character */ |
{ defheight = gfdata->image.height; /* height of this character */ |
Line 3815 int circle_raster(), /* ellipse for ()'
|
Line 4251 int circle_raster(), /* ellipse for ()'
|
subraster *uparrow_subraster(); /* up/down arrows */ |
subraster *uparrow_subraster(); /* up/down arrows */ |
int isprealloc = 1; /*pre-alloc subraster, except arrow*/ |
int isprealloc = 1; /*pre-alloc subraster, except arrow*/ |
int oldsmashmargin = smashmargin, /* save original smashmargin */ |
int oldsmashmargin = smashmargin, /* save original smashmargin */ |
wascatspace = iscatspace; /* save original iscatspace */ |
wasnocatspace = isnocatspace; /* save original isnocatspace */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 3905 if ( (lp=strchr(symbol,'(')) != NULL /*
|
Line 4341 if ( (lp=strchr(symbol,'(')) != NULL /*
|
/* --- construct brace from pieces --- */ |
/* --- construct brace from pieces --- */ |
if ( isokay ) { /* we have the pieces */ |
if ( isokay ) { /* we have the pieces */ |
/* --- add alignment fillers --- */ |
/* --- add alignment fillers --- */ |
smashmargin = iscatspace = 0; /*turn off rastcat smashing,space*/ |
smashmargin=0; isnocatspace=99; /*turn off rastcat smashing,space*/ |
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
smashmargin = oldsmashmargin; /* reset smashmargin */ |
smashmargin = oldsmashmargin; /* reset smashmargin */ |
iscatspace = wascatspace; /* reset iscatspace */ |
isnocatspace = wasnocatspace; /* reset isnocatspace */ |
/* --- #bars needed between top and bot --- */ |
/* --- #bars needed between top and bot --- */ |
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht)); /* #bars needed */ |
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht)); /* #bars needed */ |
/* --- stack pieces --- */ |
/* --- stack pieces --- */ |
Line 3967 else
|
Line 4403 else
|
/* --- construct brace from pieces --- */ |
/* --- construct brace from pieces --- */ |
if ( isokay ) { /* we have the pieces */ |
if ( isokay ) { /* we have the pieces */ |
/* --- add alignment fillers --- */ |
/* --- add alignment fillers --- */ |
smashmargin = iscatspace = 0; /*turn off rastcat smashing,space*/ |
smashmargin=0; isnocatspace=99; /*turn off rastcat smashing,space*/ |
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
midsym = (midfill>0?rastcat(new_subraster(midfill,1,1),symmid,3):symmid); |
midsym = (midfill>0?rastcat(new_subraster(midfill,1,1),symmid,3):symmid); |
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
smashmargin = oldsmashmargin; /* reset smashmargin */ |
smashmargin = oldsmashmargin; /* reset smashmargin */ |
iscatspace = wascatspace; /* reset iscatspace */ |
isnocatspace = wasnocatspace; /* reset isnocatspace */ |
/* --- #bars needed on each side of mid piece --- */ |
/* --- #bars needed on each side of mid piece --- */ |
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht/2)); /*#bars per side*/ |
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht/2)); /*#bars per side*/ |
/* --- stack pieces --- */ |
/* --- stack pieces --- */ |
Line 4165 static char *prefixes[] = /*e.g., \big
|
Line 4601 static char *prefixes[] = /*e.g., \big
|
"\\big", "\\Big", "\\bigg", "\\Bigg", |
"\\big", "\\Big", "\\bigg", "\\Bigg", |
"\\bigl", "\\Bigl", "\\biggl", "\\Biggl", |
"\\bigl", "\\Bigl", "\\biggl", "\\Biggl", |
"\\bigr", "\\Bigr", "\\biggr", "\\Biggr", NULL }; |
"\\bigr", "\\Bigr", "\\biggr", "\\Biggr", NULL }; |
|
static char *starred[] = /* may be followed by * */ |
|
{ "\\hspace", "\\!", NULL }; |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
just return the next char if it's not \ |
just return the next char if it's not \ |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 4204 for ( iprefix=0; prefixes[iprefix] != NU
|
Line 4642 for ( iprefix=0; prefixes[iprefix] != NU
|
/* --- every \ must be followed by at least one char, e.g., \[ --- */ |
/* --- every \ must be followed by at least one char, e.g., \[ --- */ |
if ( esclen < 1 ) /* \ followed by non-alpha */ |
if ( esclen < 1 ) /* \ followed by non-alpha */ |
*ptoken++ = *expression++; /*copy non-alpha, bump ptrs*/ |
*ptoken++ = *expression++; /*copy non-alpha, bump ptrs*/ |
else { /* normal alpha \sequence */ |
*ptoken = '\000'; /* null-terminate token */ |
/* --- respect spaces in text mode, except first space after \escape --- */ |
/* --- check for \hspace* or other starred commands --- */ |
|
for ( iprefix=0; starred[iprefix] != NULL; iprefix++ ) /* run thru list */ |
|
if ( strcmp(chartoken,starred[iprefix]) == 0 ) /* have an exact match */ |
|
if ( *expression == '*' ) /* follows by a * */ |
|
{ *ptoken++ = *expression++; /* copy * and bump ptr */ |
|
*ptoken = '\000'; /* null-terminate token */ |
|
break; } /* stop checking */ |
|
/* --- respect spaces in text mode, except first space after \escape --- */ |
|
if ( esclen >= 1 ) { /*only for alpha \sequences*/ |
if ( istextmode ) /* in \rm or \it text mode */ |
if ( istextmode ) /* in \rm or \it text mode */ |
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 */ |
|
/* --- back to caller --- */ |
/* --- back to caller --- */ |
end_of_job: |
end_of_job: |
if ( msgfp!=NULL && msglevel>=999 ) |
if ( msgfp!=NULL && msglevel>=999 ) |
Line 4284 int isbrace(); /* check for left,right
|
Line 4729 int isbrace(); /* check for left,right
|
int isanyright = 1; /* true matches any right with left, (...] */ |
int isanyright = 1; /* true matches any right with left, (...] */ |
int isleftdot = 0; /* true if left brace is a \. */ |
int isleftdot = 0; /* true if left brace is a \. */ |
int nestlevel = 1; /* current # of nested braces */ |
int nestlevel = 1; /* current # of nested braces */ |
int subsz=0 /*, maxsubsz=8192*/; /* #chars in returned subexpr[] buffer*/ |
int subsz=0 /*,maxsubsz=MAXSUBXSZ*/; /*#chars in returned subexpr buffer*/ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
skip leading whitespace and just return the next char if it's not { |
skip leading whitespace and just return the next char if it's not { |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 4294 if ( expression == NULL ) return(NULL);
|
Line 4739 if ( expression == NULL ) return(NULL);
|
skipwhite(expression); /* leading whitespace gone */ |
skipwhite(expression); /* leading whitespace gone */ |
if ( *expression == '\000' ) return(NULL); /* nothing left to scan */ |
if ( *expression == '\000' ) return(NULL); /* nothing left to scan */ |
/* --- set maxsubsz --- */ |
/* --- set maxsubsz --- */ |
if ( maxsubsz < 1 ) maxsubsz = 8192; /* input 0 means unlimited */ |
if ( maxsubsz < 1 ) maxsubsz = MAXSUBXSZ-2; /* input 0 means unlimited */ |
/* --- 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 */ |
Line 4309 if ( gotescape ) /* begins with \ */
|
Line 4754 if ( gotescape ) /* begins with \ */
|
return ( pright ); /*back to caller past \right*/ |
return ( pright ); /*back to caller past \right*/ |
} /* --- end-of-if(expression=="\\left") --- */ |
} /* --- 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 */ |
return ( texchar(expression,subexpr) ); /* next char to caller */ |
return ( texchar(expression,subexpr) ); /* next char to caller */ |
else /* --- kludge for super/subscripts to accommodate texscripts() --- */ |
else /* --- kludge for super/subscripts to accommodate texscripts() --- */ |
{ *subexpr++ = *expression; /* signal script */ |
{ *subexpr++ = *expression; /* signal script */ |
*subexpr = '\000'; /* null-terminate subexpr */ |
*subexpr = '\000'; /* null-terminate subexpr */ |
return ( expression ); } /* leave script in stream */ |
return ( expression ); } } /* leave script in stream */ |
/* --- extract left and find matching right delimiter --- */ |
/* --- extract left and find matching right delimiter --- */ |
*leftdelim = *(expression+gotescape); /* the left( in expression */ |
*leftdelim = *(expression+gotescape); /* the left( in expression */ |
if ( (gotescape && *leftdelim == '.') /* we have a left \. */ |
if ( (gotescape && *leftdelim == '.') /* we have a left \. */ |
Line 4333 accumulate chars between balanced {}'s,
|
Line 4778 accumulate chars between balanced {}'s,
|
/* --- first initialize by bumping past left{ or \{ --- */ |
/* --- first initialize by bumping past left{ or \{ --- */ |
if ( isdelim ) *subexpr++ = *expression++; /*caller wants { in subexpr*/ |
if ( isdelim ) *subexpr++ = *expression++; /*caller wants { in subexpr*/ |
else expression++; /* always bump past left{ */ |
else expression++; /* always bump past left{ */ |
if ( gotescape ) /*need to bump another char*/ |
if ( gotescape ) { /*need to bump another char*/ |
if ( isdelim ) *subexpr++ = *expression++; /* caller wants char, too */ |
if ( isdelim ) *subexpr++ = *expression++; /* caller wants char, too */ |
else expression++; /* else just bump past it */ |
else expression++; } /* else just bump past it */ |
/* --- set maximum size for numerical arguments --- */ |
/* --- set maximum size for numerical arguments --- */ |
if ( 0 ) /* check turned on or off? */ |
if ( 0 ) /* check turned on or off? */ |
if ( !isescape && !isdelim ) /*looking for numerical arg*/ |
if ( !isescape && !isdelim ) /*looking for numerical arg*/ |
Line 4348 while ( 1 ) /*until balanced right}
|
Line 4793 while ( 1 ) /*until balanced right}
|
{ if ( 0 && (!isescape && !isdelim) ) /*looking for numerical arg,*/ |
{ if ( 0 && (!isescape && !isdelim) ) /*looking for numerical arg,*/ |
{ expression = origexpression; /* so end-of-string is error*/ |
{ expression = origexpression; /* so end-of-string is error*/ |
subexpr = origsubexpr; } /* so reset all ptrs */ |
subexpr = origsubexpr; } /* so reset all ptrs */ |
if ( isdelim ) /* generate fake right */ |
if ( isdelim ) { /* generate fake right */ |
if ( gotescape ) /* need escaped right */ |
if ( gotescape ) /* need escaped right */ |
{ *subexpr++ = '\\'; /* set escape char */ |
{ *subexpr++ = '\\'; /* set escape char */ |
*subexpr++ = '.'; } /* and fake \right. */ |
*subexpr++ = '.'; } /* and fake \right. */ |
else /* escape not wanted */ |
else /* escape not wanted */ |
*subexpr++ = *rightdelim; /* so fake actual right */ |
*subexpr++ = *rightdelim; } /* so fake actual right */ |
*subexpr = '\000'; /* null-terminate subexpr */ |
*subexpr = '\000'; /* null-terminate subexpr */ |
return ( expression ); } /* back with final token */ |
return ( expression ); } /* back with final token */ |
/* --- check preceding char for escape --- */ |
/* --- check preceding char for escape --- */ |
Line 4469 if ( pright != (char *)NULL ) /* found
|
Line 4914 if ( pright != (char *)NULL ) /* found
|
get rightdelim and subexpr between \left...\right |
get rightdelim and subexpr between \left...\right |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- get delimiter following \right --- */ |
/* --- get delimiter following \right --- */ |
if ( rdelim != NULL ) /* caller wants right delim */ |
if ( rdelim != NULL ) { /* caller wants right delim */ |
if ( pright == (char *)NULL ) /* assume \right. at end of exprssn*/ |
if ( pright == (char *)NULL ) /* assume \right. at end of exprssn*/ |
{ strcpy(rdelim,"."); /* set default \right. */ |
{ strcpy(rdelim,"."); /* set default \right. */ |
sublen = strlen(expression); /* use entire remaining expression */ |
sublen = strlen(expression); /* use entire remaining expression */ |
Line 4477 if ( rdelim != NULL ) /* caller wants
|
Line 4922 if ( rdelim != NULL ) /* caller wants
|
else /* have explicit matching \right */ |
else /* have explicit matching \right */ |
{ skipwhite(pright); /* interpret \right ) as \right) */ |
{ skipwhite(pright); /* interpret \right ) as \right) */ |
pright = texchar(pright,rdelim); /* pull delim from expression */ |
pright = texchar(pright,rdelim); /* pull delim from expression */ |
if ( *rdelim == '\000' ) strcpy(rdelim,"."); } /* or set \right. */ |
if ( *rdelim == '\000' ) strcpy(rdelim,"."); } } /* or set \right. */ |
/* --- get subexpression between \left...\right --- */ |
/* --- get subexpression between \left...\right --- */ |
if ( sublen > 0 ) /* have subexpr */ |
if ( sublen > 0 ) /* have subexpr */ |
if ( subexpr != NULL ) { /* and caller wants it */ |
if ( subexpr != NULL ) { /* and caller wants it */ |
Line 4597 int gotescape = 0, /* true if leading c
|
Line 5042 int gotescape = 0, /* true if leading c
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
check for brace |
check for brace |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- first check for end-of-string --- */ |
/* --- first check for end-of-string or \= ligature --- */ |
if ( *expression == '\000' ) return(0); /* nothing to check */ |
if ( *expression == '\000' /* nothing to check */ |
|
|| isligature ) goto end_of_job; /* have a \= ligature */ |
/* --- check leading char for escape --- */ |
/* --- check leading char 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 */ |
Line 4614 if ( gotbrace && isthischar(*expression,
|
Line 5060 if ( gotbrace && isthischar(*expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
back to caller |
back to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( gotbrace && /* found a brace */ |
end_of_job: |
|
if ( msglevel>=999 && msgfp!=NULL ) |
|
{ fprintf(msgfp,"isbrace> expression=%.8s, gotbrace=%d (isligature=%d)\n", |
|
expression,gotbrace,isligature); fflush(msgfp); } |
|
if ( gotbrace && /* found a brace */ |
( isescape==2 || /* escape irrelevant */ |
( isescape==2 || /* escape irrelevant */ |
gotescape==isescape ) /* un/escaped as requested */ |
gotescape==isescape ) /* un/escaped as requested */ |
) return ( 1 ); return ( 0 ); /* return 1,0 accordingly */ |
) return ( 1 ); return ( 0 ); /* return 1,0 accordingly */ |
Line 4669 process preamble if present
|
Line 5119 process preamble if present
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/*process_preamble:*/ |
/*process_preamble:*/ |
if ( (dollar=strchr(expression,'$')) /* $ signals preceding preamble */ |
if ( (dollar=strchr(expression,'$')) /* $ signals preceding preamble */ |
!= NULL ) /* found embedded $ */ |
!= NULL ) { /* found embedded $ */ |
if ( (prelen = (int)(dollar-expression)) /*#chars in expression preceding $*/ |
if ( (prelen = (int)(dollar-expression)) /*#chars in expression preceding $*/ |
> 0 ) { /* must have preamble preceding $ */ |
> 0 ) { /* must have preamble preceding $ */ |
if ( prelen < 65 ) { /* too long for a prefix */ |
if ( prelen < 65 ) { /* too long for a prefix */ |
Line 4723 if ( (dollar=strchr(expression,'$')) /*
|
Line 5173 if ( (dollar=strchr(expression,'$')) /*
|
isdisplaystyle = 2; /* so set \displaystyle */ |
isdisplaystyle = 2; /* so set \displaystyle */ |
/*goto process_preamble;*/ /*check for preamble after leading $*/ |
/*goto process_preamble;*/ /*check for preamble after leading $*/ |
} /* --- end-of-if/else(prelen>0) --- */ |
} /* --- end-of-if/else(prelen>0) --- */ |
|
} /* --- end-of-if(dollar!=NULL) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
back to caller |
back to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 4758 char *expptr=expression, /* ptr within
|
Line 5209 char *expptr=expression, /* ptr within
|
*tokptr=NULL, /*ptr to token found in expression*/ |
*tokptr=NULL, /*ptr to token found in expression*/ |
*texsubexpr(), argval[8192]; /*parse for macro args after token*/ |
*texsubexpr(), argval[8192]; /*parse for macro args after token*/ |
char *strchange(); /* change leading chars of string */ |
char *strchange(); /* change leading chars of string */ |
|
char *strwstr(); /*use strwstr() instead of strstr()*/ |
char *findbraces(); /*find left { and right } for \atop*/ |
char *findbraces(); /*find left { and right } for \atop*/ |
int idelim=0, /* left- or right-index */ |
int idelim=0, /* left- or right-index */ |
isymbol=0; /*symbols[],rightcomment[],etc index*/ |
isymbol=0; /*symbols[],rightcomment[],etc index*/ |
Line 4820 static struct { char *html; char *args;
|
Line 5272 static struct { char *html; char *args;
|
#ifdef NEWCOMMANDS /* -DNEWCOMMANDS=\"filename.h\" */ |
#ifdef NEWCOMMANDS /* -DNEWCOMMANDS=\"filename.h\" */ |
#include NEWCOMMANDS |
#include NEWCOMMANDS |
#endif |
#endif |
|
/* --------------------------------------- |
|
Cyrillic termchar mimeTeX equivalent... |
|
--------------------------------------- */ |
|
{ "\\\'G", "embed\\","{\\acute{G}}" }, |
|
{ "\\\'g", "embed\\","{\\acute{g}}" }, |
|
{ "\\\'K", "embed\\","{\\acute{K}}" }, |
|
{ "\\\'k", "embed\\","{\\acute{k}}" }, |
|
{ "\\u U", "embed\\","{\\breve{U}}" }, |
|
{ "\\u u", "embed\\","{\\breve{u}}" }, |
|
/*{ "\\\"E", "embed\\","{\\ddot{E}}" },*/ |
|
/*{ "\\\"e", "embed\\","{\\ddot{e}}" },*/ |
|
{ "\\\"I", "embed\\","{\\ddot{\\=I}}" }, |
|
{ "\\\"\\i", "embed\\","{\\ddot{\\=\\i}}" }, |
/* ------------------------------------------ |
/* ------------------------------------------ |
LaTeX Macro #args,default template... |
LaTeX Macro #args,default template... |
------------------------------------------ */ |
------------------------------------------ */ |
Line 4828 static struct { char *html; char *args;
|
Line 5293 static struct { char *html; char *args;
|
{ "\\acute", "1", "{\\stackrel{\\Huge\\acutesym}{#1}}" }, /* \acute */ |
{ "\\acute", "1", "{\\stackrel{\\Huge\\acutesym}{#1}}" }, /* \acute */ |
{ "\\check", "1", "{\\stackrel{\\Huge\\checksym}{#1}}" }, /* \check */ |
{ "\\check", "1", "{\\stackrel{\\Huge\\checksym}{#1}}" }, /* \check */ |
{ "\\breve", "1", "{\\stackrel{\\Huge\\brevesym}{#1}}" }, /* \breve */ |
{ "\\breve", "1", "{\\stackrel{\\Huge\\brevesym}{#1}}" }, /* \breve */ |
|
{ "\\buildrel","3", "{\\stackrel{#1}{#3}}" }, /* ignore #2 = \over */ |
{ "\\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 */ |
/* --------------------------------------- |
/* --------------------------------------- |
Line 4837 static struct { char *html; char *args;
|
Line 5303 static struct { char *html; char *args;
|
{ "&", ";", "&" }, |
{ "&", ";", "&" }, |
{ "<", ";", "<" }, |
{ "<", ";", "<" }, |
{ ">", ";", ">" }, |
{ ">", ";", ">" }, |
|
{ "\", ";", "\\" }, /* backslash */ |
|
{ "&backslash",";", "\\" }, |
{ " ", ";", "~" }, |
{ " ", ";", "~" }, |
{ "¡", ";", "{\\raisebox{-2}{\\rotatebox{180}{!}}}" }, |
{ "¡", ";", "{\\raisebox{-2}{\\rotatebox{180}{!}}}" }, |
{ "¦", ";", "|" }, |
{ "¦", ";", "|" }, |
Line 4858 static struct { char *html; char *args;
|
Line 5326 static struct { char *html; char *args;
|
/* --------------------------------------- |
/* --------------------------------------- |
html tag termchar LaTeX equivalent... |
html tag termchar LaTeX equivalent... |
--------------------------------------- */ |
--------------------------------------- */ |
{ "<br>", NULL, "\\\\" }, |
{ "<br>", "embed\\i","\\\\" }, |
{ "<br/>", NULL, "\\\\" }, |
{ "<br/>", "embed\\i","\\\\" }, |
{ "<Br>", NULL, "\\\\" }, |
/* --------------------------------------- |
{ "<Br/>", NULL, "\\\\" }, |
garbage termchar LaTeX equivalent... |
{ "<BR>", NULL, "\\\\" }, |
--------------------------------------- */ |
{ "<BR/>", NULL, "\\\\" }, |
{ "< TEX >", "embed\\i","\000" }, |
|
{ "< / TEX >","embed\\i","\000" }, |
|
{ "<br / >", "embed\\i","\000" }, |
/* --------------------------------------- |
/* --------------------------------------- |
LaTeX termchar mimeTeX equivalent... |
LaTeX termchar mimeTeX equivalent... |
--------------------------------------- */ |
--------------------------------------- */ |
Line 4949 while ( (leftptr=strstr(expptr,leftcomme
|
Line 5419 while ( (leftptr=strstr(expptr,leftcomme
|
expptr = leftptr+1; /*resume search after this comment*/ |
expptr = leftptr+1; /*resume search after this comment*/ |
} /* --- end-of-while(leftptr!=NULL) --- */ |
} /* --- end-of-while(leftptr!=NULL) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
convert \left( to \( and \right) to \), etc. |
|
-------------------------------------------------------------------------- */ |
|
if ( xlateleft ) /* \left...\right xlation wanted */ |
|
for ( idelim=0; idelim<2; idelim++ ) /* 0 for \left and 1 for \right */ |
|
{ |
|
char *lrstr = (idelim==0?"\\left":"\\right"); /* \left on 1st pass */ |
|
int lrlen = (idelim==0?5:6); /* strlen() of \left or \right */ |
|
char *braces = (idelim==0?LEFTBRACES ".":RIGHTBRACES "."), /*([{<or)]}>*/ |
|
**lrfrom= (idelim==0?leftfrom:rightfrom), /* long braces like \| */ |
|
**lrto = (idelim==0?leftto:rightto), /* xlated to 1-char like = */ |
|
*lrsym = NULL; /* lrfrom[isymbol] */ |
|
expptr = expression; /* start search at beginning */ |
|
while ( (tokptr=strstr(expptr,lrstr)) != NULL ) /* found \left or \right */ |
|
{ |
|
if ( isthischar(*(tokptr+lrlen),braces) ) /* followed by a 1-char brace*/ |
|
{ strcpy(tokptr+1,tokptr+lrlen); /* so squeeze out "left" or "right"*/ |
|
expptr = tokptr+2; } /* and resume search past brace */ |
|
else /* may be a "long" brace like \| */ |
|
{ |
|
expptr = tokptr+lrlen; /*init to resume search past\left\rt*/ |
|
for(isymbol=0; (lrsym=lrfrom[isymbol]) != NULL; isymbol++) |
|
{ int symlen = strlen(lrsym); /* #chars in delim, e.g., 2 for \| */ |
|
if ( memcmp(tokptr+lrlen,lrsym,symlen) == 0 ) /* found long delim*/ |
|
{ strcpy(tokptr+1,tokptr+lrlen+symlen-1); /* squeeze out delim */ |
|
*(tokptr+1) = *(lrto[isymbol]); /* last char now 1-char delim*/ |
|
expptr = tokptr+2 - lrlen; /* resume search past 1-char delim*/ |
|
break; } /* no need to check more lrsym's */ |
|
} /* --- end-of-for(isymbol) --- */ |
|
} /* --- end-of-if/else(isthischar()) --- */ |
|
} /* --- end-of-while(tokptr!=NULL) --- */ |
|
} /* --- end-of-for(idelim) --- */ |
|
/* ------------------------------------------------------------------------- |
|
run thru table, converting all occurrences of each macro to its expansion |
run thru table, converting all occurrences of each macro to its expansion |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
for(isymbol=0; (htmlsym=symbols[isymbol].html) != NULL; isymbol++) |
for(isymbol=0; (htmlsym=symbols[isymbol].html) != NULL; 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 */ |
int isembedded = 0, /* true to xlate even if embedded */ |
|
isstrwstr = 0, /* true to use strwstr() */ |
|
wstrlen = 0; /* length of strwstr() match */ |
char *aleft="{([<|", *aright="})]>|"; /*left,right delims for alg syntax*/ |
char *aleft="{([<|", *aright="})]>|"; /*left,right delims for alg syntax*/ |
|
char embedkeywd[99] = "embed", /* keyword to signal embedded token*/ |
|
embedterm = '\000'; /* char immediately after embed */ |
|
int embedlen = strlen(embedkeywd); /* #chars in embedkeywd */ |
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*/ |
*latexsym = symbols[isymbol].latex; /*latex replacement for htmlsym*/ |
*latexsym = symbols[isymbol].latex; /*latex replacement for htmlsym*/ |
char abuff[8192]; int iarg,nargs=0; /* macro expansion params */ |
char abuff[8192]; int iarg,nargs=0; /* macro expansion params */ |
|
char wstrwhite[99]; /* whitespace chars for strwstr() */ |
if ( args != NULL ) /*we have args (or htmlterm) param*/ |
if ( args != NULL ) /*we have args (or htmlterm) param*/ |
if ( *args != '\000' ) /* and it's not an empty string */ |
if ( *args != '\000' ) { /* and it's not an empty string */ |
if ( strchr("0123456789",*args) != NULL ) /* is 1st char #args=0-9 ? */ |
if ( strchr("0123456789",*args) != NULL ) /* is 1st char #args=0-9 ? */ |
{ 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 */ |
else if ( strncmp(args,embedkeywd,embedlen) == 0 )/*xlate embedded token*/ |
{ htmlterm = NULL; /* if so, then we have no htmlterm */ |
{ htmlterm = NULL; /* if so, then we have no htmlterm */ |
isembedded = 1 ; } /* turn on embedded flag */ |
isembedded = 1 ; /* turn on embedded flag */ |
|
embedterm = args[embedlen]; /* char immediately after embed */ |
|
if (strlen(args) > embedlen+1) { /* have embed,white for strwstr() */ |
|
isstrwstr = 1; /* turn on strwtsr flag */ |
|
strcpy(wstrwhite,args+6); } } /* and set its whitespace arg */ |
|
} /* --- end-of-if(*args!='\000') --- */ |
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=(!isstrwstr?strstr(expptr,htmlsym): /* just use strtsr */ |
{ char termchar = *(tokptr+htmllen), /* char terminating html sequence */ |
strwstr(expptr,htmlsym,wstrwhite,&wstrlen)) ) /* or use our strwstr */ |
|
!= NULL ) /* found another sym */ |
|
{ int toklen = (!isstrwstr?htmllen:wstrlen); /* length of matched sym */ |
|
char termchar = *(tokptr+toklen), /* char terminating html sequence */ |
prevchar = (tokptr==expptr?' ':*(tokptr-1)); /*char preceding html*/ |
prevchar = (tokptr==expptr?' ':*(tokptr-1)); /*char preceding html*/ |
int escapelen = htmllen; /* total length of escape sequence */ |
int escapelen = toklen; /* 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 */ |
if ( *latexsym != '\000' ) /* and it's not an empty string */ |
if ( *latexsym != '\000' ) /* and it's not an empty string */ |
Line 5015 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 5467 for(isymbol=0; (htmlsym=symbols[isymbol]
|
escapelen += (isthischar(termchar,htmlterm)?1:0); /*add terminator*/ |
escapelen += (isthischar(termchar,htmlterm)?1:0); /*add terminator*/ |
if ( !isembedded ) /* don't xlate embedded sequence */ |
if ( !isembedded ) /* don't xlate embedded sequence */ |
if ( isalpha((int)termchar) ) /*we just have prefix of longer sym*/ |
if ( isalpha((int)termchar) ) /*we just have prefix of longer sym*/ |
{ expptr = tokptr+htmllen; /* just resume search after prefix */ |
{ expptr = tokptr+toklen; /* just resume search after prefix */ |
continue; } /* but don't replace it */ |
continue; } /* but don't replace it */ |
if ( isembedded ) /* for embedded sequence */ |
if ( isembedded ) /* for embedded sequence */ |
if ( isthischar(prevchar,ESCAPE) ) /* don't xlate escaped char */ |
if ( !isthischar(embedterm,ESCAPE) /* don't xlate escaped \token */ |
{ expptr = tokptr+htmllen; /*just resume search after literal*/ |
&& isthischar(prevchar,ESCAPE) ) /* and we have escaped \token */ |
|
{ expptr = tokptr+toklen; /*just resume search after literal*/ |
continue; } /* but don't replace it */ |
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*/ |
&& isalpha(*htmlsym) /* and our symbol starts with alpha*/ |
Line 5047 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 5500 for(isymbol=0; (htmlsym=symbols[isymbol]
|
if ( *expptr == '[' ) /* but user gave us [argval] */ |
if ( *expptr == '[' ) /* but user gave us [argval] */ |
expptr = texsubexpr(expptr,argval,0,"[","]",0,0); } /*so get it*/ |
expptr = texsubexpr(expptr,argval,0,"[","]",0,0); } /*so get it*/ |
else /* not optional, so get {argval} */ |
else /* not optional, so get {argval} */ |
if ( *expptr != '\000' ) /* check that some argval provided */ |
if ( *expptr != '\000' ) { /* check that some argval provided */ |
if ( !isalgebra ) /* only { } delims for latex macro */ |
if ( !isalgebra ) /* only { } delims for latex macro */ |
expptr = texsubexpr(expptr,argval,0,"{","}",0,0); /*get {argval}*/ |
expptr = texsubexpr(expptr,argval,0,"{","}",0,0); /*get {argval}*/ |
else /*any delim for algebra syntax macro*/ |
else /*any delim for algebra syntax macro*/ |
Line 5055 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 5508 for(isymbol=0; (htmlsym=symbols[isymbol]
|
if ( isthischar(*argval,aleft) ) /* have delim-enclosed arg */ |
if ( isthischar(*argval,aleft) ) /* have delim-enclosed arg */ |
if ( *argval != '{' ) /* and it's not { }-enclosed */ |
if ( *argval != '{' ) /* and it's not { }-enclosed */ |
{ strchange(0,argval,"\\left"); /* insert opening \left, */ |
{ strchange(0,argval,"\\left"); /* insert opening \left, */ |
strchange(0,argval+strlen(argval)-1,"\\right"); } /*\right*/ |
strchange(0,argval+strlen(argval)-1,"\\right"); } }/*\right*/ |
} /* --- end-of-if/else(!isalgebra) --- */ |
} /* --- end-of-if(*expptr!='\000') --- */ |
/* --- replace #`iarg` in macro with argval --- */ |
/* --- replace #`iarg` in macro with argval --- */ |
sprintf(argsignal,"#%d",iarg); /* #1...#9 signals argument */ |
sprintf(argsignal,"#%d",iarg); /* #1...#9 signals argument */ |
while ( (argsigptr=strstr(argval,argsignal)) != NULL ) /* #1...#9 */ |
while ( (argsigptr=strstr(argval,argsignal)) != NULL ) /* #1...#9 */ |
Line 5071 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 5524 for(isymbol=0; (htmlsym=symbols[isymbol]
|
} /* --- end-of-while(tokptr!=NULL) --- */ |
} /* --- end-of-while(tokptr!=NULL) --- */ |
} /* --- end-of-for(isymbol) --- */ |
} /* --- end-of-for(isymbol) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
|
convert \left( to \( and \right) to \), etc. |
|
-------------------------------------------------------------------------- */ |
|
if ( xlateleft ) /* \left...\right xlation wanted */ |
|
for ( idelim=0; idelim<2; idelim++ ) /* 0 for \left and 1 for \right */ |
|
{ |
|
char *lrstr = (idelim==0?"\\left":"\\right"); /* \left on 1st pass */ |
|
int lrlen = (idelim==0?5:6); /* strlen() of \left or \right */ |
|
char *braces = (idelim==0?LEFTBRACES ".":RIGHTBRACES "."), /*([{<or)]}>*/ |
|
**lrfrom= (idelim==0?leftfrom:rightfrom), /* long braces like \| */ |
|
**lrto = (idelim==0?leftto:rightto), /* xlated to 1-char like = */ |
|
*lrsym = NULL; /* lrfrom[isymbol] */ |
|
expptr = expression; /* start search at beginning */ |
|
while ( (tokptr=strstr(expptr,lrstr)) != NULL ) /* found \left or \right */ |
|
{ |
|
if ( isthischar(*(tokptr+lrlen),braces) ) /* followed by a 1-char brace*/ |
|
{ strcpy(tokptr+1,tokptr+lrlen); /* so squeeze out "left" or "right"*/ |
|
expptr = tokptr+2; } /* and resume search past brace */ |
|
else /* may be a "long" brace like \| */ |
|
{ |
|
expptr = tokptr+lrlen; /*init to resume search past\left\rt*/ |
|
for(isymbol=0; (lrsym=lrfrom[isymbol]) != NULL; isymbol++) |
|
{ int symlen = strlen(lrsym); /* #chars in delim, e.g., 2 for \| */ |
|
if ( memcmp(tokptr+lrlen,lrsym,symlen) == 0 ) /* found long delim*/ |
|
{ strcpy(tokptr+1,tokptr+lrlen+symlen-1); /* squeeze out delim */ |
|
*(tokptr+1) = *(lrto[isymbol]); /* last char now 1-char delim*/ |
|
expptr = tokptr+2 - lrlen; /* resume search past 1-char delim*/ |
|
break; } /* no need to check more lrsym's */ |
|
} /* --- end-of-for(isymbol) --- */ |
|
} /* --- end-of-if/else(isthischar()) --- */ |
|
} /* --- end-of-while(tokptr!=NULL) --- */ |
|
} /* --- end-of-for(idelim) --- */ |
|
/* ------------------------------------------------------------------------- |
run thru table, converting all {a+b\atop c+d} to \atop{a+b}{c+d} |
run thru table, converting all {a+b\atop c+d} to \atop{a+b}{c+d} |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
for(isymbol=0; (atopsym=atopcommands[isymbol]) != NULL; isymbol++) |
for(isymbol=0; (atopsym=atopcommands[isymbol]) != NULL; isymbol++) |
Line 5228 return ( nreps ); /* #replacements bac
|
Line 5713 return ( nreps ); /* #replacements bac
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: strtexchr (char *string, char *texchr ) |
* Function: strwstr (char *string, char *substr, char *white, int *sublen) |
|
* Purpose: Find first substr in string, but wherever substr contains |
|
* a whitespace char (in white), string may contain any number |
|
* (including 0) of whitespace chars. If white contains I or i, |
|
* then match is case-insensitive (and I,i _not_ whitespace). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: string (I) char * to null-terminated string in which |
|
* first occurrence of substr will be found |
|
* substr (I) char * to null-terminated string containing |
|
* "template" that will be searched for |
|
* white (I) char * to null-terminated string containing |
|
* whitespace chars. If NULL or empty, then |
|
* "~ \t\n\r\f\v" (WHITEMATH in mimetex.h) used. |
|
* If white contains I or i, then match is |
|
* case-insensitive (and I,i _not_ considered |
|
* whitespace). |
|
* sublen (O) address of int returning "length" of substr |
|
* found in string (which may be longer or |
|
* shorter than substr itself). |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( char * ) ptr to first char of substr in string |
|
* or NULL if not found or for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Wherever a single whitespace char appears in substr, |
|
* the corresponding position in string may contain any |
|
* number (including 0) of whitespace chars, e.g., |
|
* string="abc def" and string="abcdef" both match |
|
* substr="c d" at offset 2 of string. |
|
* o If substr="c d" (two spaces between c and d), |
|
* then string must have at least one space, so now "abcdef" |
|
* doesn't match. In general, the minimum number of spaces |
|
* in string is the number of spaces in substr minus 1 |
|
* (so 1 space in substr permits 0 spaces in string). |
|
* o Embedded spaces are counted in sublen, e.g., |
|
* string="c d" (three spaces) matches substr="c d" |
|
* with sublen=5 returned. But string="ab c d" will |
|
* also match substr=" c d" returning sublen=5 and |
|
* a ptr to the "c". That is, the mandatory preceding |
|
* space is _not_ counted as part of the match. |
|
* But all the embedded space is counted. |
|
* (An inconsistent bug/feature is that mandatory |
|
* terminating space is counted.) |
|
* o Moreover, string="c d" matches substr=" c d", i.e., |
|
* the very beginning of a string is assumed to be preceded |
|
* by "virtual blanks". |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
char *strwstr ( char *string, char *substr, char *white, int *sublen ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *psubstr=substr, *pstring=string,/*ptr to current char in substr,str*/ |
|
*pfound = (char *)NULL; /*ptr to found substr back to caller*/ |
|
char *pwhite=NULL, whitespace[256]; /* callers white whithout i,I */ |
|
int iscase = (white==NULL?1: /* case-sensitive if i,I in white */ |
|
strchr(white,'i')==NULL && strchr(white,'I')==NULL); |
|
int foundlen = 0; /* length of substr found in string*/ |
|
int nstrwhite=0, nsubwhite=0, /* #leading white chars in str,sub */ |
|
nminwhite=0; /* #mandatory leading white in str */ |
|
int nstrchars=0, nsubchars=0, /* #non-white chars to be matched */ |
|
isncmp=0; /*strncmp() or strncasecmp() result*/ |
|
/* ------------------------------------------------------------------------- |
|
Initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- set up whitespace --- */ |
|
strcpy(whitespace,WHITEMATH); /*default if no user input for white*/ |
|
if ( white != NULL ) /*user provided ptr to white string*/ |
|
if ( *white != '\000' ) { /*and it's not just an empty string*/ |
|
strcpy(whitespace,white); /* so use caller's white spaces */ |
|
while ( (pwhite=strchr(whitespace,'i')) != NULL ) /* have an embedded i */ |
|
strcpy(pwhite,pwhite+1); /* so squeeze it out */ |
|
while ( (pwhite=strchr(whitespace,'I')) != NULL ) /* have an embedded I */ |
|
strcpy(pwhite,pwhite+1); /* so squeeze it out */ |
|
if ( *whitespace == '\000' ) /* caller's white just had i,I */ |
|
strcpy(whitespace,WHITEMATH); } /* so revert back to default */ |
|
/* ------------------------------------------------------------------------- |
|
Find first occurrence of substr in string |
|
-------------------------------------------------------------------------- */ |
|
if ( string != NULL ) /* caller passed us a string ptr */ |
|
while ( *pstring != '\000' ) { /* break when string exhausted */ |
|
char *pstrptr = pstring; /* (re)start at next char in string*/ |
|
int leadingwhite = 0; /* leading whitespace */ |
|
psubstr = substr; /* start at beginning of substr */ |
|
foundlen = 0; /* reset length of found substr */ |
|
if ( substr != NULL ) /* caller passed us a substr ptr */ |
|
while ( *psubstr != '\000' ) { /*see if pstring begins with substr*/ |
|
/* --- check for end-of-string before finding match --- */ |
|
if ( *pstrptr == '\000' ) /* end-of-string without a match */ |
|
goto nextstrchar; /* keep trying with next char */ |
|
/* --- actual amount of whitespace in string and substr --- */ |
|
nsubwhite = strspn(psubstr,whitespace); /* #leading white chars in sub */ |
|
nstrwhite = strspn(pstrptr,whitespace); /* #leading white chars in str */ |
|
nminwhite = max2(0,nsubwhite-1); /* #mandatory leading white in str */ |
|
/* --- check for mandatory leading whitespace in string --- */ |
|
if ( pstrptr != string ) /*not mandatory at start of string*/ |
|
if ( nstrwhite < nminwhite ) /* too little leading white space */ |
|
goto nextstrchar; /* keep trying with next char */ |
|
/* ---hold on to #whitespace chars in string preceding substr match--- */ |
|
if ( pstrptr == pstring ) /* whitespace at start of substr */ |
|
leadingwhite = nstrwhite; /* save it as leadingwhite */ |
|
/* --- check for optional whitespace --- */ |
|
if ( psubstr != substr ) /* always okay at start of substr */ |
|
if ( nstrwhite>0 && nsubwhite<1 ) /* too much leading white space */ |
|
goto nextstrchar; /* keep trying with next char */ |
|
/* --- skip any leading whitespace in substr and string --- */ |
|
psubstr += nsubwhite; /* push past leading sub whitespace*/ |
|
pstrptr += nstrwhite; /* push past leading str whitespace*/ |
|
/* --- now get non-whitespace chars that we have to match --- */ |
|
nsubchars = strcspn(psubstr,whitespace); /* #non-white chars in sub */ |
|
nstrchars = strcspn(pstrptr,whitespace); /* #non-white chars in str */ |
|
if ( nstrchars < nsubchars ) /* too few chars for match */ |
|
goto nextstrchar; /* keep trying with next char */ |
|
/* --- see if next nsubchars are a match --- */ |
|
isncmp = (iscase? strncmp(pstrptr,psubstr,nsubchars): /*case sensitive*/ |
|
strncasecmp(pstrptr,psubstr,nsubchars)); /*case insensitive*/ |
|
if ( isncmp != 0 ) /* no match */ |
|
goto nextstrchar; /* keep trying with next char */ |
|
/* --- push past matched chars --- */ |
|
psubstr += nsubchars; pstrptr += nsubchars; /*nsubchars were matched*/ |
|
} /* --- end-of-while(*psubstr!='\000') --- */ |
|
pfound = pstring + leadingwhite; /* found match starting at pstring */ |
|
foundlen = (int)(pstrptr-pfound); /* consisting of this many chars */ |
|
goto end_of_job; /* back to caller */ |
|
/* ---failed to find substr, continue trying with next char in string--- */ |
|
nextstrchar: /* continue outer loop */ |
|
pstring++; /* bump to next char in string */ |
|
} /* --- end-of-while(*pstring!='\000') --- */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with ptr to first occurrence of substr in string |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( msglevel>=999 && msgfp!=NULL) { /* debugging/diagnostic output */ |
|
fprintf(msgfp,"strwstr> str=\"%.72s\" sub=\"%s\" found at offset %d\n", |
|
string,substr,(pfound==NULL?(-1):(int)(pfound-string))); fflush(msgfp); } |
|
if ( sublen != NULL ) /*caller wants length of found substr*/ |
|
*sublen = foundlen; /* give it to him along with ptr */ |
|
return ( pfound ); /*ptr to first found substr, or NULL*/ |
|
} /* --- end-of-function strwstr() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: strtexchr ( char *string, char *texchr ) |
* Purpose: Find first texchr in string, but texchr must be followed |
* Purpose: Find first texchr in string, but texchr must be followed |
* by non-alpha |
* by non-alpha |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: string (I) char * to null-terminated string in which |
* Arguments: string (I) char * to null-terminated string in which |
* firstoccurrence of delim will be found |
* first occurrence of delim will be found |
* texchr (I) char * to null-terminated string that |
* texchr (I) char * to null-terminated string that |
* will be searched for |
* will be searched for |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 5255 int texchrlen = (texchr==NULL?0:strlen(t
|
Line 5882 int texchrlen = (texchr==NULL?0:strlen(t
|
locate texchr in string |
locate texchr in string |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( string != (char *)NULL /* check that we got input string */ |
if ( string != (char *)NULL /* check that we got input string */ |
&& texchrlen > 0 ) /* and a texchr to search for */ |
&& texchrlen > 0 ) { /* and a texchr to search for */ |
while ( (ptexchr=strstr(pstring,texchr)) /* look for texchr in string */ |
while ( (ptexchr=strstr(pstring,texchr)) /* look for texchr in string */ |
!= (char *)NULL ) /* found it */ |
!= (char *)NULL ) /* found it */ |
if ( (delim = ptexchr[texchrlen]) /* char immediately after texchr */ |
if ( (delim = ptexchr[texchrlen]) /* char immediately after texchr */ |
Line 5265 if ( string != (char *)NULL /* check th
|
Line 5892 if ( string != (char *)NULL /* check th
|
|| 0 ) /* other tests to be determined */ |
|| 0 ) /* other tests to be determined */ |
pstring = ptexchr + texchrlen; /* continue search after texchr */ |
pstring = ptexchr + texchrlen; /* continue search after texchr */ |
else /* passed all tests */ |
else /* passed all tests */ |
break; /*so return ptr to texchr to caller*/ |
break; } /*so return ptr to texchr to caller*/ |
return ( ptexchr ); /* ptr to texchar back to caller */ |
return ( ptexchr ); /* ptr to texchar back to caller */ |
} /* --- end-of-function strtexchr() --- */ |
} /* --- end-of-function strtexchr() --- */ |
|
|
Line 5362 subraster *rasterize ( char *expression,
|
Line 5989 subraster *rasterize ( char *expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *preamble(), pretext[256]; /* process preamble, if present */ |
char *preamble(), pretext[512]; /* process preamble, if present */ |
char chartoken[8192], *texsubexpr(), /*get subexpression from expression*/ |
char chartoken[MAXSUBXSZ+1], *texsubexpr(), /*get subexpression from expr*/ |
*subexpr = chartoken; /* token may be parenthesized expr */ |
*subexpr = chartoken; /* token may be parenthesized expr */ |
int isbrace(); /* check subexpr for braces */ |
int isbrace(); /* check subexpr for braces */ |
mathchardef *symdef, *get_symdef(); /*get mathchardef struct for symbol*/ |
mathchardef *symdef, *get_symdef(); /*get mathchardef struct for symbol*/ |
|
int ligdef, get_ligature(); /*get symtable[] index for ligature*/ |
int natoms=0; /* #atoms/tokens processed so far */ |
int natoms=0; /* #atoms/tokens processed so far */ |
int type_raster(); /* display debugging output */ |
int type_raster(); /* display debugging output */ |
subraster *rasterize(), /* recurse */ |
subraster *rasterize(), /* recurse */ |
Line 5379 subraster *get_charsubraster(), /* char
|
Line 6007 subraster *get_charsubraster(), /* char
|
*sp=NULL, *prevsp=NULL, /* raster for current, prev char */ |
*sp=NULL, *prevsp=NULL, /* raster for current, prev char */ |
*expraster = (subraster *)NULL; /* raster returned to caller */ |
*expraster = (subraster *)NULL; /* raster returned to caller */ |
int delete_subraster(); /* free everything before returning*/ |
int delete_subraster(); /* free everything before returning*/ |
|
int family = fontinfo[fontnum].family; /* current font family */ |
|
int isleftscript = 0, /* true if left-hand term scripted */ |
|
wasscripted = 0, /* true if preceding token scripted*/ |
|
wasdelimscript = 0; /* true if preceding delim scripted*/ |
/*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 wasstring = isstring, /* initial isstring mode flag */ |
int wasstring = isstring, /* initial isstring mode flag */ |
Line 5389 int wasstring = isstring, /* initial is
|
Line 6021 int wasstring = isstring, /* initial is
|
oldshrinkfactor = shrinkfactor, /* initial shrinkfactor */ |
oldshrinkfactor = shrinkfactor, /* initial shrinkfactor */ |
oldsmashmargin = smashmargin, /* initial smashmargin */ |
oldsmashmargin = smashmargin, /* initial smashmargin */ |
oldissmashdelta = issmashdelta, /* initial issmashdelta */ |
oldissmashdelta = issmashdelta, /* initial issmashdelta */ |
|
oldisexplicitsmash = isexplicitsmash, /* initial isexplicitsmash */ |
|
oldisscripted = isscripted, /* initial isscripted */ |
*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 5400 initialization
|
Line 6034 initialization
|
recurlevel++; /* wind up one more recursion level*/ |
recurlevel++; /* wind up one more recursion level*/ |
leftexpression = NULL; /* no leading left half yet */ |
leftexpression = NULL; /* no leading left half yet */ |
isreplaceleft = 0; /* reset replaceleft flag */ |
isreplaceleft = 0; /* reset replaceleft flag */ |
|
if(1)fraccenterline = NOVALUE; /* reset \frac baseline signal */ |
/* shrinkfactor = shrinkfactors[max2(0,min2(size,LARGESTSIZE))];*/ /*set sf*/ |
/* shrinkfactor = shrinkfactors[max2(0,min2(size,LARGESTSIZE))];*/ /*set sf*/ |
shrinkfactor = shrinkfactors[max2(0,min2(size,16))]; /* have 17 sf's */ |
shrinkfactor = shrinkfactors[max2(0,min2(size,16))]; /* have 17 sf's */ |
if ( msgfp!=NULL && msglevel >= 29 ) /*display expression for debugging*/ |
if ( msgfp!=NULL && msglevel >= 9 ) { /*display expression for debugging*/ |
{ fprintf(msgfp, |
fprintf(msgfp, |
"rasterize> recursion level=%d, size=%d,\n\texpression=\"%s\"\n", |
"rasterize> recursion#%d, size=%d,\n\texpression=\"%s\"\n", |
recurlevel,size,(expression==NULL?"null":expression)); fflush(msgfp); } |
recurlevel,size,(expression==NULL?"<null>":expression)); fflush(msgfp); } |
if ( expression == NULL ) goto end_of_job; /* nothing given to do */ |
if ( expression == NULL ) goto end_of_job; /* nothing given to do */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
preocess optional $-terminated preamble preceding expression |
preocess optional $-terminated preamble preceding expression |
Line 5421 build up raster one character (or subexp
|
Line 6056 build up raster one character (or subexp
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
while ( 1 ) |
while ( 1 ) |
{ |
{ |
|
/* --- kludge for \= cyrillic ligature --- */ |
|
isligature = 0; /* no ligature found yet */ |
|
family = fontinfo[fontnum].family; /* current font family */ |
|
if ( family == CYR10 ) /* may have cyrillic \= ligature */ |
|
if ( (ligdef = get_ligature(expression,family)) /*check for any ligature*/ |
|
>= 0 ) /* got some ligature */ |
|
if ( memcmp(symtable[ligdef].symbol,"\\=",2) == 0 ) /* starts with \= */ |
|
isligature = 1; /* signal \= ligature */ |
/* --- get next character/token or subexpression --- */ |
/* --- get next character/token or subexpression --- */ |
|
subexprptr = expression; /* ptr within expression to subexpr*/ |
expression = texsubexpr(expression,chartoken,0,LEFTBRACES,RIGHTBRACES,1,1); |
expression = texsubexpr(expression,chartoken,0,LEFTBRACES,RIGHTBRACES,1,1); |
subexpr = chartoken; /* "local" copy of chartoken ptr */ |
subexpr = chartoken; /* "local" copy of chartoken ptr */ |
leftsymdef = NULL; /* no character identified yet */ |
leftsymdef = NULL; /* no character identified yet */ |
sp = NULL; /* no subraster yet */ |
sp = NULL; /* no subraster yet */ |
size = fontsize; /* in case reset by \tiny, etc */ |
size = fontsize; /* in case reset by \tiny, etc */ |
|
/*isleftscript = isdelimscript;*/ /*was preceding term scripted delim*/ |
|
wasscripted = isscripted; /* true if preceding token scripted*/ |
|
wasdelimscript = isdelimscript; /* preceding \right delim scripted */ |
|
if(1)isscripted = 0; /* no subscripted expression yet */ |
|
isdelimscript = 0; /* reset \right delim scripted flag*/ |
/* --- debugging output --- */ |
/* --- debugging output --- */ |
if ( msgfp!=NULL && msglevel >= 999 ) /* display chartoken for debugging */ |
if ( msgfp!=NULL && msglevel >= 9 ) { /* display chartoken for debugging */ |
{ fprintf(msgfp,"rasterize> recursion level=%d, atom#%d = \"%s\"\n", |
fprintf(msgfp, |
recurlevel,natoms+1,chartoken); fflush(msgfp); } |
"rasterize> recursion#%d,atom#%d=\"%s\" (isligature=%d,isleftscript=%d)\n", |
|
recurlevel,natoms+1,chartoken,isligature,isleftscript); fflush(msgfp); } |
if ( expression == NULL /* no more tokens */ |
if ( expression == NULL /* no more tokens */ |
&& *subexpr == '\000' ) break; /* and this token empty */ |
&& *subexpr == '\000' ) break; /* and this token empty */ |
if ( *subexpr == '\000' ) break; /* enough if just this token empty */ |
if ( *subexpr == '\000' ) break; /* enough if just this token empty */ |
Line 5441 while ( 1 )
|
Line 6091 while ( 1 )
|
else /* --- single-character atomic token --- */ |
else /* --- single-character atomic token --- */ |
if ( !isthischar(*subexpr,SCRIPTS) ) /* scripts handled below */ |
if ( !isthischar(*subexpr,SCRIPTS) ) /* scripts handled below */ |
{ |
{ |
/* --- first look up mathchardef for atomic token in table --- */ |
/* --- first check for opening $ in \text{ if $n-m$ even} --- */ |
if ( (leftsymdef=symdef=get_symdef(chartoken)) /*mathchardef for token*/ |
if ( istextmode /* we're in \text mode */ |
== NULL ) /* lookup failed */ |
&& *subexpr=='$' && subexpr[1]=='\000' ) { /* and have an opening $ */ |
{ char literal[512] = "[?]"; /*display for unrecognized literal*/ |
char *endptr=NULL, mathexpr[MAXSUBXSZ+1]; /* $expression$ in \text{ }*/ |
int oldfontnum = fontnum; /* error display in default mode */ |
int exprlen = 0; /* length of $expression$ */ |
if ( msgfp!=NULL && msglevel >= 29 ) /* display unrecognized symbol */ |
int textfontnum = fontnum; /* current text font number */ |
|
/*if ( (endptr=strrchr(expression,'$')) != NULL )*/ /*ptr to closing $*/ |
|
if ( (endptr=strchr(expression,'$')) != NULL ) /* ptr to closing $ */ |
|
exprlen = (int)(endptr-expression); /* #chars preceding closing $ */ |
|
else { /* no closing $ found */ |
|
exprlen = strlen(expression); /* just assume entire expression */ |
|
endptr = expression + (exprlen-1); } /*and push expression to '\000'*/ |
|
exprlen = min2(exprlen,MAXSUBXSZ); /* don't overflow mathexpr[] */ |
|
if ( exprlen > 0 ) { /* have something between $$ */ |
|
memcpy(mathexpr,expression,exprlen); /*local copy of math expression*/ |
|
mathexpr[exprlen] = '\000'; /* null-terminate it */ |
|
fontnum = 0; /* set math mode */ |
|
sp = rasterize(mathexpr,size); /* and rasterize $expression$ */ |
|
fontnum = textfontnum; } /* set back to text mode */ |
|
expression = endptr+1; /* push expression past closing $ */ |
|
} /* --- end-of-if(istextmode&&*subexpr=='$') --- */ |
|
else |
|
/* --- otherwise, look up mathchardef for atomic token in table --- */ |
|
if ( (leftsymdef=symdef=get_symdef(chartoken)) /*mathchardef for token*/ |
|
== NULL ) /* lookup failed */ |
|
{ char literal[512] = "[?]"; /*display for unrecognized literal*/ |
|
int oldfontnum = fontnum; /* error display in default mode */ |
|
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 */ |
fontnum = 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 */ |
fontnum = oldfontnum; /* reset font family */ |
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 */ |
{ int arg1=symdef->charnum, arg2=symdef->family, arg3=symdef->class; |
{ int arg1=symdef->charnum, arg2=symdef->family, arg3=symdef->class; |
if ( (sp = (subraster *) /* returned void* is subraster* */ |
if ( (sp = (subraster *) /* returned void* is subraster* */ |
(*(symdef->handler))(&expression,size,prevsp,arg1,arg2,arg3))== NULL ) |
(*(symdef->handler))(&expression,size,prevsp,arg1,arg2,arg3))==NULL) |
continue; } /* flush token if handler failed */ |
continue; } /* flush token if handler failed */ |
else /* --- no handler, so just get subraster for this character --- */ |
else /* --- no handler, so just get subraster for this character --- */ |
if ( !isstring ) /* rasterizing */ |
if ( !isstring ) /* rasterizing */ |
{ if ( (sp=get_charsubraster(symdef,size)) /* get subraster */ |
{ if ( isligature ) /* found a ligature */ |
|
expression = subexprptr + strlen(symdef->symbol); /*push past it*/ |
|
if ( (sp=get_charsubraster(symdef,size)) /* get subraster */ |
== NULL ) continue; } /* flush token if failed */ |
== NULL ) continue; } /* flush token if failed */ |
else /* constructing ascii string */ |
else /* constructing ascii string */ |
{ char *symbol = symdef->symbol; /* symbol for ascii string */ |
{ char *symbol = symdef->symbol; /* symbol for ascii string */ |
int symlen = (symbol!=NULL?strlen(symbol):0); /*#chars in symbol*/ |
int symlen = (symbol!=NULL?strlen(symbol):0); /*#chars in symbol*/ |
if ( symlen < 1 ) continue; /* no symbol for ascii string */ |
if ( symlen < 1 ) continue; /* no symbol for ascii string */ |
Line 5481 while ( 1 )
|
Line 6155 while ( 1 )
|
sp->baseline = 1; /* default (should be unused) */ |
sp->baseline = 1; /* default (should be unused) */ |
strcpy((char *)((sp->image)->pixmap),symbol); /* copy symbol */ |
strcpy((char *)((sp->image)->pixmap),symbol); /* copy symbol */ |
/*((char *)((sp->image)->pixmap))[symlen] = '\000';*/ } /*null*/ |
/*((char *)((sp->image)->pixmap))[symlen] = '\000';*/ } /*null*/ |
} /* --- end-of-if/else ... if/else --- */ |
} /* --- end-of-if(!isthischar(*subexpr,SCRIPTS)) --- */ |
/* --- handle any super/subscripts following symbol or subexpression --- */ |
/* --- handle any super/subscripts following symbol or subexpression --- */ |
sp = rastlimits(&expression,size,sp); |
sp = rastlimits(&expression,size,sp); |
|
isleftscript = (wasscripted||wasdelimscript?1:0);/*preceding term scripted*/ |
/* --- debugging output --- */ |
/* --- debugging output --- */ |
if ( msgfp!=NULL && msglevel >= 999 ) /* display raster for debugging */ |
if ( msgfp!=NULL && msglevel >= 9 ) { /* display raster for debugging */ |
{ fprintf(msgfp,"rasterize> recursion level=%d, atom#%d%s\n", |
fprintf(msgfp,"rasterize> recursion#%d,atom#%d%s\n", |
recurlevel,natoms+1,(sp==NULL?" = null":"...")); |
recurlevel,natoms+1,(sp==NULL?" = <null>":"...")); |
if(sp!=NULL) type_raster(sp->image,msgfp); /* display raster */ |
if ( msglevel >= 9 ) fprintf(msgfp, |
fflush(msgfp); } /* flush msgfp buffer */ |
" isleftscript=%d is/wasscripted=%d,%d is/wasdelimscript=%d,%d\n", |
|
isleftscript,isscripted,wasscripted,isdelimscript,wasdelimscript); |
|
if ( msglevel >= 99 ) |
|
if(sp!=NULL) type_raster(sp->image,msgfp); /* display raster */ |
|
fflush(msgfp); } /* flush msgfp buffer */ |
/* --- accumulate atom or parenthesized subexpression --- */ |
/* --- accumulate atom or parenthesized subexpression --- */ |
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 */ |
Line 5499 while ( 1 )
|
Line 6178 while ( 1 )
|
expraster = subrastcpy(sp); /* copy static CHARASTER or 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 term */ |
expraster = rastcat(expraster,sp,1); /* concat new one, free previous */ |
int prevsmashmargin = smashmargin; /* save current smash margin */ |
|
if ( isleftscript ) { /* don't smash against scripts */ |
|
isdelimscript = 0; /* reset \right delim scripted flag*/ |
|
if ( !isexplicitsmash ) smashmargin = 0; } /* signal no smash wanted */ |
|
expraster = rastcat(expraster,sp,1); /* concat new term, free previous */ |
|
smashmargin = prevsmashmargin; } /* restore current smash margin */ |
delete_subraster(prevsp); /* free prev (if not a CHARASTER) */ |
delete_subraster(prevsp); /* free prev (if not a CHARASTER) */ |
prevsp = sp; /* current becomes previous */ |
prevsp = sp; /* current becomes previous */ |
leftexpression = expraster; /* left half rasterized so far */ |
leftexpression = expraster; /* left half rasterized so far */ |
Line 5521 end_of_job:
|
Line 6205 end_of_job:
|
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
/* --- set final raster buffer --- */ |
/* --- set final raster buffer --- */ |
if ( 1 && expraster != (subraster *)NULL ) /* have an expression */ |
if ( 1 && expraster != (subraster *)NULL ) /* have an expression */ |
{ expraster->type = IMAGERASTER; /* set type to constructed image */ |
{ int type = expraster->type; /* type of constructed image */ |
|
if ( type != FRACRASTER ) /* leave \frac alone */ |
|
expraster->type = IMAGERASTER; /* set type to constructed image */ |
if ( istextmode ) /* but in text mode */ |
if ( istextmode ) /* but in text mode */ |
expraster->type = blanksignal; /* set type to avoid smash */ |
expraster->type = blanksignal; /* set type to avoid smash */ |
expraster->size = fontsize; } /* set original input font size */ |
expraster->size = fontsize; } /* set original input font size */ |
Line 5534 end_of_job:
|
Line 6220 end_of_job:
|
shrinkfactor = oldshrinkfactor; /* shrinkfactor reset */ |
shrinkfactor = oldshrinkfactor; /* shrinkfactor reset */ |
smashmargin = oldsmashmargin; /* smashmargin reset */ |
smashmargin = oldsmashmargin; /* smashmargin reset */ |
issmashdelta = oldissmashdelta; /* issmashdelta reset */ |
issmashdelta = oldissmashdelta; /* issmashdelta reset */ |
|
isexplicitsmash = oldisexplicitsmash; /* isexplicitsmash reset */ |
|
isscripted = oldisscripted; /* isscripted 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 5578 int explen = strlen(expression); /* tota
|
Line 6266 int explen = strlen(expression); /* tota
|
int isescape = 0, /* true if parens \escaped */ |
int isescape = 0, /* true if parens \escaped */ |
isrightdot = 0, /* true if right paren is \right. */ |
isrightdot = 0, /* true if right paren is \right. */ |
isleftdot = 0; /* true if left paren is \left. */ |
isleftdot = 0; /* true if left paren is \left. */ |
char left[16], right[16]; /* parens enclosing expresion */ |
char left[32], right[32]; /* parens enclosing expresion */ |
char noparens[8192]; /* get subexpr without parens */ |
char noparens[MAXSUBXSZ+1]; /* get subexpr without parens */ |
subraster *rasterize(), *sp=NULL; /* rasterize what's between ()'s */ |
subraster *rasterize(), *sp=NULL; /* rasterize what's between ()'s */ |
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[] */ |
Line 5676 Allocations and Declarations
|
Line 6364 Allocations and Declarations
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
subraster *rastscripts(), *rastdispmath(), /*one of these will do the work*/ |
subraster *rastscripts(), *rastdispmath(), /*one of these will do the work*/ |
*rastcat(), /* may need to concat scripts */ |
*rastcat(), /* may need to concat scripts */ |
*scriptsp = basesp; /* and this will become the result */ |
*rasterize(), /* may need to construct dummy base*/ |
|
*scriptsp = basesp, /* and this will become the result */ |
|
*dummybase = basesp; /* for {}_i construct a dummy base */ |
int isdisplay = (-1); /* set 1 for displaystyle, else 0 */ |
int isdisplay = (-1); /* set 1 for displaystyle, else 0 */ |
int oldsmashmargin = smashmargin; /* save original smashmargin */ |
int oldsmashmargin = smashmargin; /* save original smashmargin */ |
int type_raster(); /* display debugging output */ |
int type_raster(); /* display debugging output */ |
|
int delete_subraster(); /* free dummybase, if necessary */ |
|
int rastsmashcheck(); /* check if okay to smash scripts */ |
/* --- 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*/ |
int toklen=0; /* strlen(limtoken) */ |
int toklen=0; /* strlen(limtoken) */ |
Line 5690 determine whether or not to use displaym
|
Line 6382 determine whether or not to use displaym
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
scriptlevel++; /* first, increment subscript level*/ |
scriptlevel++; /* first, increment subscript level*/ |
*limtoken = '\000'; /* no token yet */ |
*limtoken = '\000'; /* no token yet */ |
|
isscripted = 0; /* signal term not (text) scripted */ |
if ( msgfp!=NULL && msglevel>=999 ) |
if ( msgfp!=NULL && msglevel>=999 ) |
{ fprintf(msgfp,"rastlimits> scriptlevel#%d exprptr=%.48s\n", |
{ fprintf(msgfp,"rastlimits> scriptlevel#%d exprptr=%.48s\n", |
scriptlevel,(exprptr==NULL?"null":exprptr)); fflush(msgfp); } |
scriptlevel,(exprptr==NULL?"null":exprptr)); fflush(msgfp); } |
Line 5704 if ( *limtoken != '\000' ) /* have toke
|
Line 6397 if ( *limtoken != '\000' ) /* have toke
|
if ( memcmp("\\limits",limtoken,toklen) == 0 /* may be \limits */ |
if ( memcmp("\\limits",limtoken,toklen) == 0 /* may be \limits */ |
|| memcmp("\\nolimits",limtoken,toklen) == 0 ) /* or may be \nolimits */ |
|| memcmp("\\nolimits",limtoken,toklen) == 0 ) /* or may be \nolimits */ |
if ( (tokdef= get_symdef(limtoken)) /* look up token to be sure */ |
if ( (tokdef= get_symdef(limtoken)) /* look up token to be sure */ |
!= NULL ) /* found token in table */ |
!= NULL ) { /* found token in table */ |
if ( strcmp("\\limits",tokdef->symbol) == 0 ) /* found \limits */ |
if ( strcmp("\\limits",tokdef->symbol) == 0 ) /* found \limits */ |
isdisplay = 1; /* so explicitly set displaymath */ |
isdisplay = 1; /* so explicitly set displaymath */ |
else /* wasn't \limits */ |
else /* wasn't \limits */ |
if ( strcmp("\\nolimits",tokdef->symbol) == 0 ) /* found \nolimits */ |
if ( strcmp("\\nolimits",tokdef->symbol) == 0 ) /* found \nolimits */ |
isdisplay = 0; /* so explicitly reset displaymath */ |
isdisplay = 0; } /* so explicitly reset displaymath */ |
/* --- see if we found \[no]limits --- */ |
/* --- see if we found \[no]limits --- */ |
if ( isdisplay != (-1) ) /* explicit directive found */ |
if ( isdisplay != (-1) ) /* explicit directive found */ |
*expression = exprptr; /* so bump expression past it */ |
*expression = exprptr; /* so bump expression past it */ |
else /* noexplicit directive */ |
else /* noexplicit directive */ |
{ isdisplay = 0; /* init displaymath flag off */ |
{ isdisplay = 0; /* init displaymath flag off */ |
if ( isdisplaystyle ) /* we're in displaystyle math mode */ |
if ( isdisplaystyle ) { /* we're in displaystyle math mode */ |
if ( isdisplaystyle >= 5 ) /* and mode irrevocably forced true */ |
if ( isdisplaystyle >= 5 ) /* and mode irrevocably forced true */ |
{ if ( class!=OPENING && class!=CLOSING ) /*don't force ('s and )'s*/ |
{ if ( class!=OPENING && class!=CLOSING ) /*don't force ('s and )'s*/ |
isdisplay = 1; } /* set flag if mode forced true */ |
isdisplay = 1; } /* set flag if mode forced true */ |
Line 5728 else /* noexplicit directive */
|
Line 6421 else /* noexplicit directive */
|
isdisplay = 1; } /* set flag if mode forced true */ |
isdisplay = 1; } /* set flag if mode forced true */ |
else /* determine mode from base symbol */ |
else /* determine mode from base symbol */ |
if ( class == DISPOPER ) /* it's a displaystyle operator */ |
if ( class == DISPOPER ) /* it's a displaystyle operator */ |
isdisplay = 1; } /* so set flag */ |
isdisplay = 1; } } /* so set flag */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
dispatch call to create sub/superscripts |
dispatch call to create sub/superscripts |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( isdisplay ) /* scripts above/below base symbol */ |
if ( isdisplay ) /* scripts above/below base symbol */ |
scriptsp = rastdispmath(expression,size,basesp); /* everything all done */ |
scriptsp = rastdispmath(expression,size,basesp); /* everything all done */ |
else /* scripts alongside base symbol */ |
else { /* scripts alongside base symbol */ |
if ( (scriptsp=rastscripts(expression,size,basesp)) == NULL ) /*no scripts*/ |
if ( dummybase == NULL ) /* no base symbol preceding scripts*/ |
|
dummybase = rasterize("\\rule0{10}",size); /*guess a typical base symbol*/ |
|
issmashokay = 1; /*haven't found a no-smash char yet*/ |
|
if((scriptsp=rastscripts(expression,size,dummybase)) == NULL) /*no scripts*/ |
scriptsp = basesp; /* so just return unscripted symbol*/ |
scriptsp = basesp; /* so just return unscripted symbol*/ |
else /* symbols followed by scripts */ |
else { /* symbols followed by scripts */ |
|
isscripted = 1; /*signal current term text-scripted*/ |
if ( basesp != NULL ) /* have base symbol */ |
if ( basesp != NULL ) /* have base symbol */ |
{ smashmargin = 0; /* don't smash script */ |
{ /*if(0)smashmargin = 0;*/ /*don't smash script (doesn't work)*/ |
/*scriptsp = rastcat(basesp,scriptsp,2);*//*concat scripts to base sym*/ |
/*scriptsp = rastcat(basesp,scriptsp,2);*//*concat scripts to base sym*/ |
|
/* --- smash (or just concat) script raster against base symbol --- */ |
|
if ( !issmashokay ) /* don't smash leading - */ |
|
if ( !isexplicitsmash ) scriptsp->type = blanksignal; /*don't smash*/ |
scriptsp = rastcat(basesp,scriptsp,3); /*concat scripts to base sym*/ |
scriptsp = rastcat(basesp,scriptsp,3); /*concat scripts to base sym*/ |
scriptsp->type = IMAGERASTER; /* flip type of composite object */ |
if(1) scriptsp->type = IMAGERASTER; /* flip type of composite object */ |
scriptsp->size = size; } /* and set font size */ |
/* --- smash (or just concat) scripted term to stuff to its left --- */ |
|
issmashokay = 1; /* okay to smash base expression */ |
|
if ( 0 && smashcheck > 1 ) /* smashcheck=2 to check base */ |
|
/* note -- we _don't_ have base expression available to check */ |
|
issmashokay = rastsmashcheck(*expression); /*check if okay to smash*/ |
|
if ( !issmashokay ) /* don't smash leading - */ |
|
if ( !isexplicitsmash ) scriptsp->type = blanksignal; /*don't smash*/ |
|
scriptsp->size = size; } } } /* and set font size */ |
end_of_job: |
end_of_job: |
smashmargin = oldsmashmargin; /* reset original smashmargin */ |
smashmargin = oldsmashmargin; /* reset original smashmargin */ |
|
if ( dummybase != basesp ) delete_subraster(dummybase); /*free work area*/ |
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 5804 int szval = min2(max2(size,0),LARGESTSIZ
|
Line 6512 int szval = min2(max2(size,0),LARGESTSIZ
|
/*int istweak = 1;*/ /* true to tweak script positioning */ |
/*int istweak = 1;*/ /* true to tweak script positioning */ |
int rastput(); /*put scripts in constructed raster*/ |
int rastput(); /*put scripts in constructed raster*/ |
int delete_subraster(); /* free work areas */ |
int delete_subraster(); /* free work areas */ |
|
int rastsmashcheck(); /* check if okay to smash scripts */ |
int pixsz = 1; /*default #bits per pixel, 1=bitmap*/ |
int pixsz = 1; /*default #bits per pixel, 1=bitmap*/ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Obtain subscript and/or superscript expressions, and rasterize them/it |
Obtain subscript and/or superscript expressions, and rasterize them/it |
Line 5823 issub = (subsp != (subraster *)NULL); /
|
Line 6532 issub = (subsp != (subraster *)NULL); /
|
issup = (supsp != (subraster *)NULL); /* true if we have superscript */ |
issup = (supsp != (subraster *)NULL); /* true if we have superscript */ |
isboth = (issub && issup); /* true if we have both */ |
isboth = (issub && issup); /* true if we have both */ |
if (!issub && !issup) goto end_of_job; /* quit if we have neither */ |
if (!issub && !issup) goto end_of_job; /* quit if we have neither */ |
|
/* --- check for leading no-smash chars (if enabled) --- */ |
|
issmashokay = 0; /* default, don't smash scripts */ |
|
if ( smashcheck > 0 ) { /* smash checking wanted */ |
|
issmashokay = 1; /*haven't found a no-smash char yet*/ |
|
if ( issub ) /* got a subscript */ |
|
issmashokay = rastsmashcheck(subscript); /* check if okay to smash */ |
|
if ( issmashokay ) /* clean sub, so check sup */ |
|
if ( issup ) /* got a superscript */ |
|
issmashokay = rastsmashcheck(supscript); /* check if okay to smash */ |
|
} /* --- end-of-if(smashcheck>0) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
get height, width, baseline of scripts, and height, baseline of base symbol |
get height, width, baseline of scripts, and height, baseline of base symbol |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 5863 if ( !issub ) /* we only have a super
|
Line 6582 if ( !issub ) /* we only have a super
|
supht+vabove-bdescend); /* sup's bot above base symbol bot */ |
supht+vabove-bdescend); /* sup's bot above base symbol bot */ |
baseline = height-1; } /*sup's baseline at bottom of raster*/ |
baseline = height-1; } /*sup's baseline at bottom of raster*/ |
/* --- subscript only --- */ |
/* --- subscript only --- */ |
if ( !issup ) /* we only have a subscript */ |
if ( !issup ) { /* we only have a subscript */ |
if ( subht > sdescend ) /*sub can descend below base bot...*/ |
if ( subht > sdescend ) /*sub can descend below base bot...*/ |
{ height = subht; /* ...without extra space on top */ |
{ height = subht; /* ...without extra space on top */ |
baseline = height-(sdescend+1); /* sub's bot below base symbol bot */ |
baseline = height-(sdescend+1); /* sub's bot below base symbol bot */ |
baseline = min2(baseline,max2(baseln-vbelow,0)); }/*top below base top*/ |
baseline = min2(baseline,max2(baseln-vbelow,0)); }/*top below base top*/ |
else /* sub's top will be below baseln */ |
else /* sub's top will be below baseln */ |
{ height = sdescend+1; /* sub's bot below base symbol bot */ |
{ height = sdescend+1; /* sub's bot below base symbol bot */ |
baseline = 0; } /* sub's baseline at top of raster */ |
baseline = 0; } } /* sub's baseline at top of raster */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
construct raster with superscript over subscript |
construct raster with superscript over subscript |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 5951 if (!issub && !issup) goto end_of_job; /
|
Line 6670 if (!issub && !issup) goto end_of_job; /
|
stack operator and its script(s) |
stack operator and its script(s) |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- stack superscript atop operator --- */ |
/* --- stack superscript atop operator --- */ |
if ( issup ) /* we have a superscript */ |
if ( issup ) { /* we have a superscript */ |
if ( sp == NULL ) /* but no base expression */ |
if ( sp == NULL ) /* but no base expression */ |
sp = supsp; /* so just use superscript */ |
sp = supsp; /* so just use superscript */ |
else /* have base and superscript */ |
else /* have base and superscript */ |
if ( (sp=rastack(sp,supsp,1,vspace,1,3)) /* stack supsp atop base sp */ |
if ( (sp=rastack(sp,supsp,1,vspace,1,3)) /* stack supsp atop base sp */ |
== NULL ) goto end_of_job; /* and quit if failed */ |
== NULL ) goto end_of_job; } /* and quit if failed */ |
/* --- stack operator+superscript atop subscript --- */ |
/* --- stack operator+superscript atop subscript --- */ |
if ( issub ) /* we have a subscript */ |
if ( issub ) { /* we have a subscript */ |
if ( sp == NULL ) /* but no base expression */ |
if ( sp == NULL ) /* but no base expression */ |
sp = subsp; /* so just use subscript */ |
sp = subsp; /* so just use subscript */ |
else /* have base and subscript */ |
else /* have base and subscript */ |
if ( (sp=rastack(subsp,sp,2,vspace,1,3)) /* stack sp atop base subsp */ |
if ( (sp=rastack(subsp,sp,2,vspace,1,3)) /* stack sp atop base subsp */ |
== NULL ) goto end_of_job; /* and quit if failed */ |
== NULL ) goto end_of_job; } /* and quit if failed */ |
sp->type = IMAGERASTER; /* flip type of composite object */ |
sp->type = IMAGERASTER; /* flip type of composite object */ |
sp->size = size; /* and set font size */ |
sp->size = size; /* and set font size */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 6011 int family=CMSYEX, /* get_delim() fami
|
Line 6730 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 /* *texleft(),*/ subexpr[8192]; /* chars between \left...\right */ |
char /* *texleft(),*/ subexpr[MAXSUBXSZ+1];/*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 isleftscript=0, isrightscript=0; /* true if delims are scripted */ |
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 gotldelim = 0; */ /* true if ildelim given by caller */ |
Line 6185 if ( !isleftdot ) /* if not \left. */
|
Line 6905 if ( !isleftdot ) /* if not \left. */
|
if ( lheight > rheight ) /* got bigger delim than requested */ |
if ( lheight > rheight ) /* got bigger delim than requested */ |
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*/ |
|
isleftscript = isscripted; } /* check if left delim scripted */ |
isdisplaystyle = (istextright?0: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 --- */ |
Line 6194 if ( !isrightdot ) /* and if not \righ
|
Line 6915 if ( !isrightdot ) /* and if not \righ
|
if ( rp != NULL ) /* if get_delim() succeeded */ |
if ( rp != NULL ) /* if get_delim() succeeded */ |
rp->baseline = sp->baseline + ((rp->image)->height - height)/2; |
rp->baseline = sp->baseline + ((rp->image)->height - height)/2; |
/* --- then add on any sub/superscripts attached to \right) --- */ |
/* --- then add on any sub/superscripts attached to \right) --- */ |
rp = rastlimits(expression,size,rp); } /*\right)_c^d, expression past d*/ |
rp = rastlimits(expression,size,rp); /*\right)_c^d, expression past d*/ |
|
isrightscript = isscripted; } /* check if right delim scripted */ |
isdisplaystyle = wasdisplaystyle; /* original \displystyle default */ |
isdisplaystyle = wasdisplaystyle; /* original \displystyle default */ |
/* --- check that we got delimiters --- */ |
/* --- check that we got delimiters --- */ |
if ( 0 ) |
if ( 0 ) |
Line 6216 if ( sp != NULL ) /* succeeded or igno
|
Line 6938 if ( sp != NULL ) /* succeeded or igno
|
sp = rastcat(sp,rp,3); /* concat sp||rp and free sp,rp */ |
sp = rastcat(sp,rp,3); /* concat sp||rp and free sp,rp */ |
/* --- back to caller --- */ |
/* --- back to caller --- */ |
end_of_job: |
end_of_job: |
|
isdelimscript = isrightscript; /* signal if right delim scripted */ |
return ( sp ); |
return ( sp ); |
} /* --- end-of-function rastleft() --- */ |
} /* --- end-of-function rastleft() --- */ |
|
|
Line 6291 subraster *rasterize(), *sp=NULL, *subsp
|
Line 7014 subraster *rasterize(), *sp=NULL, *subsp
|
char *exprptr = *expression, /* local copy of ptr to expression */ |
char *exprptr = *expression, /* local copy of ptr to expression */ |
*texchar(), delim[32][132], /* delimiters following \middle's */ |
*texchar(), delim[32][132], /* delimiters following \middle's */ |
*strtexchr(), /* locate \middle's */ |
*strtexchr(), /* locate \middle's */ |
subexpr[8193], *subptr=NULL; /* subexpression between \middle's */ |
subexpr[MAXSUBXSZ+1], *subptr=NULL;/*subexpression between \middle's*/ |
int height=0, habove=0, hbelow=0; /* height, above & below baseline */ |
int height=0, habove=0, hbelow=0; /* height, above & below baseline */ |
int idelim, ndelims=0, /* \middle count (max 32) */ |
int idelim, ndelims=0, /* \middle count (max 32) */ |
family = CMSYEX; /* delims from CMSY10 or CMEX10 */ |
family = CMSYEX; /* delims from CMSY10 or CMEX10 */ |
Line 6327 while ( ndelims < 30 ) /* max of 31 \m
|
Line 7050 while ( ndelims < 30 ) /* max of 31 \m
|
break; /* so we have all subexpressions */ |
break; /* so we have all subexpressions */ |
if ( (subptr = strtexchr(exprptr,"\\middle")) /* find next \middle */ |
if ( (subptr = strtexchr(exprptr,"\\middle")) /* find next \middle */ |
== NULL ) /* no more \middle's */ |
== NULL ) /* no more \middle's */ |
{ strncpy(subexpr,exprptr,8192); /* get entire remaining expression */ |
{ strncpy(subexpr,exprptr,MAXSUBXSZ); /*get entire remaining expression*/ |
subexpr[8192] = '\000'; /* make sure it's null-terminated */ |
subexpr[MAXSUBXSZ] = '\000'; /* make sure it's null-terminated */ |
exprptr += strlen(exprptr); } /* push exprptr to terminating '\0'*/ |
exprptr += strlen(exprptr); } /* push exprptr to terminating '\0'*/ |
else /* have another \middle */ |
else /* have another \middle */ |
{ int sublen = (int)(subptr-exprptr); /* #chars between \delim...\middle*/ |
{ int sublen = (int)(subptr-exprptr); /* #chars between \delim...\middle*/ |
memcpy(subexpr,exprptr,min2(sublen,8192)); /* get subexpression */ |
memcpy(subexpr,exprptr,min2(sublen,MAXSUBXSZ)); /* get subexpression */ |
subexpr[min2(sublen,8192)] = '\000'; /* and null-terminate it */ |
subexpr[min2(sublen,MAXSUBXSZ)] = '\000'; /* and null-terminate it */ |
exprptr += (sublen+strlen("\\middle")); } /* push exprptr past \middle*/ |
exprptr += (sublen+strlen("\\middle")); } /* push exprptr past \middle*/ |
/* --- rasterize subexpression --- */ |
/* --- rasterize subexpression --- */ |
subsp[ndelims] = rasterize(subexpr,size); /* rasterize subexpresion */ |
subsp[ndelims] = rasterize(subexpr,size); /* rasterize subexpresion */ |
Line 6347 if ( ndelims < 1 /* no delims */
|
Line 7070 if ( ndelims < 1 /* no delims */
|
for ( idelim=0; idelim<=ndelims; idelim++ ) |
for ( idelim=0; idelim<=ndelims; idelim++ ) |
{ |
{ |
/* --- first add on subexpression preceding delim --- */ |
/* --- first add on subexpression preceding delim --- */ |
if ( subsp[idelim] != NULL ) /* have subexpr preceding delim */ |
if ( subsp[idelim] != NULL ) { /* have subexpr preceding delim */ |
if ( sp == NULL ) /* this is first piece */ |
if ( sp == NULL ) /* this is first piece */ |
{ sp = subsp[idelim]; /* so just use it */ |
{ sp = subsp[idelim]; /* so just use it */ |
if ( idelim == 0 ) sp = subrastcpy(sp); } /* or copy leftexpression */ |
if ( idelim == 0 ) sp = subrastcpy(sp); } /* or copy leftexpression */ |
else sp = rastcat(sp,subsp[idelim],(idelim>0?3:1)); /* or concat it */ |
else sp = rastcat(sp,subsp[idelim],(idelim>0?3:1)); } /* or concat it */ |
/* --- now construct delimiter --- */ |
/* --- now construct delimiter --- */ |
if ( *(delim[idelim]) != '\000' ) /* have delimter */ |
if ( *(delim[idelim]) != '\000' ) /* have delimter */ |
{ subraster *delimsp = get_delim(delim[idelim],height,family); |
{ subraster *delimsp = get_delim(delim[idelim],height,family); |
Line 6410 char *texsubexpr(), /* parse expressio
|
Line 7133 char *texsubexpr(), /* parse expressio
|
int argvalue=NOVALUE, /* atoi(valuearg) */ |
int argvalue=NOVALUE, /* atoi(valuearg) */ |
isdelta=0, /* true if + or - precedes valuearg */ |
isdelta=0, /* true if + or - precedes valuearg */ |
valuelen=0; /* strlen(valuearg) */ |
valuelen=0; /* strlen(valuearg) */ |
double strtod(); /*convert ascii {valuearg} to double*/ |
double dblvalue=(-99.), strtod(); /*convert ascii {valuearg} to double*/ |
static int displaystylelevel = (-99); /* \displaystyle set at recurlevel */ |
static int displaystylelevel = (-99); /* \displaystyle set at recurlevel */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
set flag or value |
set flag or value |
Line 6435 switch ( flag )
|
Line 7158 switch ( flag )
|
{ bgred=255-bgred; bggreen=255-bggreen; bgblue=255-bgblue; } |
{ bgred=255-bgred; bggreen=255-bggreen; bgblue=255-bgblue; } |
if ( value==2 || value==NOVALUE ) |
if ( value==2 || value==NOVALUE ) |
isblackonwhite = !isblackonwhite; |
isblackonwhite = !isblackonwhite; |
|
if ( gammacorrection > 0.0001 ) /* have gamma correction */ |
|
gammacorrection = REVERSEGAMMA; /* use reverse video gamma instead */ |
break; |
break; |
case ISSUPER: /* set supersampling/lowpass flag */ |
case ISSUPER: /* set supersampling/lowpass flag */ |
#ifndef SSFONTS /* don't have ss fonts loaded */ |
#ifndef SSFONTS /* don't have ss fonts loaded */ |
Line 6445 switch ( flag )
|
Line 7170 switch ( flag )
|
break; |
break; |
case ISFONTSIZE: /* set fontsize */ |
case ISFONTSIZE: /* set fontsize */ |
case ISDISPLAYSIZE: /* set displaysize */ |
case ISDISPLAYSIZE: /* set displaysize */ |
|
case ISCONTENTTYPE: /*enable/disable content-type lines*/ |
case ISSHRINK: /* set shrinkfactor */ |
case ISSHRINK: /* set shrinkfactor */ |
case ISAAALGORITHM: /* set anti-aliasing algorithm */ |
case ISAAALGORITHM: /* set anti-aliasing algorithm */ |
case ISWEIGHT: /* set font weight */ |
case ISWEIGHT: /* set font weight */ |
Line 6453 switch ( flag )
|
Line 7179 switch ( flag )
|
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 ISSMASH: /* set (minimum) "smash" margin */ |
case ISSMASH: /* set (minimum) "smash" margin */ |
|
case ISGAMMA: /* set gamma correction */ |
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 int value */ |
|
dblvalue = (double)value; } /* or maybe interpreted as double */ |
else /* get value from expression */ |
else /* get value from expression */ |
{ *expression = texsubexpr(*expression,valuearg,1023,"{","}",0,0); |
{ *expression = texsubexpr(*expression,valuearg,1023,"{","}",0,0); |
if ( *valuearg != '\000' ) /* guard against empty string */ |
if ( *valuearg != '\000' ) /* guard against empty string */ |
Line 6463 switch ( flag )
|
Line 7191 switch ( flag )
|
{ isdelta = isthischar(*valuearg,"+-"); /* leading + or - */ |
{ isdelta = isthischar(*valuearg,"+-"); /* leading + or - */ |
if ( memcmp(valuearg,"--",2) == 0 ) /* leading -- signals...*/ |
if ( memcmp(valuearg,"--",2) == 0 ) /* leading -- signals...*/ |
{ isdelta=0; strcpy(valuearg,valuearg+1); } /* ...not delta */ |
{ isdelta=0; strcpy(valuearg,valuearg+1); } /* ...not delta */ |
argvalue = atoi(valuearg); } } /* convert to int */ |
switch ( flag ) { /* convert to double or int */ |
|
default: argvalue = atoi(valuearg); break; /* convert to int */ |
|
case ISGAMMA: |
|
dblvalue = strtod(valuearg,NULL); break; } /* or to double */ |
|
} /* --- end-of-if(*valuearg!='?') --- */ |
|
} /* --- end-of-if(value==NOVALUE) --- */ |
switch ( flag ) |
switch ( flag ) |
{ |
{ |
default: break; |
default: break; |
Line 6493 switch ( flag )
|
Line 7226 switch ( flag )
|
|| (1 && isdisplaystyle==2) /* displaystyle enabled and set */ |
|| (1 && isdisplaystyle==2) /* displaystyle enabled and set */ |
|| (0 && isdisplaystyle==0) )/*\textstyle disabled displaystyle*/ |
|| (0 && isdisplaystyle==0) )/*\textstyle disabled displaystyle*/ |
if ( displaystylelevel != recurlevel ) /*respect \displaystyle*/ |
if ( displaystylelevel != recurlevel ) /*respect \displaystyle*/ |
if ( !ispreambledollars ) /* respect $$...$$'s */ |
if ( !ispreambledollars ) { /* respect $$...$$'s */ |
if ( fontsize >= displaysize ) |
if ( fontsize >= displaysize ) |
isdisplaystyle = 2; /* forced */ |
isdisplaystyle = 2; /* forced */ |
else isdisplaystyle = 1; |
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 6509 switch ( flag )
|
Line 7242 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 ISCONTENTTYPE: /*enable/disable content-type lines*/ |
|
if ( argvalue != NOVALUE ) /* got a value */ |
|
isemitcontenttype = (argvalue>0?1:0); |
|
break; |
case ISSMASH: /* set (minimum) "smash" margin */ |
case ISSMASH: /* set (minimum) "smash" margin */ |
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
{ smashmargin = argvalue; /* set value */ |
{ smashmargin = argvalue; /* set value */ |
if ( arg3 != NOVALUE ) isdelta=arg3; /* hard-coded isdelta */ |
if ( arg3 != NOVALUE ) isdelta=arg3; /* hard-coded isdelta */ |
issmashdelta = (isdelta?1:0); } /* and set delta flag */ |
issmashdelta = (isdelta?1:0); } /* and set delta flag */ |
smashmargin = max2((isdelta?-5:0),min2(smashmargin,32)); /*sanity*/ |
smashmargin = max2((isdelta?-5:0),min2(smashmargin,32)); /*sanity*/ |
|
isexplicitsmash = 1; /* signal explicit \smash directive*/ |
break; |
break; |
case ISSHRINK: /* set shrinkfactor */ |
case ISSHRINK: /* set shrinkfactor */ |
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
Line 6522 switch ( flag )
|
Line 7260 switch ( flag )
|
shrinkfactor = max2(1,min2(shrinkfactor,27)); /* sanity check */ |
shrinkfactor = max2(1,min2(shrinkfactor,27)); /* sanity check */ |
break; |
break; |
case ISAAALGORITHM: /* set anti-aliasing algorithm */ |
case ISAAALGORITHM: /* set anti-aliasing algorithm */ |
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) { /* got a value */ |
aaalgorithm = argvalue; /* set algorithm number */ |
if ( argvalue >= 0 ) { /* non-negative to set algorithm */ |
aaalgorithm = max2(0,min2(aaalgorithm,3)); /* bounds check */ |
aaalgorithm = argvalue; /* set algorithm number */ |
|
aaalgorithm = max2(0,min2(aaalgorithm,4)); } /* bounds check */ |
|
else maxfollow = abs(argvalue); } /* or maxfollow=abs(negative#) */ |
break; |
break; |
case ISWEIGHT: /* set font weight number */ |
case ISWEIGHT: /* set font weight number */ |
value = (argvalue==NOVALUE? NOVALUE : /* don't have a value */ |
value = (argvalue==NOVALUE? NOVALUE : /* don't have a value */ |
Line 6553 switch ( flag )
|
Line 7293 switch ( flag )
|
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
cornerwt = argvalue; /* set lowpass corner weight */ |
cornerwt = argvalue; /* set lowpass corner weight */ |
break; |
break; |
|
case ISGAMMA: /* set gamma correction */ |
|
if ( dblvalue >= 0.0 ) /* got a value */ |
|
gammacorrection = dblvalue; /* set gamma correction */ |
|
break; |
} /* --- end-of-switch() --- */ |
} /* --- end-of-switch() --- */ |
break; |
break; |
case PNMPARAMS: /*set fgalias,fgonly,bgalias,bgonly*/ |
case PNMPARAMS: /*set fgalias,fgonly,bgalias,bgonly*/ |
Line 6595 return ( NULL ); /*just set value, not
|
Line 7339 return ( NULL ); /*just set value, not
|
* width (I) int containing #bits/pixels for space width |
* width (I) int containing #bits/pixels for space width |
* isfill (I) int containing true to \hfill complete |
* isfill (I) int containing true to \hfill complete |
* expression out to width |
* expression out to width |
|
* (Kludge: isfill=99 signals \hspace* |
|
* for negative space) |
* isheight (I) int containing true (but not NOVALUE) |
* isheight (I) int containing true (but not NOVALUE) |
* to treat width arg as height |
* to treat width arg as height |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 6611 subraster *rastspace ( char **expression
|
Line 7357 subraster *rastspace ( char **expression
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
subraster *new_subraster(), *spacesp=NULL; /* subraster for space */ |
subraster *new_subraster(), *spacesp=NULL; /* subraster for space */ |
|
raster *bp=NULL, *backspace_raster(); /* for negative space */ |
|
int delete_subraster(); /* if fail, free unneeded subraster*/ |
int baseht=1, baseln=0; /* height,baseline of base symbol */ |
int baseht=1, baseln=0; /* height,baseline of base symbol */ |
int pixsz = 1; /*default #bits per pixel, 1=bitmap*/ |
int pixsz = 1; /*default #bits per pixel, 1=bitmap*/ |
|
int isstar=0, minspace=0; /* defaults for negative hspace */ |
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 */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
|
if ( isfill > 1 ) { isstar=1; isfill=0; } /* large fill signals \hspace* */ |
if ( isfill == NOVALUE ) isfill=0; /* novalue means false */ |
if ( isfill == NOVALUE ) isfill=0; /* novalue means false */ |
if ( isheight == NOVALUE ) isheight=0; /* novalue means false */ |
if ( isheight == NOVALUE ) isheight=0; /* novalue means false */ |
|
minspace = (isstar?(-1):0); /* reset default minspace */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
determine width if not given (e.g., \hspace{width}, \hfill{width}) |
determine width if not given (e.g., \hspace{width}, \hfill{width}) |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( width <= 0 ) /* width specified in expression */ |
if ( width == 0 ) { /* width specified in expression */ |
{ int widthval; /* test {width} before using it */ |
double dwidth; int widthval; /* test {width} before using it */ |
width = 1; /* set default width */ |
int minwidth = (isfill||isheight?1:-600); /* \hspace allows negative */ |
*expression = texsubexpr(*expression,widtharg,255,"{","}",0,0); |
/* --- check if optional [minspace] given for negative \hspace --- */ |
widthval = /* convert {width} to integer */ |
if ( *(*expression) == '[' ) { /* [minspace] if leading char is [ */ |
(int)((unitlength*strtod(widtharg,NULL))+0.5); |
/* ---parse [minspace], bump expression past it, interpret as double--- */ |
if ( widthval>=2 && widthval<=600 ) /* sanity check */ |
*expression = texsubexpr(*expression,widtharg,127,"[","]",0,0); |
width = widthval; } /* replace deafault width */ |
if ( *widtharg != '\000' ) /* got [minspace] */ |
|
minspace = iround(unitlength*strtod(widtharg,NULL)); /* in pixels */ |
|
} /* --- end-of-if(*(*expression)=='[') --- */ |
|
width = 1; /* set default width */ |
|
*expression = texsubexpr(*expression,widtharg,255,"{","}",0,0); |
|
dwidth = unitlength*strtod(widtharg,NULL); /* scaled width value */ |
|
widthval = /* convert {width} to integer */ |
|
(int)( dwidth + (dwidth>=0.0?0.5:(-0.5)) ); |
|
if ( widthval>=minwidth && widthval<=600 ) /* sanity check */ |
|
width = widthval; /* replace deafault width */ |
|
} /* --- end-of-if(width==0) --- */ |
|
/* ------------------------------------------------------------------------- |
|
first check for negative space |
|
-------------------------------------------------------------------------- */ |
|
if ( width < 0 ) { /* have negative hspace */ |
|
if ( leftexpression != (subraster *)NULL ) /* can't backspace */ |
|
if ( (spacesp=new_subraster(0,0,0)) /* get new subraster for backspace */ |
|
!= NULL ) { /* and if we succeed... */ |
|
int nback=(-width), pback; /*#pixels wanted,actually backspaced*/ |
|
if ( (bp=backspace_raster(leftexpression->image,nback,&pback,minspace,0)) |
|
!= NULL ) { /* and if backspace succeeds... */ |
|
spacesp->image = bp; /* save backspaced image */ |
|
/*spacesp->type = leftexpression->type;*/ /* copy original type */ |
|
spacesp->type = blanksignal; /* need to propagate blanks */ |
|
spacesp->size = leftexpression->size; /* copy original font size */ |
|
spacesp->baseline = leftexpression->baseline; /* and baseline */ |
|
blanksymspace += -(nback-pback); /* wanted more than we got */ |
|
isreplaceleft = 1; } /*signal to replace entire expressn*/ |
|
else { /* backspace failed */ |
|
delete_subraster(spacesp); /* free unneeded envelope */ |
|
spacesp = (subraster *)NULL; } } /* and signal failure */ |
|
goto end_of_job; |
|
} /* --- end-of-if(width<0) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
see if width is "absolute" or fill width |
see if width is "absolute" or fill width |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 6659 if ( width > 0 ) /*make sure we have p
|
Line 7442 if ( width > 0 ) /*make sure we have p
|
!= NULL ) /* and if we succeed... */ |
!= NULL ) /* and if we succeed... */ |
{ /* --- ...re-init subraster parameters --- */ |
{ /* --- ...re-init subraster parameters --- */ |
spacesp->size = size; /*propagate base font size forward*/ |
spacesp->size = size; /*propagate base font size forward*/ |
|
if(1)spacesp->type = blanksignal; /* need to propagate blanks (???) */ |
spacesp->baseline = baseln; } /* ditto baseline */ |
spacesp->baseline = baseln; } /* ditto baseline */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
concat right half if \hfill-ing |
concat right half if \hfill-ing |
Line 6668 if ( rightsp != NULL ) /* we have a ri
|
Line 7452 if ( rightsp != NULL ) /* we have a ri
|
rastcat(spacesp,rightsp,3)); /* or cat right half after space */ |
rastcat(spacesp,rightsp,3)); /* or cat right half after space */ |
spacesp->type = blanksignal; /* need to propagate blanks */ |
spacesp->type = blanksignal; /* need to propagate blanks */ |
*expression += strlen((*expression)); } /* push expression to its null */ |
*expression += strlen((*expression)); } /* push expression to its null */ |
return ( spacesp ); |
end_of_job: |
|
return ( spacesp ); |
} /* --- end-of-function rastspace() --- */ |
} /* --- end-of-function rastspace() --- */ |
|
|
|
|
Line 7071 subraster *rastfrac ( char **expression,
|
Line 7856 subraster *rastfrac ( char **expression,
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), /*parse expression for numer,denom*/ |
char *texsubexpr(), /*parse expression for numer,denom*/ |
numer[8192], denom[8192]; /*numer,denom parsed from expression*/ |
numer[MAXSUBXSZ+1], denom[MAXSUBXSZ+1]; /* parsed numer, denom */ |
subraster *rasterize(), *numsp=NULL, *densp=NULL; /*rasterize numer, denom*/ |
subraster *rasterize(), *numsp=NULL, *densp=NULL; /*rasterize numer, denom*/ |
subraster *rastack(), *fracsp=NULL; /* subraster for numer/denom */ |
subraster *rastack(), *fracsp=NULL; /* subraster for numer/denom */ |
subraster *new_subraster()/*, *spacesp=NULL*/; /* space for num or den */ |
subraster *new_subraster()/*, *spacesp=NULL*/; /* space for num or den */ |
Line 7128 width = (fracsp->image)->width; /*just
|
Line 7913 width = (fracsp->image)->width; /*just
|
/* --- initialize subraster parameters --- */ |
/* --- initialize subraster parameters --- */ |
fracsp->size = size; /* propagate font size forward */ |
fracsp->size = size; /* propagate font size forward */ |
fracsp->baseline = (numheight+vspace+lineheight)+(size+2);/*default baseline*/ |
fracsp->baseline = (numheight+vspace+lineheight)+(size+2);/*default baseline*/ |
|
fracsp->type = FRACRASTER; /* signal \frac image */ |
if ( basesp != (subraster *)NULL ) /* we have base symbol for frac */ |
if ( basesp != (subraster *)NULL ) /* we have base symbol for frac */ |
{ baseht = (basesp->image)->height; /* height of base symbol */ |
{ baseht = (basesp->image)->height; /* height of base symbol */ |
baseln = basesp->baseline; /* and its baseline */ |
baseln = basesp->baseline; /* and its baseline */ |
Line 7135 if ( basesp != (subraster *)NULL ) /* we
|
Line 7921 if ( basesp != (subraster *)NULL ) /* we
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
draw horizontal line between numerator and denominator |
draw horizontal line between numerator and denominator |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
|
fraccenterline = numheight+vspace; /* signal that we have a \frac */ |
if ( isfrac ) /*line for \frac, but not for \atop*/ |
if ( isfrac ) /*line for \frac, but not for \atop*/ |
rule_raster(fracsp->image,numheight+vspace,0,width,lineheight,0); |
rule_raster(fracsp->image,fraccenterline,0,width,lineheight,0); |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
return final result to caller |
return final result to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 7179 subraster *rastackrel ( char **expressio
|
Line 7966 subraster *rastackrel ( char **expressio
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), /*parse expression for numer,denom*/ |
char *texsubexpr(), /*parse expression for upper,lower*/ |
upper[8192], lower[8192]; /*upper,lower parsed from expression*/ |
upper[MAXSUBXSZ+1], lower[MAXSUBXSZ+1]; /* parsed upper, lower */ |
subraster *rasterize(), *upsp=NULL, *lowsp=NULL; /* rasterize upper, lower */ |
subraster *rasterize(), *upsp=NULL, *lowsp=NULL; /* rasterize upper, lower */ |
subraster *rastack(), *relsp=NULL; /* subraster for upper/lower */ |
subraster *rastack(), *relsp=NULL; /* subraster for upper/lower */ |
int upsize = (base==1? size:size-1), /* font size for upper component */ |
int upsize = (base==1? size:size-1), /* font size for upper component */ |
Line 7252 subraster *rastmathfunc ( char **express
|
Line 8039 subraster *rastmathfunc ( char **express
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texscripts(), /* parse expression for _limits */ |
char *texscripts(), /* parse expression for _limits */ |
func[4096], limits[8192]; /* func as {\rm func}, limits */ |
func[MAXTOKNSZ+1], limits[MAXSUBXSZ+1]; /*func as {\rm func}, limits*/ |
char *texsubexpr(), /* parse expression for arg */ |
char *texsubexpr(), /* parse expression for arg */ |
funcarg[2048]; /* optional func arg */ |
funcarg[MAXTOKNSZ+1]; /* optional func arg */ |
subraster *rasterize(), *funcsp=NULL, *limsp=NULL; /*rasterize func,limits*/ |
subraster *rasterize(), *funcsp=NULL, *limsp=NULL; /*rasterize func,limits*/ |
subraster *rastack(), *mathfuncsp=NULL; /* subraster for mathfunc/limits */ |
subraster *rastack(), *mathfuncsp=NULL; /* subraster for mathfunc/limits */ |
int limsize = size-1; /* font size for limits */ |
int limsize = size-1; /* font size for limits */ |
Line 7358 subraster *rastsqrt ( char **expression,
|
Line 8145 subraster *rastsqrt ( char **expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192], /* parse subexpr to be sqrt-ed */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], /*parse subexpr to be sqrt-ed*/ |
rootarg[8192]; /* optional \sqrt[rootarg]{...} */ |
rootarg[MAXSUBXSZ+1]; /* optional \sqrt[rootarg]{...} */ |
subraster *rasterize(), *subsp=NULL; /* rasterize subexpr */ |
subraster *rasterize(), *subsp=NULL; /* rasterize subexpr */ |
subraster *accent_subraster(), *sqrtsp=NULL, /* subraster with the sqrt */ |
subraster *accent_subraster(), *sqrtsp=NULL, /* subraster with the sqrt */ |
*new_subraster(), *rootsp=NULL; /* optionally preceded by [rootarg]*/ |
*new_subraster(), *rootsp=NULL; /* optionally preceded by [rootarg]*/ |
Line 7474 subraster *rastaccent ( char **expressio
|
Line 8261 subraster *rastaccent ( char **expressio
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192]; /* parse subexpr to be accented */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1]; /*parse subexpr to be accented*/ |
char *texscripts(), *script=NULL, /* \under,overbrace allow scripts */ |
char *texscripts(), *script=NULL, /* \under,overbrace allow scripts */ |
subscript[512], supscript[512]; /* scripts parsed from expression */ |
subscript[MAXTOKNSZ+1], supscript[MAXTOKNSZ+1]; /* parsed scripts */ |
subraster *rasterize(), *subsp=NULL, *scrsp=NULL; /*rasterize subexpr,script*/ |
subraster *rasterize(), *subsp=NULL, *scrsp=NULL; /*rasterize subexpr,script*/ |
subraster *rastack(), *accsubsp=NULL; /* stack accent, subexpr, script */ |
subraster *rastack(), *accsubsp=NULL; /* stack accent, subexpr, script */ |
subraster *accent_subraster(), *accsp=NULL; /*raster for the accent itself*/ |
subraster *accent_subraster(), *accsp=NULL; /*raster for the accent itself*/ |
Line 7585 subraster *rastfont ( char **expression,
|
Line 8372 subraster *rastfont ( char **expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), fontchars[8192], /*parse chars to be rendered in font*/ |
char *texsubexpr(), fontchars[MAXSUBXSZ+1], /* chars to render in font */ |
subexpr[8192]; /* turn \cal{AB} into \calA\calB */ |
subexpr[MAXSUBXSZ+1]; /* 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; /* fontinfo[ifontnum].name */ |
char *name = NULL; /* fontinfo[ifontnum].name */ |
int family = 0, /* fontinfo[ifontnum].family */ |
int family = 0, /* fontinfo[ifontnum].family */ |
Line 7608 static struct {char *name; int class;}
|
Line 8395 static struct {char *name; int class;}
|
{ "\\textit", -1 }, /*(4) \it,\textit{abc}-->{\it~abc} */ |
{ "\\textit", -1 }, /*(4) \it,\textit{abc}-->{\it~abc} */ |
{ "\\mathbb", -1 }, /*(5) \bb,\mathbb{abc}-->{\bb~abc} */ |
{ "\\mathbb", -1 }, /*(5) \bb,\mathbb{abc}-->{\bb~abc} */ |
{ "\\mathbf", -1 }, /*(6) \bf,\mathbf{abc}-->{\bf~abc} */ |
{ "\\mathbf", -1 }, /*(6) \bf,\mathbf{abc}-->{\bf~abc} */ |
|
{ "\\mathrm", -1 }, /*(7) \mathrm */ |
|
{ "\\cyr", -1 }, /*(8) \cyr */ |
{ NULL, 0 } |
{ NULL, 0 } |
} ; /* --- end-of-fonts[] --- */ |
} ; /* --- end-of-fonts[] --- */ |
#endif |
#endif |
Line 7620 family = fontinfo[ifontnum].family; /* f
|
Line 8409 family = fontinfo[ifontnum].family; /* f
|
istext = fontinfo[ifontnum].istext; /*true in text mode (respect space)*/ |
istext = fontinfo[ifontnum].istext; /*true in text mode (respect space)*/ |
class = fontinfo[ifontnum].class; /* font class */ |
class = fontinfo[ifontnum].class; /* font class */ |
if ( istext ) /* text (respect blanks) */ |
if ( istext ) /* text (respect blanks) */ |
smashmargin = 0; /* don't smash internal blanks */ |
{ mathsmashmargin = smashmargin; /* needed for \text{if $n-m$ even} */ |
|
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 |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 7706 back to caller with chars rendered in fo
|
Line 8496 back to caller with chars rendered in fo
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
end_of_job: |
end_of_job: |
smashmargin = oldsmashmargin; /* restore smash */ |
smashmargin = oldsmashmargin; /* restore smash */ |
|
mathsmashmargin = SMASHMARGIN; /* this one probably not necessary */ |
if ( istext && fontsp!=NULL ) /* raster contains text mode font */ |
if ( istext && fontsp!=NULL ) /* raster contains text mode font */ |
fontsp->type = blanksignal; /* signal nosmash */ |
fontsp->type = blanksignal; /* signal nosmash */ |
return ( fontsp ); /* chars rendered in font */ |
return ( fontsp ); /* chars rendered in font */ |
Line 7742 subraster *rastbegin ( char **expression
|
Line 8533 subraster *rastbegin ( char **expression
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8210], /* \begin{} environment paramaters */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], /* \begin{} environment params*/ |
*exprptr=NULL,*begptr=NULL,*endptr=NULL,*braceptr=NULL; /* ptrs */ |
*exprptr=NULL,*begptr=NULL,*endptr=NULL,*braceptr=NULL; /* ptrs */ |
char *begtoken="\\begin{", *endtoken="\\end{"; /*tokens we're looking for*/ |
char *begtoken="\\begin{", *endtoken="\\end{"; /*tokens we're looking for*/ |
int strreplace(); /* replace substring in string */ |
int strreplace(); /* replace substring in string */ |
Line 7755 int envlen=0, sublen=0; /* #chars in en
|
Line 8546 int envlen=0, sublen=0; /* #chars in en
|
static int blevel = 0; /* \begin...\end nesting level */ |
static int blevel = 0; /* \begin...\end nesting level */ |
static char *mdelims[] = { NULL, NULL, NULL, NULL, |
static char *mdelims[] = { NULL, NULL, NULL, NULL, |
"()","[]","{}","||","==", /* for pbBvVmatrix */ |
"()","[]","{}","||","==", /* for pbBvVmatrix */ |
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
NULL, NULL, NULL, NULL, "{.", NULL, NULL, NULL, NULL, NULL, NULL, |
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; |
static char *environs[] = { /* types of environments we process*/ |
static char *environs[] = { /* types of environments we process*/ |
"eqnarray", /* 0 eqnarray environment */ |
"eqnarray", /* 0 eqnarray environment */ |
Line 7771 static char *environs[] = { /* types of
|
Line 8562 static char *environs[] = { /* types of
|
"align", /* 10 align environment */ |
"align", /* 10 align environment */ |
"verbatim", /* 11 verbatim environment */ |
"verbatim", /* 11 verbatim environment */ |
"picture", /* 12 picture environment */ |
"picture", /* 12 picture environment */ |
|
"cases", /* 13 cases environment */ |
|
"equation", /* 14 for \begin{equation} */ |
NULL }; /* trailer */ |
NULL }; /* trailer */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
determine type of environment we're beginning |
determine type of environment we're beginning |
Line 7832 switch ( ienviron )
|
Line 8625 switch ( ienviron )
|
if ( *(subexpr+8) == '\000' ) goto end_of_job; } /* quit if no arg */ |
if ( *(subexpr+8) == '\000' ) goto end_of_job; } /* quit if no arg */ |
strcat(subexpr,"{"); /* opening { after (width,height) */ |
strcat(subexpr,"{"); /* opening { after (width,height) */ |
break; |
break; |
|
case 13: /* cases */ |
|
strcat(subexpr,"\\array{ll$"); /* a&b \\ c&d etc */ |
|
break; |
|
case 14: /* \begin{equation} */ |
|
strcat(subexpr,"{"); /* just enclose expression in {}'s */ |
|
break; |
} /* --- end-of-switch(ienviron) --- */ |
} /* --- end-of-switch(ienviron) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
locate matching \end{...} |
locate matching \end{...} |
Line 7979 subraster *rastarray ( char **expression
|
Line 8778 subraster *rastarray ( char **expression
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8210], *exprptr, /* parse array subexpr */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], *exprptr, /*parse array subexpr*/ |
subtok[4096], *subptr=subtok, /* & or \\ inside { }'s not a delim*/ |
subtok[MAXTOKNSZ+1], *subptr=subtok, /* &,\\ inside { } not a delim*/ |
token[4096], *tokptr=token, /* token from subexpr to rasterize */ |
token[MAXTOKNSZ+1], *tokptr=token, /* subexpr token to rasterize */ |
*preamble(), *preptr=token; /*process optional size,lcr preamble*/ |
*preamble(), *preptr=token; /*process optional size,lcr preamble*/ |
char *coldelim="&", *rowdelim="\\"; /* need escaped rowdelim */ |
char *coldelim="&", *rowdelim="\\"; /* need escaped rowdelim */ |
int maxarraysz = 64; /* max #rows, cols */ |
int maxarraysz = 64; /* max #rows, cols */ |
Line 8128 while ( *preptr != '\000' ) /* check p
|
Line 8927 while ( *preptr != '\000' ) /* check p
|
if ( prepcase != 0 ) /* only check upper,lowercase */ |
if ( prepcase != 0 ) /* only check upper,lowercase */ |
{ |
{ |
int ispropagate = (*preptr=='+'?1:0); /* leading + propagates width/ht */ |
int ispropagate = (*preptr=='+'?1:0); /* leading + propagates width/ht */ |
if ( ispropagate ) /* set row or col propagation */ |
if ( ispropagate ) { /* set row or col propagation */ |
if ( prepcase == 1 ) colpropagate = 1; /* propagating col values */ |
if ( prepcase == 1 ) colpropagate = 1; /* propagating col values */ |
else if ( prepcase == 2 ) rowpropagate = 1; /* propagating row values */ |
else if ( prepcase == 2 ) rowpropagate = 1; } /*propagating row values*/ |
if ( !colpropagate && prepcase == 1 ) |
if ( !colpropagate && prepcase == 1 ) |
{ colwidth[icol] = 0; /* reset colwidth */ |
{ colwidth[icol] = 0; /* reset colwidth */ |
fixcolsize[icol] = 0; } /* reset width flag */ |
fixcolsize[icol] = 0; } /* reset width flag */ |
Line 8234 while ( 1 ) /* scan chars till end */
|
Line 9033 while ( 1 ) /* scan chars till end */
|
tokptr=token; skipwhite(tokptr); /* skip whitespace after // */ |
tokptr=token; skipwhite(tokptr); /* skip whitespace after // */ |
tokptr = texchar(tokptr,hltoken); /* extract first char from token */ |
tokptr = texchar(tokptr,hltoken); /* extract first char from token */ |
hltoklen = strlen(hltoken); /* length of first char */ |
hltoklen = strlen(hltoken); /* length of first char */ |
if ( hltoklen >= minhltoklen ) /*token must be at least \hl or \hd*/ |
if ( hltoklen >= minhltoklen ) { /*token must be at least \hl or \hd*/ |
if ( memcmp(hlchar,hltoken,hltoklen) == 0 ) /* we have an \hline */ |
if ( memcmp(hlchar,hltoken,hltoklen) == 0 ) /* we have an \hline */ |
hline[nrows] += 1; /* bump \hline count for row */ |
hline[nrows] += 1; /* bump \hline count for row */ |
else if ( memcmp(hdchar,hltoken,hltoklen) == 0 ) /*we have an \hdash*/ |
else if ( memcmp(hdchar,hltoken,hltoklen) == 0 ) /*we have an \hdash*/ |
hline[nrows] = (-1); /* set \hdash flag for row */ |
hline[nrows] = (-1); } /* set \hdash flag for row */ |
if ( hline[nrows] != 0 ) /* \hline or \hdash prefixes token */ |
if ( hline[nrows] != 0 ) /* \hline or \hdash prefixes token */ |
{ 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 */ |
Line 8654 end_of_job:
|
Line 9453 end_of_job:
|
* string immediately following \line to be |
* string immediately following \line to be |
* rasterized, and returning ptr immediately |
* rasterized, and returning ptr immediately |
* following last character processed. |
* following last character processed. |
* size (I) int containing 0-4 default font size |
* size (I) int containing 0-7 default font size |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \line |
* immediately preceding \line |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
Line 8739 if ( msgfp!=NULL && msglevel>=29 ) /* de
|
Line 9538 if ( msgfp!=NULL && msglevel>=29 ) /* de
|
fprintf(msgfp,"rastline> width,height,origin;x,yinc=%d,%d,%d;%g,%g\n", |
fprintf(msgfp,"rastline> width,height,origin;x,yinc=%d,%d,%d;%g,%g\n", |
width,height,origin,xinc,yinc); |
width,height,origin,xinc,yinc); |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
allocate subraster and raster for complete picture |
allocate subraster and raster for line |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- sanity check on width,height,thickness args --- */ |
/* --- sanity check on width,height,thickness args --- */ |
if ( width < 1 || width > 600 |
if ( width < 1 || width > 600 |
Line 8774 end_of_job:
|
Line 9573 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rastrule ( expression, size, basesp, arg1, arg2, arg3 ) |
|
* Purpose: \rule handler, returns subraster corresponding to rule |
|
* parameters [lift]{width}{height} |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I/O) char ** to first char of null-terminated |
|
* string immediately following \rule to be |
|
* rasterized, and returning ptr immediately |
|
* following last character processed. |
|
* size (I) int containing 0-7 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding \rule |
|
* (unused, but passed for consistency) |
|
* arg1 (I) int unused |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) ptr to subraster corresponding to rule |
|
* requested, or NULL for any parsing error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Summary of syntax... |
|
* \rule[lift]{width}{height} |
|
* o if [lift] not given, then bottom of rule on baseline |
|
* o if width=0 then you get an invisible strut 1 (one) pixel wide |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rastrule ( char **expression, int size, subraster *basesp, |
|
int arg1, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *texsubexpr(), rulexpr[257]; /* rule[lift]{wdth}{hgt} */ |
|
subraster *new_subraster(), *rulesp=NULL; /* subraster for rule */ |
|
int pixsz = 1; /* pixels are one bit each */ |
|
int lift=0, width=0, height=0; /* default rule parameters */ |
|
double strtod(), dval; /* convert ascii params to doubles */ |
|
int rwidth=0, rheight=0; /* alloc width, height plus lift */ |
|
int rule_raster(); /* draw rule in rulesp->image */ |
|
/* ------------------------------------------------------------------------- |
|
Obtain lift,width,height |
|
-------------------------------------------------------------------------- */ |
|
/* --- check for optional lift arg --- */ |
|
if ( *(*expression) == '[' ) /*check for []-enclosed optional arg*/ |
|
{ *expression = texsubexpr(*expression,rulexpr,255,"[","]",0,0); |
|
dval = (int)(strtod(rulexpr,NULL)+0.5); /* convert [lift] to int */ |
|
if ( dval <= 99 && dval >= (-99) ) /* sanity check */ |
|
lift = iround(unitlength*dval); } /* scale by unitlength and round */ |
|
/* --- parse for width --- */ |
|
*expression = texsubexpr(*expression,rulexpr,255,"{","}",0,0); |
|
if ( *rulexpr == '\000' ) goto end_of_job; /* quit if args missing */ |
|
dval = (int)(strtod(rulexpr,NULL)+0.5); /* convert {width} to int */ |
|
if ( dval <= 500 && dval >= 0 ) /* sanity check */ |
|
width = max2(0,iround(unitlength*dval)); /* scale by unitlength and round*/ |
|
/* --- parse for height --- */ |
|
*expression = texsubexpr(*expression,rulexpr,255,"{","}",0,0); |
|
if ( *rulexpr == '\000' ) goto end_of_job; /* quit if args missing */ |
|
dval = (int)(strtod(rulexpr,NULL)+0.5); /* convert {height} to int */ |
|
if ( dval <= 500 && dval > 0 ) /* sanity check */ |
|
height= max2(1,iround(unitlength*dval)); /* scale by unitlength and round*/ |
|
/* --- raster width,height in pixels --- */ |
|
rwidth = max2(1,width); /* raster must be at least 1 pixel*/ |
|
rheight = height + (lift>=0?lift: /* raster height plus lift */ |
|
(-lift<height?0:-lift-height+1)); /* may need empty space above rule */ |
|
/* ------------------------------------------------------------------------- |
|
allocate subraster and raster for rule |
|
-------------------------------------------------------------------------- */ |
|
/* --- sanity check on width,height,thickness args --- */ |
|
if ( rwidth < 1 || rwidth > 600 |
|
|| rheight < 1 || rheight > 600 ) goto end_of_job; |
|
/* --- allocate and initialize subraster for constructed rule --- */ |
|
if ( (rulesp=new_subraster(rwidth,rheight,pixsz)) /* alloc new subraster */ |
|
== NULL ) goto end_of_job; /* quit if failed */ |
|
/* --- initialize line subraster parameters --- */ |
|
rulesp->type = IMAGERASTER; /* image */ |
|
rulesp->symdef = NULL; /* not applicable for image */ |
|
rulesp->baseline = rheight-1 + (lift>=0?0:lift); /*adjust baseline for lift*/ |
|
rulesp->size = size; /* size (probably unneeded) */ |
|
/* ------------------------------------------------------------------------- |
|
draw the rule |
|
-------------------------------------------------------------------------- */ |
|
rule_raster ( rulesp->image, /* embedded raster image */ |
|
(-lift<height?0:rheight-height), /* topmost row for top-left corner*/ |
|
0, /* leftmost col for top-left corner*/ |
|
width, /* rule width */ |
|
height, /* rule height */ |
|
( width>0? 0:4 ) ); /* rule type */ |
|
/* ------------------------------------------------------------------------- |
|
return constructed rule to caller |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
return ( rulesp ); /* return rule to caller */ |
|
} /* --- end-of-function rastrule() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: rastcircle ( expression, size, basesp, arg1, arg2, arg3 ) |
* Function: rastcircle ( expression, size, basesp, arg1, arg2, arg3 ) |
* Purpose: \circle handler, returns subraster corresponding to ellipse |
* Purpose: \circle handler, returns subraster corresponding to ellipse |
* parameters (xdiam[,ydiam]) |
* parameters (xdiam[,ydiam]) |
Line 9021 end_of_job:
|
Line 9915 end_of_job:
|
* string immediately following \raisebox to be |
* string immediately following \raisebox to be |
* rasterized, and returning ptr immediately |
* rasterized, and returning ptr immediately |
* following last character processed. |
* following last character processed. |
* size (I) int containing 0-5 default font size |
* size (I) int containing 0-7 default font size |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \rotatebox |
* immediately preceding \raisebox |
* (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 9043 subraster *rastraise ( char **expression
|
Line 9937 subraster *rastraise ( char **expression
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192], *liftexpr=subexpr; /* args */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], *liftexpr=subexpr; /* args */ |
subraster *rasterize(), *raisesp=NULL; /* rasterize subexpr to be raised */ |
subraster *rasterize(), *raisesp=NULL; /* rasterize subexpr to be raised */ |
int lift=0; /* amount to raise/lower baseline */ |
int lift=0; /* amount to raise/lower baseline */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 9083 end_of_job:
|
Line 9977 end_of_job:
|
* string immediately following \rotatebox to be |
* string immediately following \rotatebox to be |
* rasterized, and returning ptr immediately |
* rasterized, and returning ptr immediately |
* following last character processed. |
* following last character processed. |
* size (I) int containing 0-5 default font size |
* size (I) int containing 0-7 default font size |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \rotatebox |
* immediately preceding \rotatebox |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
Line 9105 subraster *rastrotate ( char **expressio
|
Line 9999 subraster *rastrotate ( char **expressio
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192], *degexpr=subexpr; /* args */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], *degexpr=subexpr; /* args */ |
subraster *rasterize(), *rotsp=NULL; /* subraster for rotated subexpr */ |
subraster *rasterize(), *rotsp=NULL; /* subraster for rotated subexpr */ |
raster *rastrot(), *rotrp=NULL; /* rotate subraster->image 90 degs */ |
raster *rastrot(), *rotrp=NULL; /* rotate subraster->image 90 degs */ |
int delete_raster(); /* delete intermediate rasters */ |
int delete_raster(); /* delete intermediate rasters */ |
Line 9173 if ( rotrp != NULL ) /* rotated raster
|
Line 10067 if ( rotrp != NULL ) /* rotated raster
|
{ rotsp->type = IMAGERASTER; /* signal constructed image */ |
{ rotsp->type = IMAGERASTER; /* signal constructed image */ |
rotsp->image = rotrp; /* raster we just constructed */ |
rotsp->image = rotrp; /* raster we just constructed */ |
/* --- now try to guess pleasing baseline --- */ |
/* --- now try to guess pleasing baseline --- */ |
if ( idegrees > 2 ) /* leave unchanged if unrotated */ |
if ( idegrees > 2 ) { /* leave unchanged if unrotated */ |
if ( strlen(subexpr) < 3 /* we rotated a short expression */ |
if ( strlen(subexpr) < 3 /* we rotated a short expression */ |
|| abs(idegrees-180) < 3 ) /* or just turned it upside-down */ |
|| abs(idegrees-180) < 3 ) /* or just turned it upside-down */ |
baseline = rotrp->height - 1; /* so set with nothing descending */ |
baseline = rotrp->height - 1; /* so set with nothing descending */ |
else /* rotated a long expression */ |
else /* rotated a long expression */ |
baseline = (65*(rotrp->height-1))/100; /* roughly center long expr */ |
baseline = (65*(rotrp->height-1))/100; } /* roughly center long expr */ |
rotsp->baseline = baseline; } /* set baseline as calculated above*/ |
rotsp->baseline = baseline; } /* set baseline as calculated above*/ |
/* --- return rotated subexpr to caller --- */ |
/* --- return rotated subexpr to caller --- */ |
end_of_job: |
end_of_job: |
Line 9187 end_of_job:
|
Line 10081 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rastreflect ( expression, size, basesp, arg1, arg2, arg3 ) |
|
* Purpose: \reflectbox[axis]{subexpression} handler, returns subraster |
|
* containing subexpression reflected horizontally (i.e., around |
|
* vertical axis, |_ becomes _|) if [axis] not given or axis=1, |
|
* or reflected vertically if axis=2 given. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I/O) char ** to first char of null-terminated |
|
* string immediately following \reflectbox to |
|
* be rasterized, and returning ptr immediately |
|
* following last character processed. |
|
* size (I) int containing 0-7 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding \reflectbox |
|
* (unused, but passed for consistency) |
|
* arg1 (I) int unused |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) ptr to subraster corresponding to \reflectbox |
|
* requested, or NULL for any parsing error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Summary of syntax... |
|
* \reflectbox[axis]{subexpression} |
|
* o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rastreflect ( char **expression, int size, subraster *basesp, |
|
int arg1, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *texsubexpr(), subexpr[MAXSUBXSZ+1], *axisexpr=subexpr; /* args */ |
|
subraster *rasterize(), *refsp=NULL; /* subraster for reflected subexpr */ |
|
raster *rastref(), *refrp=NULL; /* reflect subraster->image */ |
|
int axis = 1; /* default horizontal reflection */ |
|
int delete_raster(); /* delete intermediate raster */ |
|
int baseline=0; /* baseline of rasterized image */ |
|
/* ------------------------------------------------------------------------- |
|
obtain [axis] argument immediately following \reflectbox command, if given |
|
-------------------------------------------------------------------------- */ |
|
/* --- check for optional [axis] arg --- */ |
|
if ( *(*expression) == '[' ) /*check for []-enclosed optional arg*/ |
|
{ *expression = texsubexpr(*expression,axisexpr,255,"[","]",0,0); |
|
axis = atoi(axisexpr); /* convert [axis] to int */ |
|
if ( axis<1 || axis>2 ) /* check axis input */ |
|
axis = 1; } /* back to default if illegal */ |
|
/* ------------------------------------------------------------------------- |
|
obtain {subexpr} argument after optional [axis], and rasterize it |
|
-------------------------------------------------------------------------- */ |
|
/* --- parse for {subexpr} arg, and bump expression past it --- */ |
|
*expression = texsubexpr(*expression,subexpr,0,"{","}",0,0); |
|
/* --- rasterize subexpression to be reflected --- */ |
|
if ( (refsp = rasterize(subexpr,size)) /* rasterize subexpression */ |
|
== NULL ) goto end_of_job; /* and quit if failed */ |
|
/* --- return unmodified image if no reflection requested --- */ |
|
if ( axis<1 || axis>2 ) goto end_of_job; /* don't bother reflecting image */ |
|
/* --- extract params for image to be reflected --- */ |
|
refrp = refsp->image; /* unreflected rasterized image */ |
|
baseline = refsp->baseline; /* and baseline of that image */ |
|
/* ------------------------------------------------------------------------- |
|
reflect image and adjust its parameters |
|
-------------------------------------------------------------------------- */ |
|
/* --- reflect image --- */ |
|
refrp = rastref(refsp->image,axis); /* reflect raster image */ |
|
if ( refrp == NULL ) goto end_of_job; /* failed to reflect image */ |
|
delete_raster(refsp->image); /* free original raster image */ |
|
refsp->image = refrp; /*and replace it with reflected one*/ |
|
/* --- adjust parameters --- */ |
|
if ( axis == 2 ) /* for vertical reflection */ |
|
baseline = refrp->height - 1; /* set with nothing descending */ |
|
refsp->baseline = baseline; /* reset baseline of reflected image*/ |
|
/* --- return reflected subexpr to caller --- */ |
|
end_of_job: |
|
return ( refsp ); /*back to caller with reflected expr*/ |
|
} /* --- end-of-function rastreflect() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: rastfbox ( expression, size, basesp, arg1, arg2, arg3 ) |
* Function: rastfbox ( expression, size, basesp, arg1, arg2, arg3 ) |
* Purpose: \fbox{subexpression} handler, returns subraster |
* Purpose: \fbox{subexpression} handler, returns subraster |
* containing subexpression with frame box drawn around it |
* containing subexpression with frame box drawn around it |
Line 9217 subraster *rastfbox ( char **expression,
|
Line 10190 subraster *rastfbox ( char **expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192], widtharg[512]; /* args */ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1], widtharg[512]; /* args */ |
subraster *rasterize(), *framesp=NULL; /* rasterize subexpr to be framed */ |
subraster *rasterize(), *framesp=NULL; /* rasterize subexpr to be framed */ |
raster *border_raster(), *bp=NULL; /* framed image raster */ |
raster *border_raster(), *bp=NULL; /* framed image raster */ |
double strtod(); /* interpret [width][height] */ |
double strtod(); /* interpret [width][height] */ |
Line 9305 subraster *rastinput ( char **expression
|
Line 10278 subraster *rastinput ( char **expression
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), tag[512]="\000", filename[1024]="\000"; /* args */ |
char *texsubexpr(), tag[1024]="\000", filename[1024]="\000"; /* args */ |
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] = "\000", /* concatanated lines from input file */ |
char subexpr[MAXFILESZ+1] = "\000", /*concatanated lines from input file*/ |
*mimeprep(), /* preprocess inputted data */ |
*mimeprep(), /* preprocess inputted data */ |
*dbltoa(), *reformat=NULL; /* reformat numerical input */ |
*dbltoa(), *reformat=NULL; /* reformat numerical input */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 9317 obtain [tag]{filename} argument
|
Line 10290 obtain [tag]{filename} argument
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- parse for optional [tag] or [fmt] arg, bump expression past it --- */ |
/* --- parse for optional [tag] or [fmt] arg, bump expression past it --- */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
{ char argfld[2048]; /* optional argument field */ |
{ char argfld[MAXTOKNSZ+1]; /* optional argument field */ |
*expression = texsubexpr(*expression,argfld,2047,"[","]",0,0); |
*expression = texsubexpr(*expression,argfld,MAXTOKNSZ,"[","]",0,0); |
if ( (reformat=strstr(argfld,"dtoa")) != NULL ) /*dtoa/dbltoa requested*/ |
if ( (reformat=strstr(argfld,"dtoa")) != NULL ) /*dtoa/dbltoa requested*/ |
{ format = 1; /* signal dtoa()/dbltoa() format */ |
{ format = 1; /* signal dtoa()/dbltoa() format */ |
if ( (reformat=strchr(reformat,'=')) != NULL ) /* have dtoa= */ |
if ( (reformat=strchr(reformat,'=')) != NULL ) /* have dtoa= */ |
Line 9386 subraster *rastcounter ( char **expressi
|
Line 10359 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"; /*optional log file and tag*/ |
logfile[1024]="\000", tag[1024]="\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 status=0,rastreadfile(),rastwritefile(), /*read,write counter file*/ |
int status=0,rastreadfile(),rastwritefile(), /*read,write counter file*/ |
isstrict = 1; /* true to only write to existing files */ |
isstrict = 1; /* true to only write to existing files */ |
char text[8192] = "1_", /* only line in counter file without tags */ |
char text[MAXFILESZ] = "1_", /* only line in counter file without tags */ |
*delim = NULL, /* delimiter in text */ |
*delim = NULL, /* delimiter in text */ |
utext[128] = "1_", /* default delimiter */ |
utext[128] = "1_", /* default delimiter */ |
*udelim = utext+1; /* underscore delimiter */ |
*udelim = utext+1; /* underscore delimiter */ |
Line 9414 first obtain optional [value][logfile] a
|
Line 10387 first obtain optional [value][logfile] a
|
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
{ *expression = texsubexpr(*expression,text,1023,"[","]",0,0); |
{ *expression = texsubexpr(*expression,text,1023,"[","]",0,0); |
if ( *text != '\000' ) /* got counter value (or logfile) */ |
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 ( isthischar(*text,"+-0123456789") ) /* check for leading +-digit */ |
if ( isthischar(*text,"+-0123456789") ) /* check for leading +-digit */ |
gotvalue = 1; /* signal we got optional value */ |
gotvalue = 1; /* signal we got optional value */ |
else /* not +-digit, so must be logfile */ |
else /* not +-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 ( *filename != '\000' ) /* got logfile (or counter 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 ( !(isthischar(*text,"+-0123456789")) /* not a leading +-digit */ |
if ( !(isthischar(*text,"+-0123456789")) /* not a leading +-digit */ |
|| gotvalue ) /* 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 /* leading +-digit 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 */ |
gotvalue = 1; } /* and signal we got optional value*/ |
gotvalue = 1; } } /* and signal we got optional value*/ |
} /* --- end-of-if(**expression=='[') --- */ |
} /* --- end-of-if(**expression=='[') --- */ |
/* --- evaluate [value] if present --- */ |
/* --- evaluate [value] if present --- */ |
if ( gotvalue ) { /*leading +-digit should be in text*/ |
if ( gotvalue ) { /*leading +-digit should be in text*/ |
Line 9693 subraster *rastnoop ( char **expression,
|
Line 10666 subraster *rastnoop ( char **expression,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), subexpr[8192]; /* flush dummy args eaten by \escape*/ |
char *texsubexpr(), subexpr[MAXSUBXSZ+1]; /*dummy args eaten by \escape*/ |
subraster *rasterize(), *noopsp=NULL; /* rasterize subexpr */ |
subraster *rasterize(), *noopsp=NULL; /* rasterize subexpr */ |
/* --- flush accompanying args if necessary --- */ |
/* --- flush accompanying args if necessary --- */ |
if ( nargs != NOVALUE /* not unspecified */ |
if ( nargs != NOVALUE /* not unspecified */ |
Line 9729 FILE *rastopenfile ( char *filename, cha
|
Line 10702 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, edited copy of filename */ |
char texfile[2050] = "\000", /* local, edited copy of filename */ |
*rasteditfilename(), /* prepend pathprefix if necessary */ |
*rasteditfilename(), /* prepend pathprefix if necessary */ |
amode[128] = "r"; /* test open mode if arg mode=NULL */ |
amode[512] = "r"; /* test open mode if arg mode=NULL */ |
int ismode = 0; /* true of mode!=NULL */ |
int ismode = 0; /* true of mode!=NULL */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
Check mode and open file |
Check mode and open file |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- edit filename --- */ |
/* --- edit filename --- */ |
strcpy(texfile,rasteditfilename(filename)); /*edited copy of input filename*/ |
strncpy(texfile,rasteditfilename(filename),2047); /*edited copy of filename*/ |
|
texfile[2047] = '\000'; /* make sure it's null terminated */ |
/* --- 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 */ |
{ ismode = 1; /* so flip mode flag true */ |
{ ismode = 1; /* so flip mode flag true */ |
strcpy(amode,mode); /* and replace "r" with caller's */ |
strncpy(amode,mode,254); /* and replace "r" with caller's */ |
|
amode[254] = '\000'; /* make sure it's null terminated */ |
compress(amode,' '); } /* remove embedded blanks */ |
compress(amode,' '); } /* remove embedded blanks */ |
/* --- open filename or filename.tex --- */ |
/* --- open filename or filename.tex --- */ |
if ( strlen(texfile) > 1 ) /* make sure we got actual filename*/ |
if ( strlen(texfile) > 1 ) /* make sure we got actual filename*/ |
Line 9784 char *rasteditfilename ( char *filename
|
Line 10759 char *rasteditfilename ( char *filename
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
static char editname[2048]; /*edited filename returned to caller*/ |
static char editname[2050]; /*edited filename returned to caller*/ |
char *strchange(); /* prepend pathprefix if necessary */ |
char *strchange(); /* prepend pathprefix if necessary */ |
int strreplace(), /* remove ../'s and ..\'s */ |
int strreplace(), /* remove ../'s and ..\'s */ |
isprefix = (*pathprefix=='\000'?0:1); /* true if paths have prefix */ |
isprefix = (*pathprefix=='\000'?0:1); /* true if paths have prefix */ |
Line 9845 int rastreadfile ( char *filename, int i
|
Line 10820 int rastreadfile ( char *filename, int i
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
FILE *fp = (FILE *)NULL, *rastopenfile(); /* pointer to opened filename */ |
FILE *fp = (FILE *)NULL, *rastopenfile(); /* pointer to opened filename */ |
char texfile[2048] = "\000", /* local copy of input filename */ |
char texfile[1024] = "\000", /* local copy of input filename */ |
text[4096]; /* line from input file */ |
text[MAXLINESZ+1]; /* line from input file */ |
char *tagp, tag1[512], tag2[512]; /* left <tag> and right <tag/> */ |
char *tagp, tag1[1024], tag2[1024]; /* left <tag> and right <tag/> */ |
int vallen=0, maxvallen=8000; /* #chars in value, max allowed */ |
int vallen=0, maxvallen=MAXFILESZ; /* #chars in value, max allowed */ |
int status = (-1); /* 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 */ |
/*int islock = 1;*/ /* true to lock file */ |
Line 9860 if ( value == (char *)NULL ) goto end_of
|
Line 10835 if ( value == (char *)NULL ) goto end_of
|
*value = '\000'; /* init buffer with empty string */ |
*value = '\000'; /* init buffer with empty string */ |
/* --- 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 */ |
{ strncpy(texfile,filename,1023); /* local copy of filename */ |
|
texfile[1023] = '\000'; /* make sure it's null terminated */ |
fp = rastopenfile(texfile,(islock?"r+":"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 */ |
Line 9881 if ( tag != (char *)NULL ) /* caller pa
|
Line 10857 if ( tag != (char *)NULL ) /* caller pa
|
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
Read file, concatnate lines |
Read file, concatnate lines |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
while ( fgets(text,4090,fp) != (char *)NULL ) { /* read input till eof */ |
while ( fgets(text,MAXLINESZ-1,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: status = 1; 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> */ |
Line 9939 int rastwritefile( char *filename, char
|
Line 10915 int rastwritefile( char *filename, char
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
FILE *fp = (FILE *)NULL, *rastopenfile(); /* pointer to opened filename */ |
FILE *fp = (FILE *)NULL, *rastopenfile(); /* pointer to opened filename */ |
char texfile[2048] = "\000", /* local copy of input filename */ |
char texfile[1024] = "\000", /* local copy of input filename */ |
filebuff[16384] = "\000", /* entire contents of file */ |
filebuff[MAXFILESZ+1] = "\000", /* entire contents of file */ |
tag1[512], tag2[512], /* left <tag> and right <tag/> */ |
tag1[1024], tag2[1024], /* left <tag> and right <tag/> */ |
*strchange(), /* put value between <tag>...</tag>*/ |
*strchange(), /* put value between <tag>...</tag>*/ |
*timestamp(); /* log modification time */ |
*timestamp(); /* log modification time */ |
int istag=0, rastreadfile(), /* read file if tag!=NULL */ |
int istag=0, rastreadfile(), /* read file if tag!=NULL */ |
Line 9958 if ( filename == (char *)NULL /* quit i
|
Line 10934 if ( filename == (char *)NULL /* quit i
|
if ( strlen(filename) < 2 /* quit if unreasonable filename */ |
if ( strlen(filename) < 2 /* quit if unreasonable filename */ |
|| *value == '\000' ) goto end_of_job; /* or empty value string supplied */ |
|| *value == '\000' ) goto end_of_job; /* or empty value string supplied */ |
/* --- establish filename[.tex] --- */ |
/* --- establish filename[.tex] --- */ |
strcpy(texfile,filename); /* local copy of input filename */ |
strncpy(texfile,filename,1023); /* local copy of input filename */ |
|
texfile[1023] = '\000'; /* make sure it's null terminated */ |
if ( rastopenfile(texfile,NULL) /* unchanged or .tex appended */ |
if ( rastopenfile(texfile,NULL) /* unchanged or .tex appended */ |
== (FILE *)NULL ) /* can't open, so write new file */ |
== (FILE *)NULL ) /* can't open, so write new file */ |
{ if ( isstrict ) goto end_of_job; /* fail if new files not permitted */ |
{ if ( isstrict ) goto end_of_job; /* fail if new files not permitted */ |
Line 10016 if ( istag ) /* only replacing tag in
|
Line 10993 if ( istag ) /* only replacing tag in
|
>= 0 ) /* usually <tag> precedes </tag> */ |
>= 0 ) /* usually <tag> precedes </tag> */ |
strchange(flen,tagp1+tlen1,value); /* change ...'s to value */ |
strchange(flen,tagp1+tlen1,value); /* change ...'s to value */ |
else /* weirdly, </tag> precedes <tag> */ |
else /* weirdly, </tag> precedes <tag> */ |
{ char fbuff[2048]; /* field buff for <tag>value</tag> */ |
{ char fbuff[4096]; /* field buff for <tag>value</tag> */ |
if ( (flen = ((int)(tagp1-tagp2))+tlen1) /* strlen(</tag>...<tag>) */ |
if ( (flen = ((int)(tagp1-tagp2))+tlen1) /* strlen(</tag>...<tag>) */ |
<= 0 ) goto end_of_job; /* must be internal error */ |
<= 0 ) goto end_of_job; /* must be internal error */ |
strcpy(fbuff,tag1); /* set opening <tag> */ |
strcpy(fbuff,tag1); /* set opening <tag> */ |
Line 10140 for ( idd=1; idd<=modays[month]; idd++ )
|
Line 11117 for ( idd=1; idd<=modays[month]; idd++ )
|
else /* not today's date */ |
else /* not today's date */ |
strcat(calbuff,aval); /* so just put in idd */ |
strcat(calbuff,aval); /* so just put in idd */ |
/* --- terminate cell --- */ |
/* --- terminate cell --- */ |
if ( idd < modays[month] ) /* not yet end-of-month */ |
if ( idd < modays[month] ) { /* not yet end-of-month */ |
if ( iday < 6 ) /* still have days left in week */ |
if ( iday < 6 ) /* still have days left in week */ |
strcat(calbuff,"&"); /* new cell in same week */ |
strcat(calbuff,"&"); /* new cell in same week */ |
else /* reached end-of-week */ |
else /* reached end-of-week */ |
strcat(calbuff,"\\\\ \\hline"); /* so start new week */ |
strcat(calbuff,"\\\\ \\hline"); } /* so start new week */ |
} /* --- end-of-for(idd) --- */ |
} /* --- end-of-for(idd) --- */ |
strcat(calbuff,"\\\\ \\hline"); /* final underline at end-of-month */ |
strcat(calbuff,"\\\\ \\hline"); /* final underline at end-of-month */ |
/* --- return calendar to caller --- */ |
/* --- return calendar to caller --- */ |
Line 10392 char *dbltoa ( double dblval, int npts )
|
Line 11369 char *dbltoa ( double dblval, int npts )
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
------------------------------------------------------------------------- */ |
------------------------------------------------------------------------- */ |
static char finval[128]; /* buffer returned to caller */ |
static char finval[256]; /* buffer returned to caller */ |
static char digittbl[32]="0123456789*"; /* table of ascii decimal digits */ |
static char digittbl[32]="0123456789*"; /* table of ascii decimal digits */ |
char *finptr = finval; /* ptr to next char being converted*/ |
char *finptr = finval; /* ptr to next char being converted*/ |
double floor(); /* integer which is glb(double) */ |
double floor(); /* integer which is glb(double) */ |
Line 10557 for ( irow=0; irow<rp->height; irow++ )
|
Line 11534 for ( irow=0; irow<rp->height; irow++ )
|
&& bytemap[ipixel] > blackscale ) /* weighted avg > blackscale */ |
&& bytemap[ipixel] > blackscale ) /* weighted avg > blackscale */ |
bytemap[ipixel] = grayscale-1; } /* so force it entirely black */ |
bytemap[ipixel] = grayscale-1; } /* so force it entirely black */ |
/*--- only anti-alias pixels whose adjacent pixels fall within bounds ---*/ |
/*--- only anti-alias pixels whose adjacent pixels fall within bounds ---*/ |
if ( !iscenter ) /* apply min/maxadjacent test */ |
if ( !iscenter ) { /* apply min/maxadjacent test */ |
if ( isminmaxwts ) /* min/max refer to adjacent weights*/ |
if ( isminmaxwts ) /* min/max refer to adjacent weights*/ |
{ if ( wadjacent < minadjacent /* wts of adjacent points too low */ |
{ if ( wadjacent < minadjacent /* wts of adjacent points too low */ |
|| wadjacent > maxadjacent ) /* or too high */ |
|| wadjacent > maxadjacent ) /* or too high */ |
Line 10565 for ( irow=0; irow<rp->height; irow++ )
|
Line 11542 for ( irow=0; irow<rp->height; irow++ )
|
else /* min/max refer to #adjacent points*/ |
else /* min/max refer to #adjacent points*/ |
{ if ( nadjacent < minadjacent /* too few adjacent points black */ |
{ if ( nadjacent < minadjacent /* too few adjacent points black */ |
|| nadjacent > maxadjacent ) /* or too many */ |
|| nadjacent > maxadjacent ) /* or too many */ |
bytemap[ipixel] = 0; } /* so leave point white */ |
bytemap[ipixel] = 0; } } /* so leave point white */ |
} /* --- end-of-for(irow,icol) --- */ |
} /* --- end-of-for(irow,icol) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Back to caller with gray-scale anti-aliased bytemap |
Back to caller with gray-scale anti-aliased bytemap |
Line 10607 int width=rp->width, height=rp->height,
|
Line 11584 int width=rp->width, height=rp->height,
|
icol = 0, irow = 0, /* width, height indexes */ |
icol = 0, irow = 0, /* width, height indexes */ |
imap = (-1); /* pixel index = icol + irow*width */ |
imap = (-1); /* pixel index = icol + irow*width */ |
int bgbitval=0, fgbitval=1; /* background, foreground bitval */ |
int bgbitval=0, fgbitval=1; /* background, foreground bitval */ |
|
int isfirstaa = 1; /*debugging switch signals 1st pixel*/ |
#if 0 |
#if 0 |
int totwts=12, wts[9]={1,1,1, 1,4,1, 1,1,1}; /* pnmalias default wts */ |
int totwts=12, wts[9]={1,1,1, 1,4,1, 1,1,1}; /* pnmalias default wts */ |
int totwts=16, wts[9]={1,2,1, 2,4,2, 1,2,1}; /* weights */ |
int totwts=16, wts[9]={1,2,1, 2,4,2, 1,2,1}; /* weights */ |
Line 10729 for ( irow=0; irow<height; irow++ )
|
Line 11707 for ( irow=0; irow<height; irow++ )
|
double aawtval = ((double)aasumval)/((double)totwts); /* weighted val */ |
double aawtval = ((double)aasumval)/((double)totwts); /* weighted val */ |
aabyteval= (int)(((double)(grayscale-1))*aawtval+0.5); /*0...grayscale-1*/ |
aabyteval= (int)(((double)(grayscale-1))*aawtval+0.5); /*0...grayscale-1*/ |
bytemap[imap] = (intbyte)(aabyteval); /* set antialiased pixel */ |
bytemap[imap] = (intbyte)(aabyteval); /* set antialiased pixel */ |
if ( msglevel>=99 && msgfp!=NULL ) fprintf(msgfp, /* debugging */ |
if ( msglevel>=99 && msgfp!=NULL ) { fprintf(msgfp, /*diagnostic output*/ |
"aapnm> irow,icol,imap=%d,%d,%d aawtval=%.4f aabyteval=%d\n", |
"%s> irow,icol,imap=%d,%d,%d aawtval=%.4f aabyteval=%d\n", |
|
(isfirstaa?"aapnm algorithm":"aapnm"), |
irow,icol,imap, aawtval,aabyteval); |
irow,icol,imap, aawtval,aabyteval); |
|
isfirstaa = 0; } |
} /* --- end-of-if(isedge) --- */ |
} /* --- end-of-if(isedge) --- */ |
} /* --- end-of-for(irow,icol) --- */ |
} /* --- end-of-for(irow,icol) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 10743 Back to caller with gray-scale anti-alia
|
Line 11723 Back to caller with gray-scale anti-alia
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: aapnmlookup ( rp, bytemap, grayscale ) |
|
* Purpose: calculates a lowpass anti-aliased bytemap |
|
* for rp->bitmap, with each byte 0...grayscale-1, |
|
* based on the pnmalias.c algorithm. |
|
* This version uses aagridnum() and aapatternnum() lookups |
|
* to interpret 3x3 lowpass pixel grids. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* bytemap (O) intbyte * to bytemap, calculated |
|
* by applying pnm-based filter to rp->bitmap, |
|
* and returned (as you'd expect) in 1-to-1 |
|
* addressing correspondence with rp->bitmap |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 1=success, 0=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Based on the pnmalias.c algorithm in the netpbm package |
|
* on sourceforge. |
|
* o This version uses aagridnum() and aapatternnum() lookups |
|
* to interpret 3x3 lowpass pixel grids. |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapnmlookup (raster *rp, intbyte *bytemap, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int width=rp->width, height=rp->height, /* width, height of raster */ |
|
icol = 0, irow = 0, /* width, height indexes */ |
|
imap = (-1); /* pixel index = icol + irow*width */ |
|
int bgbitval=0, fgbitval=1; /* background, foreground bitval */ |
|
int isfirstaa = 1; /*debugging switch signals 1st pixel*/ |
|
int aacenterwt=centerwt, aaadjacentwt=adjacentwt, aacornerwt=cornerwt, |
|
totwts = centerwt + 4*(adjacentwt+cornerwt); /*pnmalias default wts*/ |
|
int isfgalias = fgalias, /*(1) true to antialias fg bits */ |
|
isfgonly = fgonly, /*(0) true to only antialias fg bits*/ |
|
isbgalias = bgalias, /*(0) true to antialias bg bits */ |
|
isbgonly = bgonly; /*(0) true to only antialias bg bits*/ |
|
int gridnum=(-1), aagridnum(), /* grid# for 3x3 grid at irow,icol */ |
|
patternum=(-1), aapatternnum(); /*pattern#, 1-51, for input gridnum*/ |
|
int aapatterns(); /* to antialias special patterns */ |
|
/* --- |
|
* pattern number data |
|
* ------------------- */ |
|
/* --- number of adjacent fg pixels set in pattern --- */ |
|
static int nadjacents[] = { -1, /* #adjacent fg pixels for pattern */ |
|
0, 4, 0, 1, 4, 3, 1, 0, 1, 0, /* 1-10 */ |
|
2, 2, 3, 4, 3, 4, 2, 2, 1, 2, /* 11-20 */ |
|
1, 2, 1, 2, 0, 1, 3, 2, 3, 2, /* 21-30 */ |
|
3, 2, 3, 2, 4, 3, 1, 2, 2, 2, /* 31-40 */ |
|
2, 1, 2, 2, 3, 0, 3, 2, 2, 1, 4, /* 41-51 */ |
|
-1 } ; /* --- end-of-nadjacents[] --- */ |
|
/* --- number of corner fg pixels set in pattern --- */ |
|
static int ncorners[] = { -1, /* #corner fg pixels for pattern */ |
|
0, 4, 1, 0, 3, 4, 1, 2, 1, 2, /* 1-10 */ |
|
0, 0, 3, 2, 3, 2, 4, 4, 2, 1, /* 11-20 */ |
|
2, 1, 2, 1, 3, 2, 0, 1, 2, 3, /* 21-30 */ |
|
2, 3, 2, 3, 1, 2, 4, 3, 2, 2, /* 31-40 */ |
|
2, 3, 2, 2, 1, 4, 1, 2, 2, 3, 0, /* 41-51 */ |
|
-1 } ; /* --- end-of-ncorners[] --- */ |
|
/* --- 0,1,2=pattern contains horizontal bg,fg,both edge; -1=no edge --- */ |
|
static int horzedges[] = { -1, /* 0,1,2 = horz bg,fg,both edge */ |
|
0, 1, 0, 0, 1, 1, 0, 0, 0, -1, /* 1-10 */ |
|
0, -1, 1, 1, 1, -1, 1, -1, 2, 0, /* 11-20 */ |
|
-1, -1, -1, 0, -1, -1, -1, -1, 2, 1, /* 21-30 */ |
|
-1, -1, -1, 1, -1, -1, -1, -1, 2, -1, /* 31-40 */ |
|
-1, 1, 1, -1, -1, -1, 0, 0, -1, -1, -1, /* 41-51 */ |
|
-1 } ; /* --- end-of-horzedges[] --- */ |
|
/* --- 0,1,2=pattern contains vertical bg,fg,both edge; -1=no edge --- */ |
|
static int vertedges[] = { -1, /* 0,1,2 = vert bg,fg,both edge */ |
|
0, 1, 0, 0, 1, 1, 0, -1, -1, -1, /* 1-10 */ |
|
0, 0, 1, -1, -1, -1, 1, 1, -1, -1, /* 11-20 */ |
|
-1, 0, 0, 0, -1, -1, 0, -1, -1, -1, /* 21-30 */ |
|
-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, /* 31-40 */ |
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 41-51 */ |
|
-1 } ; /* --- end-of-vertedges[] --- */ |
|
/* --- 0,1,2=pattern contains diagonal bg,fg,both edge; -1=no edge --- */ |
|
static int diagedges[] = { -1, /* 0,1,2 = diag bg,fg,both edge */ |
|
0, 1, 0, 0, 1, 1, 0, 0, 0, 0, /* 1-10 */ |
|
2, -1, 1, 1, 1, 1, 1, -1, 0, 2, /* 11-20 */ |
|
0, -1, 0, 2, 0, -1, 1, 1, 1, 1, /* 21-30 */ |
|
1, -1, 1, 2, 1, 1, -1, 1, 2, -1, /* 31-40 */ |
|
1, 0, -1, 2, 1, 0, 1, -1, 1, -1, 1, /* 41-51 */ |
|
-1 } ; /* --- end-of-diagedges[] --- */ |
|
/* ------------------------------------------------------------------------- |
|
Calculate bytemap as 9-point weighted average over bitmap |
|
-------------------------------------------------------------------------- */ |
|
for ( irow=0; irow<height; irow++ ) |
|
for ( icol=0; icol<width; icol++ ) |
|
{ |
|
/* --- local allocations and declarations --- */ |
|
int bitval=0, /* value of rp bit at irow,icol */ |
|
isbgdiag=0, isfgdiag=0, /*does pixel border a bg or fg edge*/ |
|
aabyteval=0; /* antialiased (or unchanged) value*/ |
|
/* --- get gridnum and center bit value, init aabyteval --- */ |
|
imap++; /* first set imap=icol + irow*width*/ |
|
gridnum = aagridnum(rp,irow,icol); /*grid# coding 3x3 grid at irow,icol*/ |
|
bitval = (gridnum&1); /* center bit set if gridnum odd */ |
|
aabyteval = (intbyte)(bitval==bgbitval?0:grayscale-1); /* default aa val */ |
|
bytemap[imap] = (intbyte)(aabyteval); /* init antialiased pixel */ |
|
if ( gridnum<0 || gridnum>511 ) continue; /* gridnum out of bounds*/ |
|
/* --- check if we're antialiasing this pixel --- */ |
|
if ( (isbgonly && bitval==fgbitval) /* only antialias background bit */ |
|
|| (isfgonly && bitval==bgbitval) ) /* only antialias foreground bit */ |
|
continue; /* leave default and do next bit */ |
|
/* --- look up pattern number, 1-51, corresponding to input gridnum --- */ |
|
patternum = aapatternnum(gridnum); /* look up pattern number */ |
|
if ( patternum<1 || patternum>51 ) continue; /* some internal error */ |
|
/* --- special pattern number processing --- */ |
|
if ( (aabyteval = aapatterns(rp,irow,icol,gridnum,patternum,grayscale)) |
|
>= 0 ) { /* special processing for pattern */ |
|
bytemap[imap] = (intbyte)(aabyteval); /* set antialiased pixel */ |
|
continue; } /* and continue with next pixel */ |
|
/* --- check for diagonal edges --- */ |
|
isbgdiag = ( diagedges[patternum]==2 || /*current pixel borders a bg edge*/ |
|
diagedges[patternum]==0 ); |
|
isfgdiag = ( diagedges[patternum]==2 || /*current pixel borders a fg edge*/ |
|
diagedges[patternum]==1 ); |
|
/* ---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 */ |
|
horzedge=horzedges[patternum], vertedge=vertedges[patternum]; |
|
isbghorz = (horzedge==2||horzedge==0); /* top or bottom edge is all bg */ |
|
isfghorz = (horzedge==2||horzedge==1); /* top or bottom edge is all fg */ |
|
isbgvert = (vertedge==2||vertedge==0); /* left or right edge is all bg */ |
|
isfgvert = (vertedge==2||vertedge==1); /* left or right edge is all fg */ |
|
if ( (isbghorz && isbgvert && (bitval==fgbitval)) /* we're at an...*/ |
|
|| (isfghorz && isfgvert && (bitval==bgbitval)) ) /*...inside corner */ |
|
continue; /* don't antialias */ |
|
} /* --- end-of-if(1) --- */ |
|
#if 0 |
|
/* --- 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) --- */ |
|
#endif |
|
/* --- antialias if necessary --- */ |
|
if ( (isbgalias && isbgdiag) /* alias pixel surrounding bg */ |
|
|| (isfgalias && isfgdiag) /* alias pixel surrounding fg */ |
|
|| (isbgdiag && isfgdiag) ) /* neighboring fg and bg pixel */ |
|
{ |
|
int aasumval = /* sum wts[]*bitmap[] */ |
|
aacenterwt*bitval + /* apply centerwt to center pixel */ |
|
aaadjacentwt*nadjacents[patternum] + /* similarly for adjacents */ |
|
aacornerwt*ncorners[patternum]; /* and corners */ |
|
double aawtval = ((double)aasumval)/((double)totwts); /* weighted val */ |
|
aabyteval= (int)(((double)(grayscale-1))*aawtval+0.5); /*0...grayscale-1*/ |
|
bytemap[imap] = (intbyte)(aabyteval); /* set antialiased pixel */ |
|
if ( msglevel>=99 && msgfp!=NULL ) { fprintf(msgfp, /*diagnostic output*/ |
|
"%s> irow,icol,imap=%d,%d,%d aawtval=%.4f aabyteval=%d", |
|
(isfirstaa?"aapnmlookup algorithm":"aapnm"), |
|
irow,icol,imap, aawtval,aabyteval); |
|
if ( msglevel < 100 ) fprintf(msgfp,"\n"); /* no more output */ |
|
else fprintf(msgfp,", grid#,pattern#=%d,%d\n",gridnum,patternum); |
|
isfirstaa = 0; } |
|
} /* --- end-of-if(isedge) --- */ |
|
} /* --- end-of-for(irow,icol) --- */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with gray-scale anti-aliased bytemap |
|
-------------------------------------------------------------------------- */ |
|
/*end_of_job:*/ |
|
return ( 1 ); |
|
} /* --- end-of-function aapnmlookup() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapatterns ( rp, irow, icol, gridnum, patternum, grayscale ) |
|
* Purpose: For patterns requireing special processing, |
|
* calculates anti-aliased value for pixel at irow,icol, |
|
* whose surrounding 3x3 pixel grid is coded by gridnum |
|
* (which must correspond to a pattern requiring special |
|
* processing). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* irow (I) int containing row, 0...height-1, |
|
* of pixel to be antialiased |
|
* icol (I) int containing col, 0...width-1, |
|
* of pixel to be antialiased |
|
* gridnum (I) int containing 0...511 corresponding to |
|
* 3x3 pixel grid surrounding irow,icol |
|
* patternum (I) int containing 1...51 pattern# of |
|
* the 3x3 grid surrounding irow,icol |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0...grayscale-1 for success, |
|
* -1 = error, or no special processing required |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapatterns (raster *rp, int irow, int icol, |
|
int gridnum, int patternum, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int aaval = (-1); /* antialiased value returned */ |
|
int iscenter = (gridnum&1); /* true if center pixel set/black */ |
|
int aapatternnum(), /* if patternum not supplied */ |
|
aapattern1124(), /* routine for patterns #11,24 */ |
|
aapattern19(), /* special routine for pattern #19 */ |
|
aapattern20(), /* special routine for pattern #20 */ |
|
aapattern39(); /* special routine for pattern #39 */ |
|
/* ------------------------------------------------------------------------- |
|
special pattern number processing |
|
-------------------------------------------------------------------------- */ |
|
if ( 1 ) { |
|
if ( patternum < 1 ) /* pattern# not supplied by caller */ |
|
patternum = aapatternnum(gridnum); /* so look it up ourselves */ |
|
switch ( patternum ) { |
|
default: break; /* no special processing */ |
|
case 11: |
|
case 24: aaval = aapattern1124(rp,irow,icol,gridnum,grayscale); break; |
|
case 19: aaval = aapattern19(rp,irow,icol,gridnum,grayscale); break; |
|
case 20: aaval = aapattern20(rp,irow,icol,gridnum,grayscale); break; |
|
case 39: aaval = aapattern39(rp,irow,icol,gridnum,grayscale); break; |
|
/* case 24: if ( (gridnum&1) == 0 ) aaval=0; break; */ |
|
case 29: aaval = (iscenter?grayscale-1:0); break; /* no antialiasing */ |
|
} /* --- end-of-switch(patternum) --- */ |
|
} /* --- end-of-if() --- */ |
|
return ( aaval ); /* return antialiased val to caller*/ |
|
} /* --- end-of-function aapatterns() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapattern1124 ( rp, irow, icol, gridnum, grayscale ) |
|
* Purpose: calculates anti-aliased value for pixel at irow,icol, |
|
* whose surrounding 3x3 pixel grid is coded by gridnum |
|
* (which must correspond to pattern #11 or #24). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* irow (I) int containing row, 0...height-1, |
|
* of pixel to be antialiased |
|
* icol (I) int containing col, 0...width-1, |
|
* of pixel to be antialiased |
|
* gridnum (I) int containing 0...511 corresponding to |
|
* 3x3 pixel grid surrounding irow,icol |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0...grayscale-1 for success, -1=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Handles the eight gridnum's |
|
* (gridnum/2 shown to eliminate irrelevant low-order bit) |
|
* --- --- -*- -*- |
|
* --* = 10 *-- = 18 --* = 72 *-- = 80 (pattern$11) |
|
* -*- -*- --- --- |
|
* |
|
* --- --- -** **- |
|
* --* = 11 *-- = 22 --* = 104 *-- = 208 (pattern$24) |
|
* -** **- --- --- |
|
* o For black * center pixel, using grid#10 as an example, |
|
* pixel stays --- antialiased ---* |
|
* black if -*** if part of -** |
|
* part of a -*- a diagonal -*- |
|
* corner, eg, * line, eg, * |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapattern1124 (raster *rp, int irow, int icol, |
|
int gridnum, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int aaval = (-1); /* antialiased value returned */ |
|
int iscenter = gridnum&1; /* true if pixel at irow,icol black*/ |
|
int patternum = 24; /* init for pattern#24 default */ |
|
pixbyte *bitmap = rp->pixmap; /* local rp->pixmap ptr */ |
|
int width=rp->width, height=rp->height; /* width, height of raster */ |
|
int jrow=irow, jcol=icol; /* corner or diagonal row,col */ |
|
int vertcornval=0, horzcornval=0, /* vertical, horizontal corner bits*/ |
|
topdiagval=0, botdiagval=0, /* upper,lower diagonal pixel bits */ |
|
cornval=0, diagval=0; /* vert+horzcorn, top+botdiag */ |
|
int hdirection=99, vdirection=99, /* horz,vert corner direction */ |
|
hturn=99,vturn=99, aafollowline(); /* follow corner till turns */ |
|
/* ------------------------------------------------------------------------- |
|
Check corner and diagonal pixels |
|
-------------------------------------------------------------------------- */ |
|
if ( 0 ) goto end_of_job; /* true to turn off pattern1124 */ |
|
switch ( gridnum/2 ) { /* check pattern#11,24 corner, diag*/ |
|
default: goto end_of_job; /* not a pattern#11,24 gridnum */ |
|
case 10: patternum=11; case 11: |
|
hdirection = 2; vdirection = -1; /* directions to follow corner */ |
|
if ( (jrow=irow+2) < height ) { /* vert corner below center pixel */ |
|
vertcornval = getlongbit(bitmap,(icol+jrow*width)); |
|
if ( (icol-1) >= 0 ) /* lower diag left of center */ |
|
botdiagval = getlongbit(bitmap,((icol-1)+jrow*width)); } |
|
if ( (jcol=icol+2) < width ) { /* horz corner right of center */ |
|
horzcornval = getlongbit(bitmap,(jcol+irow*width)); |
|
if ( (irow-1) >= 0 ) /* upper diag above center */ |
|
topdiagval = getlongbit(bitmap,(jcol+(irow-1)*width)); } |
|
break; |
|
case 18: patternum=11; case 22: |
|
hdirection = -2; vdirection = -1; /* directions to follow corner */ |
|
if ( (jrow=irow+2) < height ) { /* vert corner below center pixel */ |
|
vertcornval = getlongbit(bitmap,(icol+jrow*width)); |
|
if ( (icol+1) < width ) /* lower diag right of center */ |
|
botdiagval = getlongbit(bitmap,((icol+1)+jrow*width)); } |
|
if ( (jcol=icol-2) >= 0 ) { /* horz corner left of center */ |
|
horzcornval = getlongbit(bitmap,(jcol+irow*width)); |
|
if ( (irow-1) >= 0 ) /* upper diag above center */ |
|
topdiagval = getlongbit(bitmap,(jcol+(irow-1)*width)); } |
|
break; |
|
case 72: patternum=11; case 104: |
|
hdirection = 2; vdirection = 1; /* directions to follow corner */ |
|
if ( (jrow=irow-2) >= 0 ) { /* vert corner above center pixel */ |
|
vertcornval = getlongbit(bitmap,(icol+jrow*width)); |
|
if ( (icol-1) >= 0 ) /* upper diag left of center */ |
|
topdiagval = getlongbit(bitmap,((icol-1)+jrow*width)); } |
|
if ( (jcol=icol+2) < width ) { /* horz corner right of center */ |
|
horzcornval = getlongbit(bitmap,(jcol+irow*width)); |
|
if ( (irow+1) < height ) /* lower diag below center */ |
|
botdiagval = getlongbit(bitmap,(jcol+(irow+1)*width)); } |
|
break; |
|
case 80: patternum=11; case 208: |
|
hdirection = -2; vdirection = 1; /* directions to follow corner */ |
|
if ( (jrow=irow-2) >= 0 ) { /* vert corner above center pixel */ |
|
vertcornval = getlongbit(bitmap,(icol+jrow*width)); |
|
if ( (icol+1) < width ) /* upper diag right of center */ |
|
topdiagval = getlongbit(bitmap,((icol+1)+jrow*width)); } |
|
if ( (jcol=icol-2) >= 0 ) { /* horz corner left of center */ |
|
horzcornval = getlongbit(bitmap,(jcol+irow*width)); |
|
if ( (irow+1) < height ) /* lower diag below center */ |
|
botdiagval = getlongbit(bitmap,(jcol+(irow+1)*width)); } |
|
break; |
|
} /* --- end-of-switch(gridnum/2) --- */ |
|
cornval = vertcornval+horzcornval; /* 0=no corner bits, 1, 2=both */ |
|
diagval = topdiagval+botdiagval; /* 0=no diag bits, 1, 2=both */ |
|
/* ------------------------------------------------------------------------- |
|
Handle white center |
|
-------------------------------------------------------------------------- */ |
|
if ( 1 && !iscenter ) { aaval = (patternum==11?51:64); goto end_of_job; } |
|
/* ------------------------------------------------------------------------- |
|
Handle black center |
|
-------------------------------------------------------------------------- */ |
|
if ( diagval > 1 ) aaval = ( patternum==24? 255:191 ); |
|
else { |
|
hturn = aafollowline(rp,irow,icol,hdirection); |
|
vturn = aafollowline(rp,irow,icol,vdirection); |
|
if ( vturn*hdirection < 0 && hturn*vdirection < 0 ) |
|
aaval = ( patternum==24? 255:191 ); |
|
else aaval = grayscale-1; } /* actual corner */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with grayscale antialiased value for pixel at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( aaval >= 0 ) /* have antialiasing result */ |
|
if ( msglevel>=99 && msgfp!=NULL ) fprintf(msgfp, /* diagnostic output */ |
|
"aapattern1124> irow,icol,grid#/2=%d,%d,%d, top,botdiag=%d,%d, " |
|
"vert,horzcorn=%d,%d, v,hdir=%d,%d, v,hturn=%d,%d, aaval=%d\n", |
|
irow,icol,gridnum/2, topdiagval,botdiagval, vertcornval,horzcornval, |
|
vdirection,hdirection, vturn,hturn, aaval); |
|
return ( aaval ); /* back with antialiased value */ |
|
} /* --- end-of-function aapattern1124() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapattern19 ( rp, irow, icol, gridnum, grayscale ) |
|
* Purpose: calculates anti-aliased value for pixel at irow,icol, |
|
* whose surrounding 3x3 pixel grid is coded by gridnum |
|
* (which must correspond to pattern #19). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* irow (I) int containing row, 0...height-1, |
|
* of pixel to be antialiased |
|
* icol (I) int containing col, 0...width-1, |
|
* of pixel to be antialiased |
|
* gridnum (I) int containing 0...511 corresponding to |
|
* 3x3 pixel grid surrounding irow,icol |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0...grayscale-1 for success, -1=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Handles the four gridnum's |
|
* (gridnum/2 shown to eliminate irrelevant low-order bit) |
|
* --- --* *-- *** |
|
* --- = 7 --* = 41 *-- = 148 --- = 224 |
|
* *** --* *-- --- |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapattern19 (raster *rp, int irow, int icol, |
|
int gridnum, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int aaval = (-1); /* antialiased value returned */ |
|
int iscenter = gridnum&1; /* true if pixel at irow,icol black*/ |
|
int orientation = 1, /* 1=vertical, 2=horizontal */ |
|
jrow=irow, jcol=icol; /* middle pixel of *** line */ |
|
int turn1=0,turn2=0, aafollowline(); /* follow *** line till it turns */ |
|
/* ------------------------------------------------------------------------- |
|
Initialization and calculation of antialiased value |
|
-------------------------------------------------------------------------- */ |
|
/* --- check input -- */ |
|
if ( iscenter ) goto end_of_job; /* we only antialias white pixels */ |
|
/* --- set params --- */ |
|
switch ( gridnum/2 ) { /* check pattern#19 orientation */ |
|
default: goto end_of_job; /* not a pattern#19 gridnum */ |
|
case 7: orientation=2; jrow++; break; |
|
case 41: orientation=1; jcol++; break; |
|
case 148: orientation=1; jcol--; break; |
|
case 224: orientation=2; jrow--; break; |
|
} /* --- end-of-switch(gridnum/2) --- */ |
|
/* --- get turns in both directions --- */ |
|
if ( (turn1 = aafollowline(rp,jrow,jcol,orientation)) == 0 ) goto end_of_job; |
|
if ( (turn2 = aafollowline(rp,jrow,jcol,-orientation)) == 0) goto end_of_job; |
|
if ( turn1*turn2 >= 0 ) goto end_of_job; /* both turns in same direction */ |
|
/* --- weight pixel --- */ |
|
aaval = grayscale / ( 3 + min2(abs(turn1),abs(turn2)) ); |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with grayscale antialiased value for pixel at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( aaval >= 0 ) /* have antialiasing result */ |
|
if ( msglevel>=99 && msgfp!=NULL ) fprintf(msgfp, /* diagnostic output */ |
|
"aapattern19> irow,icol,grid#/2=%d,%d,%d, turn+%d,%d=%d,%d, aaval=%d\n", |
|
irow,icol,gridnum/2, orientation,-orientation,turn1,turn2, aaval); |
|
return ( aaval ); /* back with antialiased value */ |
|
} /* --- end-of-function aapattern19() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapattern20 ( rp, irow, icol, gridnum, grayscale ) |
|
* Purpose: calculates anti-aliased value for pixel at irow,icol, |
|
* whose surrounding 3x3 pixel grid is coded by gridnum |
|
* (which must correspond to pattern #20). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* irow (I) int containing row, 0...height-1, |
|
* of pixel to be antialiased |
|
* icol (I) int containing col, 0...width-1, |
|
* of pixel to be antialiased |
|
* gridnum (I) int containing 0...511 corresponding to |
|
* 3x3 pixel grid surrounding irow,icol |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0...grayscale-1 for success, -1=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Handles the eight gridnum's |
|
* (gridnum/2 shown to eliminate irrelevant low-order bit) |
|
* --- --- --* -*- |
|
* --* = 14 *-- = 19 --* = 42 --* = 73 |
|
* **- -** -*- --* |
|
* |
|
* -*- -** *-- **- |
|
* *-- = 84 *-- = 112 *-- = 146 --* = 200 |
|
* *-- --- -*- --- |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapattern20 (raster *rp, int irow, int icol, |
|
int gridnum, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int aaval = (-1); /* antialiased value returned */ |
|
int iscenter = gridnum&1; /* true if pixel at irow,icol black*/ |
|
int direction = 1, /* direction to follow ** line */ |
|
jrow1=irow, jcol1=icol, /* coords of * */ |
|
jrow2=irow, jcol2=icol; /* coords of adjacent ** pixel */ |
|
int turn1=0,turn2=0, aafollowline(); /* follow *,** lines till turns */ |
|
/* ------------------------------------------------------------------------- |
|
Initialization and calculation of antialiased value |
|
-------------------------------------------------------------------------- */ |
|
/* --- check input -- */ |
|
if ( 1 ) goto end_of_job; /* don't want this one */ |
|
if ( iscenter ) goto end_of_job; /* we only antialias white pixels */ |
|
/* --- set params --- */ |
|
switch ( gridnum/2 ) { /* check pattern#20 orientation */ |
|
default: goto end_of_job; /* not a pattern#20 gridnum */ |
|
case 14: direction=-2; jcol1++; jrow2++; break; |
|
case 19: direction=2; jcol1--; jrow2++; break; |
|
case 42: direction=1; jrow1++; jcol2++; break; |
|
case 73: direction=-1; jrow1--; jcol2++; break; |
|
case 84: direction=-1; jrow1--; jcol2--; break; |
|
case 112: direction=2; jcol1--; jrow2--; break; |
|
case 146: direction=1; jrow1++; jcol2--; break; |
|
case 200: direction=-2; jcol1++; jrow2--; break; |
|
} /* --- end-of-switch(gridnum/2) --- */ |
|
/* --- get turns in both directions --- */ |
|
if ( (turn1=aafollowline(rp,jrow1,jcol1,-direction)) == 0 ) goto end_of_job; |
|
if ( (turn2=aafollowline(rp,jrow2,jcol2,direction)) == 0 ) goto end_of_job; |
|
if ( turn1*turn2 >= 0 ) goto end_of_job; /* both turns in same direction */ |
|
/* --- weight pixel --- */ |
|
aaval = grayscale / ( 3 + min2(abs(turn1),abs(turn2)) ); |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with grayscale antialiased value for pixel at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( aaval >= 0 ) /* have antialiasing result */ |
|
if ( msglevel>=99 && msgfp!=NULL ) fprintf(msgfp, /* diagnostic output */ |
|
"aapattern20> irow,icol,grid#/2=%d,%d,%d, turn%d,%d=%d,%d, aaval=%d\n", |
|
irow,icol,gridnum/2, -direction,direction,turn1,turn2, aaval); |
|
return ( aaval ); /* back with antialiased value */ |
|
} /* --- end-of-function aapattern20() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapattern39 ( rp, irow, icol, gridnum, grayscale ) |
|
* Purpose: calculates anti-aliased value for pixel at irow,icol, |
|
* whose surrounding 3x3 pixel grid is coded by gridnum |
|
* (which must correspond to pattern #39). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* irow (I) int containing row, 0...height-1, |
|
* of pixel to be antialiased |
|
* icol (I) int containing col, 0...width-1, |
|
* of pixel to be antialiased |
|
* gridnum (I) int containing 0...511 corresponding to |
|
* 3x3 pixel grid surrounding irow,icol |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0...grayscale-1 for success, -1=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Handles the eight gridnum's |
|
* (gridnum/2 shown to eliminate irrelevant low-order bit) |
|
* --- --- --* -** |
|
* --* = 15 *-- = 23 --* = 43 --* = 105 |
|
* *** *** -** --* |
|
* |
|
* **- *** *-- *** |
|
* *-- = 212 *-- = 240 *-- = 150 --* = 232 |
|
* *-- --- **- --- |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapattern39 (raster *rp, int irow, int icol, |
|
int gridnum, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int aaval = (-1); /* antialiased value returned */ |
|
int iscenter = gridnum&1; /* true if pixel at irow,icol black*/ |
|
int direction = 1, /* direction to follow ** line */ |
|
jrow1=irow, jcol1=icol, /* coords of * */ |
|
jrow2=irow, jcol2=icol; /* coords of adjacent ** pixel */ |
|
int turn1=0,turn2=0, aafollowline(); /* follow *,** lines till turns */ |
|
/* ------------------------------------------------------------------------- |
|
Initialization and calculation of antialiased value |
|
-------------------------------------------------------------------------- */ |
|
/* --- check input -- */ |
|
if ( iscenter ) goto end_of_job; /* we only antialias white pixels */ |
|
/* --- set params --- */ |
|
switch ( gridnum/2 ) { /* check pattern#39 orientation */ |
|
default: goto end_of_job; /* not a pattern#39 gridnum */ |
|
case 15: direction=-2; jcol1++; jrow2++; break; |
|
case 23: direction=2; jcol1--; jrow2++; break; |
|
case 43: direction=1; jrow1++; jcol2++; break; |
|
case 105: direction=-1; jrow1--; jcol2++; break; |
|
case 212: direction=-1; jrow1--; jcol2--; break; |
|
case 240: direction=2; jcol1--; jrow2--; break; |
|
case 150: direction=1; jrow1++; jcol2--; break; |
|
case 232: direction=-2; jcol1++; jrow2--; break; |
|
} /* --- end-of-switch(gridnum/2) --- */ |
|
/* --- get turns directions (tunr1==1 signals inside corner) --- */ |
|
if ( (turn1=aafollowline(rp,jrow1,jcol1,-direction)) == 1 ) |
|
{ aaval=0; goto end_of_job; } |
|
if ( 1 ) goto end_of_job; /* stop here for now */ |
|
if ( (turn2=aafollowline(rp,jrow2,jcol2,direction)) == 0 ) goto end_of_job; |
|
if ( turn1*turn2 >= 0 ) goto end_of_job; /* both turns in same direction */ |
|
/* --- weight pixel --- */ |
|
aaval = grayscale / ( 3 + min2(abs(turn1),abs(turn2)) ); |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with grayscale antialiased value for pixel at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( aaval >= 0 ) /* have antialiasing result */ |
|
if ( msglevel>=99 && msgfp!=NULL ) fprintf(msgfp, /* diagnostic output */ |
|
"aapattern39> irow,icol,grid#/2=%d,%d,%d, turn%d,%d=%d,%d, aaval=%d\n", |
|
irow,icol,gridnum/2, -direction,direction,turn1,turn2, aaval); |
|
return ( aaval ); /* back with antialiased value */ |
|
} /* --- end-of-function aapattern39() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aafollowline ( rp, irow, icol, direction ) |
|
* Purpose: starting with pixel at irow,icol, moves in |
|
* specified direction looking for a "turn" |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster containing pixel image |
|
* irow (I) int containing row, 0...height-1, |
|
* of first pixel |
|
* icol (I) int containing col, 0...width-1, |
|
* of first pixel |
|
* direction (I) int containing +1 to follow line up/north |
|
* (decreasing irow), -1 to follow line |
|
* down/south (increasing irow), +2 to follow |
|
* line right/east (increasing icol), |
|
* -2 to follow line left/west (decreasing icol) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) #rows or #cols traversed prior to turn, |
|
* or 0 if no turn detected (or for any error). |
|
* Sign is + if turn direction is right/east or |
|
* up/north, or is - if left/west or down/south. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Here are some examples illustrating turn detection in |
|
* +2 (right/east) direction. Turns in other directions |
|
* are detected similarly/symmetrically. * denotes black |
|
* bits (usually fg), - denotes white bits (usually bg), |
|
* and ? denotes "don't care" bit (won't affect outcome). |
|
* Arrow --> points to start pixel denoted by irow,icol. |
|
* |
|
* *??? -??? turn=0 (no turn) is returned |
|
* -->*??? or -->-??? because the start pixel isn't |
|
* *??? -??? on an edge to begin with |
|
* |
|
* ---- **-- turn=0 returned because the |
|
* -->***- or -->***- line ends abruptly without |
|
* ---- ---- turning (even the second case) |
|
* |
|
* ---* ---* turn=0 returned because the |
|
* -->***- or -->**** line forms a Y or T rather |
|
* ---* ---* than turning |
|
* |
|
* ***- **** turn=+3 returned |
|
* -->***- or -->***- (outside corner) |
|
* ---- ---- |
|
* |
|
* ***** ****- turn=-4 returned |
|
* -->***** or -->****- (inside corner) |
|
* ----* ----* |
|
* |
|
* ----* ----* turn=+4 returned |
|
* -->****- or -->***** (outside or inside corner) |
|
* ----- ----- |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aafollowline (raster *rp, int irow, int icol, int direction) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
pixbyte *bitmap = rp->pixmap; /* local rp->pixmap ptr */ |
|
int width=rp->width, height=rp->height; /* width, height of raster */ |
|
int drow=0, dcol=0, /* delta row,col to follow line */ |
|
jrow=irow, jcol=icol; /* current row,col following line */ |
|
int bitval=1, /* value of rp bit at irow,icol */ |
|
fgval=1, bgval=0, /* "fg" is whatever bitval is */ |
|
bitminus=0, bitplus=0; /* value of left/down, right/up bit*/ |
|
int isline=1, isedge=0; /*isline signals one-pixel wide line*/ |
|
int turn = 0, /* detected turn back to caller */ |
|
maxturn = maxfollow; /* don't follow more than max pixels*/ |
|
/* ------------------------------------------------------------------------- |
|
Initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- check input --- */ |
|
if ( irow<0 || irow>=height /* irow out-of-bounds */ |
|
|| icol<0 || icol>=width ) goto end_of_job; /* icol out-of-bounds */ |
|
/* --- starting bit -- see if we're following a fg (usual), or bg line --- */ |
|
bitval = getlongbit(bitmap,(icol+irow*width)); /* starting pixel (bg or fg)*/ |
|
fgval = bitval; bgval = (1-bitval); /* define "fg" as whatever bitval is*/ |
|
/* --- set drow,dcol corresponding to desired direction --- */ |
|
switch ( direction ) { /* determine drow,dcol for direction*/ |
|
default: goto end_of_job; /* unrecognized direction arg */ |
|
case 1: drow = (-1); break; /* follow line up/north */ |
|
case -1: drow = 1; break; /* down/south */ |
|
case 2: dcol = 1; break; /* right/east */ |
|
case -2: dcol = (-1); break; } /* left/west */ |
|
/* --- set bitminus and bitplus --- */ |
|
if ( drow == 0 ) { /* we're following line right/left */ |
|
if ( irow < height ) /* there's a pixel below current */ |
|
bitminus = getlongbit(bitmap,(icol+(irow+1)*width)); /* get it */ |
|
if ( irow > 0 ) /* there's a pixel above current */ |
|
bitplus = getlongbit(bitmap,(icol+(irow-1)*width)); } /* get it */ |
|
if ( dcol == 0 ) { /* we're following line up/down */ |
|
if ( icol < width ) /* there's a pixel to the right */ |
|
bitplus = getlongbit(bitmap,(icol+1+irow*width)); /* get it */ |
|
if ( icol > 0 ) /* there's a pixel to the left */ |
|
bitminus = getlongbit(bitmap,(icol-1+irow*width)); } /* get it */ |
|
/* --- check for lack of line to follow --- */ |
|
if ( bitval == bitplus /* starting pixel same as above */ |
|
&& bitval == bitminus ) /* and below (or right and left) */ |
|
goto end_of_job; /* so there's no line to follow */ |
|
/* --- set isline and isedge (already initted for isline) --- */ |
|
if ( bitval == bitplus ) /* starting pixel same as above */ |
|
{ isedge = (-1); isline = 0; } /* so we're at an edge below */ |
|
if ( bitval == bitminus ) /* starting pixel same as below */ |
|
{ isedge = 1; isline = 0; } /* so we're at an edge above */ |
|
/* ------------------------------------------------------------------------- |
|
follow line |
|
-------------------------------------------------------------------------- */ |
|
while ( 1 ) { /* until turn found (or max) */ |
|
/* --- local allocations and declarations --- */ |
|
int dbitval=0, /* value of bit at jrow,jcol */ |
|
dbitminus=0, dbitplus=0; /* value of left/down, right/up bit*/ |
|
/* --- bump pixel count and indexes; check for max or end-of-raster --- */ |
|
turn++; /* bump #pixels followed */ |
|
jrow += drow; jcol += dcol; /* indexes of next pixel to check */ |
|
if ( turn > maxturn /* already followed max #pixels */ |
|
|| jrow<0 || jrow>=height /* or jrow past end-of-raster */ |
|
|| jcol<0 || jcol>=width ) /* or jcol past end-of-raster */ |
|
{ turn = 0; goto end_of_job; } /* so quit without finding a turn */ |
|
/* --- set current bit (dbitval) --- */ |
|
dbitval = getlongbit(bitmap,(jcol+jrow*width)); /*value of jrow,jcol bit*/ |
|
/* --- set dbitminus and dbitplus --- */ |
|
if ( drow == 0 ) { /* we're following line right/left */ |
|
if ( irow < height ) /* there's a pixel below current */ |
|
dbitminus = getlongbit(bitmap,(jcol+(irow+1)*width)); /* get it */ |
|
if ( irow > 0 ) /* there's a pixel above current */ |
|
dbitplus = getlongbit(bitmap,(jcol+(irow-1)*width)); } /* get it */ |
|
if ( dcol == 0 ) { /* we're following line up/down */ |
|
if ( icol < width ) /* there's a pixel to the right */ |
|
dbitplus = getlongbit(bitmap,(icol+1+jrow*width)); /* get it */ |
|
if ( icol > 0 ) /* there's a pixel to the left */ |
|
dbitminus = getlongbit(bitmap,(icol-1+jrow*width)); } /* get it */ |
|
/* --- first check for abrupt end-of-line, or for T or Y --- */ |
|
if ( isline != 0 ) /* abrupt end or T,Y must be a line*/ |
|
if ( ( bgval == dbitval /* end-of-line if pixel flips to bg*/ |
|
&& bgval == dbitplus /* and bg same as above pixel */ |
|
&& bgval == dbitminus ) /* and below (or right and left) */ |
|
|| ( fgval == dbitplus /* T or Y if fg same as above pixel*/ |
|
&& fgval == dbitminus ) ) /* and below (or right and left) */ |
|
{ turn = 0; goto end_of_job; } /* so we're at a T or Y */ |
|
/* --- check for turning line --- */ |
|
if ( isline != 0 ) { /* turning line must be a line */ |
|
if ( fgval == dbitminus ) /* turning down */ |
|
{ turn = -turn; goto end_of_job; } /* so return negative turn */ |
|
else if ( fgval == dbitplus ) /* turning up */ |
|
goto end_of_job; } /* so return positive turn */ |
|
/* --- check for inside corner at edge --- */ |
|
if ( isedge != 0 ) { /* inside corner must be a edge */ |
|
if ( isedge < 0 && fgval == bitminus ) /* corner below */ |
|
{ turn = -turn; goto end_of_job; } /* so return negative turn */ |
|
if ( isedge > 0 && fgval == bitplus ) /* corner above */ |
|
goto end_of_job; } /* so return positive turn */ |
|
/* --- check for abrupt end at edge --- */ |
|
if ( isedge != 0 /* abrupt edge end must be an edge */ |
|
&& fgval == dbitval ) /* and line must not end */ |
|
if ( (isedge < 0 && bgval == bitplus) /* abrupt end above */ |
|
|| (isedge > 0 && bgval == bitminus) ) /* or abrupt end below */ |
|
{ turn = 0; goto end_of_job; } /* so edge ended abruptly */ |
|
/* --- check for outside corner at edge --- */ |
|
if ( isedge != 0 /* outside corner must be a edge */ |
|
&& bgval == dbitval ) { /* and line must end */ |
|
if ( isedge > 0 ) turn = -turn; /* outside turn down from edge above*/ |
|
goto end_of_job; } |
|
} /* --- end-of-while(1) --- */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with #rows or #cols traversed, and direction of detected turn |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( msglevel>=99 && msgfp!=NULL ) /* debugging/diagnostic output */ |
|
fprintf(msgfp,"aafollowline> irow,icol,direction=%d,%d,%d, turn=%d\n", |
|
irow,icol,direction,turn); |
|
return ( turn ); |
|
} /* --- end-of-function aafollowline() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aagridnum ( rp, irow, icol ) |
|
* Purpose: calculates gridnum, 0-511 (see Notes below), |
|
* for 3x3 grid centered at irow,icol |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster containing |
|
* bitmap image (to be anti-aliased) |
|
* irow (I) int containing row, 0...height-1, |
|
* at center of 3x3 grid |
|
* icol (I) int containing col, 0...width-1, |
|
* at center of 3x3 grid |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0-511 grid number, or -1=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Input gridnum is a 9-bit int, 0-511, coding a 3x3 pixel grid |
|
* whose bit positions (and corresponding values) in gridnum are |
|
* 876 256 128 64 |
|
* 504 = 32 1 16 |
|
* 321 8 4 2 |
|
* Thus, for example (*=pixel set/black, -=pixel not set/white), |
|
* *-- *-- -** (note that 209 is the |
|
* -*- = 259 *-- = 302 -** = 209 inverse, set<-->unset, |
|
* --* *** --- of 302) |
|
* o A set pixel is considered black, an unset pixel considered |
|
* white. |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aagridnum (raster *rp, int irow, int icol) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
pixbyte *bitmap = rp->pixmap; /* local rp->pixmap ptr */ |
|
int width=rp->width, height=rp->height, /* width, height of raster */ |
|
imap = icol + irow*width; /* pixel index = icol + irow*width */ |
|
int bitval=0, /* value of rp bit at irow,icol */ |
|
nnbitval=0, nebitval=0, eebitval=0, sebitval=0, /*adjacent vals*/ |
|
ssbitval=0, swbitval=0, wwbitval=0, nwbitval=0, /*compass pt names*/ |
|
gridnum = (-1); /* grid# 0-511 for above 9 bits */ |
|
/* ------------------------------------------------------------------------- |
|
check input |
|
-------------------------------------------------------------------------- */ |
|
if ( irow<0 || irow>=height /* irow out-of-bounds */ |
|
|| icol<0 || icol>=width ) goto end_of_job; /* icol out-of-bounds */ |
|
/* ------------------------------------------------------------------------- |
|
get the 9 bits comprising the 3x3 grid centered at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
/* --- get center bit --- */ |
|
bitval = getlongbit(bitmap,imap); /* value of rp input bit at imap */ |
|
/* --- get 8 surrounding bits --- */ |
|
if ( irow > 0 ) /* nn (north) bit available */ |
|
nnbitval = getlongbit(bitmap,imap-width); /* nn bit value */ |
|
if ( irow < height-1 ) /* ss (south) bit available */ |
|
ssbitval = getlongbit(bitmap,imap+width); /* ss bit value */ |
|
if ( icol > 0 ) /* ww (west) bit available */ |
|
{ wwbitval = getlongbit(bitmap,imap-1); /* ww bit value */ |
|
if ( irow > 0 ) /* nw bit available */ |
|
nwbitval = getlongbit(bitmap,imap-width-1); /* nw bit value */ |
|
if ( irow < height-1 ) /* sw bit available */ |
|
swbitval = getlongbit(bitmap,imap+width-1); } /* sw bit value */ |
|
if ( icol < width-1 ) /* ee (east) bit available */ |
|
{ eebitval = getlongbit(bitmap,imap+1); /* ee bit value */ |
|
if ( irow > 0 ) /* ne bit available */ |
|
nebitval = getlongbit(bitmap,imap-width+1); /* ne bit value */ |
|
if ( irow < height-1 ) /* se bit available */ |
|
sebitval = getlongbit(bitmap,imap+width+1); } /* se bit value */ |
|
/* --- set gridnum --- */ |
|
gridnum = 0; /* clear all bits */ |
|
if ( bitval ) gridnum = 1; /* set1bit(gridnum,0); */ |
|
if ( nwbitval ) gridnum += 256; /* set1bit(gridnum,8); */ |
|
if ( nnbitval ) gridnum += 128; /* set1bit(gridnum,7); */ |
|
if ( nebitval ) gridnum += 64; /* set1bit(gridnum,6); */ |
|
if ( wwbitval ) gridnum += 32; /* set1bit(gridnum,5); */ |
|
if ( eebitval ) gridnum += 16; /* set1bit(gridnum,4); */ |
|
if ( swbitval ) gridnum += 8; /* set1bit(gridnum,3); */ |
|
if ( ssbitval ) gridnum += 4; /* set1bit(gridnum,2); */ |
|
if ( sebitval ) gridnum += 2; /* set1bit(gridnum,1); */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with gridnum coding 3x3 grid centered at irow,icol |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
return ( gridnum ); |
|
} /* --- end-of-function aagridnum() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aapatternnum ( gridnum ) |
|
* Purpose: Looks up the pattern number 1...51 |
|
* corresponding to the 3x3 pixel grid coded by gridnum 0=no |
|
* pixels set (white) to 511=all pixels set (black). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: gridnum (I) int containing 0-511 coding a 3x3 pixel grid |
|
* (see Notes below) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 1 to 51, or -1=error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Input gridnum is a 9-bit int, 0-511, coding a 3x3 pixel grid |
|
* whose bit positions (and corresponding values) in gridnum are |
|
* 876 256 128 64 |
|
* 504 = 32 1 16 |
|
* 321 8 4 2 |
|
* Thus, for example (*=pixel set/black, -=pixel not set/white), |
|
* *-- *-- -** (note that 209 is the |
|
* -*- = 259 *-- = 302 -** = 209 inverse, set<-->unset, |
|
* --* *** --- of 302) |
|
* o A set pixel is considered black, an unset pixel considered |
|
* white. |
|
* o Ignoring whether the center pixel is set or unset, and |
|
* taking rotation, reflection and inversion (set<-->unset) |
|
* symmetries into account, there are 32 unique pixel patterns. |
|
* If inversions are listed separately, there are 51 patterns. |
|
* o Here are the 51 unique patterns, with ? always denoting the |
|
* undetermined center pixel. At the upper-left corner of each |
|
* pattern is the "pattern index number" assigned to it in this |
|
* function. At the upper-right is the pattern's multiplicity, |
|
* i.e., the number of different patterns obtained by rotations |
|
* and reflection of the illustrated one. Inverse patters are |
|
* illustrated immediately beneath the original (the first three |
|
* four-pixel patterns have identical inverses). |
|
* ------------------------------------------------------------- |
|
* No pixels set: |
|
* #1 1 (in this case, 1 signifies that rotation |
|
* --- and reflection give no different grids) |
|
* -?- |
|
* --- |
|
* Inverse, all eight pixels set |
|
* #2 1 (the inverse multiplicity is always the same) |
|
* *** |
|
* *?* |
|
* *** |
|
* ------------------------------------------------------------- |
|
* One pixel set: |
|
* #3 4 #4 4 |
|
* *-- -*- |
|
* -?- -?- |
|
* --- --- |
|
* Inverse, seven pixels set: |
|
* #5 4 #6 4 |
|
* -** *-* |
|
* *?* *?* |
|
* *** *** |
|
* ------------------------------------------------------------- |
|
* Two pixels set: |
|
* #7 8 #8 4 #9 8 10 2 11 4 12 2 |
|
* **- *-* *-- *-- -*- -*- |
|
* -?- -?- -?* -?- -?* -?- |
|
* --- --- --- --* --- -*- |
|
* Inverse, six pixels set: |
|
* #13 8 14 4 15 8 16 2 17 4 18 2 |
|
* --* -*- -** -** *-* *-* |
|
* *?* *?* *?- *?* *?- *?* |
|
* *** *** *** **- *** *-* |
|
* ------------------------------------------------------------- |
|
* Three pixels set: |
|
* #19 4 20 8 21 8 22 8 23 8 24 4 25 4 26 4 27 4 28 4 |
|
* *** **- **- **- **- **- *-* *-* -*- -*- |
|
* -?- -?* -?- -?- -?- *?- -?- -?- -?* -?* |
|
* --- --- --* -*- *-- --- --* -*- -*- *-- |
|
* Inverse, five pixels set: |
|
* #29 4 30 8 31 8 32 8 33 8 34 4 35 4 36 4 37 4 38 4 |
|
* --- --* --* --* --* --* -*- -*- *-* *-* |
|
* *?* *?- *?* *?* *?* -?* *?* *?* *?- *?- |
|
* *** *** **- *-* -** *** **- *-* *-* -** |
|
* ------------------------------------------------------------- |
|
* Four pixels set (including inverses): |
|
* #39 8 40 4 41 8 42 8 43 4 44 4 45 8 46 1 |
|
* *** **- **- *** *** **- **- *-* |
|
* -?* -?- -?* -?- -?- -?* -?* -?- |
|
* --- -** *-- --* -*- --* -*- *-* |
|
* |
|
* #47 8 48 4 49 4 50 8 51 1 |
|
* --- --- --* --* -*- |
|
* *?* *?* *?- *?- *?* |
|
* **- *-* **- *-* -*- |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aapatternnum ( int gridnum ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int pattern = (-1); /*pattern#, 1-51, for input gridnum*/ |
|
/* --- |
|
* pattern number corresponding to input gridnum/2 code |
|
* ( gridnum/2 strips off gridnum's low bit because it's |
|
* the same pattern whether or not center pixel is set ) |
|
* --- */ |
|
static int patternnum[] = { |
|
1, 3, 4, 7, 3, 8, 7,19, 4, 7,11,24, 9,23,20,39, /* 0- 15 */ |
|
4, 9,11,20, 7,23,24,39,12,22,27,47,22,48,47,29, /* 16- 31 */ |
|
3, 8, 9,23,10,25,21,42, 7,19,20,39,21,42,44,34, /* 32- 47 */ |
|
9,26,28,41,21,50,49,30,22,43,45,33,40,32,31,13, /* 48- 63 */ |
|
4, 9,12,22, 9,26,22,43,11,20,27,47,28,41,45,33, /* 64- 79 */ |
|
11,28,27,45,20,41,47,33,27,45,51,35,45,36,35,14, /* 80- 95 */ |
|
7,23,22,48,21,50,40,32,24,39,47,29,49,30,31,13, /* 96-111 */ |
|
20,41,45,36,44,38,31,15,47,33,35,14,31,15,16, 5, /* 112-127 */ |
|
3,10, 9,21, 8,25,23,42, 9,21,28,49,26,50,41,30, /* 128-143 */ |
|
7,21,20,44,19,42,39,34,22,40,45,31,43,32,33,13, /* 144-159 */ |
|
8,25,26,50,25,46,50,37,23,42,41,30,50,37,38,17, /* 160-175 */ |
|
23,50,41,38,42,37,30,17,48,32,36,15,32,18,15, 6, /* 176-191 */ |
|
7,21,22,40,23,50,48,32,20,44,45,31,41,38,36,15, /* 192-207 */ |
|
24,49,47,31,39,30,29,13,47,31,35,16,33,15,14, 5, /* 208-223 */ |
|
19,42,43,32,42,37,32,18,39,34,33,13,30,17,15, 6, /* 224-239 */ |
|
39,30,33,15,34,17,13, 6,29,13,14, 5,13, 6, 5, 2, /* 240-255 */ |
|
-1 } ; /* --- end-of-patternnum[] --- */ |
|
/* ------------------------------------------------------------------------- |
|
look up pattern number for gridnum |
|
-------------------------------------------------------------------------- */ |
|
/* --- first check input --- */ |
|
if ( gridnum<0 || gridnum>511 ) goto end_of_job; /* gridnum out of bounds */ |
|
/* --- look up pattern number, 1-51, corresponding to input gridnum --- */ |
|
pattern = patternnum[gridnum/2]; /* /2 strips off gridnum's low bit */ |
|
if ( pattern<1 || pattern>51 ) pattern = (-1); /* some internal error */ |
|
end_of_job: |
|
return ( pattern ); /* back to caller with pattern# */ |
|
} /* --- end-of-function aapatternnum() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aalookup ( gridnum ) |
|
* Purpose: Looks up the grayscale value 0=white to 255=black |
|
* corresponding to the 3x3 pixel grid coded by gridnum 0=no |
|
* pixels set (white) to 511=all pixels set (black). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: gridnum (I) int containing 0-511 coding a 3x3 pixel grid |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 0=white to 255=black, or -1=error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o Input gridnum is a 9-bit int, 0-511, coding a 3x3 pixel grid |
|
* o A set pixel is considered black, an unset pixel considered |
|
* white. Likewise, the returned grayscale is 255 for black, |
|
* 0 for white. You'd more typically want to use 255-grayscale |
|
* so that 255 is white and 0 is black. |
|
* o The returned number is the (lowpass) antialiased grayscale |
|
* for the center pixel (gridnum bit 0) of the grid. |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aalookup ( int gridnum ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int grayscale = (-1); /*returned grayscale, init for error*/ |
|
int pattern = (-1), aapatternnum(); /*pattern#, 1-51, for input gridnum*/ |
|
int iscenter = gridnum&1; /*low-order bit set for center pixel*/ |
|
/* --- gray scales --- */ |
|
#define WHT 0 |
|
#define LGT 64 |
|
#define GRY 128 |
|
#define DRK 192 |
|
#define BLK 255 |
|
#if 1 |
|
/* --- |
|
* modified aapnm() grayscales (second try) |
|
* --- */ |
|
/* --- grayscale for each pattern when center pixel set/black --- */ |
|
static int grayscale1[] = { -1, /* [0] index not used */ |
|
BLK,BLK,BLK,BLK,242,230,BLK,BLK,BLK,160, /* 1-10 */ |
|
/* BLK,BLK,BLK,BLK,242,230,BLK,BLK,BLK,BLK, */ /* 1-10 */ |
|
BLK,BLK,217,230,217,230,204,BLK,BLK,166, /* 11-20 */ |
|
BLK,BLK,BLK,BLK,BLK,BLK,178,166,204,191, /* 21-30 */ |
|
204,BLK,204,191,217,204,BLK,191,178,BLK, /* 31-40 */ |
|
178,BLK,BLK,178,191,BLK,191,BLK,178,BLK,204, /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale1[] --- */ |
|
/* --- grayscale for each pattern when center pixel not set/white --- */ |
|
static int grayscale0[] = { -1, /* [0] index not used */ |
|
WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT, /* 1-10 */ |
|
64,WHT,WHT,128,115,128,WHT,WHT,WHT, 64, /* 11-20 */ |
|
/* 51,WHT,WHT,128,115,128,WHT,WHT,WHT, 64, */ /* 11-20 */ |
|
WHT,WHT,WHT, 64,WHT,WHT, 76, 64,102, 89, /* 21-30 */ |
|
102,WHT,102,WHT,115,102,WHT, 89, 76,WHT, /* 31-40 */ |
|
76,WHT,WHT, 76, 89,WHT, 89,WHT, 76,WHT,102, /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale0[] --- */ |
|
#endif |
|
#if 0 |
|
/* --- |
|
* modified aapnm() grayscales (first try) |
|
* --- */ |
|
/* --- grayscale for each pattern when center pixel set/black --- */ |
|
static int grayscale1[] = { -1, /* [0] index not used */ |
|
BLK,BLK,BLK,BLK,242,230,GRY,BLK,BLK,BLK, /* 1-10 */ |
|
/* BLK,BLK,BLK,BLK,242,230,BLK,BLK,BLK,BLK, */ /* 1-10 */ |
|
BLK,BLK,217,230,217,230,204,BLK,BLK,166, /* 11-20 */ |
|
BLK,BLK,BLK,BLK,BLK,BLK,BLK,166,204,191, /* 21-30 */ |
|
/* BLK,BLK,BLK,BLK,BLK,BLK,178,166,204,191, */ /* 21-30 */ |
|
204,BLK,204,BLK,217,204,BLK,191,GRY,BLK, /* 31-40 */ |
|
/* 204,BLK,204,191,217,204,BLK,191,178,BLK, */ /* 31-40 */ |
|
178,BLK,BLK,178,191,BLK,BLK,BLK,178,BLK,204, /* 41-51 */ |
|
/* 178,BLK,BLK,178,191,BLK,191,BLK,178,BLK,204, */ /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale1[] --- */ |
|
/* --- grayscale for each pattern when center pixel not set/white --- */ |
|
static int grayscale0[] = { -1, /* [0] index not used */ |
|
WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT, /* 1-10 */ |
|
GRY,WHT,WHT,128,115,128,WHT,WHT,WHT,GRY, /* 11-20 */ |
|
/* 51,WHT,WHT,128,115,128,WHT,WHT,WHT, 64, */ /* 11-20 */ |
|
WHT,WHT,WHT,GRY,WHT,WHT, 76, 64,102, 89, /* 21-30 */ |
|
/* WHT,WHT,WHT, 64,WHT,WHT, 76, 64,102, 89, */ /* 21-30 */ |
|
102,WHT,102,WHT,115,102,WHT, 89,GRY,WHT, /* 31-40 */ |
|
/* 102,WHT,102,WHT,115,102,WHT, 89, 76,WHT, */ /* 31-40 */ |
|
76,WHT,WHT,GRY, 89,WHT, 89,WHT, 76,WHT,102, /* 41-51 */ |
|
/* 76,WHT,WHT, 76, 89,WHT, 89,WHT, 76,WHT,102, */ /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale0[] --- */ |
|
#endif |
|
#if 0 |
|
/* --- |
|
* these grayscales _exactly_ correspond to the aapnm() algorithm |
|
* --- */ |
|
/* --- grayscale for each pattern when center pixel set/black --- */ |
|
static int grayscale1[] = { -1, /* [0] index not used */ |
|
BLK,BLK,BLK,BLK,242,230,BLK,BLK,BLK,BLK, /* 1-10 */ |
|
BLK,BLK,217,230,217,230,204,BLK,BLK,166, /* 11-20 */ |
|
BLK,BLK,BLK,BLK,BLK,BLK,178,166,204,191, /* 21-30 */ |
|
204,BLK,204,191,217,204,BLK,191,178,BLK, /* 31-40 */ |
|
178,BLK,BLK,178,191,BLK,191,BLK,178,BLK,204, /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale1[] --- */ |
|
/* --- grayscale for each pattern when center pixel not set/white --- */ |
|
static int grayscale0[] = { -1, /* [0] index not used */ |
|
WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT,WHT, /* 1-10 */ |
|
51,WHT,WHT,128,115,128,WHT,WHT,WHT, 64, /* 11-20 */ |
|
WHT,WHT,WHT, 64,WHT,WHT, 76, 64,102, 89, /* 21-30 */ |
|
102,WHT,102,WHT,115,102,WHT, 89, 76,WHT, /* 31-40 */ |
|
76,WHT,WHT, 76, 89,WHT, 89,WHT, 76,WHT,102, /* 41-51 */ |
|
-1 } ; /* --- end-of-grayscale0[] --- */ |
|
#endif |
|
/* ------------------------------------------------------------------------- |
|
look up grayscale for gridnum |
|
-------------------------------------------------------------------------- */ |
|
/* --- first check input --- */ |
|
if ( gridnum<0 || gridnum>511 ) goto end_of_job; /* gridnum out of bounds */ |
|
/* --- look up pattern number, 1-51, corresponding to input gridnum --- */ |
|
pattern = aapatternnum(gridnum); /* look up pattern number */ |
|
if ( pattern<1 || pattern>51 ) goto end_of_job; /* some internal error */ |
|
if ( ispatternnumcount ) { /* counts being accumulated */ |
|
if (iscenter) patternnumcount1[pattern] += 1; /* bump diagnostic count */ |
|
else patternnumcount0[pattern] += 1; } |
|
/* --- look up grayscale for this pattern --- */ |
|
grayscale = ( iscenter? grayscale1[pattern] : grayscale0[pattern] ); |
|
end_of_job: |
|
return ( grayscale ); /* back to caller with grayscale */ |
|
} /* --- end-of-function aalookup() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: aalowpasslookup ( rp, bytemap, grayscale ) |
|
* Purpose: calls aalookup() for each pixel in rp->bitmap |
|
* to create anti-aliased bytemap |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) raster * to raster whose bitmap |
|
* is to be anti-aliased |
|
* bytemap (O) intbyte * to bytemap, calculated |
|
* by calling aalookup() for each pixel |
|
* in rp->bitmap |
|
* grayscale (I) int containing number of grayscales |
|
* to be calculated, 0...grayscale-1 |
|
* (should typically be given as 256) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) 1=success, 0=any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int aalowpasslookup (raster *rp, intbyte *bytemap, int grayscale) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int width=rp->width, height=rp->height, /* width, height of raster */ |
|
icol = 0, irow = 0, imap = (-1); /* width, height, bitmap indexes */ |
|
int bgbitval=0 /*, fgbitval=1*/; /* background, foreground bitval */ |
|
int bitval=0, /* value of rp bit at irow,icol */ |
|
aabyteval=0; /* antialiased (or unchanged) value*/ |
|
int gridnum=0, aagridnum(), /* grid# for 3x3 grid at irow,icol */ |
|
aalookup(); /* table look up antialiased value*/ |
|
/* ------------------------------------------------------------------------- |
|
generate bytemap by table lookup for each pixel of bitmap |
|
-------------------------------------------------------------------------- */ |
|
for ( irow=0; irow<height; irow++ ) |
|
for ( icol=0; icol<width; icol++ ) |
|
{ |
|
/* --- get gridnum and center bit value, init aabyteval --- */ |
|
gridnum = aagridnum(rp,irow,icol); /*grid# coding 3x3 grid at irow,icol*/ |
|
bitval = (gridnum&1); /* center bit set if gridnum odd */ |
|
aabyteval = (intbyte)(bitval==bgbitval?0:grayscale-1); /* default aa val */ |
|
imap++; /* first bump bitmap[] index */ |
|
bytemap[imap] = (intbyte)(aabyteval); /* init antialiased pixel */ |
|
/* --- look up antialiased value for this grid --- */ |
|
aabyteval = aalookup(gridnum); /* look up on grid# */ |
|
if ( aabyteval>=0 && aabyteval<=255 ) /* check for success */ |
|
bytemap[imap] = (intbyte)(aabyteval); /* init antialiased pixel */ |
|
} /* --- end-of-for(irow,icol) --- */ |
|
ispatternnumcount = 0; /* accumulate counts only once */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with gray-scale anti-aliased bytemap |
|
-------------------------------------------------------------------------- */ |
|
/*end_of_job:*/ |
|
return ( 1 ); |
|
} /* --- end-of-function aalowpasslookup() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: aasupsamp ( rp, aa, sf, grayscale ) |
* Function: aasupsamp ( rp, aa, sf, grayscale ) |
* Purpose: calculates a supersampled anti-aliased bytemap |
* Purpose: calculates a supersampled anti-aliased bytemap |
* for rp->bitmap, with each byte 0...grayscale-1 |
* for rp->bitmap, with each byte 0...grayscale-1 |
Line 10918 end_of_job:
|
Line 13074 end_of_job:
|
* (usually just #rows * #cols) |
* (usually just #rows * #cols) |
* colors (O) intbyte * (to be interpreted as ints) |
* colors (O) intbyte * (to be interpreted as ints) |
* returning a list of the discrete/different |
* returning a list of the discrete/different |
* values in bytemap, in ascending value order |
* values in bytemap, in ascending value order, |
|
* and with gamma correction applied |
* colormap (O) intbyte * returning a bytemap "image", |
* colormap (O) intbyte * returning a bytemap "image", |
* i.e., in one-to-one pixel correspondence |
* i.e., in one-to-one pixel correspondence |
* with bytemap, but where the values have been |
* with bytemap, but where the values have been |
Line 10939 int ncolors = 0, /* #different values
|
Line 13096 int ncolors = 0, /* #different values
|
igray, grayscale = 256; /* bytemap contains intbyte's */ |
igray, grayscale = 256; /* bytemap contains intbyte's */ |
intbyte *bytevalues = NULL; /* 1's where bytemap contains value*/ |
intbyte *bytevalues = NULL; /* 1's where bytemap contains value*/ |
int ibyte; /* bytemap/colormap index */ |
int ibyte; /* bytemap/colormap index */ |
int isscale = 0; /* true to scale largest val to 255*/ |
int isscale = 0, /* true to scale largest val to 255*/ |
|
isgamma = 1; /* true to apply gamma correction */ |
int maxcolors = 0; /* maximum ncolors */ |
int maxcolors = 0; /* maximum ncolors */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Accumulate colors[] from values occurring in bytemap |
Accumulate colors[] from values occurring in bytemap |
Line 10970 if ( isscale ) /* only rescale if req
|
Line 13128 if ( isscale ) /* only rescale if req
|
{ colors[igray] = min2(grayscale-1,(int)(scalefactor*colors[igray]+0.5)); |
{ colors[igray] = min2(grayscale-1,(int)(scalefactor*colors[igray]+0.5)); |
if (igray>5) colors[igray] = min2(grayscale-1,colors[igray]+2*igray); } |
if (igray>5) colors[igray] = min2(grayscale-1,colors[igray]+2*igray); } |
} /* --- end-of-if(isscale) --- */ |
} /* --- end-of-if(isscale) --- */ |
|
/* --- apply gamma correction --- */ |
|
if ( isgamma /* only gamma correct if requested */ |
|
&& gammacorrection > 0.0001 ) /* and if we have gamma correction */ |
|
if ( ncolors > 1 ) /* and if not a "blank" raster */ |
|
if ( colors[ncolors-1] > 0 ) /*and at least one pixel non-white*/ |
|
{ |
|
for ( igray=1; igray<ncolors; igray++ ) { /*gamma correct each colors[]*/ |
|
int grayval = colors[igray], /* original 0=white to 255=black */ |
|
gmax = grayscale-1; /* should be 255 */ |
|
double dgray=((double)(gmax-grayval))/((double)gmax); /*0=black 1=white*/ |
|
dgray = pow(dgray,(1.0/gammacorrection)); /* apply gamma correction */ |
|
grayval = (int)( gmax*(1.0-dgray) + 0.5 ); /* convert back to grayval */ |
|
colors[igray] = grayval; } /* store back in colors[] */ |
|
} /* --- end-of-if(isgamma) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Construct colormap |
Construct colormap |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 11164 else /* center point not black */
|
Line 13336 else /* center point not black */
|
/*end_of_job:*/ |
/*end_of_job:*/ |
return ( aaimgval ); |
return ( aaimgval ); |
} /* --- end-of-function aawtpixel() --- */ |
} /* --- end-of-function aawtpixel() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: mimetexsetmsg ( newmsglevel, newmsgfp ) |
|
* Purpose: Sets msglevel and msgfp, usually called from |
|
* an external driver (i.e., DRIVER not defined |
|
* in this module). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: newmsglevel (I) int containing new msglevel |
|
* (unchanged if newmsglevel<0) |
|
* newmsgfp (I) FILE * containing new msgfp |
|
* (unchanged if newmsgfp=NULL) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) always 1 |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int mimetexsetmsg ( int newmsglevel, FILE *newmsgfp ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
set msglevel and msgfp |
|
-------------------------------------------------------------------------- */ |
|
if ( newmsglevel >= 0 ) msglevel = newmsglevel; |
|
if ( newmsgfp != NULL ) msgfp = newmsgfp; |
|
return ( 1 ); |
|
} /* --- end-of-function mimetexsetmsg() --- */ |
#endif /* PART3 */ |
#endif /* PART3 */ |
|
|
/* --- |
/* --- |
Line 11287 messages
|
Line 13486 messages
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
static char *copyright = /* copyright, gnu/gpl notice */ |
static char *copyright = /* copyright, gnu/gpl notice */ |
"+-----------------------------------------------------------------------+\n" |
"+-----------------------------------------------------------------------+\n" |
"|mimeTeX vers 1.63, Copyright(c) 2002-2006, John Forkosh Associates, Inc|\n" |
"|mimeTeX vers 1.70, Copyright(c) 2002-2008, 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 11319 int main ( int argc, char *argv[]
|
Line 13518 int main ( int argc, char *argv[]
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- expression to be emitted --- */ |
/* --- expression to be emitted --- */ |
static char exprbuffer[16385] = "f(x)=x^2"; /* expression to be processed */ |
static char exprbuffer[MAXEXPRSZ+1] = "f(x)=x^2"; /* input TeX expression */ |
char *expression = exprbuffer; /* ptr to expression */ |
char *expression = exprbuffer; /* ptr to expression */ |
int size = NORMALSIZE; /* default font size */ |
int size = NORMALSIZE; /* default font size */ |
char *query = getenv("QUERY_STRING"); /* getenv("QUERY_STRING") result */ |
char *query = getenv("QUERY_STRING"); /* getenv("QUERY_STRING") result */ |
Line 11360 int norefmaxlen = NOREFMAXLEN; /*max que
|
Line 13559 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 */ |
gif_buffer[MAXGIFSZ] = "\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 */ |
|
int valign = (-9999); /*Vertical-Align:baseline-(height-1)*/ |
/* --- pbm/pgm (-g switch) --- */ |
/* --- pbm/pgm (-g switch) --- */ |
int ispbmpgm = 0; /* true to write pbm/pgm file */ |
int ispbmpgm = 0; /* true to write pbm/pgm file */ |
int type_pbmpgm(), ptype=0; /* entry point, graphic format */ |
int type_pbmpgm(), ptype=0; /* entry point, graphic format */ |
Line 11375 int aalowpass(), aapnm(), /*lowpass fil
|
Line 13575 int aalowpass(), aapnm(), /*lowpass fil
|
grayscale = 256; /* 0-255 grayscales in 8-bit bytes */ |
grayscale = 256; /* 0-255 grayscales in 8-bit bytes */ |
int ncolors=2, /* #colors (2=b&w) */ |
int ncolors=2, /* #colors (2=b&w) */ |
aacolormap(); /* build colormap from bytemap */ |
aacolormap(); /* build colormap from bytemap */ |
|
int ipattern; /*patternnumcount[] index diagnostic*/ |
/* --- messages --- */ |
/* --- messages --- */ |
char logfile[256] = LOGFILE, /*log queries if msglevel>=LOGLEVEL*/ |
char logfile[256] = LOGFILE, /*log queries if msglevel>=LOGLEVEL*/ |
cachelog[256] = CACHELOG; /* cached image log in cachepath/ */ |
cachelog[256] = CACHELOG; /* cached image log in cachepath/ */ |
Line 11395 initialization
|
Line 13596 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 */ |
|
isemitcontenttype = 1; /* true to emit mime content-type */ |
|
iscachecontenttype = 0; /* true to cache mime content-type */ |
|
*contenttype = '\000'; /* reset content-type:, etc. cache */ |
|
iscaching = ISCACHING; /* true if caching images */ |
|
if ( iscaching ) { /* images are being cached */ |
|
strcpy(cachepath,CACHEPATH); /* relative path to cached files */ |
|
if ( *cachepath == '%' ) { /* leading % signals cache headers */ |
|
iscachecontenttype = 1; /* signal caching mime content-type*/ |
|
strcpy(cachepath,cachepath+1); } } /* and squeeze out leading % char */ |
gifSize = 0; /* signal that image not in memory */ |
gifSize = 0; /* signal that image not in memory */ |
|
fgred=FGRED; fggreen=FGGREEN; fgblue=FGBLUE; /* default foreground colors */ |
|
bgred=BGRED; bggreen=BGGREEN; bgblue=BGBLUE; /* default background colors */ |
shrinkfactor = shrinkfactors[NORMALSIZE]; /* set shrinkfactor */ |
shrinkfactor = shrinkfactors[NORMALSIZE]; /* set shrinkfactor */ |
|
for ( ipattern=1; ipattern<=51; ipattern++ ) |
|
patternnumcount0[ipattern] = patternnumcount1[ipattern] = 0; |
/* --- |
/* --- |
* check QUERY_STRING query for expression overriding command-line arg |
* check QUERY_STRING query for expression overriding command-line arg |
* ------------------------------------------------------------------- */ |
* ------------------------------------------------------------------- */ |
if ( query != NULL ) /* check query string from environ */ |
if ( query != NULL ) /* check query string from environ */ |
if ( strlen(query) >= 1 ) /* caller gave us a query string */ |
if ( strlen(query) >= 1 ) /* caller gave us a query string */ |
{ strncpy(expression,query,16384); /* so use it as expression */ |
{ strncpy(expression,query,MAXEXPRSZ); /* so use it as expression */ |
expression[16384] = '\000'; /* make sure it's null terminated */ |
expression[MAXEXPRSZ] = '\000'; /* make sure it's null terminated */ |
|
if ( 0 ) /*true to remove leading whitespace*/ |
|
while ( isspace(*expression) && *expression!='\000' ) |
|
strcpy(expression,expression+1); /* squeeze out white space */ |
isquery = 1; } /* and set isquery flag */ |
isquery = 1; } /* and set isquery flag */ |
if ( !isquery ) /* empty query string */ |
if ( !isquery ) /* empty query string */ |
{ char *host = getenv("HTTP_HOST"), /* additional getenv("") results */ |
{ char *host = getenv("HTTP_HOST"), /* additional getenv("") results */ |
Line 11467 if ( !isquery /* don't have an html q
|
Line 13684 if ( !isquery /* don't have an html q
|
if ( 1 || *argv[argnum]=='-' ) argnum--; /*next arg is -switch*/ |
if ( 1 || *argv[argnum]=='-' ) argnum--; /*next arg is -switch*/ |
else pbm_outfile = argv[argnum]; break; /*next arg is filename*/ |
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 = (istransparent?0:1); argnum--; break; |
case 'q': isqforce = 1; 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) --- */ |
Line 11498 if ( !isquery /* don't have an html q
|
Line 13715 if ( !isquery /* don't have an html q
|
&& infilearg <= 0 ) /* and not given in input file */ |
&& infilearg <= 0 ) /* and not given in input file */ |
if ( !isquery /* no conflict if no query_string */ |
if ( !isquery /* no conflict if no query_string */ |
|| nswitches > 0 ) /* explicit -switch(es) also given */ |
|| nswitches > 0 ) /* explicit -switch(es) also given */ |
{ strncpy(expression,argv[exprarg],16384); /*expression from command-line*/ |
{ strncpy(expression,argv[exprarg],MAXEXPRSZ); /*expr from command-line*/ |
expression[16384] = '\000'; /* make sure it's null terminated */ |
expression[MAXEXPRSZ] = '\000'; /* make sure it's null terminated */ |
isquery = 0; } /* and not from a query_string */ |
isquery = 0; } /* and not from a query_string */ |
/* --- |
/* --- |
* or read expression from input file |
* or read expression from input file |
Line 11508 if ( !isquery /* don't have an html q
|
Line 13725 if ( !isquery /* don't have an html q
|
{ |
{ |
FILE *infile = fopen(argv[infilearg],"r"); /* open input file for read */ |
FILE *infile = fopen(argv[infilearg],"r"); /* open input file for read */ |
if ( infile != (FILE *)NULL ) /* opened input file successfully */ |
if ( infile != (FILE *)NULL ) /* opened input file successfully */ |
{ char instring[2049]; /* line from file */ |
{ char instring[MAXLINESZ+1]; /* line from file */ |
|
int exprsz = 0; /* total #bytes read from file */ |
isquery = 0; /* file input, not a query_string */ |
isquery = 0; /* file input, not a query_string */ |
*expression = '\000'; /* start expresion as empty string */ |
*expression = '\000'; /* start expresion as empty string */ |
while ( fgets(instring,2048,infile) != (char *)NULL ) /* read till eof*/ |
while ( fgets(instring,MAXLINESZ,infile) != (char *)NULL ) /*till eof*/ |
strcat(expression,instring); /* concat line to end of expression*/ |
if ( exprsz + strlen(instring) < MAXEXPRSZ ) { /* have room for line */ |
|
strcat(expression,instring); /* concat line to end of expression*/ |
|
exprsz += strlen(instring); } /* update expression buffer length */ |
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) --- */ |
/* --- |
/* --- |
|
* xlate +++'s to blanks only if query |
|
* ----------------------------------- */ |
|
if ( !isquery ) isplusblank = 0; /* don't xlate +++'s to blanks */ |
|
/* --- |
* check if emulating query (for testing) |
* check if emulating query (for testing) |
* -------------------------------------- */ |
* -------------------------------------- */ |
if ( isqforce ) isquery = 1; /* emulate query string processing */ |
if ( isqforce ) isquery = 1; /* emulate query string processing */ |
Line 11532 if ( !isquery /* don't have an html q
|
Line 13756 if ( !isquery /* don't have an html q
|
/* --- |
/* --- |
* check for <form> input |
* check for <form> input |
* ---------------------- */ |
* ---------------------- */ |
if ( isquery ) /* must be <form method="get"> */ |
if ( isquery ) { /* must be <form method="get"> */ |
if ( !memcmp(expression,"formdata",8) ) /*must be <input name="formdata"> */ |
if ( !memcmp(expression,"formdata",8) ) /*must be <input name="formdata"> */ |
{ char *delim=strchr(expression,'='); /* find equal following formdata */ |
{ char *delim=strchr(expression,'='); /* find equal following formdata */ |
if ( delim != (char *)NULL ) /* found unescaped equal sign */ |
if ( delim != (char *)NULL ) /* found unescaped equal sign */ |
Line 11542 if ( isquery ) /* must be <form metho
|
Line 13766 if ( isquery ) /* must be <form metho
|
/*unescape_url(expression,1);*/ /* convert unescaped %xx's to chars */ |
/*unescape_url(expression,1);*/ /* convert unescaped %xx's to chars */ |
unescape_url(expression,0); /* convert all %xx's to chars */ |
unescape_url(expression,0); /* convert all %xx's to chars */ |
unescape_url(expression,0); /* repeat */ |
unescape_url(expression,0); /* repeat */ |
msglevel = FORMLEVEL; /* msglevel for forms */ |
if(0) msglevel = FORMLEVEL; /* msglevel for forms */ |
isformdata = 1; } /* set flag to signal form data */ |
isformdata = 1; } /* set flag to signal form data */ |
else /* --- query, but not <form> input --- */ |
else /* --- query, but not <form> input --- */ |
unescape_url(expression,0); /* convert _all_ %xx's to chars */ |
unescape_url(expression,0); } /* convert _all_ %xx's to chars */ |
/* --- |
/* --- |
* check queries for embedded prefixes signalling special processing |
* check queries for embedded prefixes signalling special processing |
* ----------------------------------------------------------------- */ |
* ----------------------------------------------------------------- */ |
Line 11575 if ( isquery ) /* only log query_stri
|
Line 13799 if ( isquery ) /* only log query_stri
|
if ( msglevel >= LOGLEVEL /* check if logging */ |
if ( msglevel >= LOGLEVEL /* check if logging */ |
&& seclevel <= 5 ) /* and if logging permitted */ |
&& seclevel <= 5 ) /* and if logging permitted */ |
if ( logfile != NULL ) /* if a logfile is given */ |
if ( logfile != NULL ) /* if a logfile is given */ |
if ( *logfile != '\000' ) /*and if it's not an empty string*/ |
if ( *logfile != '\000' ) { /*and if it's not an empty string*/ |
if ( (msgfp=fopen(logfile,"a")) /* open logfile for append */ |
if ( (msgfp=fopen(logfile,"a")) /* open logfile for append */ |
!= NULL ) /* ignore logging if can't open */ |
!= NULL ) /* ignore logging if can't open */ |
{ |
{ |
Line 11626 if ( isquery ) /* only log query_stri
|
Line 13850 if ( isquery ) /* only log query_stri
|
isqlogging = 1; /* set query logging flag */ |
isqlogging = 1; /* set query logging flag */ |
} /* --- end-of-if(msglevel>=LOGLEVEL) --- */ |
} /* --- end-of-if(msglevel>=LOGLEVEL) --- */ |
else /* couldn't open logfile */ |
else /* couldn't open logfile */ |
msglevel = 0; /* can't emit messages */ |
msglevel = 0; } /* can't emit messages */ |
/* --- |
/* --- |
* prepend prefix to submitted expression |
* prepend prefix to submitted expression |
* -------------------------------------- */ |
* -------------------------------------- */ |
Line 11714 if ( isquery ) /* don't cache command
|
Line 13938 if ( isquery ) /* don't cache command
|
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 */ |
/* --- emit mime content-type line --- */ |
/* --- emit mime content-type line --- */ |
if ( 0 ) /* now done in emitcache() */ |
if ( 0 && isemitcontenttype ) /* now done in emitcache() */ |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
|
if ( abs(valign) < 999 ) /* have vertical align */ |
|
fprintf( stdout, "Vertical-Align: %d\n",valign ); |
fprintf( stdout, "Content-type: image/gif\n\n" ); } |
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,maxage,0) > 0 ) /* cached image emitted */ |
if ( emitcache(cachefile,maxage,valign,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 11761 if ( !isdumpimage ) /* don't mix ascii
|
Line 13987 if ( !isdumpimage ) /* don't mix ascii
|
rasterize expression and put a border around it |
rasterize expression and put a border around it |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- preprocess expression, converting LaTeX constructs for mimeTeX --- */ |
/* --- preprocess expression, converting LaTeX constructs for mimeTeX --- */ |
expression = mimeprep(expression); /* preprocess expression */ |
if ( expression != NULL ) { /* have expression to rasterize */ |
|
expression = mimeprep(expression); } /* preprocess expression */ |
/* --- double-check that we actually have an expression to rasterize --- */ |
/* --- double-check that we actually have an expression to rasterize --- */ |
if ( expression == NULL ) /* nothing to rasterize */ |
if ( expression == NULL ) /* nothing to rasterize */ |
{ if ( (!isquery||isqlogging) && msgfp!=NULL ) /*emit error if not a query*/ |
{ if ( (!isquery||isqlogging) && msgfp!=NULL ) /*emit error if not a query*/ |
Line 11780 if ( issupersampling ) /* no border ne
|
Line 14007 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 ( sp!=NULL && bp!=NULL ) { /* have raster */ |
|
valign = sp->baseline - (bp->height - 1); /* #pixels for Vertical-Align: */ |
|
if ( abs(valign) > 255 ) valign = (-9999); } /* sanity check */ |
if ( ispbmpgm && ptype<2 ) /* -g switch or -g1 switch */ |
if ( ispbmpgm && ptype<2 ) /* -g switch or -g1 switch */ |
type_pbmpgm(bp,ptype,pbm_outfile); /* emit b/w pbm file */ |
type_pbmpgm(bp,ptype,pbm_outfile); /* emit b/w pbm file */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 11811 if ( isaa ) /* we want anti-aliased b
|
Line 14041 if ( isaa ) /* we want anti-aliased b
|
* select anti-aliasing algorithm |
* select anti-aliasing algorithm |
* ------------------------------ */ |
* ------------------------------ */ |
if ( !isss ) /* generate bytemap for lowpass */ |
if ( !isss ) /* generate bytemap for lowpass */ |
if ( aaalgorithm == 1 ) /* 1 for aalowpass() */ |
switch ( aaalgorithm ) { /* choose antialiasing algorithm */ |
{ if ( aalowpass(bp,bytemap_raster,grayscale) /* my lowpass filter */ |
default: isaa = 0; break; /* unrecognized algorithm */ |
== 0 ) isaa = 0; } /*failed, so turn off anti-aliasing*/ |
case 1: /* 1 for aalowpass() */ |
else /* or 2 for aapnm() */ |
if ( aalowpass(bp,bytemap_raster,grayscale) /*my own lowpass filter*/ |
if ( aaalgorithm == 2 ) /*2 for netpbm pnmalias.c algorithm*/ |
== 0 ) isaa = 0; /*failed, so turn off anti-aliasing*/ |
{ if ( aapnm(bp,bytemap_raster,grayscale) /* pnmalias.c filter */ |
break; |
== 0 ) isaa = 0; } /*failed, so turn off anti-aliasing*/ |
case 2: /*2 for netpbm pnmalias.c algorithm*/ |
else isaa = 0; /* unrecognized algorithm */ |
if ( aapnm(bp,bytemap_raster,grayscale) /* pnmalias.c filter */ |
|
== 0 ) isaa = 0; /*failed, so turn off anti-aliasing*/ |
|
break; |
|
case 3: /*3 for aapnm() based on aagridnum()*/ |
|
if ( aapnmlookup(bp,bytemap_raster,grayscale) /* pnmalias.c filter */ |
|
== 0 ) isaa = 0; /*failed, so turn off anti-aliasing*/ |
|
break; |
|
case 4: /* 4 for aalookup() table lookup */ |
|
if ( aalowpasslookup(bp,bytemap_raster,grayscale) /* aalookup() */ |
|
== 0 ) isaa = 0; /*failed, so turn off anti-aliasing*/ |
|
break; |
|
} /* --- end-of-switch(aaalgorithm) --- */ |
|
/* --- |
|
* emit aalookup() pattern# counts/percents diagnostics |
|
* ---------------------------------------------------- */ |
|
if ( !isquery && msgfp!=NULL && msglevel>=99 ) { /*emit patternnumcounts*/ |
|
int pcount0=0, pcount1=0; /* init total w,b center counts */ |
|
for ( ipattern=1; ipattern<=51; ipattern++ ) { /*each possible pattern*/ |
|
if ( ipattern > 1 ) /* ignore all-white squares */ |
|
pcount0 += patternnumcount0[ipattern]; /* bump total white centers */ |
|
pcount1 += patternnumcount1[ipattern]; } /* bump total black centers */ |
|
if ( pcount0+pcount1 > 0 ) /* have pcounts (using aalookup) */ |
|
fprintf(msgfp, " aalookup() patterns excluding#1 white" |
|
" (%%'s are in tenths of a percent)...\n"); |
|
for ( ipattern=1; ipattern<=51; ipattern++ ) { /*each possible pattern*/ |
|
int tot = patternnumcount0[ipattern] + patternnumcount1[ipattern]; |
|
if ( tot > 0 ) /* this pattern occurs in image */ |
|
fprintf(msgfp, |
|
" pattern#%2d: %7d(%6.2f%%) +%7d(%6.2f%%) =%7d(%6.2f%%)\n", |
|
ipattern, patternnumcount0[ipattern], (ipattern<=1? 999.99: |
|
1000.*((double)patternnumcount0[ipattern])/((double)pcount0)), |
|
patternnumcount1[ipattern], |
|
1000.*((double)patternnumcount1[ipattern])/((double)pcount1), |
|
tot, (ipattern<=1? 999.99: |
|
1000.*((double)tot)/((double)(pcount0+pcount1))) ); } |
|
if ( pcount0+pcount1 > 0 ) /* true when using aalookup() */ |
|
fprintf(msgfp, |
|
"all patterns: %7d +%7d =%7d total pixels\n", |
|
pcount0,pcount1,pcount0+pcount1); } |
/* --- |
/* --- |
* finally, generate colors and colormap |
* finally, generate colors and colormap |
* ------------------------------------- */ |
* ------------------------------------- */ |
Line 11884 if ( isquery /* called from browser
|
Line 14152 if ( isquery /* called from browser
|
------------------------------------------------------------------------- */ |
------------------------------------------------------------------------- */ |
/* --- don't use memory buffer if outout file given --- */ |
/* --- don't use memory buffer if outout file given --- */ |
if ( gif_outfile != NULL ) isinmemory = 0; /* reset memory buffer flag */ |
if ( gif_outfile != NULL ) isinmemory = 0; /* reset memory buffer flag */ |
|
/* --- construct contenttype[] buffer containing mime headers --- */ |
|
if ( 1 ) { /* always construct buffer */ |
|
sprintf( contenttype, "Cache-Control: max-age=%d\n", maxage ); |
|
/*sprintf(contenttype+strlen(contenttype), |
|
"Expires: Fri, 31 Oct 2003 23:59:59 GMT\n" );*/ |
|
/*sprintf(contenttype+strlen(contenttype), |
|
"Last-Modified: Wed, 15 Oct 2003 01:01:01 GMT\n");*/ |
|
if ( abs(valign) < 999 ) /* have Vertical-Align: header info*/ |
|
sprintf( contenttype+strlen(contenttype), |
|
"Vertical-Align: %d\n", valign ); |
|
sprintf( contenttype+strlen(contenttype), |
|
"Content-type: image/gif\n\n" ); } |
/* --- emit mime content-type line --- */ |
/* --- emit mime content-type line --- */ |
if ( !isdumpimage /* don't mix ascii with image dump */ |
if ( isemitcontenttype /* content-type lines wanted */ |
|
&& !isdumpimage /* don't mix ascii with image dump */ |
&& !isinmemory /* done below if in memory */ |
&& !isinmemory /* done below if in memory */ |
&& !iscaching ) /* done by emitcache() if caching */ |
&& !iscaching ) /* done by emitcache() if caching */ |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
{ fputs(contenttype,stdout); } /* emit content-type: header buffer*/ |
/*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, "Content-type: image/gif\n\n" ); } |
|
/* --- write output to memory buffer, possibly for testing --- */ |
/* --- write output to memory buffer, possibly for testing --- */ |
if ( isinmemory /* want gif written to memory */ |
if ( isinmemory /* want gif written to memory */ |
|| isdumpbuffer ) /*or dump memory buffer for testing*/ |
|| isdumpbuffer ) /*or dump memory buffer for testing*/ |
if ( gif_outfile == NULL ) /* and don't already have a file */ |
if ( gif_outfile == NULL ) /* and don't already have a file */ |
{ *gif_buffer = '\000'; /* init buffer as empty string */ |
{ *gif_buffer = '\000'; /* init buffer as empty string */ |
memset(gif_buffer,0,4096); /* zero out buffer */ |
memset(gif_buffer,0,MAXGIFSZ); /* zero out buffer */ |
gif_outfile = gif_buffer; /* and point outfile to buffer */ |
gif_outfile = gif_buffer; /* and point outfile to buffer */ |
if ( isdumpbuffer ) /* buffer dump test requested */ |
if ( isdumpbuffer ) /* buffer dump test requested */ |
isdumpbuffer = 999; } /* so signal dumping to buffer */ |
isdumpbuffer = 999; } /* so signal dumping to buffer */ |
Line 11917 if ( isquery /* called from browser
|
Line 14195 if ( isquery /* called from browser
|
*gif_outfile = '\000'; } /* empty string signals buffer */ |
*gif_outfile = '\000'; } /* empty string signals buffer */ |
else { /* or */ |
else { /* or */ |
gif_outfile = (char *)NULL; /* emit images to stdout */ |
gif_outfile = (char *)NULL; /* emit images to stdout */ |
fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
if ( isemitcontenttype ) { /* content-type lines wanted */ |
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" ); } } |
} /* --- end-of-while(1) --- */ |
} /* --- 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 */ |
Line 11953 if ( isquery /* called from browser
|
Line 14232 if ( isquery /* called from browser
|
|| msglevel >= 99 ) { /* or debugging */ |
|| msglevel >= 99 ) { /* or debugging */ |
int maxage2 = (isdumpimage?(-1):maxage); /* no headers if dumping image */ |
int maxage2 = (isdumpimage?(-1):maxage); /* no headers if dumping image */ |
if ( iscaching ) /* caching enabled */ |
if ( iscaching ) /* caching enabled */ |
emitcache(cachefile,maxage2,0); /* cached image (hopefully) emitted*/ |
emitcache(cachefile,maxage2,valign,0); /*emit cached image (hopefully)*/ |
else if ( isinmemory ) /* or emit image from memory buffer*/ |
else if ( isinmemory ) /* or emit image from memory buffer*/ |
emitcache(gif_buffer,maxage2,1); } /* emitted from memory buffer */ |
emitcache(gif_buffer,maxage2,valign,1); } /*emitted from memory buffer*/ |
/* --- for testing, may need to write image buffer to file --- */ |
/* --- for testing, may need to write image buffer to file --- */ |
if ( isdumpbuffer > 99 ) /* gif image in memory buffer */ |
if ( isdumpbuffer > 99 ) /* gif image in memory buffer */ |
if ( gifSize > 0 ) /* and it's not an empty buffer */ |
if ( gifSize > 0 ) /* and it's not an empty buffer */ |
Line 12194 end_of_job:
|
Line 14473 end_of_job:
|
* ftp://ftp.ncsa.uiuc.edu/Web/httpd/Unix/ncsa_httpd/cgi/ncsa-default.tar.Z |
* ftp://ftp.ncsa.uiuc.edu/Web/httpd/Unix/ncsa_httpd/cgi/ncsa-default.tar.Z |
* o Not quite "verbatim" -- I added the "isescape logic" 4-Dec-03 |
* o Not quite "verbatim" -- I added the "isescape logic" 4-Dec-03 |
* so unescape_url() can be safely applied to input which may or |
* so unescape_url() can be safely applied to input which may or |
* may not have been url-encoded. |
* may not have been url-encoded. (Note: currently, all calls |
|
* to unescape_url() pass iescape=0, so it's not used.) |
|
* o Added +++'s to blank xlation on 24-Sep-06 |
|
* o Added ^M,^F,etc to blank xlation 0n 01-Oct-06 |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
int unescape_url(char *url, int isescape) { |
int unescape_url(char *url, int isescape) { |
int x=0,y=0,prevescape=0,gotescape=0; |
int x=0,y=0,prevescape=0,gotescape=0; |
|
int xlateplus = (isplusblank==1?1:0); /* true to xlate plus to blank */ |
|
int strreplace(); /* replace + with blank, if needed */ |
char x2c(); |
char x2c(); |
static char *hex="0123456789ABCDEFabcdef"; |
static char *hex="0123456789ABCDEFabcdef"; |
|
/* --- |
|
* xlate ctrl chars to blanks |
|
* -------------------------- */ |
|
if ( 1 ) { /* xlate ctrl chars to blanks */ |
|
char *ctrlchars = "\n\t\v\b\r\f\a\015"; |
|
int seglen = strspn(url,ctrlchars); /*initial segment with ctrlchars*/ |
|
int urllen = strlen(url); /* total length of url string */ |
|
/* --- first, entirely remove ctrlchars from beginning and end --- */ |
|
if ( seglen > 0 ) { /*have ctrlchars at start of string*/ |
|
strcpy(url,url+seglen); /* squeeze out initial ctrlchars */ |
|
urllen -= seglen; } /* string is now shorter */ |
|
while ( --urllen >= 0 ) /* now remove ctrlchars from end */ |
|
if ( isthischar(url[urllen],ctrlchars) ) /* ctrlchar at end */ |
|
url[urllen] = '\000'; /* re-terminate string before it */ |
|
else break; /* or we're done */ |
|
urllen++; /* length of url string */ |
|
/* --- now, replace interior ctrlchars with ~ blanks --- */ |
|
while ( (seglen=strcspn(url,ctrlchars)) < urllen ) /*found a ctrlchar*/ |
|
url[seglen] = '~'; /* replace ctrlchar with ~ */ |
|
} /* --- end-of-if(1) --- */ |
|
/* --- |
|
* xlate +'s to blanks if requested or if deemed necessary |
|
* ------------------------------------------------------- */ |
|
if ( isplusblank == (-1) ) { /*determine whether or not to xlate*/ |
|
char *searchfor[] = { " ","%20", "%2B","%2b", "+++","++", |
|
"+=+","+-+", NULL }; |
|
int isearch = 0, /* searchfor[] index */ |
|
nfound[11] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; /*#occurrences*/ |
|
/* --- locate occurrences of searchfor[] strings in url --- */ |
|
for ( isearch=0; searchfor[isearch] != NULL; isearch++ ) { |
|
char *psearch = url; /* start search at beginning */ |
|
nfound[isearch] = 0; /* init #occurrences count */ |
|
while ( (psearch=strstr(psearch,searchfor[isearch])) != NULL ) { |
|
nfound[isearch] += 1; /* count another occurrence */ |
|
psearch += strlen(searchfor[isearch]); } /*resume search after it*/ |
|
} /* --- end-of-for(isearch) --- */ |
|
/* --- apply some common-sense logic --- */ |
|
if ( nfound[0] + nfound[1] > 0 ) /* we have actual " "s or "%20"s */ |
|
isplusblank = xlateplus = 0; /* so +++'s aren't blanks */ |
|
if ( nfound[2] + nfound[3] > 0 ) { /* we have "%2B" for +++'s */ |
|
if ( isplusblank != 0 ) /* and haven't disabled xlation */ |
|
isplusblank = xlateplus = 1; /* so +++'s are blanks */ |
|
else /* we have _both_ "%20" and "%2b" */ |
|
xlateplus = 0; } /* tough call */ |
|
if ( nfound[4] + nfound[5] > 0 /* we have multiple ++'s */ |
|
|| nfound[6] + nfound[7] > 0 ) /* or we have a +=+ or +-+ */ |
|
if ( isplusblank != 0 ) /* and haven't disabled xlation */ |
|
xlateplus = 1; /* so xlate +++'s to blanks */ |
|
} /* --- end-of-if(isplusblank==-1) --- */ |
|
if ( xlateplus > 0 ) { /* want +'s xlated to blanks */ |
|
char *xlateto[] = { ""," "," "," + "," "," "," "," "," " }; |
|
while ( xlateplus > 0 ) { /* still have +++'s to xlate */ |
|
char plusses[99] = "++++++++++++++++++++"; /* longest +++ string */ |
|
plusses[xlateplus] = '\000'; /* null-terminate +++'s */ |
|
strreplace(url,plusses,xlateto[xlateplus],0); /* xlate +++'s */ |
|
xlateplus--; /* next shorter +++ string */ |
|
} /* --- end-of-while(xlateplus>0) --- */ |
|
} /* --- end-of-if(xlateplus) --- */ |
|
isplusblank = 0; /* don't iterate this xlation */ |
|
/* --- |
|
* xlate %nn to corresponding char |
|
* ------------------------------- */ |
for(;url[y];++x,++y) { |
for(;url[y];++x,++y) { |
gotescape = prevescape; |
gotescape = prevescape; |
prevescape = (url[x]=='\\'); |
prevescape = (url[x]=='\\'); |
Line 12268 return ( nlogged ); /* back to caller
|
Line 14614 return ( nlogged ); /* back to caller
|
} /* --- end-of-function logger() --- */ |
} /* --- end-of-function logger() --- */ |
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: emitcache ( cachefile, maxage, isbuffer ) |
* Function: emitcache ( cachefile, maxage, valign, 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 |
* or contains buffer of bytes to be dumped |
* maxage (I) int containing maxage. in seconds, for |
* maxage (I) int containing maxage, in seconds, for |
* http header, or -1 to not emit headers |
* http header, or -1 to not emit headers |
|
* valign (I) int containing Vertical-Align:, in pixels, |
|
* for http header, or <= -999 to not emit |
* isbuffer (I) 1 if cachefile is buffer of bytes to be |
* isbuffer (I) 1 if cachefile is buffer of bytes to be |
* dumped |
* dumped |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 12284 return ( nlogged ); /* back to caller
|
Line 14632 return ( nlogged ); /* back to caller
|
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
int emitcache ( char *cachefile, int maxage, int isbuffer ) |
int emitcache ( char *cachefile, int maxage, int valign, int isbuffer ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
int nbytes=gifSize, readcachefile(); /* read cache file */ |
int nbytes=gifSize, readcachefile(); /* read cache file */ |
FILE *emitptr = stdout; /* emit cachefile to stdout */ |
FILE *emitptr = stdout; /* emit cachefile to stdout */ |
unsigned char buffer[64000]; /* bytes from cachefile */ |
unsigned char buffer[MAXGIFSZ+1]; /* bytes from cachefile */ |
unsigned char *buffptr = buffer; /* ptr to buffer */ |
unsigned char *buffptr = buffer; /* ptr to buffer */ |
|
int isvalign = (abs(valign)<999?1:0); /* true to emit Vertical-Align: */ |
|
int iscontenttypecached = iscachecontenttype; /*true if headers cached*/ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 12300 initialization
|
Line 14650 initialization
|
if ( emitptr == (FILE *)NULL ) /* failed to open emit file */ |
if ( emitptr == (FILE *)NULL ) /* 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 */ |
/* --- read the file if necessary --- */ |
/* --- read the file if necessary --- */ |
if ( isbuffer ) /* cachefile is buffer */ |
if ( isbuffer ) { /* cachefile is buffer */ |
buffptr = (unsigned char *)cachefile; /* so reset buffer pointer */ |
buffptr = (unsigned char *)cachefile; /* so reset buffer pointer */ |
else /* cachefile is file name */ |
iscontenttypecached = 0; } /* and iscontenttypecached flag */ |
if ( (nbytes = readcachefile(cachefile,buffer)) /* read the file */ |
else { /* cachefile is file name */ |
< 1 ) goto end_of_job; /* quit if file not read */ |
if ( (nbytes = readcachefile(cachefile,buffer)) /* read the file */ |
|
< 1 ) goto end_of_job; } /* quit if file not read */ |
/* --- first emit http headers if requested --- */ |
/* --- first emit http headers if requested --- */ |
if ( maxage >= 0 ) /* caller wants http headers */ |
if ( isemitcontenttype /* content-type lines enabled */ |
|
&& !iscontenttypecached /* and not in cached image */ |
|
&& maxage >= 0 ) /* caller wants http headers */ |
{ /* --- emit mime content-type line --- */ |
{ /* --- emit mime content-type line --- */ |
fprintf( emitptr, "Cache-Control: max-age=%d\n",maxage ); |
fprintf( emitptr, "Cache-Control: max-age=%d\n",maxage ); |
fprintf( emitptr, "Content-Length: %d\n",nbytes ); |
fprintf( emitptr, "Content-Length: %d\n",nbytes ); |
|
if ( isvalign ) /* Vertical-Align: header wanted */ |
|
fprintf( emitptr, "Vertical-Align: %d\n",valign ); |
fprintf( emitptr, "Content-type: image/gif\n\n" ); } |
fprintf( emitptr, "Content-type: image/gif\n\n" ); } |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
set stdout to binary mode (for Windows) |
set stdout to binary mode (for Windows) |
Line 12362 FILE *cacheptr = fopen(cachefile,"rb");
|
Line 14717 FILE *cacheptr = fopen(cachefile,"rb");
|
unsigned char cachebuff[64]; /* bytes from cachefile */ |
unsigned char cachebuff[64]; /* bytes from cachefile */ |
int buflen = 32, /* #bytes we try to read from file */ |
int buflen = 32, /* #bytes we try to read from file */ |
nread = 0, /* #bytes actually read from file */ |
nread = 0, /* #bytes actually read from file */ |
maxbytes = 64000, /* max #bytes returned in buffer */ |
maxbytes = MAXGIFSZ, /* max #bytes returned in buffer */ |
nbytes = 0; /* total #bytes read */ |
nbytes = 0; /* total #bytes read */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |