Back to index

tetex-bin  3.0
Classes | Defines | Functions | Variables
special.c File Reference
#include <setjmp.h>
#include "xdvi-config.h"
#include "xdvi.h"
#include <ctype.h>
#include "kpathsea/c-fopen.h"
#include "kpathsea/c-stat.h"
#include "kpathsea/line.h"
#include "kpathsea/tex-file.h"
#include "special.h"
#include "hypertex.h"
#include "dvi.h"
#include "message-window.h"
#include "events.h"
#include "dvi-init.h"
#include "dvi-draw.h"
#include "statusline.h"
#include "util.h"
#include "image-magick.h"
#include "pagesel.h"
#include "my-snprintf.h"
#include "string-utils.h"

Go to the source code of this file.

Classes

struct  bbox_info

Defines

#define S_IRUSR   0400
#define S_IWUSR   0200
#define MAXPOINTS   300 /* Max points in a path */
#define MAX_PEN_SIZE   7 /* Max pixels of pen width */
#define TWOPI   (3.14159265359 * 2.0)
#define rint(x)   floor((x) + 0.5)
#define CMD(x, y)   ((x) << 8 | (y))
#define toint(x)   ((int) ((x) + 0.5))
#define xconv(x)   (toint(tpic_conv*(x))/currwin.shrinkfactor + PXL_H)
#define yconv(y)   (toint(tpic_conv*(y))/currwin.shrinkfactor + PXL_V)
#define dist(x0, y0, x1, y1)   (abs(x0 - x1) + abs(y0 - y1))
#define KEY_LLX   keyval[0]
#define KEY_LLY   keyval[1]
#define KEY_URX   keyval[2]
#define KEY_URY   keyval[3]
#define KEY_RWI   keyval[4]
#define KEY_RHI   keyval[5]
#define NKEYS   (sizeof keytab /sizeof *keytab)
#define N_ARGLESS_KEYS   1
#define SCR_LEN   16
#define CMD(x, y)   ((x) << 8 | (y))
#define xpixel_conv(x)   ((int) ((x) >> 16))
#define G_PXL_H   xpixel_conv(currinf.data.dvi_h)

Functions

double floor (double)
static void line_btw (int fx, int fy, int tx, int ty)
static void dot_at (int x, int y)
static void do_attribute_path (int last_min_x, int last_max_x, int last_min_y, int last_max_y)
static void set_pen_size (char *cp)
static void flush_path (void)
static void flush_dashed (char *cp, Boolean dotted)
static void add_path (char *cp)
static void im_fdraw (double x, double y)
static void draw_ellipse (int xc, int yc, int xr, int yr)
static void arc (char *cp, Boolean invis)
static void flush_spline (void)
static void shade_last (void)
static void whiten_last (void)
static void blacken_last (void)
static void append_bbox_info (int x, int y, int w, int h, int angle)
static void draw_bbox0 (int xcorner, int ycorner)
void display_bboxes (void)
void clear_bboxes (void)
void save_bbox (void)
void draw_bbox (void)
void init_prescan (void)
static void psfig_special (char *cp)
static void epsf_special (char *cp)
static void quote_special (char *cp)
static unsigned int myatopix (const char **pp)
static void scan_papersize (const char *cp0)
static char * endofcommand (char *cp)
void applicationDoSpecial (char *cp, size_t len)
Boolean scan_special (char *cp, int cp_len, void *data)
void geom_do_special (struct scan_info *info, char *cp, double current_dimconv)

Variables

static int xx [MAXPOINTS]
static int yy [MAXPOINTS]
static int path_len = 0
static int pen_size = 1
static Boolean whiten = False
static Boolean shade = False
static Boolean blacken = False
Boolean psfig_begun = False
static int bbox_angle
static Boolean bbox_valid
static unsigned int bbox_width
static unsigned int bbox_height
static int bbox_voffset
static struct bbox_infog_bbox_info = NULL
static size_t g_bbox_info_size = 0
static size_t g_bbox_info_max_size = 0
static const char * keytab []

Class Documentation

struct bbox_info

Definition at line 4403 of file dvi-draw.c.

Class Members
int angle
int h
long max_x
long max_y
long min_x
long min_y
long spcl_max_x
long spcl_max_y
long spcl_min_x
long spcl_min_y
int w
int x
int y

Define Documentation

#define CMD (   x,
  y 
)    ((x) << 8 | (y))

Definition at line 2354 of file special.c.

#define CMD (   x,
  y 
)    ((x) << 8 | (y))

Definition at line 2354 of file special.c.

#define dist (   x0,
  y0,
  x1,
  y1 
)    (abs(x0 - x1) + abs(y0 - y1))

Definition at line 528 of file special.c.

#define G_PXL_H   xpixel_conv(currinf.data.dvi_h)

Definition at line 2673 of file special.c.

#define KEY_LLX   keyval[0]

Definition at line 1504 of file special.c.

#define KEY_LLY   keyval[1]

Definition at line 1505 of file special.c.

#define KEY_RHI   keyval[5]

Definition at line 1509 of file special.c.

#define KEY_RWI   keyval[4]

Definition at line 1508 of file special.c.

#define KEY_URX   keyval[2]

Definition at line 1506 of file special.c.

#define KEY_URY   keyval[3]

Definition at line 1507 of file special.c.

#define MAX_PEN_SIZE   7 /* Max pixels of pen width */

Definition at line 181 of file special.c.

#define MAXPOINTS   300 /* Max points in a path */

Definition at line 180 of file special.c.

#define N_ARGLESS_KEYS   1

Definition at line 1512 of file special.c.

#define NKEYS   (sizeof keytab /sizeof *keytab)

Definition at line 1511 of file special.c.

#define rint (   x)    floor((x) + 0.5)

Definition at line 185 of file special.c.

#define S_IRUSR   0400

Definition at line 164 of file special.c.

#define S_IWUSR   0200

Definition at line 167 of file special.c.

#define SCR_LEN   16
#define toint (   x)    ((int) ((x) + 0.5))

Definition at line 204 of file special.c.

#define TWOPI   (3.14159265359 * 2.0)

Definition at line 182 of file special.c.

