/* 
 * DviP.h - Private definitions for Dvi widget
 */

#ifndef _XtDviP_h
#define _XtDviP_h

#ifdef USE_XFT
#include <X11/Xft/Xft.h>
#endif

#include "Dvi.h"
#include <X11/Xaw/SimpleP.h>
#include "DviChar.h"

/***********************************************************************
 *
 * Dvi Widget Private Data
 *
 ***********************************************************************/

/************************************
 *
 *  Class structure
 *
 ***********************************/

/*
 * New fields for the Dvi widget class record
 */

typedef struct _DviClass {
    int makes_compiler_happy;   /* not used */
} DviClassPart;

/*
 * Full class record declaration
 */

typedef struct _DviClassRec {
    CoreClassPart core_class;
    SimpleClassPart simple_class;
    DviClassPart command_class;
} DviClassRec;

extern DviClassRec dviClassRec;

/***************************************
 *
 *  Instance (widget) structure 
 *
 **************************************/

/*
 * a list of fonts we've used for this widget
 */

typedef struct _dviFontSizeList {
    struct _dviFontSizeList *next;
    int size;
    char *x_name;
#ifdef USE_XFT
    XftFont *font;
    Bool core;
#else
    XFontStruct *font;
#endif
    int doesnt_exist;
} DviFontSizeList;

typedef struct _dviFontList {
    struct _dviFontList *next;
    char *dvi_name;
    char *x_name;
    int dvi_number;
    Boolean initialized;
    Boolean scalable;
    DviFontSizeList *sizes;
    DviCharNameMap *char_map;
} DviFontList;

typedef struct _dviFontMap {
    struct _dviFontMap *next;
    char *dvi_name;
    char *x_name;
} DviFontMap;

#define DVI_TEXT_CACHE_SIZE	256
#define DVI_CHAR_CACHE_SIZE	1024

#ifdef USE_XFT
typedef struct _dviTextItem {
    char *chars;
    int nchars;
    int x;
    XftFont *font;
} DviTextItem;
#endif

typedef struct _dviCharCache {
#ifdef USE_XFT
    DviTextItem cache[DVI_TEXT_CACHE_SIZE];
#else
    XTextItem cache[DVI_TEXT_CACHE_SIZE];
#endif
    char char_cache[DVI_CHAR_CACHE_SIZE];
    int index;
    int max;
    int char_index;
    int font_size;
    int font_number;
#ifdef USE_XFT
    XftFont *font;
#else
    XFontStruct *font;
#endif
    int start_x, start_y;
    int x, y;
} DviCharCache;

typedef struct _dviState {
    struct _dviState *next;
    int font_size;
    int font_bound;
    int font_number;
    int line_style;
    int line_width;
    int x;
    int y;
} DviState;

typedef struct _dviFileMap {
    struct _dviFileMap *next;
    long position;
    int page_number;
} DviFileMap;

/*
 * New fields for the Dvi widget record
 */

typedef struct {
    /*
     * resource specifiable items
     */
    char *font_map_string;
    unsigned long foreground;
    int requested_page;
    int last_page;
    FILE *file;
    Boolean seek;               /* file is "seekable" */
#ifdef USE_XFT
    XftFont *default_font;
#else
    XFontStruct *default_font;
#endif
    int backing_store;
    Boolean noPolyText;
    int screen_resolution;
    float page_width;
    float page_height;
    int size_scale_set;
    /*
     * private state
     */
    FILE *tmpFile;              /* used when reading stdin */
    char readingTmp;            /* reading now from tmp */
    char ungot;                 /* have ungetc'd a char */
    GC normal_GC;
#ifdef USE_XFT
    XftDraw *draw;
    XftColor black;
#endif
    DviFileMap *file_map;
    DviFontList *fonts;
    DviFontMap *font_map;
    int current_page;
    int font_size;
    int font_number;
    int device_resolution;
    int line_width;
    int line_style;
    int desired_width;
    int desired_height;
    int size_scale;             /* font size scale */
#ifdef USE_XFT
    XftFont *font;
#else
    XFontStruct *font;
#endif
    int display_enable;
    double scale;               /* device coordinates to pixels */
    struct ExposedExtents {
        int x1, y1, x2, y2;
    } extents;
    DviState *state;
    DviCharCache cache;
} DviPart;

