Back to index

tetex-bin  3.0
Classes | Defines | Functions
dvi-draw.h File Reference
#include "xdvi-config.h"
#include "xdvi.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  drawinf
struct  src_parsed_special

Defines

#define pixel_conv(x)   ((int) ((x) / currwin.shrinkfactor >> 16))
#define pixel_round(x)   ((int) ROUNDUP(x, currwin.shrinkfactor << 16))
#define DVI_H   currinf.data.dvi_h
#define PXL_H   pixel_conv(currinf.data.dvi_h)
#define DVI_V   currinf.data.dvi_v
#define PXL_V   currinf.data.pxl_v
#define WW   currinf.data.w
#define XX   currinf.data.x
#define YY   currinf.data.y
#define ZZ   currinf.data.z
#define DVI_BUFFER_LEN   2048

Functions

void prescan (FILE *fp)
void src_parse (const char *str, int str_len, struct src_parsed_special *parsed)
void draw_page (void)
void source_reverse_search (int, int, wide_bool)
void source_special_show (wide_bool)
void source_forward_search (const char *)
void anchor_search (const char *str)
long text_do_char (FILE *fp, struct scan_info *info, wide_ubyte ch)
Boolean spcl_scan (Boolean(*spcl_proc)(char *str, int str_len, void *data), void *data, Boolean return_if_found, FILE *fp)
void geom_scan_part (long(*char_proc)(FILE *, struct scan_info *, wide_ubyte), FILE *fp, struct scan_info *info, struct frame *min_frame, double current_dimconv)
void geom_scan (long(*char_proc)(FILE *, struct scan_info *, wide_ubyte), FILE *fp, struct scan_info *info, int pageno)
off_t save_file_status (FILE *fp, struct drawinf *currinf_save, ubyte *maxchar_save)
void reinit_text_scan (void)
void restore_file_status (FILE *fp, struct drawinf currinf_save, ubyte maxchar_save, off_t pos_save)
void htex_do_special (const char *str, size_t len)
setcharRetvalT set_char (wide_ubyte ch)
setcharRetvalT load_n_set_char (wide_ubyte ch)
setcharRetvalT set_vf_char (wide_ubyte ch)
void dvi_fmt_error (const char *message,...)

Class Documentation

struct drawinf

Definition at line 39 of file dvi-draw.h.

Collaboration diagram for drawinf:
Class Members
ubyte * end
struct font * fontp
ubyte * pos
set_char_proc set_char_p
struct tn * tn_head
struct font ** tn_table
unsigned long tn_table_len
struct font * virtual
struct src_parsed_special

Definition at line 53 of file dvi-draw.h.

Class Members
int col
char * filename
size_t filename_len
int line

Define Documentation

#define DVI_BUFFER_LEN   2048

Definition at line 111 of file dvi-draw.h.

#define DVI_H   currinf.data.dvi_h

Definition at line 77 of file dvi-draw.h.

#define DVI_V   currinf.data.dvi_v

Definition at line 79 of file dvi-draw.h.

#define pixel_conv (   x)    ((int) ((x) / currwin.shrinkfactor >> 16))

Definition at line 71 of file dvi-draw.h.

#define pixel_round (   x)    ((int) ROUNDUP(x, currwin.shrinkfactor << 16))

Definition at line 72 of file dvi-draw.h.

#define PXL_H   pixel_conv(currinf.data.dvi_h)

Definition at line 78 of file dvi-draw.h.

#define PXL_V   currinf.data.pxl_v

Definition at line 80 of file dvi-draw.h.

#define WW   currinf.data.w

Definition at line 81 of file dvi-draw.h.

#define XX   currinf.data.x

Definition at line 82 of file dvi-draw.h.

#define YY   currinf.data.y

Definition at line 83 of file dvi-draw.h.

#define ZZ   currinf.data.z

Definition at line 84 of file dvi-draw.h.


Function Documentation

void anchor_search ( const char *  str)

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

