📄 mimetex.c
字号:
/* --- allocate rotated raster with flipped width<-->height --- */
if ( (rotated = new_raster(height,width,pixsz)) /* flip width,height */
!= NULL ) /* check that allocation succeeded */
/* --- fill rotated 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);
/* setpixel(rotated,icol,irow,value); } */
setpixel(rotated,icol,(height-1-irow),value); }
return ( rotated ); /* return rotated raster to caller */
} /* --- end-of-function rastrot() --- */
/* ==========================================================================
* Function: rastput ( target, source, top, left, isopaque )
* Purpose: Overlays source onto target,
* with the 0,0-bit of source onto the top,left-bit of target.
* --------------------------------------------------------------------------
* Arguments: target (I) ptr to target raster struct
* source (I) ptr to source raster struct
* top (I) int containing 0 ... target->height - 1
* left (I) int containing 0 ... target->width - 1
* isopaque (I) int containing false (zero) to allow
* original 1-bits of target to "show through"
* 0-bits of source.
* --------------------------------------------------------------------------
* Returns: ( int ) 1 if completed successfully,
* or 0 otherwise (for any error).
* --------------------------------------------------------------------------
* Notes:
* ======================================================================= */
/* --- entry point --- */
int rastput ( raster *target, raster *source,
int top, int left, int isopaque )
{
/* -------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
int irow, icol, /* indexes over source raster */
twidth=target->width, theight=target->height, /*target width,height*/
tpix, ntpix = twidth*theight; /* #pixels in target */
int isfatal = 0, /* true to abend on out-of-bounds error */
isstrict = 0/*1*/, /* true for strict bounds check - no "wrap"*/
isokay = 1; /* true if no pixels out-of-bounds */
/* -------------------------------------------------------------------------
superimpose source onto target, one bit at a time
-------------------------------------------------------------------------- */
if ( isstrict && (top<0 || left<0) ) /* args fail strict test */
isokay = 0; /* so just return error */
else
for ( irow=0; irow<source->height; irow++ ) /* for each scan line */
{
tpix = (top+irow)*target->width + left - 1; /*first target pixel (-1)*/
for ( icol=0; icol<source->width; icol++ ) /* each pixel in scan line */
{
int svalue = getpixel(source,irow,icol); /* source pixel value */
++tpix; /* bump target pixel */
if ( msgfp!=NULL && msglevel>=9999 ) /* debugging output */
{ fprintf(msgfp,"rastput> tpix,ntpix=%d,%d top,irow,theight=%d,%d,%d "
"left,icol,twidth=%d,%d,%d\n", tpix,ntpix, top,irow,theight,
left,icol,twidth); fflush(msgfp); }
if ( tpix >= ntpix /* bounds check failed */
|| (isstrict && (irow+top>=theight || icol+left>=twidth)) )
{ isokay = 0; /* reset okay flag */
if ( isfatal ) goto end_of_job; /* abort if error is fatal */
else break; } /*or just go on to next row*/
if ( tpix >= 0 ) /* bounds check okay */
if ( svalue!=0 || isopaque ) /*got dark or opaque source*/
setpixel(target,irow+top,icol+left,svalue); /*overlay source on target*/
} /* --- end-of-for(icol) --- */
} /* --- end-of-for(irow) --- */
/* -------------------------------------------------------------------------
Back to caller with 1=okay, 0=failed.
-------------------------------------------------------------------------- */
end_of_job:
return ( isokay /*isfatal? (tpix<ntpix? 1:0) : 1*/ );
} /* --- end-of-function rastput() --- */
/* ==========================================================================
* Function: rastcompose ( sp1, sp2, offset2, isalign, isfree )
* Purpose: Overlays sp2 on top of sp1, leaving both unchanged
* and returning a newly-allocated composite subraster.
* Frees/deletes input sp1 and/or sp2 depending on value
* of isfree (0=none, 1=sp1, 2=sp2, 3=both).
* --------------------------------------------------------------------------
* Arguments: sp1 (I) subraster * to "underneath" subraster,
* whose baseline is preserved
* sp2 (I) subraster * to "overlaid" subraster
* offset2 (I) int containing 0 or number of pixels
* to horizontally shift sp2 relative to sp1,
* either positive (right) or negative
* isalign (I) int containing 1 to align baselines,
* or 0 to vertically center sp2 over sp1
* isfree (I) int containing 1=free sp1 before return,
* 2=free sp2, 3=free both, 0=free none.
* --------------------------------------------------------------------------
* Returns: ( subraster * ) pointer to constructed subraster
* or NULL for any error
* --------------------------------------------------------------------------
* Notes:
* ======================================================================= */
/* --- entry point --- */
subraster *rastcompose ( subraster *sp1, subraster *sp2, int offset2,
int isalign, int isfree )
{
/* -------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
subraster *new_subraster(), *sp=(subraster *)NULL; /* returned subraster */
raster *rp=(raster *)NULL; /* new composite raster in sp */
int delete_subraster(); /* in case isfree non-zero */
int rastput(); /*place sp1,sp2 in composite raster*/
int base1 = sp1->baseline, /*baseline for underlying subraster*/
height1 = (sp1->image)->height, /* height for underlying subraster */
width1 = (sp1->image)->width, /* width for underlying subraster */
pixsz1 = (sp1->image)->pixsz, /* pixsz for underlying subraster */
base2 = sp2->baseline, /*baseline for overlaid subraster */
height2 = (sp2->image)->height, /* height for overlaid subraster */
width2 = (sp2->image)->width, /* width for overlaid subraster */
pixsz2 = (sp2->image)->pixsz; /* pixsz for overlaid subraster */
int height=0, width=0, pixsz=0, base=0; /* overlaid composite */
/* -------------------------------------------------------------------------
Initialization
-------------------------------------------------------------------------- */
/* --- determine height, width and baseline of composite raster --- */
if ( isalign ) /* baselines of sp1,sp2 aligned */
{ height = max2(base1+1,base2+1) /* max height above baseline */
+ max2(height1-base1-1,height2-base2-1); /*+ max descending below*/
base = max2(base1,base2); } /* max space above baseline */
else /* baselines not aligned */
{ height = max2(height1,height2); /* max height */
base = base1 + (height-height1)/2; } /* baseline for sp1 */
width = max2(width1,width2+abs(offset2)); /* max width */
pixsz = max2(pixsz1,pixsz2); /* bitmap,bytemap becomes bytemap */
/* -------------------------------------------------------------------------
allocate concatted composite subraster
-------------------------------------------------------------------------- */
/* --- allocate returned subraster (and then initialize it) --- */
if ( (sp=new_subraster(width,height,pixsz)) /* allocate new subraster */
== (subraster *)NULL ) goto end_of_job; /* failed, so quit */
/* --- initialize subraster parameters --- */
sp->type = IMAGERASTER; /* image */
sp->baseline = base; /* composite baseline */
sp->size = sp1->size; /* underlying char is sp1 */
/* --- extract raster from subraster --- */
rp = sp->image; /* raster allocated in subraster */
/* -------------------------------------------------------------------------
overlay sp1 and sp2 in new composite raster
-------------------------------------------------------------------------- */
if ( isalign )
{ rastput (rp, sp1->image, base-base1, (width-width1)/2, 1); /*underlying*/
rastput (rp, sp2->image, base-base2, /*overlaid*/
(width-width2)/2+offset2, 0); }
else
{ rastput (rp, sp1->image, base-base1, (width-width1)/2, 1); /*underlying*/
rastput (rp, sp2->image, (height-height2)/2, /*overlaid*/
(width-width2)/2+offset2, 0); }
/* -------------------------------------------------------------------------
free input if requested
-------------------------------------------------------------------------- */
if ( isfree > 0 ) /* caller wants input freed */
{ if ( isfree==1 || isfree>2 ) delete_subraster(sp1); /* free sp1 */
if ( isfree >= 2 ) delete_subraster(sp2); } /* and/or sp2 */
/* -------------------------------------------------------------------------
Back to caller with pointer to concatted subraster or with null for error
-------------------------------------------------------------------------- */
end_of_job:
return ( sp ); /* back with subraster or null ptr */
} /* --- end-of-function rastcompose() --- */
/* ==========================================================================
* Function: rastcat ( sp1, sp2, isfree )
* Purpose: "Concatanates" subrasters sp1||sp2, leaving both unchanged
* and returning a newly-allocated subraster.
* Frees/deletes input sp1 and/or sp2 depending on value
* of isfree (0=none, 1=sp1, 2=sp2, 3=both).
* --------------------------------------------------------------------------
* Arguments: sp1 (I) subraster * to left-hand subraster
* sp2 (I) subraster * to right-hand subraster
* isfree (I) int containing 1=free sp1 before return,
* 2=free sp2, 3=free both, 0=free none.
* --------------------------------------------------------------------------
* Returns: ( subraster * ) pointer to constructed subraster sp1||sp2
* or NULL for any error
* --------------------------------------------------------------------------
* Notes:
* ======================================================================= */
/* --- entry point --- */
subraster *rastcat ( subraster *sp1, subraster *sp2, int isfree )
{
/* -------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
subraster *new_subraster(), *sp=(subraster *)NULL; /* returned subraster */
raster *rp=(raster *)NULL; /* new concatted raster */
int delete_subraster(); /* in case isfree non-zero */
int rastput(); /*place sp1,sp2 in concatted raster*/
int type_raster(); /* debugging display */
int base1 = sp1->baseline, /*baseline for left-hand subraster*/
height1 = (sp1->image)->height, /* height for left-hand subraster */
width1 = (sp1->image)->width, /* width for left-hand subraster */
pixsz1 = (sp1->image)->pixsz, /* pixsz for left-hand subraster */
type1 = sp1->type, /* image type for left-hand */
base2 = sp2->baseline, /*baseline for right-hand subraster*/
height2 = (sp2->image)->height, /* height for right-hand subraster */
width2 = (sp2->image)->width, /* width for right-hand subraster */
pixsz2 = (sp2->image)->pixsz, /* pixsz for right-hand subraster */
type2 = sp2->type; /* image type for right-hand */
int height=0, width=0, pixsz=0, base=0; /*concatted sp1||sp2 composite*/
int issmash = (smashmargin!=0?1:0), /* true to "squash" sp1||sp2 */
isopaque = (issmash?0:1), /* not oppaque if smashing */
rastsmash(), isblank=0, nsmash=0, /* #cols to smash */
oldsmashmargin = smashmargin; /* save original smashmargin */
mathchardef *symdef1 = sp1->symdef, /*mathchardef of last left-hand char*/
*symdef2 = sp2->symdef; /* mathchardef of right-hand char */
int class1 = (symdef1==NULL?ORDINARY:symdef1->class), /* symdef->class */
class2 = (symdef2==NULL?ORDINARY:symdef2->class), /* or default */
smash1 = (symdef1!=NULL)&&(class1==ORDINARY||class1==VARIABLE||
class1==OPENING||class1==CLOSING||class1==PUNCTION),
smash2 = (symdef2!=NULL)&&(class2==ORDINARY||class2==VARIABLE||
class2==OPENING||class2==CLOSING||class2==PUNCTION),
space = fontsize/2+1; /* #cols between sp1 and sp2 */
/* -------------------------------------------------------------------------
Initialization
-------------------------------------------------------------------------- */
/* --- determine inter-character space from character class --- */
if ( !isstring )
space = max2(2,(symspace[class1][class2] + fontsize-3)); /* space */
else space = 1; /* space for ascii string */
if ( !iscatspace ) space=0; /* spacing explicitly turned off */
/* --- determine smash --- */
if ( !isstring ) /* don't smash strings */
if ( issmash ) { /* raster smash wanted */
int maxsmash = rastsmash(sp1,sp2), /* calculate max smash space */
margin = smashmargin; /* init margin without delta */
if ( (1 && smash1 && smash2) /* concatanating two chars */
|| (1 && type1!=IMAGERASTER && type2!=IMAGERASTER) )
/*maxsmash = 0;*/ /* turn off smash */
margin = max2(space-1,0); /* force small smashmargin */
else /* adjust for delta if images */
if ( issmashdelta ) /* smashmargin is a delta value */
margin += fontsize; /* add displaystyle base to margin */
if ( maxsmash == blanksignal ) /* sp2 is intentional blank */
isblank = 1; /* set blank flag signal */
else /* see how much extra space we have*/
if ( maxsmash > margin ) /* enough space for adjustment */
nsmash = maxsmash-margin; /* make adjustment */
if ( msgfp!=NULL && msglevel>=99 ) /* display smash results */
{ fprintf(msgfp,"rastcat> maxsmash=%d, margin=%d, nsmash=%d\n",
maxsmash,margin,nsmash);
fprin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -