]> www.fi.muni.cz Git - evince.git/blobdiff - dvi/mdvi-lib/dviread.c
Allow the user to override document restrictions. Fix for bug 305818.
[evince.git] / dvi / mdvi-lib / dviread.c
index e2ca6c73e602d3085b7fe16fca1b1bfa401fec31..8398c2702085521fa98195e239a19b83dac23485 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "mdvi.h"
 #include "private.h"
+#include "color.h"
 
 typedef int (*DviCommand) __PROTO((DviContext *, int));
 
@@ -211,7 +212,7 @@ static int get_bytes(DviContext *dvi, size_t n)
                if(dvi->buffer.data == NULL) {
                        /* first allocation */
                        dvi->buffer.size = Max(DVI_BUFLEN, n);
-                       dvi->buffer.data = (Uchar *)xmalloc(dvi->buffer.size);
+                       dvi->buffer.data = (Uchar *)mdvi_malloc(dvi->buffer.size);
                        dvi->buffer.length = 0;
                        dvi->buffer.frozen = 0;
                } else if(dvi->buffer.pos < dvi->buffer.length) {
@@ -298,7 +299,7 @@ static long dtell(DviContext *dvi)
 static void dreset(DviContext *dvi)
 {
        if(!dvi->buffer.frozen && dvi->buffer.data)
-               xfree(dvi->buffer.data);
+               mdvi_free(dvi->buffer.data);
        dvi->buffer.data = NULL;
        dvi->buffer.size = 0;
        dvi->buffer.length = 0;
@@ -417,7 +418,7 @@ static DviFontRef *define_font(DviContext *dvi, int op)
        hdpi = FROUND(dvi->params.mag * dvi->params.dpi * scale / dsize);
        vdpi = FROUND(dvi->params.mag * dvi->params.vdpi * scale / dsize);
        n = duget1(dvi) + duget1(dvi);
-       name = xmalloc(n + 1);
+       name = mdvi_malloc(n + 1);
        dread(dvi, name, n);
        name[n] = 0;
        DEBUG((DBG_FONTS, "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n",
@@ -426,10 +427,10 @@ static DviFontRef *define_font(DviContext *dvi, int op)
        ref = font_reference(&dvi->params, arg, name, checksum, hdpi, vdpi, scale);
        if(ref == NULL) {
                error(_("could not load font `%s'\n"), name);
-               xfree(name);
+               mdvi_free(name);
                return NULL;
        }
-       xfree(name);
+       mdvi_free(name);
        return ref;
 }
 
@@ -443,11 +444,11 @@ static char *opendvi(const char *name)
        if(len >= 4 && STREQ(name+len-4, ".dvi")) {
                DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", name));
                if(access(name, R_OK) == 0)
-                       return xstrdup(name);
+                       return mdvi_strdup(name);
        }
                
        /* try appending .dvi */
-       file = xmalloc(len + 5);
+       file = mdvi_malloc(len + 5);
        strcpy(file, name);
        strcpy(file+len, ".dvi");
        DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file));
@@ -458,7 +459,7 @@ static char *opendvi(const char *name)
        DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file));
        if(access(file, R_OK) == 0)
                return file;
-       xfree(file);
+       mdvi_free(file);
        return NULL;
 }
 
@@ -487,7 +488,7 @@ int mdvi_reload(DviContext *dvi, DviParams *np)
        font_drop_chain(dvi->fonts);
        /* destroy our font map */
        if(dvi->fontmap)
-               xfree(dvi->fontmap);
+               mdvi_free(dvi->fontmap);
        dvi->currfont = NULL;
 
        /* and use the ones we just loaded */
@@ -504,27 +505,27 @@ int       mdvi_reload(DviContext *dvi, DviParams *np)
        dvi->dvivconv = newdvi->dvivconv;
        dvi->modtime = newdvi->modtime;
 
-       if(dvi->fileid) xfree(dvi->fileid);
+       if(dvi->fileid) mdvi_free(dvi->fileid);
        dvi->fileid = newdvi->fileid;
                
        dvi->dvi_page_w = newdvi->dvi_page_w;
        dvi->dvi_page_h = newdvi->dvi_page_h;
 