{
    off_t pos_save = 0;
    struct drawinf currinf_save;
    ubyte maxchar_save;
    volatile int test_page = 0;
    Boolean found_anchor = False;
    int y_pos = -1;
    struct scan_info info;
    struct geom_info g_info;

    ASSERT(str != NULL, "Argument to anchor_search() musn't be NULL");
    TRACE_HTEX((stderr, "Entering anchor_search(%s)", str));

    /* Save status of dvi_file reading (in case we hit an error and resume drawing).  */
    if (dvi_pointer_frame != NULL)
       pos_save = lseek(fileno(globals.dvi_file.bak_fp), 0L, SEEK_CUR) - (dvi_pointer_frame->end - dvi_pointer_frame->pos);
    (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(0), SEEK_SET);

    currinf_save = currinf;
    maxchar_save = maxchar;

    memset((char *)&currinf.data, '\0', sizeof currinf.data);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;

    /* Start search over pages */
    for (test_page = 0; test_page < total_pages; test_page++) {
       if (spcl_scan(htex_scan_special, NULL, True, globals.dvi_file.bak_fp)) {
           found_anchor = True;
           break;
       }
    }

    if (!found_anchor) {
       /* Restore file position.  */
       maxchar = maxchar_save;
       currinf = currinf_save;
       
       if (dvi_pointer_frame != NULL) {
           (void)lseek(fileno(globals.dvi_file.bak_fp), pos_save, SEEK_SET);
           dvi_pointer_frame->pos = dvi_pointer_frame->end = dvi_buffer;
       }
       XBell(DISP, 0);
       statusline_print(STATUS_MEDIUM, "Error: Anchor \"%s\" not found.", str);
       return;
    }

    /*
     * In this case we don't need to restore maxchar and currinf, since
     * we won't resume drawing -- we'll jump to a new page instead.
     */

    /* Move to that page.  */
    (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(test_page), SEEK_SET);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;

    info.geom_special = htex_scan_special_noreturn;

    g_info.geom_box = htex_dummy_box;
    g_info.geom_data = &y_pos;

    info.data = &g_info;
    
    if (!setjmp(info.done_env))
       geom_scan_part(geom_do_char, globals.dvi_file.bak_fp, &info, geom_current_frame = &geom_frame0, dimconv);

    if (y_pos == -1) { /* not found */
       XDVI_ERROR((stderr, "%s:%d: shouldn't happen: geom_scan_part() failed to re-find the link.", __FILE__, __LINE__));
    }
    else {
       goto_page(test_page, resource.keep_flag ? NULL : home, False);
       page_history_insert(test_page);
       do_autoscroll = True;
       htex_set_anchormarker(y_pos);
    }
    /* reset info */
    free(g_anchor_pos);
    g_anchor_pos = NULL;
    g_anchor_len = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
#if 0
    volatile double save_gamma = 0.0;
#endif /* 0 */
    /* Check for changes in dvi file. */
    if (dvi_file_changed()) {
       return;
    }

    if (globals.dvi_file.bak_fp == NULL) {
       return;
    }

#ifdef PS
    have_raw_postscript = False;
#endif
    
#if COLOR
    color_bottom = &fg_initial;
    color_bot_size = 1;

    if (page_colors.stack != NULL && current_page > 0) {
       color_bottom = page_colors.stack[current_page - 1].colorstack;
       color_bot_size = page_colors.stack[current_page - 1].stacksize;
    }
    rcs_top = NULL;
    ASSERT(color_bot_size > 0, "color_bot_size mustn't become negative!");
    ASSERT(color_bottom != NULL, "color_bottom mustn't become negative!");
    set_fg_color(&color_bottom[color_bot_size - 1]);
#endif /* COLOR */

#if !FIXED_FLUSHING_PAGING    
    draw_border(-currwin.base_x, -currwin.base_y,
              ROUNDUP(pageinfo_get_page_width(current_page), currwin.shrinkfactor) + 2,
              ROUNDUP(pageinfo_get_page_height(current_page), currwin.shrinkfactor) + 2, globals.gc.high);
#endif /* MOTIF */

    (void) lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(current_page), SEEK_SET);

    memset((char *)&currinf.data, '\0', sizeof currinf.data);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;
    dvi_pointer_frame = &currinf;
    drawing_mag = (currwin.win == magnifier.win);
    psfig_begun = False;

    htex_initpage(False, False, current_page);

    if (currwin.win == mane.win) {
       XRectangle rect;
       rect.x = globals.win_expose.min_x;
       rect.y = globals.win_expose.min_y;
       rect.width = globals.win_expose.max_x - globals.win_expose.min_x;
       rect.height = globals.win_expose.max_y - globals.win_expose.min_y;
/*     fprintf(stderr, "clip: %d, %d, %d, %d\n", */
/*            globals.win_expose.min_x, */
/*            globals.win_expose.min_y, */
/*            globals.win_expose.max_x - globals.win_expose.min_x, */
/*            globals.win_expose.max_y - globals.win_expose.min_y); */
#define SET_CLIP(gc) if (gc != NULL) XSetClipRectangles(DISP, gc, 0, 0, &rect, 1, Unsorted)
#define CLEAR_CLIP(gc)  if (gc != NULL) XSetClipMask(DISP, gc, None)
       /* Set clip masks for all GC's */
       SET_CLIP(globals.gc.fore);
       SET_CLIP(globals.gc.fore2);
       SET_CLIP(globals.gc.fore2_bak);
       SET_CLIP(globals.gc.fore2_bak1);
       SET_CLIP(globals.gc.rule);
       SET_CLIP(globals.gc.high);
       SET_CLIP(globals.gc.linkcolor);
       SET_CLIP(globals.gc.copy);
    }
    
    if (!setjmp(globals.ev.canit)) {
       /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BUG ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

          ALL GLYPH DRAWING/RULE SETTING COMMANDS THAT MIGHT INVOKE
          longjmp(globals.ev.canit)
          MUST GO INSIDE THIS IF CASE, AND MUST NOT BE INVOKED FROM
          SOMEWHERE ELSE!
          
          Failure to check whether a command could (indirectly) invoke
          such a drawing routine (like e.g. put_rule()) will result
          in *really* strange bugs (see e.g. #616920, and probably also #471021).
          
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BUG ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       */
       /* generate an expose event */
       if (search_have_match(current_page)) {
           search_erase_highlighting(False);
       }
       if (resource.mouse_mode == MOUSE_TEXT_MODE) {
           text_change_region(TEXT_SEL_ERASE, NULL);
       }
       draw_part(globals.dvi_file.bak_fp, current_frame = &frame0, dimconv);

       if (have_raw_postscript) {
           warn_raw_postscript();
       }
    }
    else {
       /* If we were interrupted, put the expose event back, so that the
        * region gets redrawn.  The if statement is necessary because the
        * magnifier may have been destroyed as part of the interrupt.  */
       if (currwin.win == mane.win || currwin.win == magnifier.win) {
           expose(currwin.win == mane.win ? &mane : &magnifier,
                 globals.win_expose.min_x - currwin.base_x, globals.win_expose.min_y - currwin.base_y,
                 globals.win_expose.max_x - globals.win_expose.min_x, globals.win_expose.max_y - globals.win_expose.min_y);
       }

#ifdef PS
       psp.interrupt();
       /* reset this flag too, just to make sure ... */
#if GS_PIXMAP_CLEARING_HACK
       had_ps_specials = False;
#endif
#endif
       globals.ev.flags &= ~EV_MAG_GONE;
#if 0
       if (search_have_match() && save_gamma != 0.0) {
           resource.gamma = save_gamma;
           do_color_change();
           reset_fonts();
       }
#endif /* 0 */
    }

    drawing_mag = False;
    dvi_pointer_frame = NULL;
    if (currwin.win == mane.win) {
       if (globals.src.fwd_box_page >= 0) {
           source_fwd_draw_box(); /* draw box showing found source line */
       }
       htex_draw_anchormarkers();
    }
#ifdef PS
    psp.endpage();
#endif
    if (currwin.win == mane.win && resource.postscript != 1) {
       display_bboxes();
    }
    if (search_have_match(current_page)) {
       /* highlight search match */
       search_draw_inverted_regions();
    }
    if (currwin.win == mane.win && resource.mouse_mode == MOUSE_TEXT_MODE) {
       /* highlight selection */
       text_change_region(TEXT_SEL_REDRAW, NULL);
    }
    if (resource.mouse_mode == MOUSE_RULER_MODE) {
       redraw_ruler();
    }

    clear_bboxes();

    if (currwin.win == mane.win) {
       CLEAR_CLIP(globals.gc.fore);
       CLEAR_CLIP(globals.gc.fore2);
       CLEAR_CLIP(globals.gc.fore2_bak);
       CLEAR_CLIP(globals.gc.fore2_bak1);
       CLEAR_CLIP(globals.gc.rule);
       CLEAR_CLIP(globals.gc.high);
       CLEAR_CLIP(globals.gc.linkcolor);
       CLEAR_CLIP(globals.gc.copy);
    }
#undef SET_CLIP
#undef CLEAR_CLIP

    currwin.win = (Window) 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dvi_fmt_error ( const char *  message,
  ... 
)

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

{
    
    va_list args;
    va_start(args, message);
    fprintf(stderr, "%s: ", globals.program_name);
    (void)vfprintf(stderr, message, args);
    va_end(args);
    if (currinf.virtual)
       fprintf(stderr, " in virtual font %s\n", currinf.virtual->fontname);
    else
       fprintf(stderr, ", offset %ld\n", (long)xtell(globals.dvi_file.bak_fp, currinf.pos - 1));
    /* #ifndef NDEBUG */
    /*     xdvi_exit(EXIT_FAILURE); */
    /* #else */
    XDVI_ABORT((stderr, "I'll abort now, to help you debugging this."));
    /* #endif */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void geom_scan ( long(*)(FILE *, struct scan_info *, wide_ubyte char_proc,
FILE fp,
struct scan_info info,
int  pageno 
)

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

{
    volatile off_t pos_save = 0;
    struct drawinf currinf_save;
    ubyte maxchar_save;

#if PS
    if (info->geom_special != NULL && scanned_page < current_page) {
       fprintf(stderr, "shouldn't happen: %d >= %d!\n", scanned_page, current_page);
       return;       /* should not happen */
    }
#endif

    if (dvi_pointer_frame != NULL)
       pos_save = lseek(fileno(fp), 0L, SEEK_CUR) - (dvi_pointer_frame->end - dvi_pointer_frame->pos);

    (void) lseek(fileno(fp), pageinfo_get_offset(pageno), SEEK_SET);
    
    currinf_save = currinf;
    maxchar_save = maxchar;

    memset((char *)&currinf.data, '\0', sizeof currinf.data);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;

    if (!setjmp(info->done_env)) {
       geom_scan_part(char_proc, fp, info, geom_current_frame = &geom_frame0, dimconv);
    }

    maxchar = maxchar_save;
    currinf = currinf_save;

    if (dvi_pointer_frame != NULL) {
       (void)lseek(fileno(fp), pos_save, SEEK_SET);
       dvi_pointer_frame->pos = dvi_pointer_frame->end = dvi_buffer;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void geom_scan_part ( long(*)(FILE *, struct scan_info *, wide_ubyte char_proc,
FILE fp,
struct scan_info info,
struct frame min_frame,
double  current_dimconv 
)

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

{
    ubyte ch;
#ifdef TEXXET
    struct drawinf oldinfo;
    ubyte oldmaxchar = 0;
    off_t file_pos = 0;
    int refl_count = 0;
#endif

    currinf.fontp = NULL;
    currinf.set_char_p = set_no_char;
#ifdef TEXXET
    currinf.dir = 1;
    geom_scan_frame = NULL; /* indicates we're not scanning */
#endif
    for (;;) {
       ch = xone(fp);
       if (ch <= (ubyte)(SETCHAR0 + 127))
           DVI_H += char_proc(fp, info, ch);
       else if (FNTNUM0 <= ch && ch <= (ubyte) (FNTNUM0 + 63)) {
           change_font((unsigned long)(ch - FNTNUM0));
       }
       else {
           long a, b;

           switch (ch) {
           case SET1:
           case PUT1:
              a = char_proc(fp, info, xone(fp));
              if (ch != PUT1)
                  DVI_H += a;
              break;

           case SET2:
           case PUT2:
              if (!resource.omega)
                  dvi_fmt_error("%s:%d: draw_part: op-code %d only works with the \"-omega\" option",
                              __FILE__, __LINE__, ch);
              else {
#ifdef TEXXET
                  char_proc(fp, info, xnum(fp, 2));
#else
                  a = char_proc(fp, info, xnum(fp, 2));
                  if (ch != PUT2)
                     DVI_H += a;
#endif
              }
              break;

           case SETRULE:
              /* Be careful, dvicopy outputs rules with
                 height = 0x80000000.  We don't want any
                 SIGFPE here. */
              a = xsfour(fp);
              b = xspell_conv(xsfour(fp));
              if (a >= 0 && b >= 0
#ifdef TEXXET
                  && geom_scan_frame == NULL
#endif
                  ) {
                  /* is this a geom scan? */
                  if (info->geom_special != NULL)
                     geom_do_rule(info, xspell_conv(a), b);
              }
              DVI_H += DIR * b;
              break;

           case PUTRULE:
              a = xspell_conv(xsfour(fp));
              b = xspell_conv(xsfour(fp));
              if (a >= 0 && b >= 0
#ifdef TEXXET
                  && geom_scan_frame == NULL
#endif
                  ) {
                  /* is this a geom scan? */
                  if (info->geom_special != NULL)
                     geom_do_rule(info, a, b);
              }
              break;

           case NOP:
              break;

           case BOP:
              xskip(fp, (long)11 * 4);
              DVI_H = G_OFFSET_X;
              DVI_V = G_OFFSET_Y;
              PXL_V = xpixel_conv(DVI_V);
              WW = XX = YY = ZZ = 0;
              /* create pagebreak in character scan */
              if (info->geom_special == NULL) {
                  do_newpage(info);
              }
              break;

           case PUSH:
              if (geom_current_frame->next == NULL) {
                  struct frame *newp = xmalloc(sizeof *newp);

                  geom_current_frame->next = newp;
                  newp->prev = geom_current_frame;
                  newp->next = NULL;
              }
              geom_current_frame = geom_current_frame->next;
              geom_current_frame->data = currinf.data;
              break;

           case POP:
              if (geom_current_frame == minframe)
                  dvi_fmt_error("more POPs than PUSHes");
              currinf.data = geom_current_frame->data;
              geom_current_frame = geom_current_frame->prev;
              break;

#ifdef TEXXET
           case SREFL:
              if (geom_scan_frame == NULL) {
                  /* we're not scanning:  save some info. */
                  oldinfo = currinf;
                  oldmaxchar = maxchar;
                  if (!currinf.virtual)
                     file_pos = xtell(fp, currinf.pos);
                  geom_scan_frame = geom_current_frame; /* start scanning */
                  refl_count = 0;
                  break;
              }
              /* we are scanning */
              if (geom_current_frame == geom_scan_frame)
                  ++refl_count;
              break;

           case EREFL:
              if (geom_scan_frame != NULL) {     /* if we're scanning */
                  if (geom_current_frame == geom_scan_frame
                     && --refl_count < 0) {
                     /* we've hit the end of our scan */
                     geom_scan_frame = NULL;
                     /* first:  push */
                     if (geom_current_frame->next == NULL) {
                         struct frame *newp = xmalloc(sizeof *newp);

                         geom_current_frame->next = newp;
                         newp->prev = geom_current_frame;
                         newp->next = NULL;
                     }
                     geom_current_frame = geom_current_frame->next;
                     geom_current_frame->data = currinf.data;
                     /* next:  restore old file position, XX, etc. */
                     if (!currinf.virtual) {
                         off_t bgn_pos = xtell(fp, G_dvi_buf_ptr);

                         if (file_pos >= bgn_pos) {
                            oldinfo.pos = dvi_buffer + (file_pos - bgn_pos);
                            oldinfo.end = currinf.end;
                         }
                         else {
                            (void)lseek(fileno(fp), file_pos,
                                       SEEK_SET);
                            oldinfo.pos = oldinfo.end;
                         }
                     }
                     currinf = oldinfo;
                     maxchar = oldmaxchar;
                     /* and then:  recover position info. */
                     DVI_H = geom_current_frame->data.dvi_h;
                     DVI_V = geom_current_frame->data.dvi_v;
                     PXL_V = geom_current_frame->data.pxl_v;
                     /* and finally, reverse direction */
                     currinf.dir = -currinf.dir;
                  }
                  break;
              }
              /* we're not scanning, */
              /* so just reverse direction and then pop */
              currinf.dir = -currinf.dir;
              currinf.data = geom_current_frame->data;
              geom_current_frame = geom_current_frame->prev;
              break;
#endif /* TEXXET */

           case RIGHT1:
           case RIGHT2:
           case RIGHT3:
           case RIGHT4:
              DVI_H += DIR * xspell_conv(xsnum(fp, ch - RIGHT1 + 1));
              break;

           case W1:
           case W2:
           case W3:
           case W4:
              WW = xspell_conv(xsnum(fp, ch - W0));
           case W0:
              DVI_H += DIR * WW;
              break;

           case X1:
           case X2:
           case X3:
           case X4:
              XX = xspell_conv(xsnum(fp, ch - X0));
           case X0:
              DVI_H += DIR * XX;
              break;

           case DOWN1:
           case DOWN2:
           case DOWN3:
           case DOWN4:
              DVI_V += xspell_conv(xsnum(fp, ch - DOWN1 + 1));
              PXL_V = xpixel_conv(DVI_V);
              break;

           case Y1:
           case Y2:
           case Y3:
           case Y4:
              YY = xspell_conv(xsnum(fp, ch - Y0));
           case Y0:
              DVI_V += YY;
              PXL_V = xpixel_conv(DVI_V);
              break;

           case Z1:
           case Z2:
           case Z3:
           case Z4:
              ZZ = xspell_conv(xsnum(fp, ch - Z0));
           case Z0:
              DVI_V += ZZ;
              PXL_V = xpixel_conv(DVI_V);
              break;

           case FNT1:
           case FNT2:
           case FNT3:
           case FNT4:
              change_font(xnum(fp, ch - FNT1 + 1));
              break;

           case XXX1:
           case XXX2:
           case XXX3:
           case XXX4:
              a = xnum(fp, ch - XXX1 + 1);
              if (a > 0) {
                  char *str = read_special(fp, a);

                  /* is this a geom scan? */
                  if (info->geom_special != NULL) {
                     /* process the bounding box */
                     geom_do_special(info, str, current_dimconv);
                     /* process the specials we're looking for */
                     info->geom_special(info, str, a);
                  }
              }
              break;

           case FNTDEF1:
           case FNTDEF2:
           case FNTDEF3:
           case FNTDEF4:
              xskip(fp, (long)(12 + ch - FNTDEF1 + 1));
              a = (long)xone(fp);
              xskip(fp, a + (long)xone(fp));
              break;

#ifndef TEXXET
           case SREFL:
           case EREFL:
#endif
           case PRE:
           case POST:
           case POSTPOST:
           case EOP:
           default:
              return;

           }  /* end switch */
       }      /* end else (ch not a SETCHAR or FNTNUM) */
    }  /* end for */
}

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_do_special ( const char *  str,
size_t  len 
)

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    if (!load_font(currinf.fontp, resource.t1lib)) {    /* if not found */
       if (globals.ev.flags & EV_GE_NEWDOC) {    /* if abort */
           longjmp(globals.ev.canit, 1);
       }

       /* FIXME: does this need to be replaced by GUI warning, or has this case already been covered? */
       XDVI_WARNING((stderr, "load_n_set_char: Character(s) will be left blank."));
       currinf.set_char_p = currinf.fontp->set_char_p = set_empty_char;

#ifdef TEXXET
       return;
#else
       return 0L;
#endif
    }
    maxchar = currinf.fontp->maxchar;
    currinf.set_char_p = currinf.fontp->set_char_p;
#ifdef TEXXET
    (*currinf.set_char_p) (cmd, ch);
    return;
#else
    return (*currinf.set_char_p) (ch);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void prescan ( FILE fp)

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

{
    if (fp == NULL) {
       return;
    }

    TRACE_FILES((stderr, "prescan on %p", (void *)fp));
    
    (void)lseek(fileno(fp), pageinfo_get_offset(scanned_page + 1), SEEK_SET);
    G_dvi_buf_ptr = dvi_buffer;
    currinf.pos = currinf.end = G_dvi_buf_ptr;
    for (;;) {
       if (scanned_page == -1) { /* on first page */
           TRACE_FILES((stderr, "prescan on page 1"));
           pageinfo_set_page_width(scanned_page + 1, pageinfo_get_page_width(total_pages));
           pageinfo_set_page_height(scanned_page + 1, pageinfo_get_page_height(total_pages));
           pageinfo_set_window_width(scanned_page + 1, pageinfo_get_window_width(total_pages));
           pageinfo_set_window_height(scanned_page + 1, pageinfo_get_window_height(total_pages));
       }
       else {
           TRACE_FILES((stderr, "prescan on page %d", scanned_page));
           pageinfo_set_page_width(scanned_page + 1, pageinfo_get_page_width(scanned_page));
           pageinfo_set_page_height(scanned_page + 1, pageinfo_get_page_height(scanned_page));
           pageinfo_set_window_width(scanned_page + 1, pageinfo_get_window_width(scanned_page));
           pageinfo_set_window_height(scanned_page + 1, pageinfo_get_window_height(scanned_page));
       }
       if (read_events(EV_NOWAIT) & EV_GE_NEWPAGE) {
           break;
       }
       /* NOTE:  longjmp(globals.ev.canit) should not be done within
          read_events(). */
       htex_prescan_save();
       htex_prescan_initpage();

       if (!setjmp(globals.ev.canit)) {
           struct htex_prescan_data data;
           int pre_depth, depth;
           data.pageno = scanned_page + 1;
           data.scan_type = HTEX_ANCHOR_NUM; /* just for the anchor numbers */
           pre_depth = htex_prescan_get_depth();
           (void)spcl_scan(scan_special, &data, False, fp);
           
           depth = htex_prescan_get_depth();

           if (depth > pre_depth) {
              /* we have a mismatched anchor. We currently don't deal with
                 _nested_ mismatched anchors (ugh), so there's only one
                 anchor string that can be used as info on the next page. */
              int anchor_num = htex_prescan_get_mismatched_anchor_num(depth);
              /* scan again to find the anchor string at anchor number `anchor_num' */
              (void)lseek(fileno(fp), pageinfo_get_offset(scanned_page + 1), SEEK_SET);
              currinf.pos = currinf.end = G_dvi_buf_ptr;
              data.anchor_num = anchor_num;
              data.scan_type = HTEX_ANCHOR_STRING;
              htex_prescan_reset_firstpass();
              (void)spcl_scan(scan_special, &data, False, fp);
              depth = htex_prescan_get_depth();
           }
           else if (depth > 0 && scanned_page >= 0) { /* mismatch was on a previous page */
              htex_prescan_carry_over(scanned_page, scanned_page + 1);
           }
       }
       else { /* if interrupted */
           htex_prescan_restore(scanned_page + 1);
#if PS
           psp.interrupt();
#endif
           break;
       }
       if (globals.ev.flags & EV_GE_NEWPAGE)
           break;
       ++scanned_page;
#if COLOR
       if (scanned_page_color < scanned_page) {
           scan_color_eop();
           scanned_page_color = scanned_page;
       }
#endif
#if PS
       if (scanned_page_ps < scanned_page)
           scanned_page_ps = scanned_page;
#endif
       if (scanned_page >= current_page)
           break;
    }
    
#if PS
    if (!(globals.ev.flags & EV_GE_NEWPAGE))
       psp.endheader();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

                       {
    reinit_scan = True;
}

Here is the caller graph for this function:

void restore_file_status ( FILE fp,
struct drawinf  currinf_save,
ubyte  maxchar_save,
off_t  pos_save 
)

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

{
    maxchar = maxchar_save;
    currinf = currinf_save;
    
    if (dvi_pointer_frame != NULL) {
       (void)lseek(fileno(fp), pos_save, SEEK_SET);
       dvi_pointer_frame->pos = dvi_pointer_frame->end = dvi_buffer;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

off_t save_file_status ( FILE fp,
struct drawinf currinf_save,
ubyte maxchar_save 
)

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

{
    off_t pos_save = 0;
    if (dvi_pointer_frame != NULL)
       pos_save = lseek(fileno(fp), 0L, SEEK_CUR)
           - (dvi_pointer_frame->end - dvi_pointer_frame->pos);
    
    *currinf_save = currinf;
    *maxchar_save = maxchar;
    return pos_save;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    struct glyph *g;
#ifdef TEXXET
    long dvi_h_sav;
#endif

    if (ch > maxchar)
       realloc_font(currinf.fontp, (wide_ubyte)ch);
    if ((g = &currinf.fontp->glyph[ch])->bitmap.bits == NULL) {
       if (g->addr == 0) {
           if (!resource.hush_chars)
              XDVI_WARNING((stderr, "Character %d not defined in font %s", ch, currinf.fontp->fontname));
           g->addr = -1;
#ifdef TEXXET
           return;
#else
           return 0L;
#endif
       }
       if (g->addr == -1) {
#ifdef TEXXET
           return;
#else
           return 0L; /* previously flagged missing char */
#endif
       }
       open_font_file(currinf.fontp);
       fseek(currinf.fontp->file, g->addr, SEEK_SET);
       (*currinf.fontp->read_char) (currinf.fontp, ch);
       if (globals.debug & DBG_BITMAP)
           print_char((ubyte) ch, g);
       currinf.fontp->timestamp = ++current_timestamp;
    }

#ifdef TEXXET
    dvi_h_sav = DVI_H;
    if (currinf.dir < 0)
       DVI_H -= g->dvi_adv;

    if (scan_frame == NULL) {
#endif
       
#ifdef RGB_ANTI_ALIASING
       if (currwin.shrinkfactor == -1) {
           put_bitmap(&g->bitmap, PXL_H - g->x, PXL_V - g->y);
       }
#ifdef __GNUC__
#warning TODO: implement horizontal AA at shrink 1
#endif
#else
       if (currwin.shrinkfactor == 1) {
           put_bitmap(&g->bitmap, PXL_H - g->x, PXL_V - g->y);
       }
#endif
       else {
#ifdef GREY
           if (resource.use_grey) {
              if (g->pixmap2 == NULL) {
#ifdef DBG_AA
                  fprintf(stderr, "shinking the bitmap!\n");
#endif /* DBG_AA */
/*                print_bitmap(&g->bitmap); */
                  shrink_glyph_grey(g);
              }
              put_image(g, PXL_H - g->x2, PXL_V - g->y2);
           }
           else {
              if (g->bitmap2.bits == NULL) {
                  shrink_glyph(g);
              }
              put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
           }
#else
           if (g->bitmap2.bits == NULL) {
              shrink_glyph(g);
           }
           put_bitmap(&g->bitmap2, PXL_H - g->x2, PXL_V - g->y2);
#endif
       }
#ifdef TEXXET
    }
    if (cmd == PUT1 || (resource.omega && cmd == PUT2))
       DVI_H = dvi_h_sav;
    else if (currinf.dir > 0)
       DVI_H += g->dvi_adv;
    return;
#else
    return g->dvi_adv;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    struct macro *m;
    struct drawinf oldinfo;
    wide_ubyte oldmaxchar;
    static ubyte c;
#ifdef TEXXET
    long dvi_h_sav;
#endif

    if (ch > maxchar)
       realloc_virtual_font(currinf.fontp, ch);
    if ((m = &currinf.fontp->macro[ch])->pos == NULL) {
       if (!resource.hush_chars)
           XDVI_WARNING((stderr, "Character %d not defined in font %s", ch, currinf.fontp->fontname));
       m->pos = m->end = &c;
#ifdef TEXXET
       return;
#else
       return 0L;
#endif
    }
#ifdef TEXXET
    dvi_h_sav = DVI_H;
    if (currinf.dir < 0)
       DVI_H -= m->dvi_adv;
    if (scan_frame == NULL) {
#endif
       oldinfo = currinf;
       if (!currinf.virtual)
           dvi_pointer_frame = &oldinfo;
       oldmaxchar = maxchar;
       WW = XX = YY = ZZ = 0;
       currinf.tn_table_len = VFTABLELEN;
       currinf.tn_table = currinf.fontp->vf_table;
       currinf.tn_head = currinf.fontp->vf_chain;
       currinf.pos = m->pos;
       currinf.end = m->end;
       currinf.virtual = currinf.fontp;

       draw_part(globals.dvi_file.bak_fp, current_frame, currinf.fontp->dimconv);
       if (currinf.pos != currinf.end + 1)
           dvi_fmt_error("virtual character macro does not end correctly");
       currinf = oldinfo;
       if (!currinf.virtual)
           dvi_pointer_frame = &currinf;
       maxchar = oldmaxchar;
#ifdef TEXXET
    }
    if (cmd == PUT1 || (resource.omega && cmd == PUT2))
       DVI_H = dvi_h_sav;
    else if (currinf.dir > 0)
       DVI_H += m->dvi_adv;
    return;
#else
    return m->dvi_adv;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    volatile off_t pos_save = 0;
    struct drawinf currinf_save;
    ubyte maxchar_save;
    struct scan_info info;
    struct geom_info g_info;
    
    TRACE_CLIENT((stderr, "Entering source_forward_search(%s)", str));

    max_offset = 0;
    src_file = str;
    while (*src_file == '0')
       ++src_file;
    if (*src_file < '1' || *src_file > '9') {
       XDVI_WARNING((stderr, "Ignoring malformed source special \"%s\"", str));
       return;
    }
    src_line = atoi(src_file);
    while (*src_file >= '0' && *src_file <= '9')
       ++src_file;

    src_col = 0;
    if (*src_file == ':') {
       ++src_file;
       src_col = atoi(src_file);
       while (*src_file >= '0' && *src_file <= '9')
           ++src_file;
    }

    if (*src_file == ' ')
       ++src_file;

    TRACE_CLIENT((stderr, "File = \"%s\", line = %d, col = %d", src_file, src_line, src_col));

    /* Save status of dvi_file reading (in case we hit an error and resume
       drawing).  */

    if (dvi_pointer_frame != NULL)
       pos_save = lseek(fileno(globals.dvi_file.bak_fp), 0L, SEEK_CUR) - (dvi_pointer_frame->end - dvi_pointer_frame->pos);
    (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(0), SEEK_SET);

    currinf_save = currinf;
    maxchar_save = maxchar;

    memset((char *)&currinf.data, '\0', sizeof currinf.data);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;

    /* Start search over pages */
#if 0
    rdtscl(time_start);
#endif

    found_src = False;
    best_distance = best_col_dist = ULONG_MAX;
    src_this_line = 0;      /* initialize things that are kept as defaults */
    src_this_file_equal = False;

    /* These two lines do the actual scanning (first pass).  */
    for (src_page = 0; src_page < total_pages; ++src_page)
       (void)spcl_scan(src_scan_special, NULL, False, globals.dvi_file.bak_fp);

    if (best_distance == ULONG_MAX) {
       if (!found_src) {
           popup_message(globals.widgets.top_level,
                       MSG_WARN,
                       /* helptext */
                       reverse_search_helptext,
                       /* popup */
                       "No source specials in this DVI file - couldn't do reverse search.");
       }
       else {
           popup_message(globals.widgets.top_level,
                       MSG_WARN,
                       /* helptext */
                       "To enable reverse search, the TeX file has to be compiled with source specials. "
                       "See the xdvi man page (section SOURCE SPECIALS) for details.",
                       /* popup */
                       "No references to source file \"%s\" in DVI file.",
                       src_file);
       }

       /* Restore file position.  */
       maxchar = maxchar_save;
       currinf = currinf_save;

       if (dvi_pointer_frame != NULL) {
           (void)lseek(fileno(globals.dvi_file.bak_fp), pos_save, SEEK_SET);
           dvi_pointer_frame->pos = dvi_pointer_frame->end = dvi_buffer;
       }

       return;
    }
    TRACE_CLIENT((stderr, "Match:  line %d on page %d, offset %lu",
                best_line, best_page + globals.pageno_correct, (unsigned long)best_offset));

    /*
     * In this case we don't need to restore maxchar and currinf, since
     * we won't resume drawing -- we'll jump to a new page instead.
     */

    /* Move to that page.  */
    goto_page(best_page, resource.keep_flag ? NULL : home, False);
    page_history_insert(best_page);
    globals.ev.flags |= EV_NEWPAGE; /* so that existing mark gets erased */
    /* Now search that particular page.  */

    info.geom_special = src_spec_fwd_special;

    g_info.geom_box = src_spec_fwd_box;
    g_info.geom_data = NULL;

    src_fwd_active = False;
    bbox_info_idx = 0;

    g_bbox_info[bbox_info_idx].min_x =
       g_bbox_info[bbox_info_idx].min_y =
       g_bbox_info[bbox_info_idx].spcl_min_x =
       g_bbox_info[bbox_info_idx].spcl_min_y = LONG_MAX;
    g_bbox_info[bbox_info_idx].max_x =
       g_bbox_info[bbox_info_idx].max_y =
       g_bbox_info[bbox_info_idx].spcl_max_x =
       g_bbox_info[bbox_info_idx].spcl_max_y = 0;
    globals.src.fwd_box_page = -1; /* in case of error, suppress box */

    (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(best_page), SEEK_SET);
    currinf.tn_table_len = TNTABLELEN;
    currinf.tn_table = tn_table;
    currinf.tn_head = tn_head;
    currinf.pos = currinf.end = dvi_buffer;
    currinf.virtual = NULL;

    info.data = &g_info;
    
    if (!setjmp(info.done_env))
       geom_scan_part(geom_do_char, globals.dvi_file.bak_fp, &info, geom_current_frame = &geom_frame0, dimconv);

    if (!src_fwd_active) {
       XDVI_ERROR((stderr, "%s:%d: shouldn't happen: geom_scan_part() failed to re-find the special.", __FILE__, __LINE__));
    }
    else {
       long x_min = g_bbox_info[bbox_info_idx].min_x;
       long y_min = g_bbox_info[bbox_info_idx].min_y;
       long x_max = g_bbox_info[bbox_info_idx].max_x;
       long y_max = g_bbox_info[bbox_info_idx].max_y;
       do_autoscroll = True;
       globals.src.fwd_box_page = current_page;
       if (x_min == LONG_MAX || x_max == LONG_MAX) {
           /* If no glyphs or rules, use hot point of special instead.  */
           x_min = g_bbox_info[bbox_info_idx].spcl_min_x;
           y_min = g_bbox_info[bbox_info_idx].spcl_min_y;
           x_max = g_bbox_info[bbox_info_idx].spcl_max_x;
           y_max = g_bbox_info[bbox_info_idx].spcl_max_y;
       }
       scroll_page_if_needed((int)(x_min / currwin.shrinkfactor) + 2, (int)(x_max / currwin.shrinkfactor) - 2,
                           (int)(y_min / currwin.shrinkfactor) + 10, (int)(y_max / currwin.shrinkfactor) - 10);
    }
#if 0
    rdtscl(time_end);
    printf("time search: %lu\n", time_end - time_start);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    struct scan_info info;
    struct geom_info g_info;
    struct src_spec_data data;
    struct src_parsed_special *foundp;
    
    info.geom_special = src_spec_special;

    g_info.geom_box = src_spec_box;
    g_info.geom_data = &data;

    info.data = &g_info;
    
    data.x = x;
    data.y = y;
    data.distance = 0xffffffff;
    data.recent_in_best = True;
    data.best.filename_len = data.recent.filename_len = 0;
    foundp = &data.best;

    geom_scan(geom_do_char, globals.dvi_file.bak_fp, &info, current_page);

    if (data.best.filename_len == 0) {
       /*
        * nothing found on current page;
        * scan next and previous pages with increasing offset
        */
       volatile int upper, lower;
       volatile off_t pos_save;
       struct drawinf currinf_save;
       ubyte maxchar_save;

       /* Save file position */
       pos_save = save_file_status(globals.dvi_file.bak_fp, &currinf_save, &maxchar_save);
       
       upper = lower = current_page;
       found.filename_len = 0;     /* mark it as empty */
       for (;;) {
           if (++upper < total_pages) {
              (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(upper), SEEK_SET);
              memset((char *)&currinf.data, '\0', sizeof currinf.data);
              currinf.tn_table_len = TNTABLELEN;
              currinf.tn_table = tn_table;
              currinf.tn_head = tn_head;
              currinf.pos = currinf.end = dvi_buffer;
              currinf.virtual = NULL;

              if (spcl_scan(scan_first_src_spcl, NULL, True, globals.dvi_file.bak_fp)) {
                  lower = upper;
                  break;
              }
           }
           else if (lower < 0)
              break;

           if (--lower >= 0) {
              (void)lseek(fileno(globals.dvi_file.bak_fp), pageinfo_get_offset(lower), SEEK_SET);

              memset((char *)&currinf.data, '\0', sizeof currinf.data);
              currinf.tn_table_len = TNTABLELEN;
              currinf.tn_table = tn_table;
              currinf.tn_head = tn_head;
              currinf.pos = currinf.end = dvi_buffer;
              currinf.virtual = NULL;

              (void)spcl_scan(scan_last_src_spcl, NULL, False, globals.dvi_file.bak_fp);
              if (found.filename_len != 0)
                  break;
           }
       }

       if (found.filename_len != 0)
           statusline_print(STATUS_MEDIUM,
                          "No source specials on this page - nearest on page %d",
                          lower + globals.pageno_correct);
       else {
           /* nothing found at all; complain */
           XBell(DISP, 0);
           popup_message(globals.widgets.top_level,
                       MSG_ERR,
                       /* helptext */
                       reverse_search_helptext,
                       /* popup */
                       "No source specials in this DVI file - couldn't do reverse search.");
       }

       /* Restore file status.  */
       restore_file_status(globals.dvi_file.bak_fp, currinf_save, maxchar_save, pos_save);

       foundp = &found;
    }

    if (data.recent.filename_len != 0)
       free(data.recent.filename);

    if (foundp->filename_len != 0) {
       if (call_editor) {
           src_spawn_editor(foundp);
       }
       else {
           statusline_print(STATUS_MEDIUM, "nearest special at (%d,%d): \"%s:%d\"",
                          x / currwin.shrinkfactor, y / currwin.shrinkfactor, foundp->filename, foundp->line);
       }
       free(foundp->filename);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

{
    struct scan_info info;
    struct geom_info g_info;
    struct src_spec_show_data src_data;

    info.geom_special = src_spec_show_special;

    g_info.geom_box = src_spec_show_box;
    g_info.geom_data = &src_data;

    info.data = &g_info;
    
    src_data.do_this_one = src_data.do_them_all = do_them_all;

    geom_scan(geom_do_char, globals.dvi_file.bak_fp, &info, current_page);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Boolean spcl_scan ( Boolean(*)(char *str, int str_len, void *data spcl_proc,
void data,
Boolean  return_if_found,
FILE fp 
)

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

{
    ubyte ch;
    ubyte n;
    long a;

    for (;;) {
       ch = xone(fp);
/*     print_dvi(ch); */
       n = scantable[ch];
       if (n < MM)
           while (n-- != 0)
              (void)xone(fp);
       else if (n == M1)
           break;    /* end of page */
       else
           switch (n) {
           case M2:  /* special */
              a = xnum(fp, ch - XXX1 + 1);
              if (a > 0) {
                  if (spcl_proc(read_special(fp, a), a, data) && return_if_found) {
                     return True;
                  }
              }
              break;
           case M3:  /* FNTDEF */
              xskip(fp, (long)(12 + ch - FNTDEF1 + 1));
              ch = xone(fp);
              xskip(fp, (long)ch + (long)xone(fp));
              break;
           case M4:  /* unrecognizable */
              XDVI_FATAL((stderr, "unknown op-code %d", ch));
              break;
           case M5:  /* doesn't belong */
              dvi_fmt_error("spcl_scan: shouldn't happen: %s encountered",
                           dvi_table2[ch - (FNTNUM0 + 64)]);
              break;
           }
    }
    return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void src_parse ( const char *  str,
int  str_len,
struct src_parsed_special parsed 
)

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

{
    const char *p = str;

    if (*p >= '0' && *p <= '9') {
       parsed->line = atoi(p);
       do {
           ++p;
           str_len--;
       }
       while (*p >= '0' && *p <= '9');
    }

    parsed->col = 0;
    if (*p == ':') {
       ++p;
       str_len--;
       parsed->col = atoi(p);
       while (*p >= '0' && *p <= '9') {
           ++p;
           str_len--;
       }
    }

    if (*p == ' ') {
       ++p;
       str_len--;
    }

    if (*p != '\0') {
       size_t len = str_len + 1;

       if (len > parsed->filename_len) {
           if (parsed->filename_len != 0)
              free(parsed->filename);
           parsed->filename_len = (len & -8) + 64; /* rounding? */
           parsed->filename = xmalloc(parsed->filename_len);
       }
       memcpy(parsed->filename, p, len);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

long text_do_char ( FILE fp,
struct scan_info info,
wide_ubyte  ch 
)

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

{
    if (currinf.set_char_p == set_no_char) {
       if (currinf.virtual == NULL
           || (currinf.fontp = currinf.virtual->first_font) == NULL)
           return 0; /* error; we'll catch it later */
       maxchar = currinf.fontp->maxchar;
       currinf.set_char_p = currinf.fontp->set_char_p;
    }

    if (currinf.set_char_p == set_empty_char)
       return 0;     /* error; we'll catch it later */

    if (currinf.set_char_p == load_n_set_char) {
       if (globals.ev.flags & EV_GE_NEWDOC)      /* if abort */
           return 0;
       if (!load_font(currinf.fontp, resource.t1lib)) { /* if not found */
           if (globals.ev.flags & EV_GE_NEWDOC)  /* if abort */
              return 0;

           /* FIXME: replace by GUI warning! */
           fputs("geom_do_char: Character(s) will be left blank.\n", stderr);
           currinf.set_char_p = currinf.fontp->set_char_p = set_empty_char;
           return 0;
       }
       maxchar = currinf.fontp->maxchar;
       currinf.set_char_p = currinf.fontp->set_char_p;
    }

    if (currinf.set_char_p == set_char) {
       struct glyph *g;
       long x, y;

       if (ch > maxchar)
           return 0; /* catch the error later */
       if ((g = &currinf.fontp->glyph[ch])->bitmap.bits == NULL) {
           if (g->addr == 0)
              return 0;     /* catch the error later */
           if (g->addr == -1)
              return 0;     /* previously flagged missing char */
           open_font_file(currinf.fontp);
           fseek(currinf.fontp->file, g->addr, SEEK_SET);
           (*currinf.fontp->read_char) (currinf.fontp, ch);
           if (globals.debug & DBG_BITMAP)
              print_char((ubyte) ch, g);
           currinf.fontp->timestamp = ++current_timestamp;
       }
#ifdef TEXXET
       if (geom_scan_frame == NULL) {
           long dvi_h_sav = DVI_H;
           if (currinf.dir < 0)
              DVI_H -= g->dvi_adv;
#endif
           x = G_PXL_H - g->x;
           y = PXL_V - g->y;
           do_char(ch, currinf, info, PXL_V, y, x, x + g->bitmap.w - 1, g);
#ifdef TEXXET
           DVI_H = dvi_h_sav;
       }
#endif
       return DIR * g->dvi_adv;
    }
    else if (currinf.set_char_p == set_vf_char) {
       struct macro *m;
       struct drawinf oldinfo;
       ubyte oldmaxchar;
#ifdef TEXXET
       long dvi_h_sav;
#endif

       if (ch > maxchar)
           return 0; /* catch the error later */
       if ((m = &currinf.fontp->macro[ch])->pos == NULL)
           return 0; /* catch the error later */
#ifdef TEXXET
       dvi_h_sav = DVI_H;
       if (currinf.dir < 0)
           DVI_H -= m->dvi_adv;
       if (geom_scan_frame == NULL) {
#endif
           oldinfo = currinf;
           oldmaxchar = maxchar;
           WW = XX = YY = ZZ = 0;
           currinf.tn_table_len = VFTABLELEN;
           currinf.tn_table = currinf.fontp->vf_table;
           currinf.tn_head = currinf.fontp->vf_chain;
           currinf.pos = m->pos;
           currinf.end = m->end;
           currinf.virtual = currinf.fontp;
           geom_scan_part(text_do_char, fp, info, geom_current_frame, currinf.fontp->dimconv);
           currinf = oldinfo;
           maxchar = oldmaxchar;
#ifdef TEXXET
           DVI_H = dvi_h_sav;
       }
#endif
       return DIR * m->dvi_adv;
    }
#ifdef T1LIB
    else if (currinf.set_char_p == set_t1_char) {
       struct glyph *g ;
       long x, y;
       t1FontLoadStatusT status;

#ifdef TEXXET
       g = get_t1_glyph(0, ch, &status, True);
       if (status == FAILURE_BLANK)
           return 0;
       if (geom_scan_frame == NULL) {
           long dvi_h_sav = DVI_H;
           if (currinf.dir < 0)
              DVI_H -= g->dvi_adv;
           x = G_PXL_H - g->x;
           y = PXL_V - g->y;
           do_char(ch, currinf, info, PXL_V, y, x, x + g->bitmap.w - 1, g);
           DVI_H = dvi_h_sav;
       }
#else
       g = get_t1_glyph(ch, &status, True);
       if (status == FAILURE_BLANK)
           return 0;
       x = G_PXL_H - g->x;
       y = PXL_V - g->y;
       do_char(ch, currinf, info, PXL_V, y, x, x + g->bitmap.w - 1, g);
#endif
       return DIR * g->dvi_adv;
    }
#endif /* T1LIB */
    else {
       XDVI_FATAL((stderr, "currinf.set_char_p not a registered routine!"));
    }
    /* NOTREACHED */
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function: