summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipng/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipng/draw.c')
-rw-r--r--Build/source/texk/dvipng/draw.c301
1 files changed, 174 insertions, 127 deletions
diff --git a/Build/source/texk/dvipng/draw.c b/Build/source/texk/dvipng/draw.c
index 4e91c5f9e93..4722ee8b751 100644
--- a/Build/source/texk/dvipng/draw.c
+++ b/Build/source/texk/dvipng/draw.c
@@ -4,84 +4,102 @@
Part of the dvipng distribution
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
- Copyright (C) 2002-2008 Jan-Åke Larsson
+ Copyright (C) 2002-2006 Jan-Åke Larsson
************************************************************************/
#include "dvipng.h"
+/* #define NO_DRIFT */
+
#ifdef DEBUG
#include <ctype.h> /* isprint */
#endif
struct stack_entry {
dviunits h, v, w, x, y, z; /* stack entry */
- subpixels hh,vv;
-} stack[STACK_SIZE+1]; /* stack + space for current pos */
-struct stack_entry* dvi_stack=stack;
+#ifndef NO_DRIFT
+ subpixels hh,vv;
+#endif
+} stack[STACK_SIZE]; /* stack */
+int sp = 0; /* stack pointer */
-#define MAXDRIFT 1
-#define CHECK_MAXDRIFT(x,xx) \
- if ( xx-PIXROUND(x,dvi->conv*shrinkfactor) < -MAXDRIFT ) { \
- DEBUG_PRINT(DEBUG_DVI,(" add 1 to")); \
- xx += 1; \
- } \
- if ( xx-PIXROUND(x,dvi->conv*shrinkfactor) > MAXDRIFT ) { \
- DEBUG_PRINT(DEBUG_DVI,(" sub 1 to")); \
- xx -= 1; \
- } \
- if (PIXROUND(dvi_stack->h,dvi->conv*shrinkfactor) != dvi_stack->hh \
- || PIXROUND(dvi_stack->v,dvi->conv*shrinkfactor) != dvi_stack->vv)\
- DEBUG_PRINT(DEBUG_DVI, \
- (" drift (%d,%d)", \
- dvi_stack->hh-PIXROUND(dvi_stack->h,dvi->conv*shrinkfactor), \
- dvi_stack->vv-PIXROUND(dvi_stack->v,dvi->conv*shrinkfactor)));
+dviunits h; /* current horizontal position */
+dviunits v; /* current vertical position */
+dviunits w=0; /* current horizontal spacing */
+dviunits x=0; /* current horizontal spacing */
+dviunits y=0; /* current vertical spacing */
+dviunits z=0; /* current vertical spacing */
+#ifndef NO_DRIFT
+subpixels hh; /* current rounded horizontal position */
+subpixels vv; /* current rounded vertical position */
+#else
+# define hh PIXROUND(h,dvi->conv*shrinkfactor)
+# define vv PIXROUND(v,dvi->conv*shrinkfactor)
+#endif
-#define MoveRight(x) \
- temp=x; dvi_stack->h += temp; \
- if ( currentfont==NULL \
- || temp > currentfont->s/6 || temp < -currentfont->s/6*4 ) \
- dvi_stack->hh = PIXROUND(dvi_stack->h,dvi->conv*shrinkfactor); \
- else \
- dvi_stack->hh += PIXROUND( temp,dvi->conv*shrinkfactor ); \
- CHECK_MAXDRIFT(dvi_stack->h,dvi_stack->hh)
-#define MoveDown(x) \
- temp=x; dvi_stack->v += temp; \
- if ( currentfont==NULL \
- || temp > currentfont->s/6*5 || temp < currentfont->s/6*(-5) ) \
- dvi_stack->vv = PIXROUND(dvi_stack->v,dvi->conv*shrinkfactor); \
- else \
- dvi_stack->vv += PIXROUND( temp,dvi->conv*shrinkfactor ); \
- CHECK_MAXDRIFT(dvi_stack->v,dvi_stack->vv)
+#ifndef NO_DRIFT
+#define MAXDRIFT 1
+#define CHECK_MAXDRIFT(x,xx) if ( xx-PIXROUND(x,dvi->conv*shrinkfactor) < -MAXDRIFT ) { \
+ DEBUG_PRINT(DEBUG_DVI,(" add 1 to")); \
+ xx += 1; \
+ } \
+ if ( xx-PIXROUND(x,dvi->conv*shrinkfactor) > MAXDRIFT ) { \
+ DEBUG_PRINT(DEBUG_DVI,(" sub 1 to")); \
+ xx -= 1; \
+ } \
+ if (PIXROUND(h,dvi->conv*shrinkfactor) != hh \
+ || PIXROUND(v,dvi->conv*shrinkfactor) != vv) \
+ DEBUG_PRINT(DEBUG_DVI,(" drift (%d,%d)", \
+ hh-PIXROUND(h,dvi->conv*shrinkfactor), \
+ vv-PIXROUND(v,dvi->conv*shrinkfactor)));
+#define MoveRight(x) temp=x; h += temp; \
+ if ( currentfont==NULL \
+ || temp > currentfont->s/6 || temp < -currentfont->s/6*4 ) \
+ hh = PIXROUND(h,dvi->conv*shrinkfactor); \
+ else \
+ hh += PIXROUND( temp,dvi->conv*shrinkfactor ); \
+ CHECK_MAXDRIFT(h,hh)
+#define MoveDown(x) temp=x; v += temp; \
+ if ( currentfont==NULL \
+ || temp > currentfont->s/6*5 || temp < currentfont->s/6*(-5) ) \
+ vv = PIXROUND(v,dvi->conv*shrinkfactor); \
+ else \
+ vv += PIXROUND( temp,dvi->conv*shrinkfactor ); \
+ CHECK_MAXDRIFT(v,vv)
+#else
+#define MoveRight(b) h += (dviunits) b
+#define MoveDown(a) v += (dviunits) a
+#endif
+
#define DO_VFCONV(a) ((((struct font_entry*) parent)->type==DVI_TYPE)?a:\
- (dviunits)((int64_t) a * ((struct font_entry*) parent)->s / (1 << 20)))
+ (dviunits)((int64_t) a * ((struct font_entry*) parent)->s / (1 << 20)))
dviunits SetChar(int32_t c)
{
- struct char_entry* ptr=NULL;
+ struct char_entry* ptr;
if (currentfont==NULL)
Fatal("faulty DVI, trying to set character from null font");
-
- if (c>=0 && c<=LASTFNTCHAR)
- ptr = currentfont->chr[c];
+ ptr = currentfont->chr[c];
#ifdef DEBUG
switch (currentfont->type) {
case FONT_TYPE_VF: DEBUG_PRINT(DEBUG_DVI,("\n VF CHAR:\t")); break;
@@ -92,13 +110,12 @@ dviunits SetChar(int32_t c)
}
if (isprint(c))
DEBUG_PRINT(DEBUG_DVI,("'%c' ",c));
- DEBUG_PRINT(DEBUG_DVI,("%d at (%d,%d) tfmw %d", c,
- dvi_stack->hh,dvi_stack->vv,ptr?ptr->tfmw:0));
+ DEBUG_PRINT(DEBUG_DVI,("%d at (%d,%d) tfmw %d", c,hh,vv,ptr?ptr->tfmw:0));
#endif
if (currentfont->type==FONT_TYPE_VF) {
return(SetVF(c));
- } else {
- if (ptr!=NULL && ptr->data == NULL)
+ } else if (ptr) {
+ if (ptr->data == NULL)
switch(currentfont->type) {
case FONT_TYPE_PK: LoadPK(c, ptr); break;
#ifdef HAVE_LIBT1
@@ -111,13 +128,13 @@ dviunits SetChar(int32_t c)
Fatal("undefined fonttype %d",currentfont->type);
}
if (page_imagep != NULL)
- return(SetGlyph(c, dvi_stack->hh, dvi_stack->vv));
- else if (ptr!=NULL) {
+ return(SetGlyph(c, hh, vv));
+ else {
/* Expand bounding box if necessary */
- min(x_min,dvi_stack->hh - ptr->xOffset/shrinkfactor);
- min(y_min,dvi_stack->vv - ptr->yOffset/shrinkfactor);
- max(x_max,dvi_stack->hh - ptr->xOffset/shrinkfactor + ptr->w);
- max(y_max,dvi_stack->vv - ptr->yOffset/shrinkfactor + ptr->h);
+ min(x_min,hh - ptr->xOffset/shrinkfactor);
+ min(y_min,vv - ptr->yOffset/shrinkfactor);
+ max(x_max,hh - ptr->xOffset/shrinkfactor + ptr->w);
+ max(y_max,vv - ptr->yOffset/shrinkfactor + ptr->h);
return(ptr->tfmw);
}
}
@@ -131,9 +148,11 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
if (/*command >= SETC_000 &&*/ *command <= SETC_127) {
temp = SetChar((int32_t)*command);
- dvi_stack->h += temp;
- dvi_stack->hh += PIXROUND(temp,dvi->conv*shrinkfactor);
- CHECK_MAXDRIFT(dvi_stack->h,dvi_stack->hh);
+ h += temp;
+#ifndef NO_DRIFT
+ hh += PIXROUND(temp,dvi->conv*shrinkfactor);
+ CHECK_MAXDRIFT(h,hh);
+#endif
} else if (*command >= FONT_00 && *command <= FONT_63) {
SetFntNum((int32_t)*command - FONT_00,parent);
} else switch (*command) {
@@ -147,9 +166,11 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
UNumRead(command+1, dvi_commandlength[*command]-1)));
{
temp = SetChar(UNumRead(command+1, dvi_commandlength[*command]-1));
- dvi_stack->h += temp;
- dvi_stack->hh += PIXROUND(temp,dvi->conv*shrinkfactor);
- CHECK_MAXDRIFT(dvi_stack->h,dvi_stack->hh);
+ h += temp;
+#ifndef NO_DRIFT
+ hh += PIXROUND(temp,dvi->conv*shrinkfactor);
+ CHECK_MAXDRIFT(h,hh);
+#endif
}
break;
case SET_RULE:
@@ -157,17 +178,19 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
UNumRead(command+1, 4), UNumRead(command+5, 4)));
temp = SetRule(DO_VFCONV(UNumRead(command+1, 4)),
DO_VFCONV(UNumRead(command+5, 4)),
- dvi_stack->hh, dvi_stack->vv);
- dvi_stack->h += temp;
- dvi_stack->hh += PIXROUND(temp,dvi->conv*shrinkfactor);
- CHECK_MAXDRIFT(dvi_stack->h,dvi_stack->hh);
+ hh, vv);
+ h += temp;
+#ifndef NO_DRIFT
+ hh += PIXROUND(temp,dvi->conv*shrinkfactor);
+ CHECK_MAXDRIFT(h,hh);
+#endif
break;
case PUT_RULE:
DEBUG_PRINT(DEBUG_DVI,(" %d %d",
UNumRead(command+1, 4), UNumRead(command+5, 4)));
(void) SetRule(DO_VFCONV(UNumRead(command+1, 4)),
DO_VFCONV(UNumRead(command+5, 4)),
- dvi_stack->hh, dvi_stack->vv);
+ hh, vv);
break;
case BOP:
Fatal("BOP occurs within page");
@@ -175,26 +198,34 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
case EOP:
break;
case PUSH:
- /* is next item on stack? */
- if (dvi_stack == &stack[STACK_SIZE-1])
+ if (sp >= STACK_SIZE)
Fatal("DVI stack overflow");
- {
- struct stack_entry *next=dvi_stack+1;
- next->h = dvi_stack->h;
- next->v = dvi_stack->v;
- next->w = dvi_stack->w;
- next->x = dvi_stack->x;
- next->y = dvi_stack->y;
- next->z = dvi_stack->z;
- next->hh = dvi_stack->hh;
- next->vv = dvi_stack->vv;
- dvi_stack=next;
- }
+ stack[sp].h = h;
+ stack[sp].v = v;
+ stack[sp].w = w;
+ stack[sp].x = x;
+ stack[sp].y = y;
+ stack[sp].z = z;
+#ifndef NO_DRIFT
+ stack[sp].hh = hh;
+ stack[sp].vv = vv;
+#endif
+ sp++;
break;
case POP:
- if (dvi_stack == stack)
+ --sp;
+ if (sp < 0)
Fatal("DVI stack underflow");
- dvi_stack--;
+ h = stack[sp].h;
+ v = stack[sp].v;
+ w = stack[sp].w;
+ x = stack[sp].x;
+ y = stack[sp].y;
+ z = stack[sp].z;
+#ifndef NO_DRIFT
+ hh = stack[sp].hh;
+ vv = stack[sp].vv;
+#endif
break;
case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4:
DEBUG_PRINT(DEBUG_DVI,(" %d",
@@ -202,16 +233,16 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
MoveRight(DO_VFCONV(SNumRead(command+1, dvi_commandlength[*command]-1)));
break;
case W1: case W2: case W3: case W4:
- dvi_stack->w = SNumRead(command+1, dvi_commandlength[*command]-1);
- DEBUG_PRINT(DEBUG_DVI,(" %d",dvi_stack->w));
+ w = SNumRead(command+1, dvi_commandlength[*command]-1);
+ DEBUG_PRINT(DEBUG_DVI,(" %d",w));
case W0:
- MoveRight(DO_VFCONV(dvi_stack->w));
+ MoveRight(DO_VFCONV(w));
break;
case X1: case X2: case X3: case X4:
- dvi_stack->x = SNumRead(command+1, dvi_commandlength[*command]-1);
- DEBUG_PRINT(DEBUG_DVI,(" %d",dvi_stack->x));
+ x = SNumRead(command+1, dvi_commandlength[*command]-1);
+ DEBUG_PRINT(DEBUG_DVI,(" %d",x));
case X0:
- MoveRight(DO_VFCONV(dvi_stack->x));
+ MoveRight(DO_VFCONV(x));
break;
case DOWN1: case DOWN2: case DOWN3: case DOWN4:
DEBUG_PRINT(DEBUG_DVI,(" %d",
@@ -219,16 +250,16 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
MoveDown(DO_VFCONV(SNumRead(command+1, dvi_commandlength[*command]-1)));
break;
case Y1: case Y2: case Y3: case Y4:
- dvi_stack->y = SNumRead(command+1, dvi_commandlength[*command]-1);
- DEBUG_PRINT(DEBUG_DVI,(" %d",dvi_stack->y));
+ y = SNumRead(command+1, dvi_commandlength[*command]-1);
+ DEBUG_PRINT(DEBUG_DVI,(" %d",y));
case Y0:
- MoveDown(DO_VFCONV(dvi_stack->y));
+ MoveDown(DO_VFCONV(y));
break;
case Z1: case Z2: case Z3: case Z4:
- dvi_stack->z = SNumRead(command+1, dvi_commandlength[*command]-1);
- DEBUG_PRINT(DEBUG_DVI,(" %d",dvi_stack->z));
+ z = SNumRead(command+1, dvi_commandlength[*command]-1);
+ DEBUG_PRINT(DEBUG_DVI,(" %d",z));
case Z0:
- MoveDown(DO_VFCONV(dvi_stack->z));
+ MoveDown(DO_VFCONV(z));
break;
case FNT1: case FNT2: case FNT3: case FNT4:
DEBUG_PRINT(DEBUG_DVI,(" %d",
@@ -238,8 +269,9 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
case XXX1: case XXX2: case XXX3: case XXX4:
DEBUG_PRINT(DEBUG_DVI,(" %d",
UNumRead(command+1, dvi_commandlength[*command]-1)));
- SetSpecial((char*)command + dvi_commandlength[*command],
- dvi_stack->hh,dvi_stack->vv);
+ SetSpecial((char*)command + dvi_commandlength[*command],
+ UNumRead(command+1, dvi_commandlength[*command]-1),
+ hh,vv);
break;
case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
if (((struct font_entry*)parent)->type==DVI_TYPE) {
@@ -262,24 +294,39 @@ void DrawCommand(unsigned char* command, void* parent /* dvi/vf */)
void BeginVFMacro(struct font_entry* currentvf)
{
- struct stack_entry *next=dvi_stack+1;
- if (dvi_stack == &stack[STACK_SIZE-1])
- Fatal("DVI stack overflow");
- next->h = dvi_stack->h;
- next->v = dvi_stack->v;
- next->w = next->x = next->y = next->z = 0;
- next->hh = dvi_stack->hh;
- next->vv = dvi_stack->vv;
- dvi_stack = next;
+ if (sp >= STACK_SIZE)
+ Fatal("stack overflow");
+ stack[sp].h = h;
+ stack[sp].v = v;
+ stack[sp].w = w;
+ stack[sp].x = x;
+ stack[sp].y = y;
+ stack[sp].z = z;
+#ifndef NO_DRIFT
+ stack[sp].hh = hh;
+ stack[sp].vv = vv;
+#endif
+ sp++;
+ w = x = y = z = 0;
DEBUG_PRINT(DEBUG_DVI,("\n START VF:\tPUSH, W = X = Y = Z = 0"));
SetFntNum(currentvf->defaultfont,currentvf);
}
void EndVFMacro(void)
{
- if (dvi_stack == stack)
- Fatal("DVI stack underflow");
- dvi_stack--;
+ --sp;
+ if (sp < 0)
+ Fatal("stack underflow");
+ h = stack[sp].h;
+ v = stack[sp].v;
+ w = stack[sp].w;
+ x = stack[sp].x;
+ y = stack[sp].y;
+ z = stack[sp].z;
+#ifndef NO_DRIFT
+ hh = stack[sp].hh;
+ vv = stack[sp].vv;
+#endif
DEBUG_PRINT(DEBUG_DVI,("\n END VF:\tPOP "));
}
@@ -291,11 +338,13 @@ void DrawPage(dviunits hoffset, dviunits voffset)
{
unsigned char* command; /* current command */
- dvi_stack->h = hoffset;
- dvi_stack->v = voffset;
- dvi_stack->w = dvi_stack->x = dvi_stack->y = dvi_stack->z = 0;
- dvi_stack->hh = PIXROUND( dvi_stack->h , dvi->conv*shrinkfactor );
- dvi_stack->vv = PIXROUND( dvi_stack->v , dvi->conv*shrinkfactor );
+ h = hoffset;
+ v = voffset;
+ w = x = y = z = 0;
+#ifndef NO_DRIFT
+ hh = PIXROUND( h , dvi->conv*shrinkfactor );
+ vv = PIXROUND( v , dvi->conv*shrinkfactor );
+#endif
currentfont = NULL; /* No default font */
command=DVIGetCommand(dvi);
@@ -311,14 +360,13 @@ void DrawPages(void)
{
struct page_list *dvi_pos;
pixels x_width,y_width,x_offset,y_offset;
- int pagecounter=(option_flags & DVI_PAGENUM)?0:10;
dvi_pos=NextPPage(dvi,NULL);
if (dvi_pos!=NULL) {
while(dvi_pos!=NULL) {
SeekPage(dvi,dvi_pos);
- Message(BE_NONQUIET,"[%d", dvi_pos->count[pagecounter]);
- if (dvi_pos->count[pagecounter]!=dvi_pos->count[0])
+ Message(BE_NONQUIET,"[%d", dvi_pos->count[(flags & DVI_PAGENUM)?0:10]);
+ if (dvi_pos->count[(flags & DVI_PAGENUM)?0:10]!=dvi_pos->count[0])
Message(BE_NONQUIET," (%d)", dvi_pos->count[0]);
x_max = y_max = INT32_MIN;
x_min = y_min = INT32_MAX;
@@ -327,7 +375,7 @@ void DrawPages(void)
by the color at EOP rather than the color at BOP. */
StoreBackgroundColor(dvi_pos);
/* Store pagesize */
- if (dvi->flags & DVI_PREVIEW_LATEX_TIGHTPAGE) {
+ if (flags & PREVIEW_LATEX_TIGHTPAGE) {
x_width_def=x_width_tightpage;
y_width_def=y_width_tightpage;
x_offset_def=x_offset_tightpage;
@@ -339,7 +387,7 @@ void DrawPages(void)
min(y_min,-y_offset_def);
max(y_max,y_min + y_width_def);
}
- if (x_width_def <= 0 || option_flags & EXPAND_BBOX) {
+ if (x_width_def <= 0 || flags & EXPAND_BBOX) {
x_width = x_max-x_min;
y_width = y_max-y_min;
x_offset = -x_min; /* offset by moving topleft corner */
@@ -364,11 +412,10 @@ void DrawPages(void)
#endif
Message(REPORT_DEPTH," depth=%d", y_width-y_offset-1);
Message(REPORT_HEIGHT," height=%d", y_offset+1);
- page_flags &= ~PAGE_PREVIEW_BOP;
DrawPage(x_offset*dvi->conv*shrinkfactor,
y_offset*dvi->conv*shrinkfactor);
- if ( ! (option_flags & MODE_PICKY && page_flags & PAGE_GAVE_WARN )) {
- WriteImage(dvi->outname,dvi_pos->count[pagecounter]);
+ if ( ! (flags & MODE_PICKY && flags & PAGE_GAVE_WARN )) {
+ WriteImage(dvi->outname,dvi_pos->count[(flags & DVI_PAGENUM)?0:10]);
#ifdef TIMING
++ndone;
#endif
@@ -379,7 +426,7 @@ void DrawPages(void)
}
Message(BE_NONQUIET,"] ");
fflush(stdout);
- page_flags = 0;
+ flags &= ~(PAGE_GAVE_WARN | PAGE_TRUECOLOR);
dvi_pos=NextPPage(dvi,dvi_pos);
}
Message(BE_NONQUIET,"\n");