-       xfree(dvi->pagemap);
+       mdvi_free(dvi->pagemap);
        dvi->pagemap = newdvi->pagemap;
        dvi->npages = newdvi->npages;
        if(dvi->currpage > dvi->npages-1)
                dvi->currpage = 0;
                
-       xfree(dvi->stack);
+       mdvi_free(dvi->stack);
        dvi->stack = newdvi->stack;
        dvi->stacksize = newdvi->stacksize;
 
        /* remove fonts that are not being used anymore */
        font_free_unused(&dvi->device);
                
-       xfree(newdvi->filename);                
-       xfree(newdvi);
+       mdvi_free(newdvi->filename);            
+       mdvi_free(newdvi);
 
        DEBUG((DBG_DVI, "%s: reload successful\n", dvi->filename));
        if(dvi->device.refresh)
@@ -578,11 +579,6 @@ int mdvi_configure(DviContext *dvi, DviParamCode option, ...)
                        break;
                case MDVI_SET_GAMMA:
                        np.gamma = va_arg(ap, double);
-                       if(np.pixels) {
-                               xfree(np.pixels);
-                               np.pixels = 0;
-                               np.npixels = 0;
-                       }
                        reset_font = MDVI_FONTSEL_GREY;
                        break;
                case MDVI_SET_DENSITY:
@@ -690,7 +686,7 @@ DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *fil
        p = fopen(filename, "r");
        if(p == NULL) {
                perror(file);
-               xfree(filename);
+               mdvi_free(filename);
                return NULL;
        }
        dvi = xalloc(DviContext);
@@ -745,8 +741,6 @@ DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *fil
        dvi->params.orientation = par->orientation;
        dvi->params.fg = par->fg;
        dvi->params.bg = par->bg;
-       dvi->params.pixels = NULL;
-       dvi->params.npixels = 0;
 
        /* initialize colors */
        dvi->curr_fg = par->fg;
@@ -765,7 +759,7 @@ DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *fil
 
        /* get the comment from the preamble */
        n = fuget1(p);
-       dvi->fileid = xmalloc(n + 1);
+       dvi->fileid = mdvi_malloc(n + 1);
        fread(dvi->fileid, 1, n, p);
        dvi->fileid[n] = 0;
        DEBUG((DBG_DVI, "%s: %s\n", filename, dvi->fileid));
@@ -859,7 +853,7 @@ DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *fil
                for(i = 1; i <= 10; i++)
                        page[i] = fsget4(p);
                page[0] = offset;
