home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1990, 1991 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gsstate.c */
- /* Miscellaneous graphics state operators for Ghostscript library */
- #include "gx.h"
- #include "memory_.h"
- #include "gserrors.h"
- #include "gxfixed.h"
- #include "gxmatrix.h" /* for gzstate */
- #include "gzstate.h"
- #include "gzdevice.h"
- #include "gzcolor.h" /* requires gxdevice.h */
- #include "gzht.h"
- #include "gzline.h"
- #include "gzpath.h"
-
- /* Size of graphics state object (so clients can copy the top level) */
- const uint gs_state_sizeof = sizeof(gs_state);
-
- /* Forward references */
- private int alloc_state_contents(P2(gs_state *, proc_alloc_t));
- private void free_state_contents(P1(gs_state *));
-
- /* Allocate and initialize a graphics state. */
- private float
- null_transfer(floatp gray)
- { return gray;
- }
- gs_state *
- gs_state_alloc(proc_alloc_t palloc, proc_free_t pfree)
- { register gs_state *pgs = (gs_state *)(*palloc)(1, sizeof(gs_state), "gs_state_alloc");
- if ( pgs == 0 ) return 0;
- if ( alloc_state_contents(pgs, palloc) < 0 ) return 0;
- pgs->saved = 0;
- pgs->memory_procs.alloc = palloc;
- pgs->memory_procs.free = pfree;
- /* Initialize things not covered by initgraphics */
- pgs->path->first_subpath = 0;
- pgs->clip_path->first_subpath = 0;
- pgs->halftone->width = pgs->halftone->height =
- pgs->halftone->order_size = 0;
- gs_sethalftonephase(pgs, 0, 0);
- /* Initialize the color so that gx_remap_color won't crash. */
- gx_set_gray_only(pgs->color, 0.0);
- /* Initialize the transfer functions ditto. */
- gx_set_transfer_only(pgs, null_transfer);
- gs_nulldevice(pgs);
- gs_setflat(pgs, 1.0);
- /****** What about the font ? ******/
- pgs->in_cachedevice = pgs->in_charpath = 0;
- pgs->level = 0;
- if ( gs_initgraphics(pgs) < 0 )
- { /* Something went very wrong */
- return 0;
- }
- return pgs;
- }
-
- /* Free a graphics state */
- int
- gs_state_free(gs_state *pgs)
- { free_state_contents(pgs);
- (*pgs->memory_procs.free)((char *)pgs, 1, sizeof(gs_state), "gs_state_free");
- return 0;
- }
-
- /* Save the graphics state */
- int
- gs_gsave(gs_state *pgs)
- { gs_state *pnew = (gs_state *)(*pgs->memory_procs.alloc)(1, sizeof(gs_state), "gs_gsave");
- if ( pnew == 0 )
- return_error(gs_error_VMerror);
- *pnew = *pgs;
- if ( alloc_state_contents(pgs, pgs->memory_procs.alloc) < 0 )
- return_error(gs_error_VMerror);
- #define gcopy(element,type)\
- *pgs->element = *pnew->element
- gcopy(path, gx_path);
- gcopy(clip_path, gx_path);
- gcopy(line_params, line_params);
- gcopy(halftone, halftone);
- gcopy(color, gs_color);
- gcopy(dev_color, gx_device_color);
- gcopy(device, device);
- #undef gcopy
- gx_path_share(pgs->path);
- gx_path_share(pgs->clip_path);
- pgs->saved = pnew;
- pgs->level++;
- return 0;
- }
-
- /* Restore the graphics state. */
- int
- gs_grestore(gs_state *pgs)
- { gs_state *saved = pgs->saved;
- if ( !saved ) return gs_gsave(pgs); /* shouldn't happen */
- free_state_contents(pgs);
- *pgs = *saved;
- (*pgs->memory_procs.free)((char *)saved, 1, sizeof(gs_state), "gs_grestore");
- return (pgs->saved == 0 ? gs_gsave(pgs) : 0);
- }
-
- /* Restore to the bottommost graphics state. */
- int
- gs_grestoreall(gs_state *pgs)
- { if ( !pgs->saved ) return gs_gsave(pgs); /* shouldn't happen */
- while ( pgs->saved->saved ) gs_grestore(pgs);
- return gs_grestore(pgs);
- }
-
- /* Swap the saved pointer of the graphics state. */
- /* This is provided only for save/restore. */
- gs_state *
- gs_state_swap_saved(gs_state *pgs, gs_state *new_saved)
- { gs_state *saved = pgs->saved;
- pgs->saved = new_saved;
- return saved;
- }
-
- /* Swap the contents of two graphics states, except for the saved pointer. */
- /* This is provided only for save/restore. */
- void
- gs_state_swap(gs_state *p1, gs_state *p2)
- { gs_state temp;
- temp = *p1, *p1 = *p2, *p2 = temp;
- /* Restore the saved pointers. */
- p2->saved = p1->saved;
- p1->saved = temp.saved;
- }
-
- /* Reset most of the graphics state */
- int
- gs_initgraphics(register gs_state *pgs)
- { int code;
- gs_initmatrix(pgs);
- if ( (code = gs_newpath(pgs)) < 0 ||
- (code = gs_initclip(pgs)) < 0 ||
- (code = gs_setlinewidth(pgs, 1.0)) < 0 ||
- (code = gs_setlinecap(pgs, gs_cap_butt)) < 0 ||
- (code = gs_setlinejoin(pgs, gs_join_miter)) < 0 ||
- (code = gs_setdash(pgs, (float *)0, 0, 0.0)) < 0 ||
- (code = gs_setgray(pgs, 0.0)) < 0 ||
- (code = gs_setmiterlimit(pgs, 10.0)) < 0
- ) return code;
- return 0;
- }
-
- /* setflat */
- int
- gs_setflat(gs_state *pgs, floatp flat)
- { if ( flat <= 0.2 ) flat = 0.2;
- else if ( flat > 100 ) flat = 100;
- pgs->flatness = flat;
- return 0;
- }
-
- /* currentflat */
- float
- gs_currentflat(gs_state *pgs)
- { return pgs->flatness;
- }
-
- /* ------ Internal routines ------ */
-
- /* Allocate the contents of a graphics state object. */
- /* Return -1 if the allocation fails. */
- private int
- alloc_state_contents(gs_state *pgs, proc_alloc_t palloc)
- { char *elt;
- static char *cname = "(gs)alloc_state_contents";
- #define galloc(element,type)\
- if ( (elt = (*palloc)(1, sizeof(type), cname)) == 0 ) return -1;\
- pgs->element = (type *)elt
- galloc(path, gx_path);
- galloc(clip_path, gx_path);
- galloc(line_params, line_params);
- galloc(halftone, halftone);
- galloc(color, gs_color);
- galloc(dev_color, gx_device_color);
- galloc(device, device);
- #undef galloc
- pgs->device_is_shared = 0;
- return 0;
- }
-
- /* Free the contents of a graphics state, but not the state itself. */
- private void
- free_state_contents(gs_state *pgs)
- { proc_free_t pfree = pgs->memory_procs.free;
- static char *cname = "(gs)free_state_contents";
- gx_path_release(pgs->clip_path);
- gx_path_release(pgs->path);
- #define gfree(element,type)\
- (*pfree)((char *)pgs->element, 1, sizeof(type), cname)
- if ( !pgs->device_is_shared )
- gfree(device, device);
- gfree(dev_color, gx_device_color);
- gfree(color, gs_color);
- gfree(halftone, halftone);
- gfree(line_params, line_params);
- gfree(clip_path, gx_path);
- gfree(path, gx_path);
- #undef gfree
- }
-