#define xconv (   x)    (toint(tpic_conv*(x))/currwin.shrinkfactor + PXL_H)

Definition at line 205 of file special.c.

#define xpixel_conv (   x)    ((int) ((x) >> 16))

Definition at line 2672 of file special.c.

#define yconv (   y)    (toint(tpic_conv*(y))/currwin.shrinkfactor + PXL_V)

Definition at line 206 of file special.c.


Function Documentation

static void add_path ( char *  cp) [static]

Definition at line 402 of file special.c.

{
    int pathx, pathy;

    if (++path_len >= MAXPOINTS)
       XDVI_FATAL((stderr, "Too many points"));
    if (sscanf(cp, " %d %d ", &pathx, &pathy) != 2)
       XDVI_FATAL((stderr, "Malformed path command"));
    xx[path_len] = pathx;
    yy[path_len] = pathy;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void append_bbox_info ( int  x,
int  y,
int  w,
int  h,
int  angle 
) [static]

Definition at line 695 of file special.c.

{
    Boolean found = False;
    size_t i;
    const size_t SIZE_STEP = 16;
    
    /* is this box already present? */
    for (i = 0; i < g_bbox_info_size; i++) {
       if (g_bbox_info[i].x == x
           && g_bbox_info[i].y == y
           && g_bbox_info[i].w == w
           && g_bbox_info[i].h == h
           && g_bbox_info[i].angle == angle) {
           found = True;
           break;
       }
    }

    if (!found) {
       g_bbox_info_size++;
       
       while (g_bbox_info_size >= g_bbox_info_max_size) {
           g_bbox_info_max_size += SIZE_STEP;
       }
       
       g_bbox_info = xrealloc(g_bbox_info, g_bbox_info_max_size * sizeof *g_bbox_info);
       g_bbox_info[g_bbox_info_size - 1].x = x;
       g_bbox_info[g_bbox_info_size - 1].y = y;
       g_bbox_info[g_bbox_info_size - 1].w = w;
       g_bbox_info[g_bbox_info_size - 1].h = h;
       g_bbox_info[g_bbox_info_size - 1].angle = angle;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void applicationDoSpecial ( char *  cp,
size_t  len 
)

Definition at line 2357 of file special.c.

{
    char *p;

    if (globals.debug & DBG_DVI)
       printf("          `%s'\n", cp);

    while (isspace((int)*cp))
       ++cp;

    /* Ignore initial "xdvi:" */
    if (memcmp(cp, "xdvi:", 5) == 0) {
       cp += 5;
       while (isspace((int)*cp))
           ++cp;
    }
       
    /* PostScript specials */
#ifdef MAGICK
    if (resource.useMAGICK) {
       if (Magick_parse_special(cp))
           return;
    }
#endif

    if (*cp == '"') {
       quote_special(cp);
       return;
    }
    if (memicmp(cp, "ps:", 3) == 0) {
       cp += 3;
       psfig_special(cp);
       /* check for hdvips hyperlinks */
       if (memicmp(cp, "sdict begin ", strlen("sdict begin ")) == 0) {
           static Boolean warned_hypertex_too_old = False;
           char *match = NULL;
           if (warned_hypertex_too_old) /* don't continue evaluating links in this case */
              return;
           cp += strlen("sdict begin ");
           if (memcmp(cp, "H.S", 3) == 0
              || memcmp(cp, "H.R", 3) == 0
              || memcmp(cp, "H.B", 3) == 0
              /* following 2 conditions could be more restrictive: between `begin' and H.A/H.L,
                 there should be a single number (baselineskip in pt) */
              || (match = strstr(cp, "H.A")) != NULL
              || (match = strstr(cp, "H.L")) != NULL
              || (match = strstr(cp, "/Action")) != NULL
              || (match = strstr(cp, "/Link")) != NULL
              || (match = strstr(cp, "/View")) != NULL) {
              if (match != NULL)
                  htex_do_special(match, len - 3 - (match - cp) - strlen("sdict begin "));
              else
                  htex_do_special(cp, len - strlen("sdict begin "));
           }
           else if (!warned_hypertex_too_old && strstr(cp, "HyperStart") != NULL) {
              popup_message(globals.widgets.top_level,
                           MSG_WARN, NULL,
                           "This DVI was created with a too old version of the `dvips' hyperref driver - "
                           "disabling hyperlinks.\n"
                           "To fix this, you should either upgrade to a current version of hyperref "
                           "(see http://www.tug.org/applications/hyperref/), "
                           "or use the `hypertex' package option, like this:\n\\usepackage[hypertex]{hyperref}\n"
                           "(Be aware though that this option won't work for PS->PDF conversion!)");
              warned_hypertex_too_old = True;
           }
       }
       else {
           /* When not ignoring SDict entries, the distiller and pagecolor
              code in lshort.dvi from CTAN:info/lshort/russian/lshrtdvi.zip
              causes a failed assertion for 'color_bot_size > 0' in dvi-draw.c;
              there's something wrong with the parsing order/event handling here
              (see bug #856547).
              But we also don't want those entries to trigger erasepage_gs(), so
              it's correct to ignore them here.
           */
#if PS_GS && GS_PIXMAP_CLEARING_HACK
           had_ps_specials = True;
#endif
       }
       return;
    }
    if (memicmp(cp, "psfile", 6) == 0 && (p = endofcommand(cp + 6)) != NULL) {
       epsf_special(p);
#if PS_GS && GS_PIXMAP_CLEARING_HACK
       had_ps_specials = True;
#endif
       return;
    }
    if (memicmp(cp, "html:", 5) == 0) {
       htex_do_special(cp + 5, len - 5);
       return;
    }

#if COLOR
    if (memicmp(cp, "color ", 6) == 0) {
/*     fprintf(stderr, "------------- color special\n"); */
       if (resource.use_color)
           color_special(cp + 6);
       return;
    }
#endif
    
    /* these should have been scanned */
    if (*cp == '!'
       || (memicmp(cp, "header", 6) == 0 && endofcommand(cp + 6) != NULL)) {
#ifdef PS
       if (resource.postscript != 0 && scanned_page_reset >= 0) {
           /* turn on scanning and redraw the page */
           scanned_page = scanned_page_ps = scanned_page_reset = -1;
# if COLOR
           scanned_page_color = scanned_page;
# endif
           globals.ev.flags |= EV_NEWPAGE;              /* force a redraw */
           longjmp(globals.ev.canit, 1);
       }
#endif /* PS */
       return;
    }

    if (memicmp(cp, "background ", 11) == 0) {
#if COLOR
       if (resource.use_color && scanned_page_reset >= 0) {
           /* turn on scanning and redraw the page */
           scanned_page = scanned_page_color = scanned_page_reset = -1;
# if PS
           scanned_page_ps = scanned_page;
# endif
/*         fprintf(stderr, "forcing redraw!\n"); */
           globals.ev.flags |= EV_NEWPAGE;              /* force a redraw */
           longjmp(globals.ev.canit, 1);
       }
#endif /* COLOR */
       return;
    }

    if (memcmp(cp, "papersize", 9) == 0 && endofcommand(cp + 9) != NULL) {
       m_have_papersize_special = True;
       if (scanned_page_reset >= 0) {
           /* turn on scanning and redraw the page */
           scanned_page = scanned_page_reset = -1;
#if PS
           scanned_page_ps = scanned_page;
#endif
#if COLOR
           scanned_page_color = scanned_page;
#endif
           globals.ev.flags |= EV_NEWPAGE; /* force a redraw */
           longjmp(globals.ev.canit, 1);
       }
       return;
    }

    /* tpic specials */

    if (*cp >= 'a' && *cp <= 'z' && cp[1] >= 'a' && cp[1] <= 'z' &&
       (isspace((int)cp[2]) || cp[2] == '\0')) {
       switch (CMD(*cp, cp[1])) {
       case CMD('p', 'n'):
           set_pen_size(cp + 2);
           return;
       case CMD('f', 'p'):
           flush_path();
           return;
       case CMD('d', 'a'):
           flush_dashed(cp + 2, False);
           return;
       case CMD('d', 't'):
           flush_dashed(cp + 2, True);
           return;
       case CMD('p', 'a'):
           add_path(cp + 2);
           return;
       case CMD('a', 'r'):
           arc(cp + 2, False);
           return;
       case CMD('i', 'a'):
           arc(cp + 2, True);
           return;
       case CMD('s', 'p'):
           flush_spline();
           return;
       case CMD('s', 'h'):
           shade_last();
           return;
       case CMD('w', 'h'):
           whiten_last();
           return;
       case CMD('b', 'k'):
           blacken_last();
           return;
       case CMD('i', 'p'):  /* throw away the path -- jansteen */
           path_len = 0;
           return;
       }
    }

    if (memcmp(cp, "src:", 4) == 0) {
       have_src_specials = True;
    }
    else if (globals.warn_spec_now)
       XDVI_WARNING((stderr, "Special \"%s\" not implemented.", cp));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void arc ( char *  cp,
Boolean  invis 
) [static]

Definition at line 468 of file special.c.

{
    int xc, yc, xrad, yrad, n;
    float start_angle, end_angle, angle, theta, r;
    double xradius, yradius, xcenter, ycenter;

    n = sscanf(cp, " %d %d %d %d %f %f ", &xc, &yc, &xrad, &yrad,
              &start_angle, &end_angle);

    if (n != 6) {
       XDVI_WARNING((stderr, "invalid arc specification: %s", cp));
       return;
    }

    if (invis)
       return;

    /* We have a specialized fast way to draw closed circles/ellipses */
    if (start_angle <= 0.0 && end_angle >= 6.282) {
       draw_ellipse(xc, yc, xrad, yrad);
       return;
    }
    xcenter = xc;
    ycenter = yc;
    xradius = xrad;
    yradius = yrad;
    r = (xradius + yradius) / 2.0;
    theta = sqrt(1.0 / r);
#if BUG_888087_FIXED
    n = (pen_size * TWOPI) / (theta * currwin.shrinkfactor) + 0.5;
#else
    n = 0.3 * TWOPI / theta + 0.5;
#endif
    if (n < 12)
       n = 12;
    else if (n > 80)
       n = 80;
    n /= 2;
    theta = TWOPI / n;
    flush_path();
    im_fdraw(xcenter + xradius * cos(start_angle),
            ycenter + yradius * sin(start_angle));
    angle = start_angle + theta;
    if (end_angle < start_angle)
       end_angle += TWOPI;
    while (angle < end_angle) {
       im_fdraw(xcenter + xradius * cos(angle),
               ycenter + yradius * sin(angle));
       angle += theta;
    }
    im_fdraw(xcenter + xradius * cos(end_angle),
            ycenter + yradius * sin(end_angle));
    flush_path();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void blacken_last ( void  ) [static]

Definition at line 606 of file special.c.

Here is the caller graph for this function:

Definition at line 813 of file special.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 780 of file special.c.

{
    size_t i;
    
    for (i = 0; i < g_bbox_info_size; i++) {
       if (globals.debug & DBG_PS) {
           fprintf(stderr, "drawing bbox %lu at %d %d, %d x %d, angle %d\n",
                  (unsigned long)i,
                  g_bbox_info[i].x,
                  g_bbox_info[i].y,
                  g_bbox_info[i].w,
                  g_bbox_info[i].h,
                  g_bbox_info[i].angle);
       }
#if 0
       XDrawRectangle(DISP, currwin.win, globals.gc.high,
                     g_bbox_info[i].x,
                     g_bbox_info[i].y,
                     g_bbox_info[i].w,
                     g_bbox_info[i].h);
#else
       bbox_valid = True;
       bbox_width = g_bbox_info[i].w;
       bbox_height = bbox_voffset = g_bbox_info[i].h;
       bbox_angle = g_bbox_info[i].angle;
       draw_bbox0(g_bbox_info[i].x, g_bbox_info[i].y + bbox_height);
#endif
    }
    bbox_angle = 0;
    bbox_valid = False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_attribute_path ( int  last_min_x,
int  last_max_x,
int  last_min_y,
int  last_max_y 
) [static]

Definition at line 256 of file special.c.

{
    UNUSED(last_min_x);
    UNUSED(last_max_x);
    UNUSED(last_min_y);
    UNUSED(last_max_y);
}

Here is the caller graph for this function:

static void dot_at ( int  x,
int  y 
) [static]

Definition at line 235 of file special.c.

{
    int cx = xconv(x);
    int cy = yconv(y);

    if (cx < globals.win_expose.max_x && cx >= globals.win_expose.min_x && cy < globals.win_expose.max_y && cy >= globals.win_expose.min_y){
#if COLOR
       if (fg_active != fg_current)
           do_color_change();
#endif
       XDrawPoint(DISP, currwin.win, globals.gc.rule,
                 cx - currwin.base_x, cy - currwin.base_y);
    }
}

Here is the caller graph for this function:

Definition at line 843 of file special.c.

{
    draw_bbox0(PXL_H - currwin.base_x, PXL_V - currwin.base_y);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void draw_bbox0 ( int  xcorner,
int  ycorner 
) [static]

Definition at line 730 of file special.c.

{
    if (bbox_valid) {
#if COLOR
       if (fg_active != fg_current)
           do_color_change();
#endif

       if (bbox_angle == 0) {
           ycorner -= bbox_voffset;
           XDrawRectangle(DISP, currwin.win, globals.gc.high, xcorner, ycorner, bbox_width, bbox_height);
           if (resource.postscript == 0) {
              if (htex_inside_href) {
                  htex_set_anchorsize(xcorner, ycorner, xcorner + bbox_width, ycorner + bbox_height);
                  htex_set_objecttype(HTEX_IMG);
              }
           }
       }
       else {
           float sin_a = sin(bbox_angle * (TWOPI / 360));
           float cos_a = cos(bbox_angle * (TWOPI / 360));
           float a, b, c, d;

           a = cos_a * bbox_width;
           b = -sin_a * bbox_width;
           c = -sin_a * bbox_height;
           d = -cos_a * bbox_height;

           XDrawLine(DISP, currwin.win, globals.gc.high,
                    xcorner, ycorner,
                    xcorner + (int)rint(a), ycorner + (int)rint(b));
           XDrawLine(DISP, currwin.win, globals.gc.high,
                    xcorner + (int)rint(a), ycorner + (int)rint(b),
                    xcorner + (int)rint(a + c), ycorner + (int)rint(b + d));
           XDrawLine(DISP, currwin.win, globals.gc.high,
                    xcorner + (int)rint(a + c), ycorner + (int)rint(b + d),
                    xcorner + (int)rint(c), ycorner + (int)rint(d));
           XDrawLine(DISP, currwin.win, globals.gc.high,
                    xcorner + (int)rint(c), ycorner + (int)rint(d),
                    xcorner, ycorner);
       }
       bbox_valid = False;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void draw_ellipse ( int  xc,
int  yc,
int  xr,
int  yr 
) [static]

Definition at line 434 of file special.c.

{
    double angle, theta;
    int n;
    int px0, py0, px1, py1;

    angle = (xr + yr) / 2.0;
    theta = sqrt(1.0 / angle);
    n = TWOPI / theta + 0.5;
    if (n < 12)
       n = 12;
    else if (n > 80)
       n = 80;
    n /= 2;
    theta = TWOPI / n;

    angle = 0.0;
    px0 = xc + xr;   /* cos(0) = 1 */
    py0 = yc; /* sin(0) = 0 */
    while ((angle += theta) <= TWOPI) {
       px1 = xc + xr * cos(angle) + 0.5;
       py1 = yc + yr * sin(angle) + 0.5;
       line_btw(px0, py0, px1, py1);
       px0 = px1;
       py0 = py1;
    }
    line_btw(px0, py0, xc + xr, yc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* endofcommand ( char *  cp) [static]

Definition at line 2342 of file special.c.

{
    while (isspace((int)*cp))
       ++cp;
    if (*cp != '=')
       return NULL;
    do
       ++cp;
    while (isspace((int)*cp));
    return cp;
}

Here is the caller graph for this function:

static void epsf_special ( char *  cp) [static]

Definition at line 1515 of file special.c.

{
    char *filename;
    static char *buffer;
    static unsigned int buflen = 0;
    unsigned int len;
    char *q;
    int flags = 0;
    double keyval[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };

    filename = cp;
    if (*cp == '\'' || *cp == '"') {
       do
           ++cp;
       while (*cp != '\0' && *cp != *filename);
       ++filename;
    }
    else
       while (*cp != '\0' && !isspace((int)*cp))
           ++cp;
    if (*cp != '\0')
       *cp++ = '\0';
    while (isspace((int)*cp))
       ++cp;
    len = strlen(cp) + NKEYS + 30;
    if (buflen < len) {
       if (buflen != 0)
           free(buffer);
       buflen = len;
       buffer = xmalloc(buflen);
    }
    strcpy(buffer, "@beginspecial");
    q = buffer + strlen(buffer);
    while (*cp != '\0') {
       char *p1 = cp;
       size_t keyno;

       while (*p1 != '=' && !isspace((int)*p1) && *p1 != '\0')
           ++p1;
       for (keyno = 0;; ++keyno) {
           if (keyno >= NKEYS) {
              if (globals.warn_spec_now)
                  XDVI_WARNING((stderr, "Ignoring unknown keyword (%.*s) in \\special",
                              (int)(p1 - cp), cp));
              break;
           }
           if (memcmp(cp, keytab[keyno], p1 - cp) == 0) {
              if (keyno >= N_ARGLESS_KEYS) {
                  while (isspace((int)*p1))
                     ++p1;
                  if (*p1 == '=') {
                     ++p1;
                     while (isspace((int)*p1))
                         ++p1;
                  }
                  if (keyno < N_ARGLESS_KEYS + 6) {
                     keyval[keyno - N_ARGLESS_KEYS] = atof(p1);
                     flags |= (1 << (keyno - N_ARGLESS_KEYS));
                  }
                  *q++ = ' ';
                  while (!isspace((int)*p1) && *p1 != '\0')
                     *q++ = *p1++;
              }
              *q++ = ' ';
              *q++ = '@';
              strcpy(q, keytab[keyno]);
              q += strlen(q);
              break;
           }
       }
       cp = p1;
       while (!isspace((int)*cp) && *cp != '\0')
           ++cp;
       while (isspace((int)*cp))
           ++cp;
    }
    strcpy(q, " @setspecial\n");

    bbox_valid = False;
    /* Validate the case where both rwi and rhi are undefined
     * (and llx, lly, urx, ury are properly defined) */
    if (!(flags & 0x30) && (flags & 0xf) == 0xf) {
       KEY_RWI = (KEY_URX - KEY_LLX) * 10;
       flags |= 0x10;
    }
    if ((flags & 0x30) == 0x30 || ((flags & 0x30) && (flags & 0xf) == 0xf)) {
       bbox_valid = True;
       bbox_width = 0.1 * ((flags & 0x10) ? KEY_RWI
                         : KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY -
                                                        KEY_LLY)) *
           dimconv / currwin.shrinkfactor + 0.5;
       bbox_voffset = bbox_height =
           0.1 * ((flags & 0x20) ? KEY_RHI : KEY_RWI * (KEY_URY - KEY_LLY) /
                 (KEY_URX - KEY_LLX))
           * dimconv / currwin.shrinkfactor + 0.5;
    }

    if (INSIDE_MANE_WIN) {
#if    PS
       psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y, buffer);
       /* talk directly with the DPSHandler here */
       send_ps_file(filename, kpse_pict_format);
       psp.drawend(" @endspecial");
#else
       draw_bbox();
#endif
    }
    bbox_valid = False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

double floor ( double  )

Here is the caller graph for this function:

static void flush_dashed ( char *  cp,
Boolean  dotted 
) [static]

Definition at line 336 of file special.c.

{
    int i;
    int numdots;
    int lx0, ly0, lx1, ly1;
    int cx0, cy0, cx1, cy1;
    float inchesperdash;
    double d, spacesize, a, b = 0.0, dx, dy, milliperdash;

    if (sscanf(cp, " %f ", &inchesperdash) != 1) {
       XDVI_WARNING((stderr, "invalid format for dotted/dashed line: %s", cp));
       return;
    }
    if (path_len <= 1 || inchesperdash <= 0.0) {
       XDVI_WARNING((stderr, "invalid conditions for dotted/dashed line"));
       return;
    }
    milliperdash = inchesperdash * 1000.0;
    lx0 = xx[1];
    ly0 = yy[1];
    lx1 = xx[2];
    ly1 = yy[2];
    dx = lx1 - lx0;
    dy = ly1 - ly0;
    if (dotted) {
       numdots = sqrt(dx * dx + dy * dy) / milliperdash + 0.5;
       if (numdots == 0)
           numdots = 1;
       for (i = 0; i <= numdots; i++) {
           a = (float)i / (float)numdots;
           cx0 = lx0 + a * dx + 0.5;
           cy0 = ly0 + a * dy + 0.5;
           dot_at(cx0, cy0);
       }
    }
    else {
       d = sqrt(dx * dx + dy * dy);
       numdots = d / (2.0 * milliperdash) + 1.0;
       if (numdots <= 1)
           line_btw(lx0, ly0, lx1, ly1);
       else {
           spacesize = (d - numdots * milliperdash) / (numdots - 1);
           for (i = 0; i < numdots - 1; i++) {
              a = i * (milliperdash + spacesize) / d;
              b = a + milliperdash / d;
              cx0 = lx0 + a * dx + 0.5;
              cy0 = ly0 + a * dy + 0.5;
              cx1 = lx0 + b * dx + 0.5;
              cy1 = ly0 + b * dy + 0.5;
              line_btw(cx0, cy0, cx1, cy1);
              b += spacesize / d;
           }
           cx0 = lx0 + b * dx + 0.5;
           cy0 = ly0 + b * dy + 0.5;
           line_btw(cx0, cy0, lx1, ly1);
       }
    }
    path_len = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void flush_path ( void  ) [static]

Definition at line 297 of file special.c.

{
    int i;
    int last_min_x, last_max_x, last_min_y, last_max_y;

    last_min_x = 30000;
    last_min_y = 30000;
    last_max_x = -30000;
    last_max_y = -30000;
    for (i = 1; i < path_len; i++) {
       if (xx[i] > last_max_x)
           last_max_x = xx[i];
       if (xx[i] < last_min_x)
           last_min_x = xx[i];
       if (yy[i] > last_max_y)
           last_max_y = yy[i];
       if (yy[i] < last_min_y)
           last_min_y = yy[i];
       line_btw(xx[i], yy[i], xx[i + 1], yy[i + 1]);
    }
    if (xx[path_len] > last_max_x)
       last_max_x = xx[path_len];
    if (xx[path_len] < last_min_x)
       last_min_x = xx[path_len];
    if (yy[path_len] > last_max_y)
       last_max_y = yy[path_len];
    if (yy[path_len] < last_min_y)
       last_min_y = yy[path_len];
    path_len = 0;
    do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void flush_spline ( void  ) [static]

Definition at line 536 of file special.c.

{
    int xp, yp;
    int N;
    int lastx = -1, lasty = -1;
    Boolean lastvalid = False;
    int t1, t2, t3;
    int steps;
    int j;
    int i, w;

    N = path_len + 1;
    xx[0] = xx[1];
    yy[0] = yy[1];
    xx[N] = xx[N - 1];
    yy[N] = yy[N - 1];
    for (i = 0; i < N - 1; i++) {  /* interval */
       steps = (dist(xx[i], yy[i], xx[i + 1], yy[i + 1]) +
               dist(xx[i + 1], yy[i + 1], xx[i + 2], yy[i + 2])) / 80;
       for (j = 0; j < steps; j++) {      /* points within */
           w = (j * 1000 + 500) / steps;
           t1 = w * w / 20;
           w -= 500;
           t2 = (750000 - w * w) / 10;
           w -= 500;
           t3 = w * w / 20;
           xp =
              (t1 * xx[i + 2] + t2 * xx[i + 1] + t3 * xx[i] + 50000) / 100000;
           yp =
              (t1 * yy[i + 2] + t2 * yy[i + 1] + t3 * yy[i] + 50000) / 100000;
           if (lastvalid)
              line_btw(lastx, lasty, xp, yp);
           lastx = xp;
           lasty = yp;
           lastvalid = True;
       }
    }
    path_len = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void geom_do_special ( struct scan_info info,
char *  cp,
double  current_dimconv 
)

Definition at line 2677 of file special.c.

{
    const char *p;
    struct geom_info *g_info = (struct geom_info *)info->data;
    
    UNUSED(current_dimconv);
    
    while (isspace((int)*cp))
       ++cp;

    /* Ignore initial "xdvi:" */
    if (memcmp(cp, "xdvi:", 5) == 0) {
       cp += 5;
       while (isspace((int)*cp))
           ++cp;
    }

    if (memicmp(cp, "psfile", 6) == 0 && (p = endofcommand(cp + 6)) != NULL) {
       /* compute epsf bounding box */
       char c;
       int flags = 0;
       double keyval[6];

       c = *p;
       if (c == '\'' || c == '"') {
           do
              ++p;
           while (*p != '\0' && *p != c);
       }
       else
           while (*p != '\0' && !isspace((int)*p))
              ++p;
       while (isspace((int)*p))
           ++p;
       while (*p != '\0') {
           const char *p1 = p;
           size_t keyno;

           while (*p1 != '=' && !isspace((int)*p1) && *p1 != '\0')
              ++p1;
           for (keyno = 0; keyno < NKEYS; ++keyno) {
              if (memcmp(p, keytab[keyno], p1 - p) == 0) {
                  if (keyno >= N_ARGLESS_KEYS) {
                     while (isspace((int)*p1))
                         ++p1;
                     if (*p1 == '=') {
                         ++p1;
                         while (isspace((int)*p1))
                            ++p1;
                     }
                     if (keyno < N_ARGLESS_KEYS + 6) {
                         keyval[keyno - N_ARGLESS_KEYS] = atof(p1);
                         flags |= (1 << (keyno - N_ARGLESS_KEYS));
                     }
                     while (!isspace((int)*p1) && *p1 != '\0')
                         ++p1;
                  }
                  break;
              }
           }
           p = p1;
           while (!isspace((int)*p) && *p != '\0')
              ++p;
           while (isspace((int)*p))
              ++p;
       }

       if ((flags & 0x30) == 0x30 || ((flags & 0x30) && (flags & 0xf) == 0xf)) {
           long x = G_PXL_H;
           long y = PXL_V;
           long bbox_w;
           long bbox_h;

           bbox_w = 0.1 * ((flags & 0x10) ? KEY_RWI
                         : KEY_RHI * (KEY_URX - KEY_LLX) / (KEY_URY -
                                                        KEY_LLY)) *
              dimconv + 0.5;
           bbox_h =
              0.1 * ((flags & 0x20) ? KEY_RHI : KEY_RWI *
                     (KEY_URY - KEY_LLY) / (KEY_URX - KEY_LLX))
              * dimconv + 0.5;

           g_info->geom_box(info, x, y - bbox_h, x + bbox_w, y);
       }
    }
    else if (memicmp(cp, "ps::[begin]", 11) == 0) {
       /* compute psfig bounding box */
       long bbox_w, bbox_h;

       if (sscanf(cp + 11, "%ld %ld\n", &bbox_w, &bbox_h) >= 2) {
           long x = G_PXL_H;
           long y = PXL_V;

           bbox_w = xpixel_conv(spell_conv(bbox_w));
           bbox_h = xpixel_conv(spell_conv(bbox_h));

           g_info->geom_box(info, x, y, x + bbox_w, y + bbox_h);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void im_fdraw ( double  x,
double  y 
) [static]

Definition at line 420 of file special.c.

{
    if (++path_len >= MAXPOINTS)
       XDVI_FATAL((stderr, "Too many arc points"));
    xx[path_len] = x + 0.5;
    yy[path_len] = y + 0.5;
}

Here is the caller graph for this function:

Definition at line 1343 of file special.c.

{
#if PS
    struct tickrec   *tikp;
#endif

    scanned_page = scanned_page_reset = resource.prescan ? -1 : total_pages + 1;
#if PS
    scanned_page_ps = scanned_page_ps_bak = scanned_page;
#if COLOR
    scanned_page_color = scanned_page;
#endif /* COLOR */
#endif /* PS */

    TRACE_FILES((stderr, "init_prescan: scanned_page = %d", scanned_page));
#if PS
    if (resource.postscript == 0)
       scanned_page_ps = total_pages + 1;

    for (tikp = tickhead; tikp != NULL; tikp = tikp->next)
       tikp->pageno = -1;
    psp.newdoc();
#endif

#if COLOR
    if (!resource.use_color)
       scanned_page_color = total_pages + 1;
#endif

    if (ignore_papersize_specials) {
#if PS && COLOR
       scanned_page = scanned_page_ps < scanned_page_color ? scanned_page_ps : scanned_page_color;
#elif PS
       scanned_page = scanned_page_ps;
#elif COLOR
       scanned_page = scanned_page_color;
#else
       scanned_page = total_pages + 1;
#endif
    }
}

Here is the caller graph for this function:

static void line_btw ( int  fx,
int  fy,
int  tx,
int  ty 
) [static]

Definition at line 212 of file special.c.

{
    int fcx = xconv(fx);
    int tcx = xconv(tx);
    int fcy = yconv(fy);
    int tcy = yconv(ty);

    if ((fcx < globals.win_expose.max_x || tcx < globals.win_expose.max_x) && (fcx >= globals.win_expose.min_x || tcx >= globals.win_expose.min_x) &&
       (fcy < globals.win_expose.max_y || tcy < globals.win_expose.max_y) && (fcy >= globals.win_expose.min_y || tcy >= globals.win_expose.min_y)) {
#if COLOR
       if (fg_active != fg_current)
           do_color_change();
#endif
       XDrawLine(DISP, currwin.win, globals.gc.rule,
                fcx - currwin.base_x, fcy - currwin.base_y,
                tcx - currwin.base_x, tcy - currwin.base_y);
    }
}

Here is the caller graph for this function:

static unsigned int myatopix ( const char **  pp) [static]

Definition at line 2242 of file special.c.

{
#define SCR_LEN 16
    unsigned int value;
    const char *cp = *pp;
    char scr[16];
    const char *p0, *p1;

    p0 = cp;
    while ((*cp >= '0' && *cp <= '9') || *cp == '.')
       ++cp;
    p1 = cp;
    while (isspace((int)*cp))
       ++cp;
    if (*cp >= 'a' && *cp <= 'z' && cp[1] >= 'a' && cp[1] <= 'z') {
       /* if units are present */
       if (p1 - p0 <= SCR_LEN - 3) {
           sprintf(scr, "%.*s%c%c", (int)(p1 - p0), p0, *cp, cp[1]);
           value = atopix(scr, False);
       }
       else
           value = 0;
       cp += 2;
    }
    else
       value = atopix(p0, False);

    *pp = cp;
    return value;
#undef SCR_LEN
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void psfig_special ( char *  cp) [static]

Definition at line 1387 of file special.c.

{
    char *filename;
    int raww, rawh;

    if (strncmp(cp, ":[begin]", 8) == 0) {
       cp += 8;
       bbox_valid = False;
       bbox_angle = 0;
       if (sscanf(cp, "%d %d\n", &raww, &rawh) >= 2) {
           bbox_valid = True;
           bbox_width = pixel_conv(spell_conv(raww));
           bbox_height = pixel_conv(spell_conv(rawh));
           bbox_voffset = 0;
       }
       if (INSIDE_MANE_WIN) {
#if    PS
           psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y, cp);
#else
           draw_bbox();
#endif
       }
       psfig_begun = True;
    }
    else if (strncmp(cp, " plotfile ", 10) == 0) {
       cp += 10;
       while (isspace((int)*cp))
           cp++;
       /* handle "`zcat file". Borrowed from dvipsk... */
       if (*cp == '"') {
           cp++;
           for (filename = cp; *cp && (*cp != '"'); ++cp);
       }
       else {
           for (filename = cp; *cp && !isspace((int)*cp); ++cp);
       }
       *cp = '\0';
#if    PS
       if (INSIDE_MANE_WIN)
           send_ps_file(filename, kpse_pict_format);
#endif
    }
    else if (strncmp(cp, ":[end]", 6) == 0) {
       cp += 6;
#if    PS
       if (INSIDE_MANE_WIN) {
           psp.drawend(cp);
       }
#endif
       bbox_valid = False;
       psfig_begun = False;
    }
    else if (*cp == ':') {
       /* I am going to send some raw postscript stuff */
       ++cp;  /* skip the colon */
#if    PS
       if (ps_parseraw(cp))
           have_raw_postscript = True;
       if (INSIDE_MANE_WIN)
           psp.drawraw(cp);
#endif
    }
    else { /* attempt to parse pstricks color specials */
#if COLOR
       struct rgb color;
       if (parse_color(cp, cp, &color, True)) {
           /* clear stack */
           if (rcs_head == NULL) {
              rcs_head = xmalloc(sizeof *rcs_head);
              rcs_head->prev = rcs_head->next = NULL;
           }
           rcs_top = rcs_head;
           color_bot_size = 0;
           
           /* Change top of stack */
           rcs_top->color = color;
           
           set_fg_color(&color);
       }
#endif     
       /* also raw PostScript, but no extra colon to skip */
#if PS
       if (INSIDE_MANE_WIN) {
           if (ps_parseraw(cp))
              have_raw_postscript = True;
           
           if (psfig_begun)
              psp.drawraw(cp);
           else {
              psp.drawbegin(PXL_H - currwin.base_x,
                           PXL_V - currwin.base_y, cp);
              psp.drawend("");
           }
       }
#endif
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void quote_special ( char *  cp) [static]

Definition at line 1627 of file special.c.

{
    bbox_valid = False;

#if    PS
    if (currwin.win == mane.win) {
       psp.drawbegin(PXL_H - currwin.base_x, PXL_V - currwin.base_y,
                    "@beginspecial @setspecial ");
       /* talk directly with the DPSHandler here */
       psp.drawraw(cp + 1);
       psp.drawend(" @endspecial");
    }
#endif

    /* nothing else to do--there's no bbox here */
}

Here is the caller graph for this function:

Definition at line 822 of file special.c.

{
    int xcorner, ycorner;

    if (bbox_valid) {
       xcorner = PXL_H - currwin.base_x;
       ycorner = PXL_V - currwin.base_y;
       
       ycorner -= bbox_voffset;
       append_bbox_info(xcorner, ycorner, bbox_width, bbox_height, bbox_angle);

       /* register boundaries of this box as anchor boundaries */
       if (htex_inside_href) {
           htex_set_anchorsize(xcorner, ycorner, xcorner + bbox_width, ycorner + bbox_height);
           htex_set_objecttype(HTEX_IMG);
       }
    }
}

Here is the call graph for this function:

static void scan_papersize ( const char *  cp0) [static]

Definition at line 2275 of file special.c.

{
    const char *cp = cp0;
    unsigned int w, h;
    double mag = 1.0;

    if (ignore_papersize_specials)
       return;

    if (*cp == '*') {
       do
           ++cp;
       while (isspace((int)*cp));
       mag = magnification * .001;
    }
           
    w = myatopix(&cp) * mag + 0.5;

    while (isspace((int)*cp))
       ++cp;
    if (*cp == ',')
       do
           ++cp;
       while (isspace((int)*cp));

    h = myatopix(&cp) * mag + 0.5;

    if (w == 0 || h == 0)
       XDVI_WARNING((stderr, "Invalid papersize special `%s'", cp0));
    else {
       /* we have a paper size special; disable xdvirc_geometry:
          fprintf(stderr, "---------- scanned papersize: %dx%d\n", w, h);
          resource.xdvirc_geometry = NULL;
       */
       pageinfo_set_page_width(scanned_page + 1, w);
       pageinfo_set_window_width(scanned_page + 1, w);
       pageinfo_set_page_height(scanned_page + 1, h);
       pageinfo_set_window_height(scanned_page + 1, h);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Boolean scan_special ( char *  cp,
int  cp_len,
void data 
)

Definition at line 2564 of file special.c.

{
    char *p;
    Boolean dummy_ret = True; /* currently unused;
                             FIXME: use return value to avoid redundant calls (instead of longjmp()) */
    UNUSED(cp_len); /* TODO: could probably utilize this in call to htex_prescan_special() */
    ASSERT(data != NULL, "Must pass a data pointer when using HTEX");
    
    if (globals.debug & DBG_PS)
       printf("Scanning special `%s'.\n", cp);

    while (isspace((int)*cp))
       ++cp;
    
    /* Ignore initial "xdvi:" */
    if (memcmp(cp, "xdvi:", 5) == 0) {
       cp += 5;
       while (isspace((int)*cp))
           ++cp;
    }

    if (memicmp(cp, "ps:", 3) == 0) {
       Boolean found;
       cp += 3;
       /* check for hdvips hyperlinks */
       if (memicmp(cp, "sdict begin ", strlen("sdict begin ")) == 0) {
           static Boolean hypertex_too_old = False;
           char *match = NULL;
           cp += strlen("sdict begin ");

           if (strstr(cp, "HyperStart") != NULL)
              hypertex_too_old = True;
           if (hypertex_too_old)
              return False;
           
           if (memcmp(cp, "H.S", 3) == 0
              || memcmp(cp, "H.R", 3) == 0
              || memcmp(cp, "H.B", 3) == 0
              /* following 2 conditions could be more restrictive: between `begin' and H.A/H.L,
                 there should be a single number (baselineskip in pt) */
              || (match = strstr(cp, "H.A")) != NULL
              || (match = strstr(cp, "H.L")) != NULL
              || (match = strstr(cp, "/Action")) != NULL
              || (match = strstr(cp, "/Link")) != NULL
              || (match = strstr(cp, "/View")) != NULL) {
              if (match != NULL)
                  found = htex_prescan_special(match, cp_len, data);
              else
                  found = htex_prescan_special(cp, cp_len, data);
           }
       }
           
    }
    else if (memicmp(cp, "html:", strlen("html:")) == 0) {
       Boolean found;
       size_t offset = strlen("html:");
       found = htex_prescan_special(cp + offset, cp_len - offset, data);
       /* if searching for a specific string, return as soon as it's found - not yet implemented */
#if 0
       if (my_data != NULL && my_data->scan_type == HTEX_ANCHOR_STRING && found) {
           return True;
       }
#endif
    }
    /* do the following only if not searching for an anchor string */
    if (((struct htex_prescan_data *)data)->scan_type != HTEX_ANCHOR_STRING) {
#if PS
# if COLOR
       if (scanned_page_ps <= scanned_page)
# endif
           {
              if (*cp == '!') {
                  scan_bang(cp);
                  return dummy_ret;
              }
              else if (memicmp(cp, "header", 6) == 0 && (p = endofcommand(cp + 6)) != NULL) {
                  scan_header(p);
                  return dummy_ret;
              }
           }
#endif /* PS */
       
#if COLOR
# if PS
       if (scanned_page_color <= scanned_page)
# endif
           {
              if (memicmp(cp, "background ", 11) == 0) {
                  scan_bg_color(cp);
                  return dummy_ret;
              }
              else if (memicmp(cp, "color ", 6) == 0) {
                  scan_color(cp);
                  return dummy_ret;
              }
           }
#endif /* COLOR */
       if (memcmp(cp, "papersize", 9) == 0 && (p = endofcommand(cp + 9)) != NULL) {
           m_have_papersize_special = True;
           scan_papersize(p);
           return dummy_ret;
       }
    }
    return dummy_ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void set_pen_size ( char *  cp) [static]

Definition at line 268 of file special.c.

{
    int ps;

    if (sscanf(cp, " %d ", &ps) != 1) {
       XDVI_WARNING((stderr, "invalid .ps command format: %s", cp));
       return;
    }
    pen_size = (2 * ps * resource.pixels_per_inch / currwin.shrinkfactor + 1000) / 2000;
    if (pen_size < 1)
       pen_size = 1;
    else if (pen_size > MAX_PEN_SIZE)
       pen_size = MAX_PEN_SIZE;

#if BUG_888087_FIXED
    if (globals.gc.rule) {
       XGCValues values;
       values.line_width = pen_size;
       XChangeGC(DISP, globals.gc.rule, GCLineWidth, &values);
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void shade_last ( void  ) [static]

Definition at line 582 of file special.c.

Here is the caller graph for this function:

static void whiten_last ( void  ) [static]

Definition at line 594 of file special.c.

Here is the caller graph for this function:


Variable Documentation

int bbox_angle [static]

Definition at line 669 of file special.c.

unsigned int bbox_height [static]

Definition at line 672 of file special.c.

Boolean bbox_valid [static]

Definition at line 670 of file special.c.

int bbox_voffset [static]

Definition at line 673 of file special.c.

unsigned int bbox_width [static]

Definition at line 671 of file special.c.

Boolean blacken = False [static]

Definition at line 193 of file special.c.

struct bbox_info* g_bbox_info = NULL [static]

Definition at line 685 of file special.c.

Definition at line 687 of file special.c.

size_t g_bbox_info_size = 0 [static]

Definition at line 686 of file special.c.

const char* keytab[] [static]
Initial value:
 { "clip",
                              "llx",
                              "lly",
                              "urx",
                              "ury",
                              "rwi",
                              "rhi",
                              "hsize",
                              "vsize",
                              "hoffset",
                              "voffset",
                              "hscale",
                              "vscale",
                              "angle"
}

Definition at line 1488 of file special.c.

int path_len = 0 [static]

Definition at line 188 of file special.c.

int pen_size = 1 [static]

Definition at line 189 of file special.c.

Definition at line 195 of file special.c.

Boolean shade = False [static]

Definition at line 192 of file special.c.

Boolean whiten = False [static]

Definition at line 191 of file special.c.

int xx[MAXPOINTS] [static]

Definition at line 187 of file special.c.

int yy[MAXPOINTS] [static]

Definition at line 187 of file special.c.