extern int DviGetAndPut(DviWidget, int *);

#define DviGetIn(dw,cp)\
    (dw->dvi.tmpFile ? (\
	DviGetAndPut (dw, cp) \
    ) :\
	(*cp = getc (dw->dvi.file))\
)

#define DviGetC(dw, cp)\
    (dw->dvi.readingTmp ? (\
	((*cp = getc (dw->dvi.tmpFile)) == EOF) ? (\
	    fseek (dw->dvi.tmpFile, 0l, SEEK_END),\
	    (dw->dvi.readingTmp = 0),\
	    DviGetIn (dw,cp)\
	) : (\
	    *cp\
	)\
    ) : (\
	DviGetIn(dw,cp)\
    )\
)

#define DviUngetC(dw, c)\
    (dw->dvi.readingTmp ? (\
	ungetc (c, dw->dvi.tmpFile)\
    ) : ( \
	(dw->dvi.ungot = 1),\
	ungetc (c, dw->dvi.file)))

#define ToX(dw,device)		    ((int) ((device) * (dw)->dvi.scale + 0.5))
#define ToDevice(dw,x)		    ((int) ((x) / (dw)->dvi.scale + 0.5))
#define SizeScale(dw)		    ((dw)->dvi.size_scale ? (dw)->dvi.size_scale : 4)
#define FontSizeInPixels(dw,size)   ((int) ((size) * (dw)->dvi.screen_resolution / (SizeScale(dw) * 72)))
#define FontSizeInDevice(dw,size)   ((int) ((size) * (dw)->dvi.device_resolution / (SizeScale(dw) * 72)))

/*
 * Full widget declaration
 */

typedef struct _DviRec {
    CorePart core;
    SimplePart simple;
    DviPart dvi;
} DviRec;

/* previously in draw.c */
static inline void
HorizontalMove(DviWidget dw, int delta)
{
    dw->dvi.state->x += delta;
}

static inline void
HorizontalGoto(DviWidget dw, int NewPosition)
{
    dw->dvi.state->x = NewPosition;
}

static inline void
VerticalMove(DviWidget dw, int delta)
{
    dw->dvi.state->y += delta;
}

static inline void
VerticalGoto(DviWidget dw, int NewPosition)
{
    dw->dvi.state->y = NewPosition;
}

/* draw.c */
extern void FlushCharCache(DviWidget);
extern void SetGCForDraw(DviWidget);
extern void DrawLine(DviWidget, int, int);
extern void DrawCircle(DviWidget, int);
extern void DrawEllipse(DviWidget, int, int);
extern void DrawArc(DviWidget, int, int, int, int);
extern void DrawSpline(DviWidget, const char *, int);

/* font.c */
extern void ParseFontMap(DviWidget);
extern void DestroyFontMap(DviFontMap *);
extern void SetFontPosition(DviWidget, int, const char *, const char *);

#ifdef USE_XFT
extern XftFont *QueryFont(DviWidget, int, int);
#else
extern XFontStruct *QueryFont(DviWidget, int, int);
#endif
extern DviCharNameMap *QueryFontMap(DviWidget, int);

/* lex.c */
extern char *GetLine(DviWidget, char *, int);
extern char *GetWord(DviWidget, char *, int);
extern int GetNumber(DviWidget);

/* page.c */
extern void DestroyFileMap(DviFileMap *);
extern void ForgetPagePositions(DviWidget);
extern void RememberPagePosition(DviWidget, int);
extern long SearchPagePosition(DviWidget, int);
extern void FileSeek(DviWidget, long);

/* parse.c */
extern int ParseInput(DviWidget);

/* Dvi.c */
extern void SetDeviceResolution(DviWidget, int);

#endif                          /* _XtDviP_h */