-               offset = (long)fuget4(p);
+               offset = fsget4(p);
                /* check if the page is selected */
                if(spec && mdvi_page_selected(spec, page, n) == 0) {
                        DEBUG((DBG_DVI, "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n",
@@ -902,9 +896,6 @@ DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *fil
        dvi->device.set_color    = dummy_dev_set_color;
        dvi->device.device_data  = NULL;
 
-       /* initialize associations */
-       mdvi_hash_init(&dvi->assoc);
-
        DEBUG((DBG_DVI, "%s read successfully\n", filename));
        return dvi;
 
@@ -927,24 +918,23 @@ void      mdvi_destroy_context(DviContext *dvi)
                font_free_unused(&dvi->device);
        }
        if(dvi->fontmap)
-               xfree(dvi->fontmap);
+               mdvi_free(dvi->fontmap);
        if(dvi->filename)
-               xfree(dvi->filename);
+               mdvi_free(dvi->filename);
        if(dvi->stack)
-               xfree(dvi->stack);
+               mdvi_free(dvi->stack);
        if(dvi->pagemap)
-               xfree(dvi->pagemap);
+               mdvi_free(dvi->pagemap);
        if(dvi->fileid)
-               xfree(dvi->fileid);
+               mdvi_free(dvi->fileid);
        if(dvi->in)
                fclose(dvi->in);
        if(dvi->buffer.data && !dvi->buffer.frozen)
-               xfree(dvi->buffer.data);
+               mdvi_free(dvi->buffer.data);
        if(dvi->color_stack)
-               xfree(dvi->color_stack);
-       mdvi_assoc_flush(dvi);
+               mdvi_free(dvi->color_stack);
        
-       xfree(dvi);
+       mdvi_free(dvi);
 }
 
 void   mdvi_setpage(DviContext *dvi, int pageno)
@@ -1059,7 +1049,7 @@ again:
        dvi->curr_layer = 0;
        
        if(dvi->buffer.data && !dvi->buffer.frozen)
-               xfree(dvi->buffer.data);
+               mdvi_free(dvi->buffer.data);
 
        /* reset our buffer */
        dvi->buffer.data   = NULL;
@@ -1175,6 +1165,50 @@ static void inline fix_after_horizontal(DviContext *dvi)
        (a), (b) > 0 ? '+' : '-', \
        (b) > 0 ? (b) : -(b), (c)
 
+/*
+ * Draw rules with some sort of antialias support. Usefult for high-rate
+ * scale factors.
+ */ 
+
+static void draw_shrink_rule (DviContext *dvi, int x, int y, Uint w, Uint h, int f)
+{              
+       int hs, vs, npixels;
+       Ulong fg, bg;
+       Ulong *pixels;
+       
+       hs = dvi->params.hshrink;
+       vs = dvi->params.vshrink;
+       fg = dvi->params.fg;
+       bg = dvi->params.bg;
+
+       if (MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) {
+               npixels = vs * hs + 1;
+               pixels = get_color_table(&dvi->device, npixels, bg, fg,
+                                        dvi->params.gamma, dvi->params.density);
+       
+               if (pixels) {
+                   int color;
+                   
+                   /*  Lines with width 1 should be perfectly visible
+                    *  in shrink about 15. That is the reason of constant
+                    */
+                    
+                   color = (pow (vs / h * hs, 2) + pow (hs / w * vs, 2)) / 225;
+                   if (color < npixels) {
+                       fg = pixels[color];
+                   } else {    
+                       fg = pixels[npixels - 1];
+                   }
+               }
+        }
+
+       mdvi_push_color (dvi, fg, bg);
+       dvi->device.draw_rule(dvi, x, y, w, h, f);
+       mdvi_pop_color (dvi);
+       
+       return;
+}
+
 /* 
  * The only commands that actually draw something are:
  *   set_char, set_rule
@@ -1233,8 +1267,7 @@ static void draw_box(DviContext *dvi, DviFontChar *ch)
                break;
        }
                
-       dvi->device.draw_rule(dvi,
-               dvi->pos.hh - x, dvi->pos.vv - y, w, h, 1);
+       draw_shrink_rule(dvi, dvi->pos.hh - x, dvi->pos.vv - y, w, h, 1);
 }
 
 int    set_char(DviContext *dvi, int opcode)
@@ -1306,9 +1339,10 @@ int      set_rule(DviContext *dvi, int opcode)
                        b, a, w, h));
                /* the `draw' functions expect the origin to be at the top left
                 * corner of the rule, not the bottom left, as in DVI files */
-               if(dvi->curr_layer <= dvi->params.layer)
-                       dvi->device.draw_rule(dvi,
-                               dvi->pos.hh, dvi->pos.vv - h + 1, w, h, 1);
+               if(dvi->curr_layer <= dvi->params.layer) {
+                       draw_shrink_rule(dvi,
+                                        dvi->pos.hh, dvi->pos.vv - h + 1, w, h, 1);
+               }
        } else { 
                SHOWCMD((dvi, opcode == DVI_SET_RULE ? "setrule" : "putrule", -1,
                        "(moving left only, by %d)\n", b));
@@ -1502,13 +1536,13 @@ int     special(DviContext *dvi, int opcode)
        Int32   arg;
        
        arg = dugetn(dvi, opcode - DVI_XXX1 + 1);
-       s = xmalloc(arg + 1);
+       s = mdvi_malloc(arg + 1);
        dread(dvi, s, arg);
        s[arg] = 0;
        mdvi_do_special(dvi, s);
        SHOWCMD((dvi, "XXXX", opcode - DVI_XXX1 + 1,
                "[%s]", s));
-       xfree(s);
+       mdvi_free(s);
        return 0;
 }