xfig.3.2.5c/Imakefile0000700002656300244210000005005212010767747015201 0ustar bvsmithDomain Users#ifndef XCOMM #define XCOMM # #endif XCOMM FIG : Facility for Interactive Generation of figures XCOMM Copyright (c) 1985-1988 by Supoj Sutanthavibul XCOMM Parts Copyright (c) 1989-2007 by Brian V. Smith XCOMM Parts Copyright (c) 1991 by Paul King XCOMM XCOMM Any party obtaining a copy of these files is granted, free of charge, a XCOMM full and unrestricted irrevocable, world-wide, paid up, royalty-free, XCOMM nonexclusive right and license to deal in this software and documentation XCOMM files (the "Software"), including without limitation the rights to use, XCOMM copy, modify, merge, publish distribute, sublicense and/or sell copies of XCOMM the Software, and to permit persons who receive copies from any such XCOMM party to do so, with the only requirement being that the above copyright XCOMM and this permission notice remain intact. XCOMM ------------------------------ XCOMM IMPORTANT GENERAL NOTE: XCOMM ------------------------------ XCOMM XCOMM Anytime the Imakefile is changed, you must do either "xmkmf" or "make Makefile", XCOMM followed by "make clean" before doing a "make" or "make install" of any kind. XCOMM If you want to install xfig in a directory other than the default X11 binary XCOMM directory, uncomment the following "BINDIR" line and change the path XCOMM to the full path of the directory where you want xfig to be installed. XCOMM Also, you may have to uncomment and redefine MKDIRHIER because "make" looks XCOMM for it relative to the BINDIR variable. XCOMM XCOMM BINDIR = /usr/bin XCOMM MKDIRHIER = /bin/sh /usr/bin/X11/mkdirhier -p MKDIRHIER = mkdirhier XCOMM Uncomment and change XAPPLOADDIR to the directory where you want the XCOMM app-defaults resource files to go. You will have to use the environment XCOMM variable XAPPLRESDIR to point to this directory. XCOMM On Sun systems running Openwindows you probably need to set the environment XCOMM variable XUSERFILESEARCHPATH to point to your app-defaults directory, and XCOMM append a "%N" to the path, e.g. /users/me/xfig/app-defaults/%N XCOMM XCOMM Don't set the DESTDIR variable unless you want to install xfig in a totally XCOMM different tree than the "correct" tree that your X system expects. The usual XCOMM purpose of DESTDIR is to test an install process by installing in a benign area. XCOMM XAPPLOADDIR = /home/user/xfig XCOMM Comment out the following definition for XAW3D if you don't to want to use XCOMM the 3d Athena Widget Set #define XAW3D #ifdef XAW3D XAWLIB = -lXaw3d #endif XCOMM Uncomment the following if you have David Hawkey's Xaw3D version 1.5E which has XCOMM some new features, including "Tips", which replace xfig's "help balloons" XCOMM NOTE: This is the default for many X systems now. #define XAW3D1_5E #ifdef XAW3D1_5E DUSEXAW3D = -DXAW3D -DXAW3D1_5E #else XAW_SRC = w_menuentry.c SmeCascade.c SmeBSB.c SimpleMenu.c XAW_OBJ = w_menuentry.o SmeCascade.o SmeBSB.o SimpleMenu.o # ifdef XAW3D DUSEXAW3D = -DXAW3D # endif /* XAW3D */ #endif /* XAW3D1_5E */ XCOMM Redefine the following if your PNG library, zlib library and/or include file XCOMM are in different places PNGLIBDIR = $(USRLIBDIR) PNGINC = -I/usr/include ZLIBDIR = $(USRLIBDIR) XCOMM If don't want JPEG support, comment out the #define USEJPEG line XCOMM Uncomment the #define for USEJPEG if you want to be able to import XCOMM JPEG (Joint Photographic Experts Group) files. #define USEJPEG XCOMM If you don't have the jpeg library in your system library area (meaning XCOMM that it must be compiled first), comment out the USEINSTALLEDJPEG variable XCOMM (using XCOMM), change the JPEGLIBDIR variable to the directory where your XCOMM jpeg library resides and change the JPEGINCDIR to the directory where your XCOMM jpeg header files (include) reside. XCOMM You must have version 5b or newer of the jpeg library. #define USEINSTALLEDJPEG #ifdef USEJPEG # ifdef USEINSTALLEDJPEG JPEGLIBDIR = /usr/local/lib JPEGINC = -I/usr/include/X11 # else JPEGLIBDIR = ../jpeg JPEGINC = -I$(JPEGLIBDIR) # endif /* USEINSTALLEDJPEG */ #endif /* USEJPEG */ XCOMM Uncomment the #define for USEXPM if you want to use the XPM XCOMM (color pixmap) package. XCOMM XCOMM USEXPM will allow import/export of XPM files. XCOMM USEXPM_ICON uses a color xpm icon for xfig itself (USEXPM must be XCOMM defined if you use USEXPM_ICON) XCOMM You need XPM version 3.4c or newer. This is available from ftp.x.org XCOMM in /contrib/libraries. XCOMM Change XPMLIBDIR if necessary to point to the xpm library (libXpm) XCOMM Change XPMINC if necessary to point to the include file for xpm (xpm.h) #define USEXPM #define USEXPM_ICON #ifdef USEXPM XPMLIBDIR = /usr/local/lib XPMINC = -I/usr/include/X11 #endif XCOMM Uncomment the following definiton if you want to use the small icons XCOMM for the panel buttons. Use this if you have a 800x600 or smaller screen. XCOMM #define USESMALLICONS XCOMM Change the location of your printcap file if necessary PRINTCAP = -DPRINTCAP=\"/etc/printcap\" XCOMM Uncomment the following if needed for DECstations running older X11R4 XCOMM INCROOT=/usr/include/mit XCOMM If you do not want to use the CompKeyDB but the standard behavior of XCOMM the Compose key, uncomment the next line XCOMM NO_COMPKEYDB = -DNO_COMPKEYDB XCOMM If you have a Compose indicator LED and you would it turned on when you XCOMM are entering multi-key characters (like a-umlaut, c-cedilla, etc) XCOMM uncomment the next line. You may have to change the value from 2 XCOMM to 1, 3, or 4 depending on your workstation model and X libraries. COMP_LED = -DCOMP_LED=3 XCOMM Comment out the next two lines if you have any problems with the locale. XCOMM If your setlocale() doesn't support the locale, you should XCOMM add -DSETLOCALE to I18N_DEFS. XCOMM #define I18N XCOMM XAW_INTERN = -DXAW_INTERNATIONALIZATION XCOMM If using an input tablet uncomment the following XCOMM TABLIB = $(XILIB) XCOMM USETAB = -DUSE_TAB XCOMM uncomment the following line if your compiler supports XCOMM inline functions. With the "INLINE" keyword, you should notice that XCOMM the display will be a bit faster in complex figures XCOMM USEINLINE = -DUSE_INLINE XCOMM use (and change) the following if you want the multi-key data base file XCOMM somewhere other than the standard X11 library directory XCOMM be sure to comment out the second copy of XFIGLIBDIR if you use this one XCOMM XFIGLIBDIR = $(LIBDIR) XCOMM use this if you want the multi-key data base file in the standard X11 tree XFIGLIBDIR = $(LIBDIR)/xfig XCOMM XFIGDOCDIR tells where the html and pdf documentation should go XCOMM XFIGDOCDIR = $(DOCDIR)/xfig XFIGDOCDIR = /usr/local/xfig/doc XCOMM MANDIR tells where the standard man pages should go (no need to change it XCOMM if you want the man pages installed in the standard place on your system MANDIR = $(MANSOURCEPATH)$(MANSUFFIX) XCOMM MANDIR = /usr/local/xfig/man XCOMM If your system doesn't have strstr undefine the following definition XCOMM HAVE_NO_NOSTRSTR = -DNOSTRSTR XCOMM If your system doesn't have strcasecmp and/or strncasecmp XCOMM undefine the following two definitions XCOMM HAVE_NO_STRCASECMP = -DHAVE_NO_STRCASECMP XCOMM HAVE_NO_STRNCASECMP = -DHAVE_NO_STRNCASECMP XCOMM If your system doesn't have the strerror() function (has sys_errlist) then XCOMM uncomment NEED_STRERROR. XCOMM NEED_STRERROR = -DNEED_STRERROR XCOMM If your system doesn't have dirent.h undefine the following definition XCOMM HAVE_NO_DIRENT = -DHAVE_NO_DIRENT XCOMM For the rotated text code: XCOMM Add one of `-DCACHE_XIMAGES' or `-DCACHE_BITMAPS' to decide what is XCOMM cached. If you are concerned about memory usage in your X server (e.g. XCOMM if you are using an X terminal) then you might want to cache Ximages, XCOMM which reside on the client-side. On the other hand it is much slower, XCOMM so you might want to cache bitmaps (which reside in the X server) XCOMM instead. XCOMM Add `-DCACHE_SIZE_LIMIT=xxxx' where xxxx is the cache size in kilobytes. XCOMM A cache size of zero turns caching off. CACHE = -DCACHE_BITMAPS -DCACHE_SIZE_LIMIT=300 XCOMM For SYSV systems with BSD-style printer command which use lpr instead of XCOMM lp (SGI is one such machine), add -DBSDLPR to the DEFINES variable XCOMM XCOMM If you have VERY large objects (e.g. polylines etc) you may want to XCOMM increase MAXNUMPTS, the maximum number of points that are displayed. The XCOMM default can be found in w_drawprim.h. This option may be specified by XCOMM adding -DMAXNUMPTS=xxxx to the DEFINES line, where xxxx is the maximum XCOMM number of vertices. XCOMM If you want a compiler other than "cc", define it here XCOMM CC = /opt/SUNWspro/bin/cc XCOMM Shorten unnecessary dependencies: XCOMM #define XawClientLibs $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XPMLIB) $(EXTRAXAWCLIENTLIBS) $(XLIB) #ifdef XawClientLibs # undef XawClientLibs # define XawClientLibs $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XTOOLONLYLIIB) $(XPMLIB) $(EXTRAXAWCLIENTLIBS) $(XONLYLIB) #endif XCOMM ***************************************************** XCOMM ***************************************************** XCOMM You shouldn't have to change anything below this line XCOMM ***************************************************** XCOMM ***************************************************** INSTDATFLAGS = -m 0644 #ifdef USEJPEG #ifdef USEINSTALLEDJPEG JPEGLIB = -L$(JPEGLIBDIR) -ljpeg #else JPEGCONF = configure JPEGLIB = $(JPEGLIBDIR)/libjpeg.a DEPLIBJPEG = $(JPEGLIBDIR)/libjpeg.a #endif /* USEINSTALLEDJPEG */ #endif /* USEJPEG */ #ifdef I18N I18N_DEFS = -DI18N I18N_SRC = w_i18n.c I18N_OBJ = w_i18n.o #endif DIR_DEFS= -DXFIGLIBDIR=\"$(XFIGLIBDIR)\" \ -DXFIGDOCDIR=\"$(XFIGDOCDIR)\" $(PRINTCAP) XCOMM location of Fig object libraries OBJLIBDIR = $(XFIGLIBDIR)/Libraries OBJLIB = -DOBJLIBDIR=\"$(OBJLIBDIR)\" STRDEFINES = $(HAVE_NO_NOSTRSTR) \ $(HAVE_NO_STRNCASECMP) \ $(HAVE_NO_STRCASECMP) \ $(NEED_STRERROR) #ifdef InstallManPage #undef InstallManPage #endif #define InstallManPage(file,dest) @@\ InstallManPageLong(file,dest,file) #ifdef USESMALLICONS DUSESMALLICONS = -DUSE_SMALL_ICONS #endif /* USESMALLICONS */ PNGLIBS = -L$(PNGLIBDIR) -lpng -L$(ZLIBDIR) -lz #ifdef USEJPEG DUSEJPEG = -DUSE_JPEG READJPEGS = f_readjpg.c READJPEGO = f_readjpg.o #endif /* USEJPEG */ #ifdef USEXPM DUSEXPM = -DUSE_XPM XPMLIBS = -L$(XPMLIBDIR) -lXpm READXPMS = f_readxpm.c READXPMO = f_readxpm.o #ifdef USEXPM_ICON DUSEXPMICON = -DUSE_XPM_ICON #endif /* USEXPM_ICON */ #endif /* USEXPM */ DEFINES = $(STRDEFINES) $(DDUSEINLINE) $(DUSEXPM) $(DUSEXAW3D) $(XAW_INTERN)\ $(DUSEJPEG) $(I18N_DEFS) $(HAVE_NO_DIRENT) -DNEWARROWTYPES XFIGSRC = d_arc.c d_arcbox.c d_box.c d_ellipse.c d_picobj.c \ d_subspline.c d_line.c d_regpoly.c d_spline.c d_text.c \ e_addpt.c e_align.c e_arrow.c e_break.c e_compound.c \ e_convert.c e_copy.c e_delete.c e_deletept.c \ e_edit.c e_flip.c e_glue.c e_joinsplit.c e_measure.c e_move.c \ e_movept.c e_placelib.c e_rotate.c e_scale.c e_tangent.c e_update.c \ f_load.c f_neuclrtab.c f_picobj.c f_read.c f_readold.c \ f_readppm.c f_readpng.c f_readtif.c f_readeps.c \ f_readxbm.c f_readgif.c $(READJPEGS) f_readpcx.c $(READXPMS) \ f_save.c f_util.c f_wrpcx.c f_wrpng.c \ main.c mode.c object.c resources.c \ u_bound.c u_create.c u_drag.c u_draw.c \ u_elastic.c u_error.c u_fonts.c u_free.c u_geom.c \ u_list.c u_markers.c u_pan.c u_print.c u_redraw.c u_scale.c u_search.c \ u_smartsearch.c u_translate.c u_undo.c w_digitize.c w_listwidget.c \ w_browse.c w_capture.c w_srchrepl.c w_help.c w_layers.c \ w_canvas.c w_cmdpanel.c w_color.c w_cursor.c w_dir.c w_drawprim.c \ w_export.c w_file.c w_fontbits.c w_fontpanel.c w_grid.c w_icons.c \ w_indpanel.c w_library.c w_modepanel.c w_mousefun.c w_msgpanel.c \ w_print.c w_rottext.c w_rulers.c w_setup.c w_style.c w_util.c w_zoom.c \ e_chop.c u_quartic.c w_snap.c w_keyboard.c w_intersect.c \ $(I18N_SRC) $(XAW_SRC) XFIGOBJ = d_arc.o d_arcbox.o d_box.o d_ellipse.o d_picobj.o \ d_subspline.o d_line.o d_regpoly.o d_spline.o d_text.o \ e_addpt.o e_align.o e_arrow.o e_break.o e_compound.o \ e_convert.o e_copy.o e_delete.o e_deletept.o \ e_edit.o e_flip.o e_glue.o e_joinsplit.o e_measure.o e_move.o \ e_movept.o e_placelib.o e_rotate.o e_scale.o e_tangent.o e_update.o \ f_load.o f_neuclrtab.o f_picobj.o f_read.o f_readold.o \ f_readppm.o f_readpng.o f_readtif.o f_readeps.o \ f_readxbm.o f_readgif.o $(READJPEGO) f_readpcx.o $(READXPMO) \ f_save.o f_util.o f_wrpcx.o f_wrpng.o \ main.o mode.o object.o resources.o \ u_bound.o u_create.o u_drag.o u_draw.o \ u_elastic.o u_error.o u_fonts.o u_free.o u_geom.o \ u_list.o u_markers.o u_pan.o u_print.o u_redraw.o u_scale.o u_search.o \ u_smartsearch.o u_translate.o u_undo.o w_digitize.o w_listwidget.o \ w_browse.o w_capture.o w_srchrepl.o w_help.o w_layers.o \ w_canvas.o w_cmdpanel.o w_color.o w_cursor.o w_dir.o w_drawprim.o \ w_export.o w_file.o w_fontbits.o w_fontpanel.o w_grid.o w_icons.o \ w_indpanel.o w_library.o w_modepanel.o w_mousefun.o w_msgpanel.o \ w_print.o w_rottext.o w_rulers.o w_setup.o w_style.o w_util.o w_zoom.o \ e_chop.o u_quartic.o w_snap.o w_keyboard.o w_intersect.o \ $(I18N_OBJ) $(XAW_OBJ) XCOMM Other dependencies should be handled by "make depend" MAINDEPFILES = patchlevel.h version.h SRCS = $(XFIGSRC) OBJS = $(XFIGOBJ) EXTRA_INCLUDES = $(JPEGINC) $(PNGINC) $(XPMINC) -I. DEPLIBS = XawClientDepLibs LOCAL_LIBRARIES = $(JPEGLIB) SYS_LIBRARIES= $(XPMLIBS) $(PNGLIBS) $(TABLIB) XawClientLibs -lm #define PassCDebugFlags xfig: $(DEPLIBJPEG) XCOMM only compile our jpeg if the user doesn't have one installed #ifdef USEJPEG #ifndef USEINSTALLEDJPEG $(JPEGLIBDIR)/libjpeg.a: $(JPEGLIBDIR)/jconfig.h cd $(JPEGLIBDIR); $(MAKE) libjpeg.a $(JPEGLIBDIR)/jconfig.h: cd $(JPEGLIBDIR) ; ./$(JPEGCONF) CC='$(CC)' #endif /* USEINSTALLEDJPEG */ #endif /* USEJPEG */ PROGRAM = xfig AllTarget(xfig) ComplexProgramTarget(xfig) InstallAppDefaults(Fig) XCOMM Install the compose key database, object libraries and documentation XCOMM here with "make install" install:: @if [ -d $(DESTDIR)$(XFIGLIBDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XFIGLIBDIR) ; set +x; ); fi chmod a+x,u+w $(DESTDIR)$(XFIGLIBDIR) $(INSTALL) -m 644 -c CompKeyDB $(DESTDIR)$(XFIGLIBDIR) XCOMM Install program, libraries and documentation with "make install.all" install.all:: $(MAKE) install $(MAKE) install.doc $(MAKE) install.libs xfig.man: Doc/xfig.man rm -f xfig.man $(LN) Doc/xfig.man xfig.man XCOMM Install the documentation here with "make install.doc" install.doc:: @echo Installing man pages to $(MANDIR) @if [ -d $(DESTDIR)$(XFIGDOCDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XFIGDOCDIR) ; set +x; ); fi @$(MAKE) install.man @$(MAKE) install.html XCOMM Install the HTML documentation here with "make install.html" #ifdef I18N install.html:: @$(MAKE) install.jhtml @$(MAKE) install.rhtml #else install.html:: @$(MAKE) install.rhtml #endif install.rhtml:: @(cd Doc ; \ echo Copying pdf and html files to $(DESTDIR)$(XFIGDOCDIR) ; \ if [ -d $(DESTDIR)$(XFIGDOCDIR)/html ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XFIGDOCDIR)/html ); fi ; \ $(INSTALL) -m 644 -c xfig_man.html $(DESTDIR)$(XFIGDOCDIR) ; \ $(INSTALL) -m 644 -c xfig_ref_en.pdf $(DESTDIR)$(XFIGDOCDIR) ; \ $(INSTALL) -m 644 -c xfig-howto.pdf $(DESTDIR)$(XFIGDOCDIR) ; \ if [ -d html ]; then \ ( cd html ; tar cf - *.* images ) | ( cd $(DESTDIR)$(XFIGDOCDIR)/html ; tar xf - ) ; fi ; \ ) ; #ifdef I18N install.jhtml:: @echo "Copying japanese html files to $(DESTDIR)$(XFIGDOCDIR)" @(cd Doc/html/japanese ; \ if [ -d $(DESTDIR)$(XFIGDOCDIR)/html/japanese ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XFIGDOCDIR)/html/japanese ); fi ; \ tar cf - * | ( cd $(DESTDIR)$(XFIGDOCDIR)/html/japanese ; tar xf - ) ; \ ) ; #endif XCOMM Install the object libraries here with "make install.libs" install.libs:: @echo "Copying Fig Object Libraries" @if [ -d $(DESTDIR)$(OBJLIBDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(OBJLIBDIR) ; set +x; ); fi @if [ -d Libraries ]; then \ (cd Libraries ; tar cf - */. ) | ( cd $(DESTDIR)$(OBJLIBDIR) ; tar xf - ) ; \ else echo No Object Libraries to install ; \ fi; SpecialObjectRule(main.o, main.c $(MAINDEPFILES) mode.h w_setup.h, $(USETAB) $(OBJLIB) $(DUSESMALLICONS) $(DUSEXPMICON) ) SpecialObjectRule(f_read.o, f_read.c $(MAINDEPFILES) mode.h, ) SpecialObjectRule(u_error.o, u_error.c $(MAINDEPFILES) mode.h, ) SpecialObjectRule(resources.o, resources.c resources.h, ) SpecialObjectRule(e_edit.o, e_edit.c mode.h, ) SpecialObjectRule(f_readeps.o, f_readeps.c, $(PCXBUG) -DGSBIT ) SpecialObjectRule(w_capture.o, w_capture.c w_capture.h, ) SpecialObjectRule(w_help.o, w_help.c, $(DIR_DEFS) ) SpecialObjectRule(w_canvas.o, w_canvas.c mode.h, $(DIR_DEFS) $(COMP_LED) $(NO_COMPKEYDB) ) SpecialObjectRule(w_icons.o, w_icons.c w_icons.h, $(DUSESMALLICONS) $(DUSEXPMICON) ) SpecialObjectRule(w_print.o, w_print.c w_print.h, $(DIR_DEFS) ) SpecialObjectRule(w_setup.o, w_setup.c w_setup.h w_icons.h, $(DUSESMALLICONS) ) SpecialObjectRule(w_rottext.o, w_rottext.c, $(CACHE) ) SpecialObjectRule(d_arc.o, d_arc.c mode.h, ) SpecialObjectRule(d_arcbox.o, d_arcbox.c mode.h, ) SpecialObjectRule(d_box.o, d_box.c mode.h, ) SpecialObjectRule(d_ellipse.o, d_ellipse.c mode.h, ) SpecialObjectRule(d_line.o, d_line.c mode.h, ) SpecialObjectRule(d_picobj.o, d_picobj.c mode.h, ) SpecialObjectRule(d_regpoly.o, d_regpoly.c mode.h, ) SpecialObjectRule(d_spline.o, d_spline.c mode.h, ) SpecialObjectRule(d_text.o, d_text.c mode.h, ) SpecialObjectRule(e_addpt.o, e_addpt.c mode.h, ) SpecialObjectRule(e_align.o, e_align.c mode.h, ) SpecialObjectRule(e_arrow.o, e_arrow.c mode.h, ) SpecialObjectRule(e_break.o, e_break.c mode.h, ) SpecialObjectRule(e_compound.o, e_compound.c mode.h, ) SpecialObjectRule(e_convert.o, e_convert.c mode.h, ) SpecialObjectRule(e_copy.o, e_copy.c mode.h, ) SpecialObjectRule(e_delete.o, e_delete.c mode.h, ) SpecialObjectRule(e_deletept.o, e_deletept.c mode.h, ) SpecialObjectRule(e_flip.o, e_flip.c mode.h, ) SpecialObjectRule(e_glue.o, e_glue.c mode.h, ) SpecialObjectRule(e_movept.o, e_movept.c mode.h, ) SpecialObjectRule(e_placelib.o, e_placelib.c mode.h, ) SpecialObjectRule(e_rotate.o, e_rotate.c mode.h, ) SpecialObjectRule(e_scale.o, e_scale.c mode.h, ) SpecialObjectRule(e_update.o, e_update.c mode.h, ) SpecialObjectRule(f_load.o, f_load.c mode.h, ) SpecialObjectRule(f_picobj.o, f_picobj.c mode.h, ) SpecialObjectRule(f_save.o, f_save.c mode.h, ) SpecialObjectRule(f_util.o, f_util.c mode.h, ) SpecialObjectRule(mode.o, mode.c mode.h, ) SpecialObjectRule(object.o, object.c object.h mode.h, ) SpecialObjectRule(u_bound.o, u_bound.c mode.h, ) SpecialObjectRule(u_create.o, u_create.c mode.h, ) SpecialObjectRule(u_drag.o, u_drag.c mode.h, ) SpecialObjectRule(u_draw.o, u_draw.c u_draw_spline.c mode.h, ) SpecialObjectRule(u_geom.o, u_geom.c u_draw_spline.c, ) SpecialObjectRule(u_elastic.o, u_elastic.c mode.h, ) SpecialObjectRule(u_list.o, u_list.c mode.h, ) SpecialObjectRule(u_markers.o, u_markers.c mode.h, ) SpecialObjectRule(u_pan.o, u_pan.c mode.h, ) SpecialObjectRule(u_print.o, u_print.c mode.h, ) SpecialObjectRule(u_search.o, u_search.c mode.h, ) SpecialObjectRule(u_undo.o, u_undo.c mode.h, ) SpecialObjectRule(w_browse.o, w_browse.c mode.h, ) SpecialObjectRule(w_cmdpanel.o, w_cmdpanel.c mode.h, ) SpecialObjectRule(w_dir.o, w_dir.c mode.h, ) SpecialObjectRule(w_drawprim.o, w_drawprim.c mode.h, ) SpecialObjectRule(w_export.o, w_export.c mode.h, ) SpecialObjectRule(w_file.o, w_file.c mode.h, ) SpecialObjectRule(w_grid.o, w_grid.c mode.h, ) SpecialObjectRule(w_indpanel.o, w_indpanel.c mode.h w_indpanel.h object.h, ) SpecialObjectRule(w_library.o, w_library.c mode.h, ) SpecialObjectRule(w_modepanel.o, w_modepanel.c mode.h w_indpanel.h w_icons.h object.h, $(DUSESMALLICONS)) SpecialObjectRule(w_msgpanel.o, w_msgpanel.c mode.h, ) SpecialObjectRule(w_rulers.o, w_rulers.c mode.h, ) SpecialObjectRule(w_zoom.o, w_zoom.c mode.h, ) #ifndef XAW3D1_5E SpecialObjectRule(w_menuentry.o, w_menuentry.c w_menuentry.h w_menuentryP.h, ) #endif #ifdef USEJPEG #ifndef USEINSTALLEDJPEG SpecialObjectRule(f_readjpg.o, f_readjpg.c $(JPEGLIBDIR)/jconfig.h, ) #endif /* USEINSTALLEDJPEG */ #endif /* USEJPEG */ xfig.3.2.5c/CHANGES0000700002656300244210000036666712207675165014411 0ustar bvsmithDomain UsersChanges to Xfig ============================================================================= Version 3.2 ============================================================================= IMPORTANT NOTE: Please use bvsmith@lbl.gov to report xfig problems or questions. Also please note that I don't have much time anymore to work on xfig/transfig, so while you may have a great contribution to make, unfortunately I won't have time to work it into a release. However, I will still try to fix bugs. Patchlevel 5c (August, 2013) BUGS FIXED: o Increased default width of layer panel from 58 to 64 to accomodate scrollbar width o missing comma in FIXED_JAPANESE_PDF #ifdef case in w_cmdpanel.c o printer name enclosed in apostrophes when printing in case has spaces in name o new link from Elizabeth Bailey for Fig applications referenced in installation.html o old link to duke.uask.ca for Fig applications has new link in installation.html o Typo in message "GIF read error on extention ..." should be "extension" o Possibility of stack overflow with malformed Fig files. o In version 1.4 of the PNG library dither was removed so xfig now uses quantize when importing PNG images with palettes o Other updates for PNG library version 1.5 from Peter Volkov o Some versions of Cygwin don't have either REG_NOERROR or REG_OKAY defined so REG_NOERROR defined to be 0 o Changed X-Spline parameter to match original intent of X-Spline authors: changed definition of Q(s) from -s to -0.5 * s in u_draw_spline.c o Allowance for stricter ghostscript in -dSAFER mode. Was causing error on reading EPS images. From Hans de Goede o Security vulnerability with importing images fixed (RedHat bug # 657981 - xfig buffer overflow when opening .fig file with malicius color definition) o When exporting to combined PS/PDF/LATEX the -D option to exclude all but active layers was not passed to fig2dev o Uses 24-bit color instead of 8-bit when importing eps files (pcx24b driver for ghostscript) o Bug in freeing null fontset o Semicolon (;) added at end of MimeType line in xfig.desktop as per http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html o Reference to "Darwin Ports" changed to "MacPorts" o Renamed O_TEXT to O_TXT to avoid conflicts with system define o On lines with Round or Projecting cap style and arrowheads, the line endpoint stuck out beyond the arrowhead From Vladsilav Zavjalov: o Uses fontsets for all fonts in international mode o SEGV when zooming while creating object (e.g. text) o Add locale_encoding appres which acts similar to euc_encoding, but uses system locale and mbrlen function for multibyte character length calculation. o Move "file not found" error message from check_docfile() to launch_viewer(), remove excess check_docfile() call. Error message is not shown when looking for a locale-dependent docs. It is shown only if no docs found at all. o Do not do strcpy with equal arguments in w_cmdpanel.c/update_cur_filename() o Print to file had extra argument in sprintf in international mode o Message panel not tall enough with 3D Athena widgets o Warnings about different size of int and void * on 64-bit system. To fix this problem I changed int to intptr_t in some places. NEW FEATURES: o New library objects from Markus Laner: Networks: NodeB.fig, cloud.fig, router.fig, wlan.fig Computers: datacard.fig, screen.fig, usbpen.fig, xbox.fig o New command-line option -nowrite_bak to turn off automatic renaming of .fig to .fig.bak when saving .fig file. X resource is "write_bak". Also command-line option -write_bak to force renaming to true. o Can now specify small buttons with command-line argument -smallicons From Ed Rosten ----------------------------------- Patchlevel 5b (Jun 1, 2009) BUGS FIXED: o Dimension line indicator incorrectly showed arrow length/width o Several patches from Fedora xfig maintainer o divide by 0 under certain circumstances in ruler code From Libor Pechacek o Segfault if PRINTER env variable was not defined ----------------------------------- Patchlevel 5a (Mar 16, 2009): NEW FEATURES: o "Chop" tool which allows you to chop polylines, arcs and circles into individual objects that together, approximate the original object. From Chris Moller o Fig-color merged into Fig app-defaults file because almost no one knows about the "*customization: -color" option to make X programs read the color def file. o 22 new arrowhead types o changed default browser to firefox and default pdf viewer to xpdf o HTML MAP export (fig2dev) produces reference to .png file instead of .gif now o A note added to i18n.html that says if you run fig2dev standalone, you must pass the -j option to it o No need to have the C99 complex functions in the math library. o New computers from Andre Esser (Libraries/Computers) o Some network icons colored and/or combined by Roland Rosenfeld. o When exporting only active layers have choice of bounding area of whole figure or only the active layers o Two new library figures - piano_keyboard.fig, top view of a piano keyboard by Reinaert Albrecht, and piano_keyboard_perspect.fig, a perspective view of a piano keyboard by Brian Smith, both in the Libraries/Music directory. o New library figure - scissors.fig in Libraries/OfficeEquip from Kasie Breezer Talbot o Search tolerance increased from 4 pixels to 10 for zoom < 20 o Isometric grid to ease making isometric drawings From Jasper Wesselingh o New 37-pin D connector and 50-pin ribbon connector in Libraries/Electronic/Physical BUGS FIXED: o dimension line arrowhead width and length used %d instead of %f in dialog, always displaying 0 o leftover debugging printf(...color = ) in startup o finally fixed size of mode panel so it doesn't cover indicator panel under certain circumstances o removed "Alpha" from splash o updated copyright date in Help/About o problem with depth panel height due to snap mode indicator o snap indicator indicated "Focus" when "Diameter" was selected o w_keyboard.c had pointer assignment reversed o extraneous "done" in Imakefile in "install.jhtml" section From Eric Scott o many protoytpe cleanups from Eric Scott o #ifndef __FreeBSD__ added around #include from Eric Scott o uses rint() instead of lrint() for those with non-C99 compilers o Solaris doesn't have REG_NOERROR for regex, so have new #define for that o added dependency on version.h and patchlevel.h for f_util.c and f_save.c to Imakefile o In imperial fractional scale mode, if the user scale factor wasn't 1.0, xfig would switch to decimal mode. This has been fixed to remain in fractional mode. o Added condition for GLIBC to not declare srandom(int) o Better resizing of message popup panel o Map of Spain included Portugal. From Eugen Dedu. o Double-clicking on either style or family would crash xfig o Export/Print grid units were not reset when loading Fig file of different units o When converting empty export/print grid units to fractional inches would make 0/2 o Escaped hyphens in man page From Roland Rosendfeld o When exporting to all three: PostScript, PDF and TeX, incorrectly generated PostScript and PDF that included LaTeX-only (special) text o Bug when doing Save As to a shorter filename - would corrupt name sometimes o Note about 450 pixels/cm didn't make it from the FORMAT3.1 file to FORMAT3.2 o Print command was using -P instead of -d for lp o On Cygwin, needed to double-escape PRINTER environment when backslashes in name o w_library.c had incompatible poiner type in call to ScanLibraryDirectory o Not enough characters allocated for ruler inch/cm indicators. Would cause segfault on zooming out because of longer ruler text, e.g. -10210cm ----------------------------------- Patchlevel 5 (Feb 22, 2007): NEW FEATURES: o Shift-U accelerator added to popup units panel o The library menu button sizes with the library panel, to show longer path names if the user wants. o The cursor for drawing lines, splines, etc. is a crosshair now instead of an arrow. o Snap features to allow snapping points to endpoints, midpoints and intersections of other objects. From Chris Moller. o Keyboard input of object coordinates for precise positioning. From Chris Moller. o Can grab arc anywhere along the curve instead of just at grab points From Chris Moller. o Added -noflipvisualhints for cases where, due to "different" pointer devices, they aren't really flipped, but the mapping indicates they are. o Export to all of PS, PDF and LaTeX in one operation From Alistair Ramsey o Reorganized Networks library and new devices: ASX-200, 1000, and 4000 by Bill Chimiak o New figures "betty.fig" (Betty Boop) and "nikke.fig" (German detective Nick Knatter) in Libraries/Examples drawn by Markku Reunanen o Can finish text input by pressing Escape. This removes the cancellation of a compose sequence (e.g. a-umlaut) o Actually a bug fix, import of PDF files is now possible. The code was there since version 3.2.3, but the user interface was not. o Nearly-full ANSI protoization of code by Harald Koenig o Installation of Libraries and doc files faster with tar instead of shell loop o New Gregorian chant music symbols from Bill Chimiak. Also, Music library divided into "chant" and "modern" o Popup edit panel slightly more compact vertically o New library "Fasteners" containing various bolts and screws From Jim Yuzwalk o Increased size of numeric entry fields in indicator panels o N-channel IGBT in Electronic/Schematics Library from Art Blair o starting values for arrow type, width, length, thickness may be specified on command-line or in X resources: -startarrowtype, -startarrowwidth, -startarrowlength, -startarrowthick BUGS FIXED: o xfig would crash on 64-bit processors because of a missing include, which causes new_string() to be declared implicitly as returning an integer. This may cause the top 32 bits to get lost and hence the crash. o Blanks not preserved in imported picture filename when reading Fig file o When in metric mode, decimal precision was ignored for dimension lines o When showing vertex numbers on objects, first vertex is now 0 to match edit window vertex numbers o Also, vertex numbers are not shown on inactive (grayed) layers o Widget shadow resources moved from Fig-color to Fig because they don't really have anything to do with color. There was a problem when running KDE because it set a global resource *Scrollbar*height: which made xfig freeze when *customization: -color was NOT used. o The point positioning indicator is turned on when editing a compound object to show the user that it is used o Increased the maximum size of images that can be imported. There was a limit in the PostScript image encoder of 4096x4096 pixels. This was increased to 8192x8192. o Centered text was changed to left-justified when flipped horizontally inside a compound object. o With -v option, after reporting the version, xfig would say that -v was an unknown option o Local locale was being used when writing the xfig cut buffer file instead of switching to "C" locale. This created commas instead of decimal (.) for numbers in those particular locales. From Dirk Osswald o Local locale was used when forming command for calling fig2dev, resulting in commas instead of decimals for floating point numbers. o count_user_colors buffer overflow fixed o Under Cygwin, temporary file stayed around after unlink(), causing error when importing more than one ps/eps/pdf file o Segfault when using -update because appres resources were NULL o -update option failed when not first option passed to xfig o Clicking window manager "close window" button in library titlebar didn't close the window o Wasn't distributing objects in compounds when there were only 2 objects o Some compilers complain about the order of declaration in u_fonts.h - fixed o Northern part of map of India was incorrect (Libraries/Maps/Asia/india.fig) o Map of Serbia was misnamed "yugoslavia.fig" (Libraries/Maps/Europe/yugoslavia.fig) o Map of Central Europe had old Yugoslavia instead of Croatia, Serbia, Bosnia- Herzegovina, and Macedonia (also, Slovenia was mistakenly inside the border) o Editing a compound object with more than 200 texts would crash xfig ----------------------------------- Patchlevel 5-alpha5 (April, 26, 2004): NEW FEATURES: o Added note to README and FAQ html file: If the Xaw or Xaw3d Athena widget sets are compiled with the ARROW_SCROLLBAR style of scrollbars, there is no StartScroll action and you won't be able to scroll using the wheel on the mouse. If you want to be able to scroll using the wheel, you must recompile the Xaw library from sources, disabling the ARROW_SCROLLBAR option. o Astrological symbols for planets in Miscellaneous/Astrology by Andrew Collier o Added key bindings to text dialogs to be more like modern systems (the Athena Widget Set that xfig uses is very old): Home: beginning-of-line End: end-of-line Del: delete-character-right o Added *.jpeg* to picture browse options o New libraries for electronics from Fabio González in Libraries/Electronics/Schematic/More BUGS FIXED: o typo in latex_and_xfig.html and LATEX_AND_XFIG files. Text should be: \convertMPtoPDF{foo.0}{1}{1} It was missing parameters {1}{1} o -correct_font_size missing from -help option list and man pages o -help and -version didn't work unless they were first in the options o -O option wasn't passed to fig2dev for overlapping pages in multiple page mode for PostScript export ----------------------------------- Patchlevel 5-alpha4 (Feb, 19, 2004): Note: There is a minor change to the copyright/permission notice for xfig. Basically, I have restored the part that allows one to sell xfig regardless of whether it is bundled as part of a package or not. This is identical to the original copyright/permission notice for xfig, which was based on the MIT (then later, the X Consortium) copyright notice. Here is the new notice (different files have different author copyrights at the top): > FIG : Facility for Interactive Generation of figures > Copyright (c) 1985-1988 by Supoj Sutanthavibul > Parts Copyright (c) 1989-2002 by Brian V. Smith > Parts Copyright (c) 1991 by Paul King > Any party obtaining a copy of these files is granted, free of charge, a > full and unrestricted irrevocable, world-wide, paid up, royalty-free, > nonexclusive right and license to deal in this software and documentation > files (the "Software"), including without limitation the rights to use, > copy, modify, merge, publish distribute, sublicense and/or sell copies of > the Software, and to permit persons who receive copies from any such > party to do so, with the only requirement being that the above copyright > and this permission notice remain intact. NEW FEATURES: o Introduction.html and installation.html updated to include Macintosh port of xfig o Button to collapse depths of a compound object (make all same depth) in popup object editor o Grid changed from dotted line to light red solid line o Candle in Libraries/Miscellaneous by Dr. Lyman Hazelton o Right-click on depth checkbox sets current depth in indicator panel to that depth o Library of symbols used when diagramming folding instructions to make origami models and example contributed by Marc Vigo o Can adjust width and height directly in popup editor for picture objects o Support for David Hawkey's Xaw3D version 1.5E (http://www.visi.com/~hawkeyd/xaw3d.html) BUGS FIXED: o When loading a library object, if it contained only a compound and nothing else, when xfig promoted that compound to the toplevel the main comment was lost o Incorrect header files used for SmeBSB resulted in either segfault or none of the command panel entries being underlined o Drawing very large splines (e.g. at zoom = 0.01) caused integer roundoff errors, making xfig loop indefinitely o Bug where a line that had a zero width or length arrowhead was not redrawn after being moved, copied, canvas redraw, etc. o The page border and axis lines would obscure Fig objects when moving, copying etc. other objects on the canvas. o In the popup picture editor, if the relative position of the corners of the picture were changed, the rotation field was not updated (this bug was in 3.2.5-alpha3 only) o line, arc, ellipse length tool was reporting 0 length ----------------------------------- Patchlevel 5-alpha3 (Dec, 9, 2003): NOTE: o URL for information about the color optimization code (written by Anthony Dekker) has changed to: http://members.ozemail.com.au/~dekker/NEUQUANT.HTML NEW FEATURES: o -autorefresh command-line option (resource: Fig.autorefresh) which will make xfig look at the timestamp on the .fig file and automatically load it and display it everytime it changes. o Removed requirement to compile with WHEELMOUSE when using wheelmouse o New tower computers (Libraries/Computers/AOpenKF45E.fig and AOpenKF45E.fig from Dirko van Schalkwyk) o New 10/100 8port hub (Libraries/Networks/3Com3C16750.fig also from Dirko van Schalkwyk) o When placing library objects, the name and comments are displayed in message window o New flags (Libraries/Flags): Africa/Eritrea, Africa/Zimbabwe, Asia/Myanmar, Asia/Tajikstan, Asia/Kyrgystan, Europe/Croatia o non-polar capacitor added to Libraries/Electronic/Schematic o Mouse wheel can be used to scroll through filename lists in File and Export panels and icons or object lists in Library panel o Thickness of ticks in dimension lines are user-adjustable now o For attribute popup dialogs with only one text entry, keyboard now focuses on the entry as long as the pointer is anywhere in the dialog o When using the "Open compound, keep rest visible", the other objects are drawn in shades of gray similar to the inactive layers feature. o New library objects: adder, multiplier, sine-source and voltage-source in Electronic/Schematic by Hubert Lam o Zooming in or out with the Z or z key respectively will keep the canvas centered on the mouse pointer o Full version and patchlevel is included in Fig file header for diagnostics o Can explicitly set the rotation of imported pictures in edit panel after importing o Export option to produce both EPS and PDF (in two files) in one step. Useful for those who both use LaTeX and PDFLaTeX o "Epoch" added to rpm spec o New HP/GL2 (fig2dev) driver from Glenn Burkhardt with paper size selection, offset, centering and orientation options o New library object "atom" in Libraries/Miscellaneous is the classic drawing of an atom with electrons circling From Andrew B. Collier BUGS FIXED: o Missing #ifdef XAW3D in SimpleMenu.c o Bug when breaking a compound object - depths were added twice to the counts o When implicitly cancelling the placement of a library object by choosing another mode, xfig would do one of two things: 1. tell user to cancel or finish the current operation, but there was no way to do that 2. create the object that was being cancelled with extremely large, negative coordinates o Picture Reread button was active before file was read the first time o Rereading picture in edit popup produced bad colors o When using multiple copies of an imported picture, h/w ratio was not computed for copies o Importing PCX images were incorrect when bytes per line different from width*bpp o When passed a filename containing a directory name for a Fig object library using -library_dir, and that directory only contains Fig files and no subdirectories with Fig files, xfig segfaulted o Several checks for memory allocation failure added to the library loading procs o Forgot to free allocated memory when return abnormally from loading libraries o Path length check in loading libraries fixed o Missing include for put_msg prototype in e_measeure.c o Needed #ifdef for XtVersion in SmeBSB.c (X11R5 doesn't have international fontset) o Added SIGPIPE signal to ignore in case an external program dies when we're using pipes o Screen capture on an MSBFirst X server with 24/32 bits per pixel was incorrect. o Importing any image file on such a server was incorrect (bytes/bits reversed). o Reading GIF or PCX files on 24-bit server *and* on big-endian machine (e.g. Sparcstation) resulted in bytes being swapped and funny colors o Could popup unit dialog when drawing/editing objects o Embedded whitespace in filenames in recently loaded files weren't parsed properly (.xfigrc) o When pasting an object on the canvas, point positioning grid wasn't used o Bug when reading a compressed eps file (file handle was passed to open proc instead of name) o Minor grid spec used twice instead of minor/major when passed to fig2dev o Fixed conversions of export/print grid values when switching to/from metric, decimal or fraction o When loading or merging a file, xfig appended ".fig" to the name if there wasn't ".fig" in the name. Now it only appends ".fig" if there is no suffix (no "."). o When appending the ".fig" before the previous change, xfig would segfault o Libraries/Electronic/Schematic/transformer and transformer_ironcore aligned to 1/16" grid o Bugs in indicator panel display of text flags, dimension line params and arrow size params when cycling through settings with middle or right mouse button o Bug in callbacks for dimension line checkboxes that select actual length or user text o When exporting to Combined PDF/LaTeX it uses ".pdf" and ".pdf_t" suffixes because LaTeX doesn't recognize ".pdftex" as a PDF file o Better clipping around arrowheads on thick lines (lines that are thicker than the arrowhead is wide) o Checks for open splines of < 2 points when reading figure file and removes them o Clicking middle mouse button after creating first point of closed spline switched to freehand mode o Export panel sections would get messed up when changing export languages o Now checks whether scrollbars support StartScroll before trying to use it for the wheel scrolling. When the Xaw widgets are compiled with ARROW_SCROLLBAR, there is no such action. o pstex_t export lacked border option (-b) to align LaTeX text when pstex figure specified border (also fixed in fig2dev) o Create one picture object with no filename, then create another and xfig crashed o Some bugs when freeing dimension line components o Bad choices for grid dot spacing in metric mode in the 5mm grid, and decimal inch mode in the 0.5 and 1.0 inch grids o -international flag missing from xfig.html and xfig.man docs o Added call to XsetLocaleModifiers() when initializing input method (-international mode only) o xfig was limiting arrowhead lengths to 50 pixels instead of 50 inches, and the width to 10 pixels instead of 10 inches. o edit panel for circles shouldn't have "angle" entry o edit panel wasn't allowing typing in of negative angles for text and ellipses o Objects were sometimes drawn with a wild point when zooming o Full path was being added to default export filename and wasn't changing when user changed directories o When drawing a box or rounded box with the "show line lengths" on, the sizes were in Fig units (1200ppi) instead of user units. o Spacing cedilla (ISO 0xB8 / octal 270) was missing from CompKeyDB file o Changing the units in the popup edit panel for a text object caused a segfault. o Rulers and grid didn't change scale when user scale was != 1.0. Even though the message window showed the correct user scale when drawing objects, the rulers and grid still showed the unscaled values. o Axis lines through 0,0 now drawn after page border so it remains visible when there is a grid o Segfault if current directory was deleted after starting xfig o Positioning grid was set to "ANY" when editing a compound object, causing the original bounding box to be lost o Bug in arc drawing caused arcs to be drawn as circles at high zoom o Computing the area of a polygon larger than 38x38 inches overflowed calculation o Bug in bounds calculation for ellipses and circles that increased bounding box even with line width = 1 o Limit on number of styles in a family wasn't checked o If all depths were turned off and any edit operation was attempted on the canvas such as move object, delete object, xfig would hang, searching for objects indefinitely. ---------------------------- Patchlevel 4 (December 2002) SPECIAL COPYRIGHT NOTICE: *********** THE FOLLOWING HAS BEEN SUPERCEDED BY THE ONE FOR 3.2.5 *********** The xfig copyright has changed slightly since the previous version. It now states that: Any party obtaining a copy of these files is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish and/or distribute copies of the Software, and to permit persons who receive copies from any such party to do so, with the only requirement being that this copyright notice remain intact. The previous notice allowed the *selling* of xfig or any code in xfig. This is not allowed now, unless xfig is simply included in a collection of programs (e.g. on a CD) that you are selling. ******************************************************************************* NEW FEATURES: o Binary RPM available for systems with rpm (RedHat Package Manager). o Examples moved to Libraries/Examples so they are installed in a convenient place for viewing (via the library feature) o "Front" and "Back" labels in depth manager to show relative positioning of depths on drawing. o The mu (micro) character is now entered using "Compose | u" instead of "Compose / u" o If you wish to place a library object at the position it was originally created, e.g. for laser printer labels, hold down the Shift key and press mouse button 3 (`place at orign posn') to place it. o New URL for chemtool, a chemical structure editor: http://ruby.chemie.uni-freiburg.de/~martin/chemtool/chemtool.html o The minimum and maximum depth of objects are shown in the edit panel for compound objects o EMF (Enhanced Metafile) export driver (TransFig/fig2dev) based on CGM driver. Converted by M. Schrick o SVG (Scalable Vector Graphics) beta driver (for TransFig/fig2dev) from Anthony Starks with major improvements by Martin Kroeker Some caveats when using Mozilla-SVG to view these: 1. the file must be exported with magnification = 6.6% (0.066 in fig2dev) to scale to screen coords 2. the file suffix must be ".xml" o The xfig documentation is nearly entirely GIF-free (TM). Only the frames images use GIF because they use a transparent background, which many browsers don't honor. PNG is used for all other images. o Xfig reference manual now available in PDF besides html. The English version is in Doc/xfig_en.pdf and the Japanese in Doc/xfig_jp.pdf. These are also available in the Help menu. o Dimension lines - Hold the shift key down while drawing a polyline, and after specifying the two endpoints a "dimension line" is created, which is actually a compound object containing the line drawn (with arrowheads if auto arrow mode is on) in the current color, "tick" lines at each endpoint, text showing the length of the line in the current units, and a box around the text filled in the current fill color. If this compound object is rescaled or one or more endpoints are moved, the actual length is recalculated and the text is updated. o New Xfig logo courtesy of Marc-Aurele Darche. o Can now paste text in text mode using Shift+Middle-mouse-button in addition to F20 and Sun's Paste key (F18). o If xfig is compiled with #define WHEELMOUSE uncommented in the Imakefile, the wheel may be used for several things (see html docs under Miscellaneous/Wheel Mouse). o New grid/positioning option for inches mode: -grid_unit. If the value given is "1/10", "ten", "tenth", "1/10" or "10", (e.g. -grid_unit ten) then the grid and point positioning is in decimal inches. Otherwise they are in 1/16 inch units (as before). When in this mode, the grid step sizes are 0.1, 0.2, 0.5 and 1 inch and the positioning steps are 0.05, 0.10, 0.2, 0.5, and 1.0 inch. o Background (-g to fig2dev) option for tk export honored now. o New command-line argument -correct_font_size (X resource Fig.correct_font_size) to make xfig use real points for font sizes instead of units of 1/80 inch. xfig has always claimed that the font size units are points (1/72inch), but in fact they were 1/80 inch. This new option is not the default because it will break some figures by making the text too large compared to other Fig objects, but it will be the default in a future version. The corresponding argument to fig2dev is -F (xfig automatically sets this when calling fig2dev). o Added "Stop" button to stop loading library. o Much more efficient when copying large imported pictures - existing pixmap is used instead of creating new one. This also precludes the need to remap colors when running out of colors when the colors are identical. o When changing an attribute of an imported picture that doesn't change the picture itself (e.g. depth), the pixmap is not regenerated, therefore saving time. The same is true when copying a picture. o New X resource Fig.ghostscript and command-line argument -ghostscript by which you can tell xfig what your ghostscript is called (e.g. "gs" or "gswin32"). o Can now add ASCII (EPSI) preview to EPS export. See export panel. o Can now add monochrome or color TIFF preview to EPS export. This is needed by Microsoft Word, Powerpoint, etc. to display the EPS on the screen. Select from the pulldown menu of export languages. You must have fig2dev 3.2.4 for these features. See export panel. o Translations of LATEX.AND.XFIG document into two popular Chinese encodings (GB2312 and Big5). These are called LATEX.AND.XFIG.zh_CN and LATEX.AND.XFIG.zh_TW respectively. From Mendel Chan o When text becomes too small to see (e.g. small zoom), xfig will "Greek" it, meaning it draws a gray line segment for each word in the string. o When resizing canvas to a smaller height, the number of buttons per row of the mode (side) panel increases so that it doesn't protrude into the indicator (bottom) panel o Smarter redraw when turning on depths from the depth manager. If depth N is turned on and there are no active depths < N, only depth N is drawn - otherwise, the canvas is erased and the whole figure is redrawn. o If the user's pointer (mouse) buttons are switched (usually 3 2 1) xfig will automatically flip the mouse hints messages. This overrides the -flipvisualhints command-line argument. o If the user clicks on or modifies an existing text, and presses return, the new text on the next line will use the attributes of the first text instead of the attributes from the indicator panel. o Note in README and Imakefile about not casually setting the DESTDIR make variable. o Picture objects are drawn as filled gray boxes when their layer is inactive in gray mode. o xfig no longer requires fonts that are named "-adobe-..." (e.g. for RedHat systems with URW fonts). o Updating the attribute panel from a compound object will retrieve (only) the smallest depth from the compound. o When scaling an object, the line thickness is no longer scaled with it o New measuring modes: angle, length, area and tangent. See Editing section in html docs. From Alex Durner. o New feature to add tangents and normal lines to curves. See Editing section in html docs. From Alex Durner. o Splash screen on startup. Disable with -nosplash (resource Fig.splash). Interior logo by Marc-Aurčle Darche. o New command-line option -grid_color (resource grid_color) to set the color of the canvas grid (default: red). o New option to print grid when exporting or printing (see printing/ exporting section in html docs). o When drawing an arc by specifying the center point, a circle is drawn showing the radius of the arc as the user drags the mouse, then when the first end point is clicked an arc is drawn as the mouse is dragged. The user then clicks in the direction the arc should go, followed by the final angle to complete it. o If the Ruler unit is Imperial (in), you may have xfig display measurements using fractions where possible. If a measurement can be shown as an integer multiple of 64ths of an inch (or 32nds, 16ths, etc.) it will show it as such (e.g. 3-5/64 in), otherwise a decimal value will be shown (e.g. 3.085 in). o When opening a compound object, if the middle button us used to open the compound, all other objects on the canvas are kept visible. From Alex Durner. o When opening a compound object, the "point positioning" indicator is enabled, allowing you to set the bounds of the compound according to the indicator when you close the compound. o Zero-crossing lines on canvas have own command-line parameter (-zero_lines) and resource (Fig.zero_lines) for setting color separate from page border color. o Smooth factor when exporting to bitmap format is now a pull-down menu with: No smoothing, Some smoothing, More smoothing. o When flipping compound objects with text, a vertical flip will now shift the text to maintain its relative position to the other objects in the compound and its angle is rotated by 180 degrees minus the original angle. This behavior will for example, keep the orientation of a text inside a polygon consistent with the polygon. A horizontal flip of a compound containing text will change the angle in the same way. o Three-D borders for buttons, etc reduced from 2 to 1 pixel for "lean" look (resource Fig*shadowWidth in Fig-color.ad). o Additional JPEG file format (EXIF) added for import. These usually come from digital cameras. o Validation for integer spinners - doesn't allow non-numeric input when typing in values directly. o When scaling an object, the scale factor is shown in the message. window in addition to the width/height. From Alex Durner. o New url for pstoedit (mentioned in installation.html). o When picking points of an object at high zoom, the tolerance has been reduced to make it easier to pick the correct point. o When "graying" inactive depths, the inactive objects are drawn first followed by active objects ensuring visibility of active objects. o xfig now draws "grayed out" picture objects (inactive depth) as a gray box with the filename only. o Line style in edit panel now shows graphic of style instead of textual description. o Cap style in edit panel was inadvertantly left off open-splines. o Popup dialog to edit behavior of spline point now pops up near the point being edited. o When cancelling drawing a picture object from the popup editor, the empty object is removed rather than showing a in the box. o Pressing Return or Escape in popup message window will dismiss it. o In picture browser popup, double clicking or clicking and pressing Return will apply the selected picture AND close the browser. o New popup query if updating the depth in a compound object would result in any depth exceeding the maximum. The popup gives the user the option to cancel the depth update part. From Marcus Eger o More consistent placement of Cancel/Ok/Set etc. buttons in dialogs. Generally, the Cancel button is first followed by the others, and where possible, they are at the bottom of the dialog. o More meaningful message "Cut buffer is empty" if there is no .xfig file in the user's home directory. o New MetaPost driver for TransFig 3.2.4 supported. o New option for binary CGM export (must have TransFig 3.2.4 too). The ralcgm program is required for this option. See ftp://ftp.cc.rl.ac.uk/pub/graphics/ralcgm/ o In popup edit panel for compound objects, one may easily shift a compound object by changing either corner's x, y values and pressing return or scale it by changing the width and/or height and pressing return. o "condensed" alias for "narrow" fonts (urw changed their helvetica- narrow to helvetica-condensed). o Pressing escape in a popup dialog will dismiss it. o Zoom/Unzoom (Shift-Z/z) changes zoom by a factor of 1.5 instead of adding or subtracting 1 from the zoom value. Also, the zoom/unzoom is centered on the canvas. o Exporting to JPEG doesn't require compiling with USE_JPEG defined in Imakefile. o Minimum and maximum depths of objects in a compound are displayed in popup edit panel. o Named styles where user can save attributes that are often used for quick access. For example, the user may want dashed, thick, red lines often so he can save those attributes and call it (e.g.) "thickred", and easily call it up later. See the html docs in Main Menus (the View/Manage Styles...) menu entry. NEW LIBRARIES and Examples: o Poster advertizing German version of "Little Shop of Horrors" in Libraries/Examples/poster.fig. From Kai-Martin Knaak o Three new Examples from Carlo Kopp (in Libraries/Examples): Python-4.fig - RAFAEL Python 4 all aspect agile heatseeking missile YF-23A.fig - Development example of the USAF's Northrop-MDC YF-23A tsr2-side.fig - Notional camouflages for BAC TSR.2 production aircraft. o Many new country flags in the Libraries/Flags directory. Now organized by region of the world (e.g. Africa, Europe, MiddleEast). o New flags of Bosnia and Slovenia with vector coat of arms in Libraries/Flags directory from Roman Maurer o New maps of Yugoslavia, Macedonia, Croatia, Bosnia-Herzegovina and Slovenia (Libraries/Maps/Europe) o New maps of Russia, Kazakstan, Kyrgyzstan, Tajikistan, Turkmenistan and Uzbekistan (Libraries/Maps/Asia) o New Avery label templates in Libraries/Labels directory, including a CD label, Avery_5931, done by William Chimiak. o New Avery and PerfectData Corp CD label templates in Libraries/Labels directory, done by Len Hickey. o New computers and printers in Libraries/Computers library from Ernst Pisch o New network library devices Extreme Networks Inc. Black Diamond and Summit 5i network switches, Net Gear Hub, and new CODECs in Audiovisual library from Bill Chimiak o New DSP component library from Jakub Stastny o Standard welding bevels library from Erik Engh (Libraries/Welding) o Canadian map from Seymour Green o A Uno hand (card game) drawn by Roland Rosendfeld (Libraries/Examples/uno_hand.fig) BUGS FIXED: o Undo of join/split now works correctly. From Pieter-Tjerk de Boer o Pulldown menu for object library didn't always go away while loading library o If -library_dir was relative path, any imported pictures in library files wouldn't be found. o If in text draw mode and user uses Alt- accelerator, the compose LED would stay on o Middle mouse emulation for 2-button mice wasn't accepting Alt-Right- click, only Meta-Right-click. o If one created a new figure and didn't save it before exporting, the export command was malformed resulting in an error message. o Numeric locale setting moved to routines that read and write Fig files so that the user's numeric convention is used in everything else. o Point positioning was truncated in the negative X and Y regions of the canvas instead of being rounded. o -b (border margin) wasn't being passed to fig2dev for PDF and PSTEX output. o xfig only recalculate the bounds of compound objects being read if there are no bounds following the "6" or they are all 0. This fixes the problem introduced in 3.2.3d where objects that were bound at a certain point positioning were rebound at the current positioning. o When xfig reads in a .fig file (merge_file or load_lib_obj) it will not put the file into another compound if it contains only one compound. This will prevent the double compounding of library objects or merged files. o If a compound with more than 64 strings was edited, xfig segfaulted because the limit wasn't checked. This is fixed, and the limit has been increased to 200. o Typo in figx.h. "#ifdef XAW3d" instead of "#ifdef XAW3D" (capital "D") o If the XFIGDOCDIR directory didn't already exist, install.doc failed. o The "make install.all" directive did not install the executable, as the README file said is would. This has been fixed. o Deleting a region (middle mouse button delete) of a figure resulted in all other objects dissappearing after a screen refresh. o If the user mistakenly clicked the *left* mouse button on a point where he wanted to *split* a line, the ability to split was turned off. o Toplevel library directory wasn't included in library menu when it contained .fig files. o Subdirectories without any .fig files appeared in the library menus, contrary to the documentation. o If xfig was renamed to anything else, the command-line arguments and X resources weren't parsed by the Intrinsics. This is fixed. o Some versions of "make" don't like the blank line produced by the "#ifdef I18N" in the install.html section of the Imakefile, so it has been reworked to get around that bug. o Array placement with horizontally/vertically constrained copy works now o Html "options" page showed "-pa" as abbreviation for -paper_size, when in fact it is now "-pap" because of the new "-pageborder" option. o If display zoom was large (> 20) and grid was turned on, very large pixmap was being created for the grid. o Inconsistancy with "char" vs "unsigned char" in get_canvas_clipboard(). o Text input and editing more efficient when redrawing large fonts. o Box curve indicator now appears when in "convert box<->arcbox" mode. o If user called xfig with empty (but existing) file, the filename was not retained for subsequent save. o Cleaned up redrawing of corner markers when editing objects from popup edit panel. o Scaling arcbox didn't report scaling messages. o When scaling rotated ellipses, scaling messages were overwritten. o Improved redraw when moving/scaling/copying objects and screen is redrawn. o Drawing units indicator was not updated when reading Fig file. o Cleaned up "move point" code. When moving a corner point of a box or compound or the radius or diameter of a circle or ellipse, it would first make the object dissappear until the mouse was moved. This doesn't happen anymore. o Command-line -userunit (X resource Fig.userunit) were overwritten when reading Fig file. Now it is only changed if units are inconsistent with value in file. E.g. if file has "Inches" and xfig has "cm", xfig changes to "in" when reading file. o A few files were left open that should be closed. o If the print and/or export panels are up and the figure units are changed from/to Metric/Imperial, the figure size wasn't updated in the print/export panel(s). o Missing link from editing.html file to "Paste Objects" in main_menus.html. o Bug in array place item - didn't work when number of X copies and Y copies = 1. o Bug in *undo* of array place - didn't account for adding back object depths o (dx, dy) values weren't displayed when moving the midpoints of a line or arc. o While drawing freehand (middle mouse button start), if the user wanted to delete points by holding down the shift key and pressing the left button, moving the mouse would still add points to the object o PNGINC Imakefile variable added to specify where png.h is located (was already there in fig2dev) o The depth counts were erased when deleting a region of a figure. o If you choose one object from a library to place on the canvas and then popup the library panel and choose another object, the depths from the temporary object following the pointer weren't accounted for. o Added "Fig*AllowShellResize: false" to the app-defaults file to fix a problem that some window managers have with xfig continually resizing itself o When saving path of imported picture, xfig thought path was relative to current directory when it wasn't o Added "|| defined(apollo)" in fig.h to include sys/types.h o Doc/FORMAT3.2 file had imported picture description line reversed with points lines o Doc/FORMAT3.2 file had incorrect values for object types in the first part of section 3. o Segfault when merging a Fig file with only color objects (no drawing objects) o No message when toggling on/off depth manager o If xfig couldn't open ~/.xfigrc for writing (e.g. because of permissions) it would segfault o Segfault when converting a 2-point line to a polygon. Bugfix from Tom Sato. o Segfault when creating a closed spline with three points, where the last two points are coincident. Bugfix from Tom Sato. o Typo in attributes.html in describing the selection of the previous or next attribute with mouse buttons 2 and 3 respectively. For mouse button 2 it should read "previous" and for button 3 "next". o Typo in Doc/FORMAT3.2 and Doc/html/fig-format.html for backward_arrow description: said "(0: no forward arrow, 1: on)" instead of ... no backward ... o Added $(DUSESMALLICONS) to dependencies for main.c in Imakefile o Reduced height of object edit panels by only displaying 3 comment lines and 6 x,y pairs before scrolling. o Special texts weren't filtered by the depth filter when exporting to combined ps/latex or pdf/latex o Various typographical errors found by Daniel Frčrejacque o Segfault if fast export (Alt-Shift-X) is done before either the file, export or browse panel was created o When xfig was compiled with WHEELMOUSE support, zooming was always "centered" even not zooming with wheel o Typo in Fig.ad resource file for pasting text using F8 key o When doing a panic save (segfault, etc.), xfig now closes any open compound objects first o Bug in importing GIF file. File descriptor changed between first open and final close. o Bug in Imakefile with JPEGINCDIR o Had to include SimpleMenu.c and header files because of changes to some Xaw SimpleMenu implementations that were incompatible with xfig's own SmeBSB object o Bug in "Figure size" label in export panel caused segfault sometimes o Macro call (up_part) in e_update.c caused problems on HP/UX ANSI compiler o Same compiler takes issue with empty action records in w_style.c: library_actions[] ={}; Removed because it isn't used anymore. o After pressing the "Reread" button in imported picture edit popup, the Shrink, Expand and Original size buttons were disabled o Bug in SmeCascadeP.h when not using 3D widget set (Xaw3d) o One remaining use of sys_errlist[] should have been changed to strerror() in f_util.c o Pressing Escape while drawing an object caused segfault o When line type is dotted and the dot gap is < 0.5, XSetDashes() produced "Bad Value" error. Found by Tom Sato o init_break_tag() and init_break_only() each had an extraneous parameter (loc_tag) which wasn't used and wasn't passed by the caller anyway. This caused havoc with (at least) the gcc optimizer on an Alpha processor. Found by Jay Estabrook. o If you open a dimension line compound object and close it with zoom != 1, the text is drawn unzoomed o Didn't allow smoothing when exporting to AutoCAD slide file. o Changing browser or pdfviewer in dialog had no effect. o Fixed problem with RedHat imake rules not installing Doc/xfig.man properly. o When making a compound object including lines that have arrowheads and large coordinates (>= 100000), an incorrect bounding box was produced. This same bug was in fig2dev 3.2.3d and earlier. o Drawing an arc by starting with the center and dragging it out now reports the angles of the endpoints after clicking on first endpoint instead of incorrectly reporting the radius. o Checks that closed splines have at least 3 points when reading Fig file and removes any that have fewer. o Exporting with color TIFF preview option missing parameter when calling fig2dev o Export grid option disabled for languages other than PS/EPS/PDF/bitmaps o Not really a bug, but the message that tells the user when xfig is converting a figure from an older file format to the current format has been removed. o When changing the height of xfig, the number of buttons per row on the mode (left) panel increase OR decrease as needed. o When reading a Fig file with different units (metric/imperial) than the current figure didn't change the ruler tick spacing. o Chemical Process Flowsheet library Valve_horizontal and Valve_vertical valves reversed. o Bug in forcing absolute path for picture objects in libraries o Bug where xfig may change the Major/Minor printing/export grid tick values from "None" to 0.0 o When an imported picture is compressed but the .fig file has the uncompressed name, export failed. o Xfig allowed "splitting" a picture box into a polyline. This has been fixed to disallow it. o Queries user if hasn't saved named styles after adding or deleting same. o Print-to-batch-file didn't call print_to_file with all parms o xfig crashed if the window manager deleted the color popup panel in the popup editors ---------------------------- Patchlevel 3d (May 29, 2001) NEW FEATURES: o New Imakefile variable XFIGDOCDIR points to directory for xfig doc files, which may be different from XFIGLIBDIR o New aircraft from Carlo Kopp in Examples directory. These may be reproduced for educational and other non-commercial use only. o Support for importing PNG image files added o GIF transparency for imported images honored by fig2dev now o New option to print only active layers when exporting or printing (see printing/exporting section in html docs). o When loading a compressed Fig file that is either read-only, or is on a read-only file system (e.g. a CDROM), xfig uncompresses it into the temp directory (env TMPDIR, or /tmp if TMPDIR environvment variable is undefined). o New Maps library - currently contains Most Canadian provinces, USA coast and states, most of the continents and a world outline World outline map and United States by Steve Eichblatt o I had forgotten to credit Kai-MartinKnaak for his Mechanical_DIN library of mechanical drawing symbols from July 1998 o New Chemical Process Flowsheet library by Volker Siepmann o New Laptop computer and Ericsson R320 cell phone in Libraries/Computers from Dirko van Schalkwyk o New PMOS FET (Field Effect Transistors) and NMOS FET library objects in Electrical/Schematic library - from Min Xu o New network devices in Networks library from Bill Chimiak: atmswitch.fig - generic ATM switch dsu-csu.fig - Digital Service Unit/Channel Service Unit smartbit.fig - Netcom Smartbit network tester o New Catalan flag in Flags library from Francesc Burrull i Mestres. o New office building (office2.fig) in Buildings library from Brian V. Smith o New variable PRINTCAP in Imakefile to specify where the printer capabilities file is (default /etc/printcap) o New drawing: plan view of house and backyard (Libraries/Examples/house_plans.fig) from Scott Gordon. It may not be used for profit without express written permission from Scott. o xfig recalculates the bounds of compound objects read in from the file, ignoring the bounds values in the file. This makes it easier for Fig file generators to produce compound objects since they don't have to know how to calculate the bounds themselves. fig2dev doesn't even use those values but recalculates them upon reading the file. o New VA Linux machines in Computers library from Yazz Atlas o Increased maximum number of libraries to 100 o New and improved library object Computers/film_digitizer (and in Hospital/film_digitizer) from Bill Chimiak BUGS FIXED: o New cascaded menu for the Fig object libraries. This reduces the height of the menu to allow many more libraries, by arranging them hierarchically. This required writing a subclass of the SmeBSB Athena widget. o When browsing libraries or merging figures, identical user colors were multiply defined o Fig library objects may use imported images because the absolute path is forced in those cases o When modifying an existing centered or right-justified text, pressing enter moved the cursor to the X position of the beginning of the string just modified instead of its anchor point o "Delete Unused" button sensitivity not reset when loading subsequent Fig files o If -library_dir (Fig.library_dir resource) pointed to a *file* of Fig library directories, sub-directories weren't added to library list o If a bad Fig file was previewed in a library, xfig would display a bad preview and segfault of the object was selected o Incorrect dx/dy distance reported when moving object/point o Better support for Cygwin - Importing eps files changes to the directory of the file to avoid pathname differences between Windows and Unix/Linux/etc From Pierre Humblet o Can now rotate boxes and arcboxes by -90, -180 and 180 degrees in addition to 90 degrees o A compressed .fig file is only uncompressed if the directory is writable o When reading a Fig file, if there was a bad object inside a compound, xfig would discard the entire compound. o When reading a Fig file, if there was an incomplete or bad object, the storage wasn't freed in some cases. o xfig would stop reading a Fig file as soon as it encountered a bad object o xfig now uses its own my_strdup() so it will compile on those machines that don't have strdup() o "Minitower" computer in Fig object library of computers had an illegal Fig object o Typo in Doc/FORMAT3.2 file in the join style descriptions. Round and bevel values were reversed (correct values: Round = 1, Bevel = 2) Also, fill pattern list was incomplete and incorrect, and arc subtypes were switched. o When cancelling modification of text using text tool, refreshing of original text wasn't done o Comments longer than 200 characters caused problems. They may be unlimited in length now. o Some functions inconsistently declared static/non-static o Wasn't allowing negative rotation angle in indicator panel o Typographical error in xfig.man - resources "canvasBackground" and "canvasForeground" should be "canvasbackground" and "canvasforeground" respectively (no uppercase letters) o Updating objects didn't refresh the updated object correctly if the bounds changed o The lengths and lines drawn when "showlengths" is enabled has been cleaned up to remove detritus left behind o There was a bug in sizing of imported EPS images. They were too small by the equivalent of one pixel in width and height. Strangely, this also affected the background color in some cases. o When merging or pasting a figure of opposite unit system (metric vs imperial), xfig used the wrong scale factor. o If malloc fails when xfig tries to create a Fig object, the null pointer was subsequently dereferenced o Objects at MAX_DEPTH (999) were sometimes unaccounted for, meaning they wouldn't be refreshed in some cases. o Balloon delay value wasn't visible in Global Settings panel o When updating depths in a compound, xfig didn't check for depths exceeding the maximum depth (999) o Grid calculations didn't coerce types properly, resulting in strange grid in negative canvas region o Empty lines in the ~/.xfigrc file were causing xfig to segfault o Updated fig-format.html to correctly reflect Doc/FORMAT3.2 o If a region was deleted (middle mouse button) and undone, the recovered objects were invisible except for their grab corners o If an object was selected from a library while it was still loading and placed on the canvas after the library finished loading, xfig would segfault o When pasting or merging objects, xfig would recompute colors of already imported pictures in current figure even if merged/pasted objects didn't contain any pictures o When scaling a compound containg text, text size may have exceeded MIN_FONT_SIZE or MAX_FONT_SIZE limits o Font name list was freed when it shouldn't have been, when using -noscalablefonts o Changing depth of an object in the edit panel didn't always update the depth manager correctly o Actual message was missing from "Error during ..." export message o Undefined user color in Libraries/Knitting/Symbols/purl-dash.fig o Removed unused user colors in various Library symbols o Bug when merging or pasting figures with user-defined colors. o No more than 100 points are displayed for polylines, polygons in popup edit panel to prevent system meltdown. This doesn't affect the maximum number of points *allowed* in a polygon/polyline, only the number displayed. o Quotes around definition of MKDIRHIER should not be there in Imakefile o Made all references to Xaw header files use #ifdef Xaw3d to include 3d header files o Added back requirement that fonts (except Zapf Dingbats and Symbol) are iso8859 encoded o When editing a compound object containing text, and the canvas zoom is != 1.0, the zoomed text size was used instead of the unzoomed o Printer choice menu now discards any empty or duplicate printers that are in /etc/printcap o A more robust algorithm for finding the center of an arc given three points on the radius is in place. The old algorithm gave up too often, making some operations on arcs (e.g. rotate) fail. o Rounding error in zoom-to-fit-canvas produced bad centering of figure o Maximum number of printers increased to 1000 for lprng systems, and is now checked for exceeding maximum o Export to PDF now disables page size, orientation, etc. since PDF is meant to be imported into pdflatex or other processors o Fixed a bug introduced in 3.2.3b which made selecting objects difficult at higher zooms o When editing a compound, if either the width or height was made 0, divide by 0 would occur o Line lengths weren't erased after creating arc box (showlengths on) o Doesn't allow coincident consecutive points in objects or boxes with zero dimensions (coincident corners). Also, doesn't allow box or arcbox with zero x- or y-dimension. o Line width indicator didn't always update on some systems o Temporary files weren't closed before deleting them in read_gif, read_tif and read_ppm o Undoing the conversion of a spline<->line or line<->spline would crash o When loading a figure from the recent files list in the File menu, imported pictures with relative paths would not load o Illegal box object removed from Libraries/Examples/lidar.fig o Typo on html docs - button 3 cancels constrained copy, not button 2 o Keyboard accelerators mislabeled - flips objects left/right, unshifted flips them up/down ----------------------------- Patchlevel 3c (Jul 26, 2000) NEW FEATURES: o New export shortcut Shift-Alt-x or Shift-Meta-x to export using current settings without popping up the panel o New print shortcut Shift-Alt-p or Shift-Meta-p to print using current settings without popping up the panel BUGS FIXED: o Added -m 644 to "install" directives in Imakefile to make updates easier in future (no read-only files) o I18N text handling fixed (bug introduced in 3.2.3b) o If a filename with an absolute path was given when starting xfig, it prepended the current path to the path given thus generating a path that didn't exist. o "Film digitizer" in Fig object library of computers had an illegal Fig object o Pixmap bits for sm_check_bits should be unsigned in w_util.c ---------------------------- Patchlevel 3b (Jul 19, 2000) NEW FEATURES: o Object library now shows icons of all objects. The size of the icons is selectable from 40 pixels to 120 via a pulldown menu and resource (Fig.library_icon_size). The the old "list" view is also available. o When drawing an arc by specifying the center point, a circle is drawn showing the radius of the arc as the user drags the mouse, then when the first end point is clicked an arc is drawn as the mouse is dragged o Simplistic super/subscripting by typing Ctrl-^ for superscript and Ctrl-_ for subscript. It creates a new string in the proper size and position for super- or subscripting. May be nested. Does NOT work for centered or right-justified text. from Ian Hutchinson with improvements by Brian V. Smith o new Imakefile variable NEED_STRERROR to allow for systems that don't have the sys_errlist[] error string array (this is already in fig2dev) o Additional JPEG file format (EXIF) added. These usually come from digital cameras o New library of knitting symbols from Kate Hedstrom o New Cisco network devices in Libraries/Networks from Louis B. Moore o New 10/100 Ether network hub in Libraries/Networks from Dirko van Schalkwyk o New libraries from Al Delgado for Chen's model of Entity Relations (Libraries/ERD) and symbols for various widgets, e.g. buttons, sliders, scrollbars, etc. (Libraries/GUI) BUGS FIXED: o If the BSD symbol is defined but has no value, the "#if" condition #if ( !(defined(BSD) && (BSD >= 199306)) && ... o Importing 24-bit PCX files works now with the new PCX reader from Russell Marks (public domain). o Importing PPM images with more than 256 colors failed because it was first converted to 24-bit PCX, which xfig couldn't read before now. o Importing TIFF files (which is first converted to PPM them to PCX) works now with new PCX reader to handle 24-bit images. o Bug where updating an arrowhead used the line thickness from the current settings instead of the line being updated to set the arrowhead thickness. o "=" instead of "==" in checking if picture type is XBM to allow updating pen color from update button o xfig would stop reading objects from a file when it encountered one bad object unless it had already read one or more good objects o If a polygon was created with ALL coincident points (i.e. zero width/ height, xfig would remove ALL points when reading the file and would subsequently crash. Objects with zero width/height are now removed when reading the file. o If a box with fewer than four points or a polygon with fewer than three points is read from a file, xfig removes it o Could still move point of object even if its depth was not active o References to "make" in Imakefile changed to "$(MAKE)" o When vertex number display was turned on, canvas wasn't refreshed to show them o When the page border was turned off, the zero-crossing lines weren't redrawn o User colors defined in the current session weren't saved with the figure. o User could click on text in disabled layer when in text mode o Bug which allowed only 511 user colors instead of 512 o Background color of RGB slider lock buttons changed to random color when lock turned off o User colors in current figure would be lost if user previewed more than one file before cancelling file popup o "Transparent" color menu button for GIF export wasn't updated after export panel was created when loading new figure o Spurious comments would appear in spline after editing control point o If editing spline point for curvature and spline line had zero thickness, the spline would dissappear during edit o Incorrect declaration for put_msg() o Prepended $(DESTDIR) to $(XFIGLIBDIR) directory variable in Imakefile to be portable o Changed w_menuentryP.h and w_menuentry.c to explicitely use X11/Xaw3d/... path for menu entry when user has XAW3D set in Imakefile to use 3D Athena Widget set o xfig now uses gunzip instead of uncompress to uncompress .Z files to be more portable for Cygwin environment o Current directory for loading/saving figures was overwritten when changing export or picture browse directory o Loading a .fig file or importing a picture from an MSDOS filesystem failed because xfig tried to see if the file existed with a suffix of .Z, .gz, or .z, all of which were reported by stat() to exist because it apparently truncates any suffixes after the first o Bounding box of objects in negative region weren't calculated correctly when positioning grid was on o If "allow negative coordinates" was turned off, one could still pan into negative region by dragging mouse on side ruler with middle button pressed o Bug which prevented dragging rulers (with middle mouse button) into negative region unless it had been moved into the positive region first o If user specified a -geometry on the command-line and then switched to Portrait mode, the geometry requested was overridden o Various bugs in export commands when calling fig2dev o Inconsistent prototypes declared for pw_arcbox() and curve() o One of the header values for TIFF files was incorrect (was "DD", should be "II") o When scaling a box and the point positioning grid is more coarse than the points in the box, and you try to grab a corner of the box, xfig thought you want to scale either horizontally or vertically only. o Excessive updating of layer buttons when reading Fig file fixed o Problem when exporting to GIF with transparent = background o Certain files are now opened in binary mode ("wb" or "rb") for DOS compatibility o Rulers show units now every 10 units (e.g. 0cm, 10cm, ...) ---------------------------- Patchlevel 3a (Jan 19, 2000) NEW FEATURES: o Library of UML objects (Unified Modelling Language) From Andreas Ludwig BUGS FIXED: o w_menuentry (subclassed menu entry widget) has been modified to be compatible with the X11R5 Intrinsics besides R6 o Several bugs in sprintf statements which create export command o Incorrect lengths reported when drawing box with "showlengths" on and user scale != 1.0 (e.g. 1cm = 3km) o Declaration for preview_widget was both static and extern o Declaration for preview_pixmap was both static and extern o Two vars passed to XGetGeometry should have been int instead of unsigned int (CreateCheckbutton() proc) o Added '#include "w_msgpanel.h"' for every file containing calls to put_msg() or file_msg() since they contain varargs and should be declared as having variable arguments ----------------------- NOTE ABOUT GIF SUPPORT: Because Unisys has stated that they WILL charge royalties for the use of the LZW compression algorithm even in FREE programs, I have removed all traces of the GIF LZW compression/decompression code from xfig. Xfig now calls giftopnm and ppmtopcx to import GIF files. Screen capture writes a PCX file. Exporting is handled by calling the ppmtogif program from fig2dev. Patchlevel 3 (Jan 14, 2000) NEW FEATURES: o Arrow thickness is a function of line width by default now instead of absolute o If figure is modified and user does "File/New", xfig first asks if user wants to save the file before doing the "new" operation o Changed the "paste text" key in app-defaults file from F20 to F12, because most systems don't have an F20 key. The "Paste" key on Sun workstations (it is really F18) may also be used to paste text. o Changed default export border margin width to 0 o Re-enabled export magnification for EPS o New "Flags" group of library objects from Roland Rosenfeld. These are flags of Europe which Roland converted from a Sketch example. There is also Japan's and the U.S.'s flag which were drawn in xfig by Brian Smith o Added Ian MacPhedran's web site http://duke.usask.ca/~macphed/soft/fig/ for FIG-related information to the html docs under "Related Applications" in the "Getting and Installing Xfig" section o Moved allocation of xfig's 32 "standard" colors last in the widget setup procedure so that there is a better chance of the widgets getting the correct colors before the colormap fills up and xfig changes to a private map. o Assumes default of Letter(or A4 if metric mode) if no %%BoundingBox in imported eps o All traces of GIF decoding/encoding have removed from xfig so as to avoid the patent royalty issue with Unisys corp. xfig now calls giftopnm (part of the netpbm package) to read the GIF file and then ppmtopcx to convert it to a colormapped image that xfig's read_pcx routine can handle. o New depth manager. Enable/disable depths individually or all at once to selectively hide parts of drawing. Can also click on one depth button and drag mouse up or down to enable/disable multiple buttons. Command-line options -showdepthmanager and -hidedepthmanager to control it (resource Fig.showdepthmanager). The default is to show it. o When updating the depth of a compound object, the relative depths of the objects inside are retained, with the object having the smallest depth number being assigned to the value updated by the user. For example, if you update a compound object to depth = 5, and it contains objects with depths 8 and 11, after the update they will have depths 5 and 8 respectively. From T. Sato. o Default depth for creating new objects is now 50 to make it easier to put new objects on top without having to remember to start the older objects at a depth > 0. o Xfig allows panning to negative x and y now. This is the default and may be turned and off with the -allow_neg command-line option and from the global settings panel. o Command panel has pull-down menus for File, Edit, View and Help operations. Default accelerators for these menus are Meta-F, Meta-E, Meta-V and Meta-H respectively. File menu includes list of recently loaded Fig files. o Comments in Fig files are preserved with the objects and are written back when the file is saved. Popup edit for objects allows entering/ editing of comments. Also, clicking mouse button 2 on the canvas in edit mode will popup a panel to edit comments for whole figure. o From the File/Open panel, you may startup another xfig process to open a Fig file. From T. Sato. o New join/split button to split a line/spline/etc into two, or to join two lines/splines etc together to make one. Also, will convert a box to a line by splitting between two corners, and close an open line or spline by joining the two ends. o Arrow keys, Home and End keys may be used to browse any of the lists in xfig. (e.g. Open file list, library popup object list, misspelled word list in spell checker) o Border option put back in for exporting to EPS and bitmap formats (fig2dev -b option). User may specify border margin in pixels (roughly). This will be a background margin area around the figure bounding area. o New background color option for printing and exporting - sets whole background of figure to this color. Available for all bitmap formats and PostScript, EPS, PSTEX and PDF o New background option to specify background color for figure. This works for all bitmap formats and PostScript (including pstex). This is passed to fig2dev as the -g option. o If your system uses /etc/printcap to define printers, xfig will make a pulldown menu for the printer selection in the printer panel. o New "smooth" button in export to smooth when exporting to bitmap format (e.g. GIF, JPEG). Causes fig2dev (using -S 2 option) to force ghostscript to render at 2x magnification which improves font rendering, then passes through pnmscale to reduce to original size, which also smooths the image by averaging colors of adjacent pixels. o Export/Print errors now appear in the popup error message window o Popup object editor positions itself adjacent to object being edited instead of possibly being on top of it o Xfig automatically chooses pwidth, pheight and the number of buttons per row on the mode panel (left side) if necessary, to fit on a small screen. If the user explicitely chooses any of those options, their choice overrides the automatic setting. o New PDF export driver (uses ps2pdf from the ghostscript distribution) o New CGM export driver (Computer Graphics Metafile) for fig2dev (and in xfig export menu). From Philippe Bekaert o More paper sizes (Japanese JIS B0-B10 and ISO A0-A9) o Middle button in paste mode will place object at its original position (where it was when it was placed in the xfig cut file) o "Spinners" increment/decrement by value appropriate to item being modified. E.g., fill intensity % now steps by 5% for each click of the mouse on the spinner arrows, and text step by 0.1. o Also, if mouse button is held down on spinup/down button, spinner counts automatically after "spinner_delay" every "spinner_rate" milliseconds (resources). o Fill intensity and Pattern fill now show image in popup edit panel o Can now draw arcs by defining: 1. Center point 2. First angle/Radius 3. Second point to deterimine direction 4. Final angle Initiate this mode by starting arc with mouse button 2. Original arc mode still available. From T. Sato o New color scheme (grayish instead of bisque) - can still use old colors by using Fig-color.bisque.ad or really old colors in Fig-color.classic.ad o I have made the web pages available from our server at: http://www-epb.lbl.gov/xfig A mirror site in Japan is http://www.lint.ne.jp/~masashi/xfig/index.html o Popup window with global settings (use Meta-g or Alt-g) containing: o checkbutton for tracking mouse in rulers o checkbutton for showing page borders o checkbutton for showing info balloons o checkbutton for lengths on lines o checkbutton for showing vertex numbers on objects o entry for max image colors o entry for image editor o entry for spelling checker o entry for HTML browser o entry for PDF viewer o checkbutton for turning on/off debug information Consequently, the balloon on/off checkbutton has been removed from the message window area o Two new "make" options: 1. "make install.doc" - install only the documentation files (i.e. man pages, html and pdf files) 2. "make install.libs" - install only xfig object libraries o Filename mask for File and Export panels can have multiple wildcard masks separated by blanks or tabs, e.g. "*.fig *.fig.gz *.fig.[Zz]" o Export wildcard mask is dynamically changed when selecting the export language (e.g. *.gif when GIF is selected for export). Thus, the Fig*export_panel*mask*string resource is defunct. o New format for browser resource will parse for "%f" and replace with the filename. Using this and the -remote option for netscape, xfig will either use a running netscape to open the help file (html) or will start one if one isn't already running. o PDF viewer resource is also parsed for %f (filename) o Xfig will first try the correct PostScript font name (e.g. AvantGarde) and then try a backup font name if the first fails. If that one fails too, it will use 6x13. In the past, because the AvantGarde, Bookman, HelveticaNarrow and Palatino fonts were NOT distributed with the X distribution from the Open Group (and the X Consortium before that), xfig would substitute fonts for those, that were close. Now it will try the correct one and switch to one of the backups if it doesn't exist. o FIGAPPS file updated with new information about GNU plotutils o Rulers shows fewer ticks for smaller zooms o Rulers show more labels between major ticks for larger zooms o New floppy disk library object in "Computers" o New firewall symbol and "generic hardware" library objects in "Networks" from Tomi Ollila o New "Optics" library includes mirrors, lenses, fiber optics from Kai-Martin Knaak o New Structural Analysis library includes plates, supports, loads, beams, coordinate systems and trusses. From Roman Putanowicz Please see copyright information in the Structural_Analysis/readme object. (Libraries/Examples/Structural_Analysis/readme.fig o More descriptive error message about non-existent or old app-defaults file o Removed restriction that fonts are ISO8859-1 encoded to allow, e.g. iso646.1991, which is what the scalable Schumacher fonts are. o New computers/terminals in Computers library, and new network comp- onents in the Networks library of objects. From T. Sato o When a compound object containing right- or left-justified text is flipped horizontally, the justification of those text objects is also swapped (i.e. right-justified text becomes left-justified and vice versa) o Warning printed if user uses Fig.geometry resource to size main xfig window - should only use -geometry command-line argument or pwidth/pheight args/resources. o Uses ANSI stdargs.h instead of varargs.h now From Roland Rosenfeld o Spell check command uses "%f" now instead of "%s" for filename o Can define BINDIR to install xfig in custom directory (see README file) o Xfig windows aren't unmapped now when user presses "Edit Image" to edit imported image file (not necessary) o When in edit mode and you hit Control-Return inside of a text box rather than just Return, it's a shortcut for DONE. From Jeff Hakner o When editing a compound object, any text objects in it are shown and editable. From Jeff Hakner o In library place mode, the change draw mode function was moved to Shift-Middle rather than Shift-Left. Shift-Left now has the behavior of placing the object and doing an edit on it. When you conclude the edit, it resumes place mode. This combined with including the text objects in editing compound objects, allows you to edit any text labels in library objects as they are placed. From Jeff Hakner o Rotation angle of objects may be floating point now From Marc Joosen o Spelling checker and search/replace popup more useful now o New "zoom to fit canvas" feature - Ctrl-Z accelerator in canavs will zoom the figure to just fit the canvas. New button in popup zoom dialog to do same. o After closing an open compound, the "Open Compound" mode is selected o If the Shift key is held down while mouse button 2 is clicked on an object, any comments in the object are displayed in a popup until the mouse button is released o New command-line option -flipvisualhints (resource Fig.flipvisualhints) which will flip left/right mouse indicator messages for mice whose buttons have been switched. o New import picture formats supported - TIFF and PPM o Added -hiddentext and -rigidtext command-line options and X resources to fill out the text flags options (first was -specialtext) BUGS FIXED: o In "move point" mode, mouse button 3 incorrectly labelled as "Locate Object", when in fact no function is associated with that button o Error reading GIF header under certain circumstances o For JPEG and GIF export, -g option was being passed to fig2dev even with no background color selected o Exporting to PDF using xfig actually exported to PS. Fig2dev does the correct thing, though. o Depth manager didn't update correctly if depth between two other depths was removed (e.g. when deleting an object of depth 51 leaving only depths 50 and 52, the indicator for depth 51 wasn't removed from the display) o PAPER_A4 pointed to A9 entry o Docmentation incorrectly mentioned "page_size" when it should say "paper_size" (Doc/html/options.html) o Split line didn't work on ArcBox o Opening a compound object, changing an object inside, closing the compound then pressing "Undo" would result in the original object outside the compound, plus the changed object still inside, and would then eventually segfault if the compound was operated on in any way. o Imakefile didn't install pdf files as advertised with "make install" o "XEvent event" missing from input tablet code in main.c o If xfig tried to import a compressed image file and the directory was not writable, it segfaulted while trying to close an unopen file o Inadvertantly removed "Help/Xfig man pages" menu entry o Wrong path for installation of the xfig-howto.pdf file o Bad hyperlink for "Help Menu" in html docs o Fig files with "#FIG" but no version number crashed xfig o "Show depth manager" missing from screenshot and description of global settings o Background color for exporting didn't have "None" option o PDF export ignored centering, background color and multiple pages options o Warnings from fig2dev weren't displayed when exporting o Various command-line options missing from man pages and html docs o When turning on or off the depth manager the canvas needed refreshing o Symbol "MAXCOMLEN" defined by xfig is already used on some systems o Character array illegally freed in screen capture procedure o There is a less restrictive copyright on the html pages. Instead of: "However, you may not modify any part of this documentation without explicit permission of T.Sato or Brian V. Smith." there is now: "Modification of this documentation is also granted as long as this copyright notice remain intact and name of the person who made the modification is explicitly written in the documentation. However, contact to T.Sato and/or Brian V. Smith is strongly recommended if you want to distribute modified version of this documentation." o "Smart links" wasn't working when copying compound object with link - the link wasn't copied o Preview figure wasn't freeing memory o Text lines with trailing carriage returns (^M) were read incorrectly from .fig file, causing following object lines to be included with the text object o Some calls to free_spline were passing wrong type of pointer Fixed by Bradley Kuszmaul o Call to init_point_array shouldn't have arguments Fixed by Bradley Kuszmaul o Changing to/from PostScript and LaTeX font type using the update button didn't work unless "update text flags" was also enabled o The CompKeyDB file didn't get installed correctly if user specified a path for DESTDIR (normally empty). o arrowhead thickness/width/height were being truncated to integers in popup edit panel o was using /tmp instead of TMPDIR env variable for xfig cut file if user .xfig file couldn't be used o cleaned up routines that "show line lengths" while drawing/moving objects (-showlengths). Much less detritus now. o bug when allocating more user colors than colortable can handle o message string not large enough for some of the balloons for the attribute panel. From Martin Kroeker o Fixed bug in arc arrows introduced when units for arrowhead width and height were changed to be the same as for arrowhead thickness o Pie-wedge arcs can no longer have arrowheads. o In the popup edit panel, if no numeric value was in either the fill intensity or fill pattern entry and carriage return was pressed, an illegal value might have appeared there o Filename sometimes trashed when trying to call external image editor from edit popup on imported picture o If the text mode is selected followed by the "Paste" mode, xfig would segfault o Another change to the "make install.doc" and "make install.libs" because some systems' install program can only take one file at a time o "make install.doc" doesn't install the Japanese html files unless I18N is set in the Imakefile (Internationalization) o If Fig.ad isn't installed, xfig died because "browser" or "pdfviewer" resources were NULL o Mouse function indicator wasn't being reset for cancel library popup o Cancelling the library popup wasn't quite working o If preview of any library object failed, user couldn't place any more library objects o Typing characters other than 'r', 'l', 'h' and 'v' are ignored when placing library objects on canvas o When calling external image editor (via "edit image" from importing picture object), argument list[0] wasn't name of image editor o When using the external image editor on an imported picture, xfig compared the file modification time before and after to re-read it if it changed, however the modification time before the edit was never obtained o Moved JPEGINCDIR definition in the Imakefile near the #ifdef USEJPEG for easier access o Bug in code which redisplays canvas sometimes left ghosts behind if a "move object" was cancelled o Center/Flushleft setting was not properly set from figure file o Align-to-canvas assumed US Size A or ISO A4 paper instead of using the current page size from export/print o Objects with large coordinates (e.g. 190000 Fig units) were drawn incorrectly because of a peculiarity in either the X server or the X Drawing procedures that didn't work correctly for screen coords > 16000. o If the canvas was either refreshed or zoomed while previewing a file, things failed miserably o Line counter corrected when reading Fig file. Was in error sometimes when reporting bad input lines. o Fill patterns (e.g. bricks, vertical lines etc.) were not zoomed correctly in figure preview o INLINE definition changed from "inline" to "__inline" to satisify DEC Unix or Irix and Solaris OSs o Removed all "NullParameter" from Imakefile because OpenWindows doesn't have it o Changed XPointer to XVisualInfo * in call to XFree in main.c for those still running OpenWindows o The "About Xfig" window didn't trap for "Delete Window" so a window manager that substitutes "Destroy Window" in that case would kill xfig o If user is previewing a figure (via popup file panel) and the canvas needs to be redrawn it is deferred until the preview is finished, preventing the Bad Window error previously seen. o Doesn't segfault now if no app-defaults file is installed o Bug fixed where a rotated string with only blanks (spaces) would segfault o Mask for attribute panel button management changed to unsigned long to insure 32-bit values o When reading in a figure containing an image, any offset in the file panel was applied to the SIZE of the image. This is obviously incorrect. o When cancelling the file panel during a file preview xfig would sometimes die with an X error. Fix from Patrick Gosling o There was a bug when converting Fig 3.1 splines to 3.2 under certain circumstances o Changed fig.h to always include (sys/param.h) o Various function mis-declarations and signed/unsigned casts fixed by Jonathan R. Ferro o Bug in image capture fixed by Jonathan R. Ferro o Not really a bug, but a change in default - define HAVE_NO_DIRENT in the Imakefile if your system DOESN'T have dirent.h o When browsing pictures in the import picture interface, if you single- click on a filename and then close the browse panel, it now applies that picture. In the past you had to double-click on a filename to apply it. o Cleaned up error reporting of line numbers in Fig file o cur_dir[] array in mode.c wasn't large enough (changed to PATH_MAX) From Martin Pahl o Hidden, Rigid and Special text flags weren't updated correctly with update tool o -international and -inputStyle added to help message. o Multiple page option was being turned off but pulldown menu showed otherwise o If the user changes directories in the file/open panel but then presses "cancel", the original directory is restored now o Stops parsing library directories when limit is reached o Doc/FORMAT3.2 file (and all previous) incorrectly described the bounding box for compound objects as having upper-right and lower-left values, when in fact they have upper-*left* and lower-*right* bound values o On a PseudoColor server, with xfig in -mono mode, it attempted to store a color illegally o Editing of comments for picture objects wasn't retained o Library directory now may include files with more than just .fig in name (e.g. .fig.gz, .fig.Z, etc). Also, explicit check is made to ensure that whatever matches *.fig* isn't a directory. o Missing quote for MKDIRHIER variable in Imakefile: XCOMM MKDIRHIER = "/bin/sh /usr/bin/X11/mkdirhier" o When using small icons, xfig would still use 3 buttons per row on small screens even when not necessary. o Allocation error in reading some pcx files o Bug in HSV color sliders when clicking left or right (increase/ descrease) mouse button o Bug in HSV color sliders on 16bpp PseudoColor visuals --------------------------- Patchlevel 2 (July 2, 1998) BUGS FIXED: o Placing a library object caused xfig to die after recursing for a long time o Arrowheads in xfig 2.x files were incorrectly converted to 3.2.1 (they came out too large) o Imakefile didn't properly install Electrical/Physical and Electrical/Schematic directories o Some variables multiply defined in u_draw.c o Some systems' "install" program don't have the "-d" (create directory) option so I have reworked the install part of the Imakefile --------------------------------- Patchlevel 1 Final (July 1, 1998) NEW FEATURES: o Preview of figure is created when you single click on a filename in the popup file panel. It also shows the size of the figure. o Library feature - load a library of Fig objects and pick and place objects from the library on the canvas where you want. See the man pages for details, and see Libraries/Examples for some examples. From Stephane Mancini modifications by Brian V. Smith o Preview of library objects in library popup similar to figure preview by Brian Smith o The library objects in the Electrical and Logic libraries were done by Peter Hiscocks o Xfig tutorial (PDF) in Doc/xfig-howto.pdf. Also available from the Help menu. Written by Peter Hiscocks o "make install" installs the Fig object libraries to the library directory. The default is $XFIGLIBDIR/Libraries (/usr/lib/X11/xfig/Libraries), which may be changed in the Imakefile. o When pasting a Fig object from the xfig cut buffer it appears under the mouse (or near the mouse if pressing the "Paste" button) where it may then be moved around on the canvas before pressing mouse button 1 to place it. o Unit box in upper-right corner now shows the scale (e.g. 1cm=3km) This necessitated making the top ruler a little narrower to make the unitbox fit. If the mode panel is on the right side, the side ruler is made wider to fit the unit box above it. o The path of imported pictures is saved as relative path if picture is in subdirectory of main figure file, else it is saved as absolute. from T. Sato o When drawing a line, moving a point on a line, or adding a point to the end of a line, the angle to horizontal is shown in the message window o Pressing -I turns on and off new feature that draws red horizontal and vertical lines near the line you are drawing, or point you are moving, to indicate rise and run. Also, the length is shown next to and above the horizontal and vertical line respectively, and the actual length of the line is shown near the line itself. The command-line argument -showlengths (resource Fig.showlengths) will enable this feature as xfig starts. o Print popup button is active even when print panel is up which makes it easy to force it to the top of the window stack if it is hidden o Pressing the File button in the command panel while the Export panel is up will popdown the export panel and popup the file panel. The converse is also true - if the Export button is pressed while the file panel is up, the file panel will be popped down and the export panel is popped up. o When merging a file/figure into the current figure it is made into a compound object first o Merging a figure keeps the file panel up to be able to merge more figures o Better memory allocation for temporary arrays when drawing objects - may be slightly faster now from T. Sato o Freehand line/polygon drawing - use mouse button 2 to start after choosing polyline. As the mouse is moved points are added to the line or polygon. NOTE - this changes the line drawing behaviour: Mouse button 3 is now used to create a single-point object. o Whole window screen capture in addition to area capture in picture object popup. The behaviour of the mouse has changed with this - Mouse button 1 captures whole window now and mouse button 2 is used to capture area of screen. o Characters added to Fig*browse_panel*mask*string to include .tif and .sld files o If xfig is started without a filename, the default filename is empty instead of unnamed.fig. This forces the file panel popup when save is done, to enter a new file name. o Variable time delay for popup information balloons, specified in milliseconds (-balloon_delay; resource Fig.balloon_delay) o If you enlarge the File, Export or Library panels only the file list area is enlarged to show more files o New "spinner" widgets to increment/decrement values in popup indicator entries (e.g. line thickness indicator popup) o Option of using either absolute values for arrowhead sizes or multiple of current line length (see arrow size popup) o Arrowhead thickness, width and height can be set explicitely in bottom panel for creating arrowheads. Update button also copies arrowhead size info to/from objects and indicator panel. The arrowhead width and height parameters are now the same units as the arrowhead thickness, which is units of line thickness, not 1/1200 inch as they were in previous versions of xfig. o Color popup menu in popup edit panel handles lots of colors better o Option of smaller icons for the mode panel (left side) by compiling with USESMALLICONS in Imakefile. See the Imakefile for details. Also see Fig.ad. Look for "icons". From Andrew Morgan (morgan@physics.ucla.edu) o New grid and point positioning setting at 1/8" (or 2mm in metric mode) o When moving, copying, moving a point of or adding a point to objects, all the "grab corners" of the other objects in the figure disappear to make the figure less cluttered. They reappear when the operation is complete. o Pull-down menu buttons have an arrow icon to show that it is a pull- down o Units such as "i" for inches and "c" for cm may be entered following coordinates in popup edit panel for editing objects (e.g. 3c for 3 cm) From Rick Richardson (rick@dgii.com) o When importing a picture file (eps, GIF, etc) xfig is more intelligent and faster about deciding the format o "Integer area zoom" option in zoom popup - if checked, when using the mouse to zoom an area of the canvas, the zoom amount will be an integral value (e.g. 2, 3, 4) o Compose key LED may be turned on for multi-key characters (e.g. a-umlaut etc) on Sun Sparcstations. See README file about COMP_LED. from Hans Werner Strube (strube@swing.physik3.gwdg.de) o New fig2dev driver for tk (tcl/tk) - Generates tk canvas and canvas objects. From Mike Markowski (mm@udel.edu) o Added "Alt" key definitions to the accelerators in Fig.ad to accomodate those machines which don't have a Meta key BUGS FIXED: o Line width is scaled with object scaling now o Arrowheads are scaled when scaling lines, splines and arcs now o Screen_res was incorrect for drawing tablets o When scaling a compound by using the "move point" edit mode, undoing the scale didn't work properly because of rounding problems. A proper "undo" is now performed. o Note: the -inverse (reverse video) option has been removed because the same effect can be achieved using "-cbg black -cfg white" o Made the export_panel*mask*string same as browse_panel*mask*string o User-defined colors weren't being merged properly in compound objects o If Paste was performed while opening a compound object, some objects outside the opened compound object may have been lost and xfig may have crashed with a segfault later. o ARC-BOX corner radius scaled incorrectly when box was scaled o ARC-BOX corner radius is now only scaled with Scale operation, not move point o Busy cursor wasn't being reset when reading some figures o Refreshing the screen while creating a Fig object (e.g. POLYLINE) refreshes that object correctly now o Updated pointer for hp2xx and additional pointer to Fig related apps in FIGAPPS file. From Ian MacPhedran o Declaration of clrtab array incorrect in f_neuclrtab.h - caused problems on Digital Unix. From Ian MacPhedran o When loading a figure that changes the canvas orientation (Portrait/ Landscape), the file modified flag was not cleared o When it can't save to a file, xfig now rings the bell and puts the error message in the *popup* message window o Trying to use the external image editor in the edit panel for an imported picture failed if the file was compressed o When switching to a private colormap because of importing a picture, xfig is better about matching the colormap of the popup edit panel o Objects not aligned correctly in large drawings due to bad choice of starting min/max values (use INT_MIN and INT_MAX now) o When running "xfig -right" (mode/edit panel on right-side) the popup balloons were too long, never showed the message and popped up and down because they appeared under the mouse. o Cleanup of many, many function declarations (mostly type void) o Inadvertantly used incorrect font for Avant-Garde o When undo'ing load figure, any objects using user-defined colors may not have been displayed correctly until doing a "Redraw". Also, non-existant user colors may have stayed in pen and/or fill color indicators. o Bug in size of imported Picture when clicking on "Use orig size" - image was slightly too small. Also bug when clicking "Use orig size" in metric mode - even worse scaling. o Code to check for bad font numbers when reading Fig file was in wrong place o Bug in pcx decoder - odd-width images caused seg fault. This would also affect importing eps files since xfig uses pcx output from gs. o Another bug in pcx decoder - wasn't allocating correct amount of memory for the image buffer. This would of course, cause segfaults. o Bug in "Fit-to-page" in metric mode fixed from Hans Werner Strube (strube@swing.physik3.gwdg.de) o Cleaned up mode button icons to fit within button area better o An old feature to prevent an expose event on the canvas from erasing a newly imported image while still in the picture editor is no longer needed and prevented screen refreshing o If screen capture is attempted with no Fig filename (e.g. when starting xfig with no file name) seg fault occurred. from T. Sato o Small correction to I18N draw_string routine from T. Sato o Not all calls to fig2dev had I18N localization options passed from T. Sato o If you create a new figure (no name yet) and try to export before saving, xfig asked you if you wanted to save the figure first. If you said yes, it would popup the file panel to choose a name and save. After that though, it wouldn't do the export as you first requested. This has been fixed. o Added && !defined(__GLIBC__) to declarations of random and srandom for systems with glibc o Imported eps files containing "initgraphics" commands weren't working correctly. This has been fixed by defining initgraphics and initmatrix as {}. o Yet another #if added to the never-ending list. This one is for sys_errlist. FreeBSD systems already define it in stdio.h. o Inconsistent declaration uncompress_file (static) o Missing braces around initializers for headers structure for imported bitmap file types o Some unused variables and procedures removed o Incorrect casts in e_align.c o Bug in figure size in export and print panels - bounding variable was clobbered soon after being calculated o Allowed saving over a read-only file if file panel wasn't created o Various problems with New figure->Export->File popup sequence either segfaulting or permanently disabling xfig buttons and canvas fixed. o GC wasn't properly setup for dragging rectangle on screen for screen capture for some systems. o Very small arcs "blew up" making very large arcs on screen o Bug in draw_arc() - would free unallocated memory if arc was small o Imakefile had w_icons.o in XFIGSRC instead of w_icons.c o Fixed annoying warning about StartScroll action not found on Linux systems that use the "modified" Xaw3d widget set (ARROW_SCROLLBAR defined, which makes the scrollbars look like the Windows scrollbars) o Mouse indicator was leaving bits of old text behind for long messages o Removed call to rint() because gcc can't find it on HP-UX o Move_point_selected() called set_mousefun() with too few args o Variable "text_translations" multiply defined o Fixed some bugs relating to updating dash-length/dot-gap in indicator panel from dashed/dotted lines o Bug fixed where update indicator (red box) didn't always toggle correctly o Undo of spline<->line conversion and box<->arc_box fixed o For some reason, the Solaris version of XtAppCreateShell references an argument beyond what the users specifies in the command line, causing a seg fault. Fixed by Martin Pahl (pahl@tnt.uni-hannover.de) o Renamed suffix for AutoCad Slide export to ".sld" (was ".acad") o Needed #ifdef USE_JPEG in w_export.c for compiling without JPEG support o Transparent color was not passed to fig2dev for GIF output (new -t option in fig2dev do do this) o Inappropriate arguments to sqrt() in spline calculations (not double) o The radius value displayed in the message window was incorrect when drawing ellipses o Both radii are reported now when drawing ellipses o Now checks whether Fig file is read-only before renaming to .bak and allowing user to save. (after second save, original, read-only file would be gone) o New #ifdef for glibc which has sys_errlist and random() defined o Conflict with definition M_PI (3.14159....) on RedHat systems fixed o Interpolated splines in Fig version 2.1 files were read incorrectly fixed by Onno Roep (O.A.Roep@twi.tudelft.nl) o If you had a line with arrowhead(s) and deleted all the points to make it a single point object, then undid the last delete point, the arrowhead(s) didn't reappear. This has been fixed. o Less multiple redrawing of figure when starting xfig with filename and it needs to change orientation (portrait/landscape) o "Ledger" paper size removed from list of paper sizes. It is really "Tabloid" size in landscape mode. o Undo of align to canvas wasn't refreshing display ============================================================================= Version 3.2 (first release Aug 22, 1997) ============================================================================= GENERAL NOTE: Because Unisys Corp. has stated that they will not charge royalties for the use of the LZW compression algorithm in *FREE* programs, xfig will continue to support importing and exporting of GIF images. However, be aware that if you sell xfig, for example as part of a CD-ROM package with freeware, you may be liable for paying royalties to Unisys. You may comment out the USEGIF variable in the Imakefile to avoid this. With USEGIF commented out, xfig will still import GIF files, but not export in that format. Also, for screen capture, xfig will create a PCX file instead of a GIF file. *** The authors of xfig and the Lawrence Berkeley National Laboratory cannot be held responsible in any case. *** NOTE: fig2dev now handles the exporting to bitmap formats (GIF, JPEG etc) instead of xfig, so there is more consistent output. Requires the netpbm package and ghostscript. See the README file. NEW FEATURES: o Japanese text objects (i18n) availble using flag I18N in Imakefile from T.Sato (VEF00200@niftyserve.or.jp) o ppm, tiff (no compression) and AutoCad (acad) output languages added o Image quality (0-100) is selectable for JPEG export o Figure size (in inches or cm) is shown in the export and print panels, taking into account current magnification o "Fit to page" button sets magnification so that figure size will just fill current paper size with (at least) 1/2 inch margin all around o Emergency save file renamed from xfig.SAVE to SAVE.fig o When doing a screen capture for a picture object, the filename of the capture is the name of the figure file + the time according to time(3) + .gif, e.g. myfigure_858367466.gif o Xfig version number in app-defaults file is checked and warning message appears if older than current version o Spell checker to find misspelled words in text objects from T.Sato (VEF00200@niftyserve.or.jp) o Search and replace - search for strings and either replace them with new string or update settings like color, etc. on matched strings from T.Sato (VEF00200@niftyserve.or.jp) o Exporting to pstex does both PostScript and LaTeX part in one step to file.pstex and file.pstex_t respectively o Popup messages (balloons): o describes drawing/editing function when mouse passes over any drawing/editing button o describes how to activate unit/scale popup when mouse passes over units box (where the rulers meet) o describes mouse function indicator when mouse passes over it o describes each command button in top row as mouse passes over buttons o toggle button labelled "Balloons" to turn on/off the balloon messages o all have configurable colors; see Fig-color.ad o New figures in Libraries/Examples directory from Bill Chimiak (chim@bgsm.edu): 1. clp_computer1.fig - computer equipment clipart 2. clp_hospit_equip.fig - hospital equipment clipart 3. clp_network.fig - updated network equipment clipart 4. musicnotes.fig - musical notes, scale lines and clef o Checks version number in app-default file with xfig version and warns if file is older BUGS FIXED: o Arrowheads on splines didn't always point correctly (fig2dev did the right thing, though) o Accomodation for 15-bit visual (believe it or not!) o Checks bits-per-pixel for image formats because some vendors use 32 bits for 24 bit depths o Minor difference in A0 and A1 page sizes o Changed XPM variables to default X include/library in Imakefile o Path added to save filename when xfig makes emergency save o Incorrect email address for xfig-bugs in man page (should be xfig-bugs@epb1.lbl.gov) o Typo about font_flags bit number for LaTeX vs PostScript in Doc/FORMAT3.2 file o Not enough space allocated for buf[] in create_print_panel() and create_export_panel() from T.Sato (VEF00200@niftyserve.or.jp) o Typo in Doc/FORMAT3.2 file about header information in Fig files o Typo in man pages - zooming uses only CONTROL key, changing spline shape factor requires both CONTROL and SHIFT keys. o Justification and page size are now disabled with EPS export o Undo of converting spline to line caused seg fault o Added #ifdef USE_GIF around transparent color in export and read file o Error in sprintf format (was %4.2lf - should be %4.2f) in bottom indicator panel buttons that have floats from T.Sato (VEF00200@niftyserve.or.jp) o Center of pie-wedge style arc wasn't included in bounding box from Andy Thomas (alt@picnic.demon.co.uk) o Better handling of mouse function indicator from T.Sato (VEF00200@niftyserve.or.jp) o If "edit spline point" panel is popped up before general edit panel, 'Warning: Action not found: apply' appeared when edit panel was later opened from T.Sato (VEF00200@niftyserve.or.jp) o Actions that had same names renamed to unique names from T.Sato (VEF00200@niftyserve.or.jp) o Mouse button 1 and 3 didn't scroll the H, S, or V sliders in the color edit panel o Unsigned/signed char pointer mix in create_pic_pixmap and get_canvas_clipboard o Cleanup of dictionary wrapped around imported EPS files from Franz Koch (franz.koch@zdv.uni-tuebingen.de) o Portrait/Landscape changes didn't properly toggle width/height o New font specified in app-defaults for those systems whose default font was too large for popup panels (Fig*Font: 7x13bold) o Zooming not allowed if drawing object in progress (panning is OK) o strcasecmp and strncasecmp bugs (s2 != '\0' and s2 == '\0' should be *s2 ...) o When exporting to bitmap format, bounding box of figure was rounded to current point positioning grid (unintended) o Unaligned access errors on 64-bit machines (e.g. Alpha) when importing bitmap pictures. Now uses unsigned int for pointers o Code to remove identical consecutive points in line objects had bug o Workaround for long-time Intrinsics bug with scrolling text widget in viewport for file and export lists provided by Mark London (mrl@psfc.mit.edu) o Bug in control-key-button-1 zoom sequence - didn't allow control key pressed when completing zoom operation o Mis-named fonts for zapf chancery and zapf dingbats (many servers don't have these fonts anyway so please don't ask me where to get them) o Error in JPEGINC variable in Imakefile - had leading "/" in path o Width of "open compound" button was slightly too large such that the mode panel (left) obscured part of the indicator panel (bottom) when -but_per_row was 3 o Transparent color for GIF export wasn't "None" as default o Box objects read in from Fig file would only have three points on some machines o Grid wasn't changed to metric when loading metric figure o 24- and 32-bit export to JPEG was incorrect o "rotate and copy" for text placed first copy correctly, but subsequent copies incorrectly o Comments after #FIG before end of header weren't parsed correctly o Landscape/Portrait is only available for PostScript export o Ledger/Tabloid sizes reversed (Tabloid is 11x17", Ledger is 17x11") o Deleting all objects (Meta-D) prevented the "New figure" function by keeping the original figure name o Arrowheads were inadvertantly allowed for closed splines via the popup edit panel o Picture objects rotated 90 or 270 degrees were also flipped o Changed sense of USEINLINE so default is NOT to use it -------------------------- V3.2 Beta 1 (Jan, 9, 1997) -------------------------- NEW EXAMPLE FILES (Examples/ directory) o fantastic figure from Robort Ford (rford@mailserv.mta.ca): transit.fig - transit map of Saint John, New Brunswick (Canada) Don't use it for locating transit routes - it is only good through July 1996 and only shows non-rush-hour routes o great figures from Carlo Kopp (carlo@cs.monash.edu.au): greenpig.fig - F/RF-111C/G Tactical Fighter rfxc.fig - RFX Strike/Recon Fighter lidar.fig - Sidelooking battlefield surveillance LIDAR sowpig.fig - RAAF F-111C fighter jet w/ 2x AGM-142 Have Nap SOWs o some nice figures from Peter Hiscocks (phiscock@ee.ryerson.ca) aircraft.fig - light aircraft ps-foil.fig - power supply circuit board foil layout ps-schematic.fig - power supply circuit board schematic o from Philipp Reisner (Austria). Linuxlogo.fig - the only entry in the Linux 2.0 Logo contest to be rendered with xfig - Unfortunately, it didn't win :-( o new clip art objects from W. Chimiak (chim@tachyon.medeng.wfu.edu): clp_computer.fig - various computers, monitors etc. clp_network.fig - computer network components o more new example files (done by me, Brian Smith) 3dhouse.fig - cutaway view of a simple house drawn in 3D ctrlbox_lay.fig - dimensioned drawing of a control box for a project in my group ctrlbox_sch.fig - electrical schematic of the control box NEW FEATURES o better error reporting from ghostscript when importing EPS files o in color popop panel, "lookup color" button allows user to grab color from any window for user-defined color in xfig uses code from xpaint (Copyright 1993 David Koblas (koblas@netcom.com) and Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk)) o There is a new mathematical model for splines. The new version uses X-splines which allows to mix interpolation and approximation points in a same curve. More precisely, it means that an X-spline curve is neither an interpolated spline nor an approximated one, it is BOTH (the behaviour of each point is controlled by one single parameter called "shape factor"). For additional information about X-splines, see: "X-Splines: A Spline Model Designed for the End User" by C. Blanc and C. Schlick, Proceedings of SIGGRAPH'95 o the shape factor of each individual point can be modified interactively with a dialog box that is displayed when pressing the right button in the EDIT OBJECT mode. o the shape factor can also be modified in any of the EDIT modes, by holding down the CONTROL key while pressing the mouse buttons. o because the CONTROL modifier is used for the shape factor edition, the zoom rectangle is now obtained by pressing the SHIFT key AND the CONTROL key while dragging the rectangle. o new features have been added in the CONVERT mode. Any conversion between polylines, polygons, open splines and closed splines are now possible. *** Caveat: Because spline models of previous versions (quadratic B-splines and Bezier with hidden points) are no longer supported, curves that are present in version 3.1 and older files are automatically converted to X-splines. This translation is only an approximation process. It means that the converted curves are not exactly the same as the original ones. Though the translation usually provides almost identical curves, some hand-fitting may be needed in some pathological cases. The new spline features were written by Carole Blanc (blanc@labri.u-bordeaux.fr) and Christophe Schlick (schlick@labri.u-bordeaux.fr) starting from an initial implementation done by C. Feuille, S. Grosbois, L. Maziere and L. Minihot as a student practice (Universite Bordeaux, France). o the file format (protocol) has changed (see Doc/FORMAT3.2 for details). This means you must also get transfig 3.2. Xfig will still read older Fig format files but will always write the new format. o multiple page flag, paper size, transparent color (GIF export) and print/ export magnification now stored in Fig file (new protocol format 3.2) o export/print magnification now command-line argument (-magnification) and resource (Fig.Magnification) o paper size now command-line argument (-paper_size) and resource (Fig.paper_size) o multiple page flag now command-line argument (-multiple) and resource (Fig.Multiple) (-single is default) o option of transparent color for GIF export (e.g. make background transparent) o new colors in Fig-color.ad resource file from Joel D. Young (jdyoung@afit.af.mil). If you want the old colors, copy Fig-color.old.ad to your app-defaults directory as "Fig-color". o works with GrayScale, TrueColor, DirectColor, StaticColor and StaticGray visuals now. Use "-visual " command-line argument or "Fig.visual: ". Also, "-depth " (Fig.depth: ) supported. thanks to help from Kevin Russell (krussell@dres.dnd.ca) o "Delete All" button changed to "New" function - all objects are delete and the current filename is cleared. Also, the file save and load shortcuts will force the file panel to popup if the current filename is empty. This will prevent a user from doing a "delete all" to create a new figure and forgetting to change the filename when saving. o new edit features when entering text on canvas: Left arrow key and Control-B moves cursor left Right arrow key and Control-F moves cursor right Home key and Control-A moves cursor to beginning of text End key and Control-E moves cursor to the end of text Delete key and Control-D delete the character to the right of the cursor Control-K deletes from the cursor to the end of the text Pan operations using the arrows and the Home key are disabled during text entry because they are used for positioning the text cursor now. o "Open Compound" operation to temporarily go inside a compound object to edit individual components. Can enter nested compounds. Close compound to group objects back into compound. Written by Bill Taylor (bill@mainstream.com) o xfig will now automatically unzip/uncompress Fig files with .Z, .z or .gz suffixes automatically. It does not recompress/zip them when saving, though. o -zoom (resource Fig.zoom) option to start xfig at any zoom value o -startposnmode (resource Fig.startposnmode) option to start xfig with point positioning mode specified. Values can be 0 ("any") to 4 (1 inch/20mm). o size of blank area (margin) around figure when exporting to bitmap-style formats (e.g. GIF, XPM etc.) is settable in export window now o when zooming larger, spacing of dots in grid lines stays constant o button to hide/show hidden directories (names that begin with ".") in file popup menus o paper size selectable for printing and when exporting to PS/EPS: "Letter", "Legal", "Ledger", "Tabloid", "A", "B", "C", "D", "E", "A0", "A1", "A2", "A3", "A4" and "B5" o in the past if an ellipse was scaled such that the radii become equal it was "converted" to a circle. This "feature" has been removed. o point objects (POLYLINES with only one point) now have thickness, as they should. Additionally, if the cap style is rounded, they will be filled circles o when exporting figure containing picture objects, xfig warns if the export filename is the same as any of the picture files o note explaining how metric units are defined in xfig in the Doc/FORMAT3.1 file o when updating objects with update button, they were drawn twice - now they are only drawn once o when deleting xfig window (WM_DELETE_WINDOW), popup confirmation gives user the option to save figure o README file updated to give credit for Example figures not done by Brian Smith o default suffix for hpgl (ibmgl) export changed to "hpl" for PC users BUGS FIXED o smart links didn't work when the box being moved had line thickness > 1 o -exportLanguage ignores case now (e.g. GIF == gif) o identical consecutive points in lines and "normal" splines are removed as file is read into xfig o some thick arrowheads still protruded into the object they touched (in fig2dev too) - fix from Tobias Ringstrom o resource for compose key database file is keyFile, not ComposeKeyDB (Fig.ad) o color of labels for color numbers/names in color panel contrast their color o edit panel allowed > 100% fill for black and white fill o additional check for bad Bounding Box in imported EPS file o when flipping objects vertically or horizontally, overlapping objects weren't redrawn o format error in sprintf for temp filename in screen capture (%d should be %ld) o some versions of imake don't like null parameters in SpecialObjectRule in Imakefile - changed to "NullParameter" o "modified" flag wasn't being set when changing spline<->line or box<->arcbox, thus one could quit without saving without xfig confirming from Matthias Braun (browny@ise.fhg.de) o when figure is read in from file, any arrowheads with width, height or thickness of 0 are given default values (were causing SIGFPE errors) o colormap must be saved before jpeg_finish_decompress or jpeg_destroy_decompress are called in read_JPEG_file() o when fore/background colors different from black/white respectively, the fill colors for black and white fill were incorrect o when merging figure with no picture objects into figure with picture objects colors were unnecessarily remapped o "rubberbanding" of object being drawn would continue after object was completed. Also, double clicking on a directory name would cause segmentation fault. fixed by Stefan Proels (proels@fmi.uni-passau.de) o Imakefile had error - $(PCXBUG) was incorrectly passed to f_readjpc.c instead of f_readeps.c where it was needed o If the directory path in a file popup was changed by typing into the path window but carriage return wasn't pressed, rescan showed the correct directory but the path wasn't correct so no files were accessible. o Redefined $(XPMINCDIR) to $(XPMINC) because some compilers have trouble with header search path with empty "-I" o string allocation errors in string widgets in popup edit panels o no return code for successful screen capture which would result in failure randomly o picture objects scaled (enlarged) correctly in metric mode so they print 1:1 o incorrect values for white colormap entry when writing jpeg file on monochrome display o Some people have older X11 include files that don't have included. fig.h explicitely includes that now for the SEEK_END identifier o Not enough space for number strings in rulers (SEG fault) o circle grab points moved even if no changes made in popup edit of circle or ellipse object o after attempt to do a horiz/vert move point of a circle was disallowed, further move points were disabled until edit mode switched o if both points of "circle-by-diameter" have same y value it thought that the edge is the center when you try to use "box scale" o colormap from jpeg file was referenced after memory was freed o #include changed to #include "jpeglib.h" to ensure corrrect path used to find header file o problems on Linux with gcc locating old jpeg library even when JPEBLIGDIR pointed to local version o buf too short in set_mixed_names o line2 too short in button struct o file not closed after writing JPEG file o pen color for picture objects disabled for all except XBM (bitmap) in popup edit o confusion with -DNOSTRSTR, NOSTRSTR and HAVE_NO_STRSTR cleaned up. See README. o possible error in rulers with sprintf %f called with integer expression o cleaned up add/delete user defined colors - no requirement to click on colorcell after "Add Color" to set color sliders o added condition in Imakefile that f_wrjpg.c depends on jconfig.h (jpeg library) o changed #include to #include "jpeglib.h" because of search rules o Version 1.0 of Xaw3d used resources topShadow and bottomShadow for colors of those resources. Version 1.1 uses topShadowPixel and bottomShadowPixel. I have included both names in the Fig.ad app-defaults file for compatibility. o removed extraneous comma (,) in length and distance messages when drawing/moving objects o cleaned up many type mismatch warnings for bitmap data o bug in skip_comment() which prevented some machines from seeing the end of file, giving erroneous "Incorrect format" error o typos in xfig.man in resources StartGridMode, StartPosnMode, StartLineWidth, StartFillStyle and StartTextStep (had lowercase 's') o pcx file was closed twice o if there is an error when writing screen capture to a file, the popup error message window shows the error o Examples/logo.fig had squished logo eps file xfig.3.2.5c/README0000700002656300244210000007326011263135220014236 0ustar bvsmithDomain Users=============================================================== XFIG - Facility for Interactive Generation of figures under X11 =============================================================== Xfig is a menu-driven tool that allows the user to draw and manipulate objects interactively in an X window. The resulting pictures can be saved, printed on postscript printers or converted to a variety of other formats (e.g. to allow inclusion in LaTeX documents). This file contains some notes about installing xfig, the directory 'Libraries/Examples' contains some example figures and the 'Doc' directory contains some further documentation including the manual in troff -man format and PostScript. You also need to get the TransFig package which contains fig2dev, the postprocessor that converts Fig files to various output formats such as PostScript (and EPS), PNG, GIF, LaTeX, etc. Xfig and the TransFig package are available from: http://www.xfig.org/xfigdist from any CTAN machine, e.g. ftp://ftp.tex.ac.uk/pub/archive/graphics The xfig distribution includes some library of Fig objects, which are available via the library object drawing mode. Included are libraries such as electrical parts, logic symbols, music symbols, computer clip art, flow charting symbols, network symbols, and some buildings. It is hoped that users will contribute to and enhance these libraries for the benefit of the xfig user community. Oh, and the $64,000 question: Yes, xfig is Year 2000 compliant. *************************************************************************** Please send email about any questions/bug fixes/contributions etc. about TransFig or xfig to bvsmith@lbl.gov. Brian V. Smith Lawrence Berkeley National Laboratory bvsmith@lbl.gov *************************************************************************** Note that although I work at Lawrence Berkeley National Laboratory (LBNL) I don't speak for LBNL nor do I represent LBNL with respect to my work on TransFig and xfig, nor does LBL make any representations about the suitability of this software for any purpose. Here is the legal part: THE LAWRENCE BERKELEY NATIONAL LABORATORY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *************************************************************************** NEW COPYRIGHT/PERMISSION NOTICE: The xfig copyright and permission notice has changed (again) slightly in version 3.2.5. It now states that: FIG : Facility for Interactive Generation of figures Copyright (c) 1985-1988 by Supoj Sutanthavibul Parts Copyright (c) 1989-2007 by Brian V. Smith Parts Copyright (c) 1991 by Paul King Any party obtaining a copy of these files is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish distribute, sublicense and/or sell copies of the Software, and to permit persons who receive copies from any such party to do so, with the only requirement being that the above copyright and this permission notice remain intact. The license for 3.2.4 didn't allow selling xfig unless it was simply included in a collection of programs (e.g. a CD) that one was selling. ______________________________________________________________________________ NOTE 1: Because Unisys has stated that they WILL charge royalties for the use of the LZW compression algorithm even in FREE programs, I have removed all traces of the GIF LZW compression/decompression code from xfig. Xfig now calls giftopnm and ppmtopcx to import GIF files. Screen capture writes a PNG file. Exporting is handled by calling the ppmtogif program from fig2dev. You should use PNG instead of GIF anyway. NOTE 2: For exporting Fig files to any of the bitmap formats (e.g. PNG, JPEG) you will need to get a version of ghostscript that has jpeg, pcx256, pbmraw, ppmraw and tiff24nc drivers. Ghostscript is available from ftp.cs.wisc.edu in /ghost/aladdin. If your ghostscript is not called "gs" then change the X resource "Fig.ghostscript" in Fig.ad to the correct name before installing xfig. fig2dev uses ghostscript for exporting and xfig uses it for importing PS and EPS files. **** Important **** You need the netpbm package which includes the ppmtojpeg program. You can get this from http://download.sourceforge.net/netpbm/ NOTE 3: It is highly recommended that you use Type1 fonts for xfig. For RedHat systems you can use following command (as root): chkfontpath --add /usr/share/fonts/default/Type1 For other X systems you can install the following ghostscript files into your X11 Type1 fonts directory (usu. /usr/lib/X11/fonts/Type1) for the best scalable on-screen fonts. You need to update the "fonts.dir" and "fonts.scale" files to reflect these fonts. Basically, if you copy the following lines into those two files and update the count in the first line to include them, then do an "xset fp rehash" the X Window System will know about them. Of course, you will have to also copy the ghostscript font files themselves (i.e. b018012l.pfb etc.) into the X11 fonts/Type1 directory. You can get these fonts from ftp://ftp.cs.wisc.edu/pub/ghost/aladdin/fonts n021003l.pfb -adobe-times-medium-r-normal--0-0-0-0-p-0-iso8859-1 n021004l.pfb -adobe-times-bold-r-normal--0-0-0-0-p-0-iso8859-1 n021023l.pfb -adobe-times-medium-i-normal--0-0-0-0-p-0-iso8859-1 n021024l.pfb -adobe-times-bold-i-normal--0-0-0-0-p-0-iso8859-1 a010013l.pfb -adobe-avantgarde-book-r-normal--0-0-0-0-p-0-iso8859-1 a010015l.pfb -adobe-avantgarde-demi-r-normal--0-0-0-0-p-0-iso8859-1 a010033l.pfb -adobe-avantgarde-book-o-normal--0-0-0-0-p-0-iso8859-1 a010035l.pfb -adobe-avantgarde-demi-o-normal--0-0-0-0-p-0-iso8859-1 b018012l.pfb -adobe-bookman-light-r-normal--0-0-0-0-p-0-iso8859-1 b018015l.pfb -adobe-bookman-demi-r-normal--0-0-0-0-p-0-iso8859-1 b018032l.pfb -adobe-bookman-light-i-normal--0-0-0-0-p-0-iso8859-1 b018035l.pfb -adobe-bookman-demi-i-normal--0-0-0-0-p-0-iso8859-1 n019003l.pfb -adobe-helvetica-medium-r-normal--0-0-0-0-p-0-iso8859-1 n019004l.pfb -adobe-helvetica-bold-r-normal--0-0-0-0-p-0-iso8859-1 n019023l.pfb -adobe-helvetica-medium-o-normal--0-0-0-0-p-0-iso8859-1 n019024l.pfb -adobe-helvetica-bold-o-normal--0-0-0-0-p-0-iso8859-1 n019043l.pfb -adobe-helvetica-medium-r-narrow--0-0-0-0-p-0-iso8859-1 n019044l.pfb -adobe-helvetica-bold-r-narrow--0-0-0-0-p-0-iso8859-1 n019063l.pfb -adobe-helvetica-medium-o-narrow--0-0-0-0-p-0-iso8859-1 n019064l.pfb -adobe-helvetica-bold-o-narrow--0-0-0-0-p-0-iso8859-1 c059013l.pfb -adobe-new century schoolbook-medium-r-normal--0-0-0-0-p-0-iso8859-1 c059033l.pfb -adobe-new century schoolbook-medium-i-normal--0-0-0-0-p-0-iso8859-1 c059016l.pfb -adobe-new century schoolbook-bold-r-normal--0-0-0-0-p-0-iso8859-1 c059036l.pfb -adobe-new century schoolbook-bold-i-normal--0-0-0-0-p-0-iso8859-1 p052003l.pfb -adobe-palatino-medium-r-normal--0-0-0-0-p-0-iso8859-1 p052004l.pfb -adobe-palatino-bold-r-normal--0-0-0-0-p-0-iso8859-1 p052023l.pfb -adobe-palatino-medium-i-normal--0-0-0-0-p-0-iso8859-1 p052024l.pfb -adobe-palatino-bold-i-normal--0-0-0-0-p-0-iso8859-1 z003034l.pfb -adobe-itc zapf chancery-medium-i-normal--0-0-0-0-p-0-iso8859-1 =================== INSTALLATION NOTES: =================== 1. Edit the Imakefile if you need to customize it (see following notes). 1a. Specifically, if you want to install xfig in a directory other than the default X11 binary directory, uncomment "BINDIR=" in the Imakefile, and change to the full path of the directory where you want xfig to be installed. 1b. You may also have to redefine MKDIRHIER because "make" looks for it relative to the BINDIR variable. Set it to: "MKDIRHIER = /bin/sh /mkdirhier" where is the path to mkdirhier. 1c. Finally, uncomment and change XAPPLOADDIR to the directory where you want the app-defaults resource files to go. You will have to use the environment variable XAPPLRESDIR in your shell to point to this directory. On Sun systems running Openwindows you probably need to set the environment variable XUSERFILESEARCHPATH to point to your app-defaults directory, and append a "%N" to the path, e.g. /users/me/xfig/app-defaults/%N 1d. Don't set the DESTDIR variable unless you want to install xfig in a totally different tree than the "correct" tree that your X system expects. The usual purpose of DESTDIR is to test an install process by installing in a benign area. 2. Type "xmkmf" to create the Makefile from the Imakefile. If you don't have xmkmf you can do "make -f Makefile.noimake Makefile". In either case you must have imake, which can be found at the Open Group site, ftp.x.org. 3. Type "make" (**** This MUST be done before "make install" ****). Note: The "configure" script will be automatically run in the JPEG directory if you have commented out the USEINSTALLEDJPEG variable (i.e. you have defined the JPEGLIBDIR and other variables). This will create the Makefile in the JPEG directory from your system configuration. If for whatever reason, the configure script doesn't run, go into the JPEG directory and type "./configure" then "make". Then go back to the xfig directory and continue with "make". 4. Type "make install.all" This will install the executable (xfig) into the execute directory, the Fig library objects into xfig's library directory XFIGLIBDIR, and the documentation files into xfig's document directory XFIGDOCDIR. To change where the standard "man" pages go, change MANDIR= in the Imakefile. There is a reference in HTML, a tutorial in PDF format, and the man pages in PDF format, although the HTML files are much better than the man pages. The Help menu in xfig will launch the browser to read the HTML files and the PDF viewer to view the other two. The programs that are used for these are specified in the app-defaults file under Fig.browser and Fig.pdfviewer respectively. The default for HTML is "netscape" and "acroread" for the PDF files. If your Netscape can read PDF files you may want to change the Fig.pdfviewer resource to say "netscape" instead of "acroread". You can get both Netscape and Acroread for just about every platform. Netscape is available from Netscape Communications at: http://home.netscape.com and Acroread is available from Adobe at: http://www.adobe.com/prodindex/acrobat/readstep.html If you only want to install the documentation files and/or the libraries of Fig objects, you can do "make install.doc" and/or "make install.libs" respectively. **** If you don't do this step, be sure to install the app-defaults files Fig.ad and Fig-color.ad in the system app-defaults directory (usually /usr/lib/X11/app-defaults) as "Fig" and "Fig-color" respectively, and the CompKeyDB file in the directory specified by XFIGLIBDIR (default: /usr/local/lib/X11/xfig). There are two app-defaults files for colors: one I call the "classic" color scheme (blues for the buttons and primary colors for OK/CANCEL buttons) and a new one provided by Joel D. Young (jdyoung@afit.af.mil) which looks more like tcl, and I think is a little nicer. It looks best when used with Xaw3d.1.0, which can show 3d relief for labels, not just buttons. This new color set is the default. If you want the "classic" colors, copy Fig-color.classic.ad to your app-defaults directory as "Fig-color". If you can't install xfig in your system directories you may put it anywhere in your search path. The app-defaults files (Fig.ad and Fig-color.ad) may be put into any directory as Fig and Fig-color respectively, and pointed to by setting the shell environment variable XAPPLRESDIR. You may also put the CompKeyDB file in that directory and compile xfig with XFIGLIBDIR (in the Imakefile) pointing there. 5. Type "make install.man". ------------------------------ IMPORTANT GENERAL NOTE: ------------------------------ Anytime the Imakefile is changed, you must do either "xmkmf" or "make Makefile", followed by "make clean" before doing a "make" or "make install" of any kind. ------------------------------ NOTES on changes to Imakefile: ------------------------------ o For a 3D look, I recommend using Kaleb Keithley's 3D Athena Widget set, a direct replacement for the Xaw library. After you compile and install that package, and after step 1 above, uncomment the following definition for XAW3D and change the XAW3DINC variable to point to the directory where your 3D Athena widget headers are located. This set is available from ftp.x.org in /contrib/widgets. o If the Xaw or Xaw3d Athena widget sets are compiled with the ARROW_SCROLLBAR style of scrollbars, there is no StartScroll action and you won't be able to scroll using the wheel on the mouse. If you want to be able to scroll using the wheel, you must recompile the Xaw library from sources, disabling the ARROW_SCROLLBAR option. o If you *don't* want JPEG support, comment out the #define USEJPEG line in the Imakefile. o If you want to be able to import JPEG images then: o If you already have a JPEG library in your system library directory leave the "#define USEINSTALLEDJPEG" line (don't comment it out) in the Imakefile. o If you don't have it installed, get it from one of the following places, comment out the #define USEINSTALLEDJPEG line in the Imakefile (using XCOMM) and point JPEGLIBDIR to the diredctory where the source is. The default is ../jpeg (relative to the xfig source directory). o You must have version 5b or newer of the JPEG library. o The JPEG library is available from several places. The official archive site is ftp.uu.net in /graphics/jpeg. Another is ftp.x.org in /contrib/libraries. o ** Make sure you delete or rename any older version of the JPEG library you might have on your system. Some Linux systems come with an older version which is incompatible with xfig. o You need the PNG library (-lpng) and the zlib (-lz) compression library. You can find the PNG sources at http://www.libpng.org/pub/png/libpng.html and the zlib sources at ftp://ftp.cdrom.com/pub/infozip/zlib. o If you want to use the XPM3 package (X11 color pixmaps) uncomment the #define USEXPM line (using XCOMM) in the Imakefile. With XPM support you can import xpm files as picture objects, and export figures as XPM files. Additionally, if you want to use the color icon for xfig (which is in XPM format) uncomment the #define USEXPM_ICON line in the Imakefile. You need xpm version 3.4c or newer. This is available from ftp.x.org in /contrib/libraries. XPM usually comes with most Linux installations. o If your system's printer capability file (printcap) is not in /etc/printcap, change the PRINTCAP variable to reflect this. o If you have a small screen (e.g. 800x600) you may want to uncomment the line with USESMALLICONS in the Imakefile to use smaller icons for the mode panel. Also, when starting xfig use -pwidth 8 -pheight 5.5 -but_per_row 3 This will make it use 3 buttons per row on the left panel and size the canvas to fit in 800x600. You can also use the X resources by putting the following in the app-defaults files or your personal X defaults file: Fig.pwidth: 8 Fig.pheight: 5.5 Fig.but_per_row: 3" o If you have Ghostscript, xfig will attempt to use it to interpret any encapsulated Postscript (EPS) files you import. Ghostscript must be compiled with with the "pcx256" and "pbmraw" drivers. The pbm driver is used when you run xfig on a monochrome display and the pcx256 driver is used on a color display. See NOTE 2 above about the pcx driver in Ghostscript. o If you don't have Ghostscript, remove the -DGSBIT flag in the "DEFINES" variable in the Imakefile. o If you are using the HP compiler, add "-Aa -D_HPUX_SOURCE | -O" to the DEFINES variable in the Imakefile. Note carefully the "|" which prevents the compiler from overriding the -O option. Problems occur if the +O3 optimization is used. o If your system doesn't have strstr(), uncomment the line with HAVE_NO_STRSTR in the Imakefile. o If your system doesn't have strcasecmp() and/or strncasecmp(), uncomment the lines in the Imakefile with HAVE_NO_STRCASECMP and HAVE_NO_STRNCASECMP. o If your system doesn't have the strerror() function then uncomment the "#define NEED_STRERROR" in the Imakefile. o If you have an input tablet and your X server supports the XInputExtension uncomment the lines that define TABLIB and USETAB in the Imakefile. Start xfig with -tablet or define the resource Fig.Tablet to use it. o The maximum width of the top ruler is set to 1600 pixels and the height of the side ruler to 1280 pixels. If your server can handle pixmaps larger than this and you need longer/taller rulers, you may set the maximum allowed in your Imakefile with -DMAX_TOPRULER_WD=2000 (or whatever value you wish) and -DMAX_SIDERULER_HT=1600 (or whatever value you wish). This limitation exists for VaxStation graphics hardware. o The SMOOTHMOTION option toggles between two methods for tracking the cursor. The first way (SMOOTHMOTION) just uses the (x,y) information given in the X pointer motion event. If your display server doesn't implement motion compression this is very slow for large movements of the mouse pointer because X sends back lots of small movement events, each of which causes the rubberband box to be erased and redrawn. The alternative way (not SMOOTHMOTION) queries the position of the X cursor whenever a motion event is received and if you make a large movement and then stop actually turns out to involve less work even though the XQueryPointer call is quite slow. The SMOOTHMOTION flag MIGHT be necessary for older versions of OpenWindows on certain machines if the performance is slow when moving or drawing objects. o If you have a Sun Sparcstation and would like the Compose LED (light) turned on when you are entering multi-key characters (like a-umlaut, c-cedilla, etc), uncomment the line: COMP_LED = -DCOMP_LED=3 (Note: older versions of X11, e.g. R5 may use 1 instead of 3 for the LED) o Look for any other comments in the Imakefile which describe options. -------------- General NOTES: -------------- The pattern shading (e.g. bricks, shingles, etc.) only work for PostScript, tk (of the tcl/tk fame), and the bitmap output formats (e.g. PNG, GIF, JPEG, etc.). Unless you have an image (picture object) in your figure, you may not gain very much by exporting in JPEG over PNG because of the nature of compression used in both methods. PNG is usually better for line drawings or drawings with large blocks of continuous color (e.g. filled polygons). JPEG is usually better for compressing (photograpic) images. If you have the default paper size for Ghostscript as A4 (metric) change the following (in gs_init.ps): % Optionally choose a default paper size other than U.S. letter. (a4) /PAPERSIZE where { pop pop } { /PAPERSIZE exch def } ifelse to systemdict /DEVICEWIDTH known systemdict /DEVICEHEIGHT known or not { (a4) /PAPERSIZE where { pop pop } { /PAPERSIZE exch def } ifelse } if ---------------------- Printing your figures: ---------------------- The program to translate your figure into one of many printer languages (Postscript, LaTex, etc) is called fig2dev and is part of the TransFig package put together by Micah Beck and maintained by me, Brian Smith. It is available from ftp.x.org in /contrib/applications/drawing_tools/transfig. See the man pages for more information. xfig relies on the user's command search path to run fig2dev, but you may also set the FIG2DEV_DIR environment variable if you want to force it to look elsewhere. If you have a SYSV system but use BSD-style printing (lpr instead of lp) you must define -DBSDLPR in the Imakefile/Makefile. You may also need to uncomment the following string in the Fig.ad app-defaults file: !Fig*job_params*string: -T PS -------------- Solaris users: -------------- You should have: #define SystemV4 YES in your imake machine config file (usually in /usr/lib/X11/config/.cf or something like that). Some people have had trouble with the Sun cc 3.0.1 compiler and optimization. You may need to shut off optimization. A common symptom is that xfig just core dumps when starting. ------------------------------------------------------ Possible problems encountered installing/running xfig: ------------------------------------------------------ Please see the FAQ in Doc/html/faq.html for an up-to-date FAQ. This is available from the Help/Xfig Reference menu entry while running xfig, or by viewing Doc/html/faq with your favorite web browser. ________________________________________________________________________________ PROBLEM: xfig crashes when pulling up a menu item POSSIBLE CAUSE AND SOLUTION: You probably have version 1.5 of the 3D Xaw Athena widget set so you need to remove the "XCOMM" from this line in the Imakefile: #define XAW3D1_5E then do "xmkmf" and "make install.all" ________________________________________________________________________________ PROBLEM: icons in side and bottom panels appear then disappear POSSIBLE CAUSE AND SOLUTION: On Linux (2.0.29 at least), the libNextaw version of the Athena Widget set (libXaw) seem to cause this problem. Relink with vanilla libXaw or libXaw3d. ________________________________________________________________________________ PROBLEM: A warning about some action not found occurs, e.g.: Warning: Actions not found: ModeOpenCompound POSSIBLE CAUSE AND SOLUTION: You didn't install the app-defaults files. ________________________________________________________________________________ PROBLEM: X error occurs with X_SetClipRectangles as the Request code or: Thick line shows through arrowhead in certain orientations. POSSIBLE CAUSE AND SOLUTION: In X11R5 there was a bug in the clipping algorithm (Xlib). Switch to X11R6 or apply the following patch to mit/lib/X/XPolyReg.c in the X11R5 library: *** XPolyReg.c.orig Tue Dec 15 12:01:22 1992 --- XPolyReg.c Wed Nov 15 09:41:13 1995 *************** *** 402,408 **** if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && pts[1].x == rects->x2 && (numRects == 1 || rects[-1].y1 != rects->y1) && ! (!i || pts[2].y > pts[1].y)) { rects->y2 = pts[1].y + 1; continue; } --- 402,409 ---- if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && pts[1].x == rects->x2 && (numRects == 1 || rects[-1].y1 != rects->y1) && ! /* Fixed version from X11 R6 */ ! (i && pts[2].y > pts[1].y)) { rects->y2 = pts[1].y + 1; continue; } ________________________________________________________________________________ PROBLEM: When using LaTeX fonts in Xfig I always end up with postscript fonts instead rather than, say, Computer Modern. POSSIBLE CAUSE AND SOLUTION: To put fonts under the control of LaTeX when generating PS, you must tag the text object as "special" and then use the pstex output mode. This mode forces special text objects to be passed through to LaTeX, allowing the use of Math mode and CM fonts among other things. ________________________________________________________________________________ PROBLEM: On a DEC Alpha the compiler may complain about something like: ".mask must have pcreg from .frame set if any bits are set in .mask or .fmask" in the file u_bound.c. POSSIBLE CAUSE AND SOLUTION: Set the optimization level to -O1 at least for that file. ________________________________________________________________________________ PROBLEM: On Sun machines the linker may give erroneous error messages about the following symbols being undefined: ld: Undefined symbol _get_applicationShellWidgetClass _get_wmShellWidgetClass This may be ignored as it is a problem with the Sun shared libraries and the way X11 builds the shared Xmu library. It doesn't affect the operation of xfig. Or you may compile with "-Bstatic -lXmu -Bdynamic". To really solve the problem if you are using OpenWindows 3.0 (X11R4-based Xt), please contact your local Sun office and request the following patches: Patch i.d. Description 100512-02 4.1.x OpenWindows 3.0 libXt Jumbo patch 100573-03 4.1.x OpenWindows 3.0 undefined symbols when using shared libXmu A source patch for use with the MIT X11R4 libraries was developed by Conrad Kimball (cek@sdc.boeing.com); it retrofits into R4 some fixes made in R5 to get around this problem. The patch is on export in [1/93] contrib/X11R4_sunos4.1.2_patch_version3.Z". The other option is to use X11R5 or X11R6. ________________________________________________________________________________ PROBLEM: Openwindows sometimes loses track of xfig's icon. POSSIBLE CAUSE AND SOLUTION: Cause unknown, here is a temporary kludge. Place the line: Fig*iconPixmap: ..../your_lib_area/fig.icon.X in your .Xdefaults file and copy fig.icon.X into your lib area. ________________________________________________________________________________ PROBLEM: When compiling on an HP 750 running HP-UX 8.05, the compiler dies with a bus error in the file u_undo.c. POSSIBLE CAUSE AND SOLUTION: There is a bug in the HP compiler. Workaround the problem by adding an extra statement between two statements in u_undo.c: Original: undo_glue() { list_delete_compound(&objects.compounds, saved_objects.compounds); tail(&objects, &object_tails); New: undo_glue() { list_delete_compound(&objects.compounds, saved_objects.compounds); >>> /* HP-UX 8.05 compiler bug fix -- don't ask */ >>> last_action = last_action; tail(&objects, &object_tails); ________________________________________________________________________________ PROBLEM: On HP machines, the capitalization of some letters in the text window in the edit popup for text objects are wrong. POSSIBLE CAUSE AND SOLUTION: Make sure that the CompKeyDB file has the lowercase letter definitions BEFORE the uppercase definitions. This should be the case for the CompKeyDB file shipped with xfig 2.1.5 and later. ________________________________________________________________________________ PROBLEM: On some HP computers using native cc compiler there is a problem with level 3 optimization. POSSIBLE CAUSE AND SOLUTION: Use +O2 instead of +O3 or get patch from HP for the compiler from http://support.mayfield.hp.com/ Choose: Patch Browsing and Downloading ________________________________________________________________________________ PROBLEM: On Linux, you may get errors such as: > f_wrjpg.o(.text+0x5b2): undefined reference to `jpeg_write_scanlines' > f_wrjpg.o(.text+0x5dc): undefined reference to `jpeg_finish_compress' > f_wrjpg.o(.text+0x5e2): undefined reference to `jpeg_destroy_compress' POSSIBLE CAUSE AND SOLUTION: On most Linux machines, there is an old version of the JPEG library already installed, and is incompatible with xfig. Delete its library files (usually /usr/local/lib/libjpeg.so and /usr/local/lib/libjpeg.a) and the header file (usually /usr/local/include/jpegdata.h) ________________________________________________________________________________ PROBLEM: Arc-boxes don't appear correct when viewing exported PostScript with ghostview or ghostscript. POSSIBLE CAUSE AND SOLUTION: Ghostscript version 4.01 has a bug with the arcto operators. Get version 4.03 or newer. ---------------- Artwork credits: ---------------- This section gives credit to those people who have contributed to the Libraries/Examples directory. Any figures not listed here were probably done by Brian Smith. Fig file Description Artist -------- ----------- ------ antennas.fig various ultra-wideband antennas (can't remember who submitted this) sowpig.fig RAAF F-111C fighter Carlo Kopp (he has an "Unofficial F-111" w/2xAGM-142 Have Nap SOWs web page at: rfxc.fig RFX Strike/Recon Fighter http://www.cs.monash.edu.au/~carlo/archive/MILITARY/F-111/ greenpig.fig F/RF-111C/G Tactical Fighter lidar.fig Sidelooking battlefield surveillance LIDAR linuxlogo.fig This was an entry in the Philipp Reisner Linux 2.0 Logo contest illusion.fig "impossible" 3-D object Vivek Khera (khera@cs.duke.edu) recycle.fig recycling logo flowchart.fig flowchart building blocks Tim P. Starrin (noid@cyborg.larc.nasa.gov) logo.fig first fig file using imported Bryan Boyter (original author of eps eps object import code for xfig) transit.fig transit map of Saint John, Robert Ford (rford@mailserv.mta.ca) New Brunswick (Canada) ** Don't use it for locating transit routes. It is only good through July 1996 and only shows non-rush-hour routes ** aircraft.fig light aircraft Peter Hiscocks (phiscock@ee.ryerson.ca) ps-foil.fig power supply circuit board foil layout ps-schematic.fig power supply circuit board schematic clp_computer.fig various computers, monitors etc. W. Chimiak (chim@tachyon.medeng.wfu.edu) clp_network.fig computer network components xfig.3.2.5c/FIGAPPS0000700002656300244210000002131407776306720014406 0ustar bvsmithDomain UsersThe following are applications which can produce Fig files as their output: ************************************************************************ There is a port of xfig for the MacIntosh running Darwin (the MacIntosh port of XFree86). See http://fink.sourceforge.net/pdb/package.php/xfig ************************************************************************ There is a version of xfig which will run under Windows, but still needs an X server (e.g. Hummingbird Exceed, or Cygwin http://www.cygwin.com/xfree/) to run. The URL is: http://aquarius.franken.de/software/develop/gnuwin32/cygwin/porters/Hirmke_Michael/GNUWin32-links.html Another is: http://www.cs.usask.ca/grads/wew036/latex/xfig.html ************************************************************************ grass2fig - The GRASS GIS (Geographic Resources Analysis Support System) is an open source Geographical Information System (GIS) with raster, topological vector, image processing, and graphics production functionality that operates on various platforms through a graphical user interface and shell in X-Windows. It is released under GNU General Public License (GPL). The grass2fig program will convert a GRASS binary vector map to a Fig file. ************************************************************************ JavaFIG - Java applet which is based on xfig. See: http://tech-www.informatik.uni-hamburg.de/applets/javafig/applet.html ************************************************************************ figbuild - figbuild reads xfig files (Version 3.x, tested with 3.1, 3.2) plus its own config file for heights, and generates a Radiance input file. Written by Peter Apian-Bennewitz at Fraunhofer ISE, Germany see: http://www.ise.fhg.de/radiance/pabs-toolbox/figbuild/figbuild.html ************************************************************************ xfigbar and xfigpie - Two C programs to produce bar and pie charts as Fig files. Written by John Conover , these programs are available at: http://www.johncon.com/john/archive/xfigutilities.shar.gz ************************************************************************ mifXfig - MIF to XFig and XFig to MIF Converter see http://www.ida.liu.se/~vaden/teaching/m2f/ for details, but it basically converts to and from MIF and Fig files From Vadim Engelson (vaden@ida.liu.se) ************************************************************************ pstoedit - converts Postscript(TM) files to other vector graphic formats that can be edited. Besides Fig output, tgif, Framemaker(TM) (MIF- format) and flattened PostScript are supported along with several others. You need a C++ compiler to install and GhostScript to run pstoedit. pstoedit should run on all Un*x like systems and has also been ported to OS/2 and DOS. http://www.pstoedit.net/pstoedit ************************************************************************ hp2xx - converts HPGL to EPS, LaTex, Fig or simplified HPGL converter Now maintained by Martin Kroeker (mk@daveg.com) available from ftp.gnu.org and the usual mirror sites ************************************************************************ chemtool - Chemical structure editor for X11 available from http://ruby.chemie.uni-freiburg.de/~martin/chemtool/chemtool.html that writes Fig output (and relies on transfig for anything more fancy than xbm) ************************************************************************ xgraph - plotting package for X - version on iworks.ecn.uiowa.edu in comp.hp has version that can output Fig files ************************************************************************ gnuplot - Plotting package; can output in Fig format. For the location of gnuplot, here is the (paraphrased) excerpt from the FAQ. Note, that although there are versions of gnuplot for several different platforms, xfig only runs under X11. The official distribution site for the gnuplot source is dartmouth.edu, in /pub/gnuplot. Official mirrors of that distribution are (for Australia) monu1.cc.monash.edu.au and (for Europe) irisa.irisa.fr. You can also get it from your friendly neighbourhood comp.sources.misc archive. MS-DOS and MS-Windows binaries are available from oak.oakland.edu (North America) as pub/msdos/plot/gpt34*.zip, garbo.uwasa.fi (Europe) as /pc/plot/gpt34*.zip and archie.au (Australia) as micros/pc/oak/plot/gpt34*.zip. The files are: gpt34doc.zip, gpt34exe.zip, gpt34src.zip and gpt34win.zip. OS/2 2.x binaries are at ftp-os2.nmsu.edu in /os2/2.x/unix/gnu/gplt34.zip. Amiga sources and binaries are available from wuarchive.wustl.edu as /pub/amiga/aminet/util/gnu/gnuplot-3.4*; there are numerous mirrors of this distribution. The NeXTSTEP front end can be found at sonata.cc.purdue.edu and cs.orst.edu. A version for OS-9/68K can be found at cabrales.cs.wisc.edu in /pub/OSK/GRAPHICS; it includes both an X and non - X versions. A version of gnuplot for the Macintosh is included in the gpcontrb file, or can be found at wuarchive.wustl.edu in edu/math/mac/graphingAids, as MacGnuPlot3.2.sea.hqx and MacGnuPlotPackage3.2.sea.hqx. ************************************************************************ pic2fig - converts PIC (used with troff/ditroff/etc) to Fig. May be found at ftp.cs.orst.edu in /localsrc/graphics and at ftp.x.org in /contrib/utilities. ************************************************************************ GNU plotutils - includes an application for XY plotting (graph), a plot filter (plot), a Tektronix translator (tek2plot), a program for displaying font character maps (plotfont), and a library for drawing 2-D vector graphics (libplot), all of which produce output in xfig format. http://www.gnu.org/software/plotutils/plotutils.html by Robert S. Maier ************************************************************************ cdraw2fig - converts cdraw to Fig Here is the cdraw README file: cdraw2fig translates pictures from "Cheap Draw" format to Fig format. The TransFig package can then be used for translation to the desired output format. Currently supported formats include PIC, (E)EPIC, LaTeX, PostScript, and several others. cdraw2fig is implemented in the awk programming language. Most Cheap Draw operations are handled in some way, although some of the transla- tions are somewhat arbitrary. Note that some output formats are con- siderably less expressive than Cheap Draw (and Fig). PIC, for example, supports neither shading or rotated text. In addition, precise text spacing is problematic across the different output formats. The following files are included in this distribution: README - this file cdraw2fig.uu - ksh script with self-contained awk program (uuencoded) example - sample "Cheap Draw" file (from the original Cheap Draw distribution) To translate a Cheap Draw file to PIC (for example): $ cdraw2fig example > example.fig $ fig2dev -Lpic example.fig > example.pic Cheap Draw 2.0 was written by Bob Pratt and is available from the UNIXPC archives at osu-cis. ************************************************************************ Msphinx - a friendly package to handle satellite images. Main features: Msphinx includes two types of analysis and processing functions: - Functions to process the basic data geometry and projection planes. - Functions to manipulate and modify the graphic display and print. Communication capabilities: - Data writes from external user programs (C or Fortran) into the memory planes. - User-to-user data exchange (text or images). - User image data base visualisation. - Direct links to other packages: - Mgraph (2d and contouring plotting) - HDFLook (HDF read write files) >>> - Xfig (Facility for Interactive Generation of figures) - mpeg_encode (mpeg format nimations) Find it at: http://loasys.univ-lille1.fr/Msphinx/Msphinx_gb.html ************************************************************************ TeXmacs - a WYSIWYG mathematical text editor which supports the inclusion of pictures created by xfig. There is also a small script which converts an xfig picture with LaTeX formulas in it to encapsulated postscript (by calling LaTeX). For more information about TeXmacs, see: http://www.math.u-psud.fr/~anh/TeXmacs/TeXmacs.html By Joris van der Hoeven ************************************************************************ As well, there are pointers to other FIG and Xfig related items at: http://duke.usask.ca/~macphed/soft/fig/ ************************************************************************ xfig.3.2.5c/LATEX.AND.XFIG0000700002656300244210000003515110015427510015310 0ustar bvsmithDomain UsersThis description was written by Eric Masson (ericm@kirk.ee.mcgill.ca) The following is a document on how to import xfig figures in latex along with a few tips to make your life easier. I wrote this quite a while back but it still applies. Salut, Eric HOW TO IMPORT XFIG FIGURES IN YOUR LATEX FILES: -------------------------------------------------------------- Getting Started --------------- When you call xfig use the following command line: xfig -specialtext -latexfonts -startlatexFont default If you want ALL of your figures to be started with special text and latex fonts, you can set the following resources in your .Xresources or whatever resource file you use: Fig.latexfonts: true Fig.specialtext: true There are several formats to which xfig can generate output and latex can read. I will only cover three cases: (A) Export Fig format directly into latex form (B) Export Fig in encapsulated postscript and import the postscript in latex. (C) Save the figure partly in postscript and partly in latex form and superimpose them in your document. All three methods have their advantages and are equally simple to handle. In method (A) the advantage is that all your work is in tex form and that your .dvi files will hold all the necessary information. In (B) you have all the power and fonts of postscript at your disposal. In (C) you get the drawing power of postscript and the typesetting of latex for your strings. --- In your latex preamble (the part that preceeds your \begin{document} statement) place the following lines: \usepackage{graphicx} So your preamble could look like: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LaTeX Preamble %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentstyle[12pt,bezier,amstex]{article} % include bezier curves \renewcommand\baselinestretch{1.0} % single space \pagestyle{empty} % no headers and page numbers \oddsidemargin -10 true pt % Left margin on odd-numbered pages. \evensidemargin 10 true pt % Left margin on even-numbered pages. \marginparwidth 0.75 true in % Width of marginal notes. \oddsidemargin 0 true in % Note that \oddsidemargin=\evensidemargin \evensidemargin 0 true in \topmargin -0.75 true in % Nominal distance from top of page to top of \textheight 9.5 true in % Height of text (including footnotes and figures) \textwidth 6.375 true in % Width of text line. \parindent=0pt % Do not indent paragraphs \parskip=0.15 true in \usepackage{color} % Need the color package \usepackage{epsfig} \usepackage{graphicx} % Graphics package %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Document Beginning %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \end{document} TYPE A - Exporting directly to latex form ----------------------------------------- In terms of drawing capabilities this is the weakest form you can use. Lines in latex can only be drawn at multiples of 30 and 45 degrees. And lines with arrows can only be drawn at multiples of 45 degrees. Several features such as ellipses, splines, etc. are not supported (xfig does not take advantage of available LaTeX macro packages such as bezier). When drawing lines for type A drawings make sure you restrict yourself to the proper angle geometry in xfig. Otherwise when you export your figures to latex format, xfig will approximate your lines to the nearest angle available in latex. Usually this has unpleasant results. In this mode, you can type any LaTeX string on your figure. Once imported to LaTeX, the string will be interpreted properly. For example: $\int_0^9 f(x) dx$ would result in a integration from 0 to 9 of the function f(x). To create your LaTeX file just choose the export option off the xfig main menu. And then select LaTeX picture as the language to export. This will create a file with a .latex extension which you can then call directly into your latex document. For example this code would import the file yourfile.latex directly into latex format: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfile.latex} \caption{The caption on your figure} \label{figure:yourreferencename} \end{center} \end{figure} TYPE B - Exporting to Encapsulated postscript --------------------------------------------- There are no limitations in drawing figures of this type. Except that one cannot use latex command strings in this format. However all of the many fonts of postscript are available when this format is selected. Once you are done drawing your figure simply choose the export menu off of the xfig main menu and select encapsulated postscript as your output language. This will create a .eps file which you can then include into you latex ducument in the following way: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \ \includegraphics[width=4in]{yourfile.eps} \end{center} \caption{Your caption} \label{figure:yourreference} \end{figure} TYPE C - Postscript/Latex format -------------------------------- You can draw any lines or curves when using this format. In this type of export, latex strings are permitted you also have the postscript fonts available to you. Therefore you can type in strings such as $\int_0^9 f(x) dx$ and they will be processed by latex. You will need to export your file to the "combined ps/latex (both parts)" language. This will create both a .pstex file and a .pstex_t file. The .pstex_t file automatically calls the .pstex file and you do not need to include it explicitely in your tex file (users of the previous version please take note of this.) To include your figure just use something similar to this: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 3 of Lecture %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfigure.pstex_t} \caption{Your figure} \label{figure:example} \end{center} \end{figure} N.B. You might want to edit the .pstex_t files created by xfig. When it refers to the other file (.pstex) it automatically gives the path specification to the .pstex file. This can be an inconvenience if you move your files to another directory because your latex processing will fail. I personally prefer to remove the full path specification and only keep the filename. SOME OTHER NOTES ---------------- xfig ---- You can import encapsulated postcript files into your latex files. This is useful if you want to doodle on top of outputs from other programs. For example you could include a MATLAB drawing and identify points of interest with strings, lines, circles, etc. Starting from version 2.1.7 of xfig there is a hook to ghostscript which permits you to view the postscript in your drawing. A neat feature. Use ps2epsi in ghostscript to encapsulate your postscript if you only have .ps files. -- ================================================================= Eric Masson - ericm@finnegan.ee.mcgill.ca - FAX: 514 398 4470 ================================================================= Notes: Sometimes one may get "mn" in your LaTeX text. Here is what one user did to work around that problem: The problem was in the \smash part of a command that was generated in the latex part of the export. If the \mddefault and \updefault are not set properly on your system you need to define them to do nothing. ================================================================= Some more notes from Stephen Eglen * changing the size of pictures in pstex_t If you just include the picture using \input{file.psttext_t} you have no way of specifying the size of the picture. There are two solutions to this. 1. Draw it the right size in xfig to start with. Or, when you are exporting the figure, change the magnification of the picture by using the magnification box in the export window. Either way you have to go back into xfig if you dont like the size of the image in your latex document. 2. Get latex to change the size of the picture, using either \scalebox or \resizebox. These are general functions for scaling text or pictures from the graphics package: \scalebox{factor}{object} Will scale the object by any factor. Factor is just a number (<1 = reduction; >1 = enlargement) Object is normally some text or graphics eg: \scalebox{2}{ \input{file.pstex_t} } will scale the picture by 2, dependent on driver (.ps works, but xdvi wont). Scaling bitmap fonts may produce ugly results, so try and avoid them! \resizebox{width}{ht} {stuff} will resize "stuff" to be of size width x ht. Using "!" as an argument retains the aspect ratio of the box. eg \resizebox{5cm}{!}{fat cat} will make "fat cat" appear 5 cm wide, and suitably high. (From p129, Lamport) ================= xfig and PDFLaTeX ================= (written by Josselin Mouette ) 1. A STANDARD PDF FILE In xfig, select the "PDF" export filter, which will generate a foo.pdf file. In your document, put in the preamble : \usepackage[pdftex]{graphicx} \DeclareGraphicsRule{.pdftex}{pdf}{.pdftex}{} and insert your picture with \includegraphics{foo.pdf} You may use all the includegraphics options as well. Pros: Very easy to use. Cons: The text in your figure will appear as is on your document, using postscript fonts; you cannot put some TeX code in it. 2. A COMBINED PDF/LaTeX FILE This is the method I would recommend in most cases. It may be difficult for the beginner at the first time, but it is really powerful. If you choose this method, you'll have to set the xfig fonts to LaTeX ones, and to set the "special" attribute of your text boxes. To do this automatically, you can add these 2 lines in your .Xresources or .Xdefaults (depends on your system): Fig.latexfonts: true Fig.specialtext: true Then, when exporting, select the "Combined PS/LaTeX" format. Until there is a "Combined PDF/LaTeX" export filter, you'll have to do an extra manipulation: just launch the script "pstex2pdf" following here (requires epstopdf to work), it will convert the foo.pstex to foo.pdf, and foo.pstex_t to foo.pdftex: --- CUT HERE --- #! /bin/sh for i in `ls *.pstex`; do AZE=`basename "$i" .pstex` if [ -r "$AZE".pdf ] && [ "$AZE".pdf -nt "$AZE".pstex ]; then echo Nothing to do for "$i". else echo -n Converting "$i". epstopdf "$AZE".pstex > "$AZE".pdf echo -n . sed "s/$AZE.pstex/$AZE.pdf/" "$AZE".pstex_t > "$AZE".pdftex echo . fi done --- CUT HERE --- Then, in your LaTeX file, put in the preamble: \usepackage[pdftex]{graphicx,color} The color package is required whenever you put some text in colors. Then include the picture with_ \input foo.pdftex_t You can also resize it: \resizebox{3cm}{!}{\input foo.pdftex_t} % sets the width to 3cm Pros: Whatever is put in your text boxes is treated just as your document's code; that means you can use your own macros, which is really cool. Cons: When putting big formulas on your figure, it is sometimes difficult to predict what place they will take. 3. METAPOST There is nothing special to do in xfig to use MetaPost. All the text you type will be treated as plain TeX code - note, this will be not compiled within your document, so you don't have acess to packages like AMS-TeX, neither have you to your macros. In xfig, export your file with the MetaPost filter, it creates foo.mp. Then, type mpost foo.mp, it will generate foo.0 (or foo.1, sometimes). In your document, put this in the preamble: \input supp-pdf.tex \usepackage[pdftex]{graphicx} And to include your figure : \convertMPtoPDF{foo.0}{1}{1} That's it. Quite simple, and you can put a bit TeX inside. Pros: Can be easily included in a dual-output (pdf/dvi) file: for including it as PS, just put a \includegraphics{foo.0} in the document. Cons: Not adapted to big formulas, as AMS-LaTeX is not accessible. Long phrases may look bad as well, if your document is not in English (babel cannot be used). 4. MULTI-METAPOST This method is designed to be used in PDF presentations. Using the \pause command, it will display step by step the layers of your figure as you click on the button, which can look very nice (and can even be useful sometimes). All that have been told about MetaPost inclusions is true, but there are a few extra things to know: When creating your figure, be careful with the depth of your objects. When exporting your figure in the MultiMetaPost format, transfig will treat the consecutive depth levels where is an object as a single layer, for example: Circle at depth 51 \__first displayed layer Text at depth 50 / *** Nothing at depth 49 Square at depth 48 \ Text at depth 48 > Second displayed layer Curve at depth 47 / ... and so on. After exporting, mpost foo.mmp will create a set of files named foo.0, foo.1... To include them in the document, you will need the mpmulti.sty provided with the latest version of PPower4 (still in Beta stage at the time of writing). The preamble of your document should look like this: \input supp-pdf.tex \usepackage[pdftex]{graphicx} \usepackage{pause,mpmulti} And to include your animation, just put: \multiinclude{foo} You can adjust it to a defined size by using: \multiinclude[graphics={width=5cm}]{foo} Compile your document, then ppower4 it. Nifty, isn't it? Pros: The only way to insert automatically animations. Benefit of the existing xfig's depth system. Cons: Are there some ? xfig.3.2.5c/LATEX.AND.XFIG.zh_CN0000700002656300244210000002017007573725276016334 0ustar bvsmithDomain UsersThis is a Simplified Chinese version of LATEX.AND.XFIG translated by Mendel L Chan on Nov 13, 2001, and converted it to a Traditional Chinese version via autoconvert written by YU GuangHui at the same time. I can be contacted via another email box at: linuxrat@gnuchina.org. ============ >8 BEGIN OF LATEX.AND.XFIG.zh_CN 8< =================== ±ľÎÄ×÷ŐßĘÇ Eri Masson (ericm@kirk.ee.mcgill.ca) ĎÂÎÄ˝˛˝âµÄĘÇĎňLaTeXĹŰćϵͳµÄµĽČëxfigͼƬµÄ·˝·¨Ł¬ĆäÖĐ»ąÓĐһЩСľ÷ÇĎŁ¬ÄÜ ČĂÄú¸üÇáŇ״ﵽĿ±ęˇŁÎŇĐ´µÄ¶«Î÷żÉÄÜÓеăłÂľÉ٬µ«ĘÇ»ąĘÇʵÓĂµÄˇŁ ×ŁÄú˝ˇżµČçŇâ! Eric ľ´ÉĎ ČçşÎÔÚÄúµÄ LaTeX ÎĵµÖеĽČë xfig ͼƬˇĂ -------------------------------------------------------------- ׼±¸żŞĘĽ -------- ÄúżÉŇÔÖ´ĐĐČçĎÂĂüÁîĆô¶Ż xfig łĚĐňˇĂ xfig -specialtext -latexfonts -startlatexFont default ČçąűÄúĎëČĂÄúËůÓеÄͼƬÔڱ༭ʱľÍ´řÓĐĚŘĘâÎıľşÍ LaTeX ×ÖĚ壬ÄúżÉŇÔÔÚÄúµÄ .Xresources »ňŐßĆäËűÄúËůĘąÓõÄŔŕËĆ×ĘÔ´ÎÄĽţĐ޸ÄČçĎÂÉčÖáà Fig.latexfonts: true Fig.specialtext: true xfig żÉŇÔĘäłö LaTeX żÉŇÔ¶ÁȡµÄĽ¸ÖÖ¸ńĘ˝ˇŁµ«ĘÇÎŇÔÚ±ľÎÄÖ»ĚÖÂŰČýÖÖ·˝·¨ˇĂ (A) ͼƬֱ˝Ó´ćłÉ LaTeX ¸ńĘ˝ˇŁ (B) ͼƬ´ćłÉ EPS ˛˘ÔÚ LaTeX ÎĵµÖеĽČë PSˇŁ (C) ͼƬ´ćłÉ˛ż·ÖµÄ PS٬˛ż·ÖµÄ LaTeX ¸ńĘ˝ˇŁ¶ţŐßͨʱÓĂÓÚÄúµÄÎĵµˇŁ ŐâČýÖÖ·˝·¨¶ĽÓи÷×ÔµÄÓĹĘĆŁ¬Í¬Ę±¶ĽŇ»ŃůĽňµĄŇ×ĐĐˇŁ·˝·¨(A)µÄÓĹĘĆÔÚÓÚÄúµÄËůÓĐ łÉĆ·¶ĽĘÇ LaTeX ¸ńĘ˝Ł¬ŐâŃůŇ»Ŕ´ÔÚ .dvi ÎÄĽţÖĐľÍÄÜą»°üş¬ËůÓбŘŇŞµÄĐĹϢˇŁ·˝ ·¨(B)µÄÓĹĘĆÔÚÓÚÄúÓĐ×ăą»µÄ×ÔÓÉËćŇâ´¦Ŕí PS ×ÖĚ塣·˝·¨(C)µÄÓĹĘĆÔňÔÚÓÚÄúżÉŇÔ ×ÔÓÉ·˘»ÓPSµÄ»ćÍĽĚŘĐÔŁ¬»ąÓĐ LaTeX µÄÎÄ×ÖĹŰ档 --- ÔÚÄúµÄ LaTeX µĽŃÔ˛ż·Ö(ҲľÍĘÇÎĵµÖĐ \begin{document} ÓďľäǰĂćµÄ˛ż·Ö)٬ ÇëĽÓČëŇÔĎÂÄÚČݡà \usepackage{graphicx} ŐâŃů٬ÄúµÄµĽŃÔ˛ż·Öż´ĆđŔ´ľÍ˛î˛»¶ŕĘÇŐâÖÖŃů×ÓµÄÁˡà %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LaTeX µĽŃÔ˛ż·Ö %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentstyle[12pt,bezier,amstex]{article} % °üş¬˝ř±´Čü¶űÇúĎß»ćÖưü \renewcommand\baselinestretch{1.0} % µĄżŐ¸ń \pagestyle{empty} % ˛»ĐčҳüşÍŇł˝ĹŇłÂë \oddsidemargin -10 true pt % ĆćĘýŇłÂëŇłĂćµÄ×ó±ßżí¶Č \evensidemargin 10 true pt % ĹĽĘýŇłÂëŇłĂćµÄ×ó±ßżí¶Č \marginparwidth 0.75 true in % ĹÔעżí¶Č \oddsidemargin 0 true in % ÇëעŇâˇĂ\oddsidemargin=\evensidemargin \evensidemargin 0 true in \topmargin -0.75 true in % Ö¸¶¨ŇłĂć¶Ą¶Ëµ˝ÎıľĽäľŕ \textheight 9.5 true in % ÎıľĐи߶Č(°üŔ¨˝ĹעşÍÍĽĘľ) \textwidth 6.375 true in % ÎıľĐĐżí¶Č \parindent=0pt % ÎŢĐč¶ÎÂäËő˝ř \parskip=0.15 true in \usepackage{graphicx} % ÔĘĐí·ĹÖĂPS»ćÍĽ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ÎĵµŐýÎÄżŞĘĽ %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \end{document} ·˝·¨(A)ˇĂ- ͼƬֱ˝Ó´ćłÉLaTeX¸ńĘ˝ ----------------------------------------- ´Ó»ćÍĽĽĽĘőµÄ˝Ç¶ČŔ´ż´Ł¬ŐâĘÇÄúÄÜÓĂÉϵÄ×îČőÖǵķ˝Ę˝ÁˡŁLaTeX ÖеÄĎßĚőÖ»ÄÜŇÔ ¶ŕ¸ö 30 şÍ 45 ¶Č˝Ç˝řĐĐ»ćÖÎٶř´řÓĐĽýÍ·µÄĎßĚőÖ»ÄÜŇÔ¶ŕ¸ö 45 ¶Č˝Ç˝řĐĐ»ćÖÎ٠»ąÓĐľÍĘÇĆäËűĽ¸¸öĚŘĐÔŁ¬±ČČçÍÖÔ˛ˇ˘ŃůĚőµČµČ٬¶Ľ˛»Ö§łÖˇŁĘµĽĘÉĎŁ¬xfig ˛˘Ă»ÓĐ ĎńŔűÓñ´Čü¶űÇúĎß°üÄÇŃůşĂşĂŔűÓĂŇŃľ­´ćÔÚµÄ LaTeX şę°üˇŁÔÚ·˝·¨(A)ËůÓĂͼƬ¸ń Ę˝ÖĐÓĂ xfig ˝řĐĐĎßĚő»ćÖĆŁ¬˝«ĎŢÖĆÄúÖ»ÄÜĘąÓĂĚض¨µÄ˝Ç¶ČˇŁČô·ÇČç´Ë٬ÔÚÄú±Ł´ć ͼƬłÉ latex ¸ńĘ˝Ę±Ł¬xfig »áÉč·¨°ŃÄúËů»ćÖƵÄĎßĚő¸ůľÝ latex żÉÓõÄÓĐЧ˝Ç ¶Č˝řĐĐ˝üËĆÄâşĎˇŁÍ¨łŁŐâŃůËůµĂµÄЧąű×ÜĘDz»»áÁîČËÂúŇâµÄˇŁ ÔÚŐâÖÖģʽ֮ĎÂŁ¬ÄúżÉŇÔÔÚÄúµÄͼƬÖĐĘäČëČÎşÎµÄ LaTeX ×Ö´®ˇŁŇ»µ©µĽČëµ˝ LaTeX ÖĐŁ¬×Ö´®»á±»ŐýČ·µŘ˝âĘÍµÄˇŁ±ČČç˵ÓďľäˇĂ $\int_0^9 f(x) dx$ ľÍÄÜą»˝âĘͳɺŻĘý f(x) µÄ´Ó 0 µ˝ 9 µÄÇóşÍ±í´ďĘ˝ˇŁ ÎŞÁË´´˝¨ LaTeX ÎÄĽţ٬ÄúÖ»ĐčŇŞ´Ó xfig Ö÷˛ËµĄÖĐѡÔňĘäłö˛ËµĄŁ¬Č»şóѡ¶¨LaTeX ͼƬ×÷ÎŞĘäłö¸ńĘ˝ˇŁČç´ËŇ»Ŕ´Ł¬ľÍÄÜą»´´˝¨Ň»¸öŔ©ŐąĂűÎŞ .latex µÄÎÄĽţˇŁ¸ĂÎÄĽţ żÉŇÔÔÚÄúµÄ LaTeX ÎĵµÖĐÖ±˝Óµ÷ÓĂˇŁ±ČČçŇÔϵÄÓďľä´úÂëľÍÄÜ˝« yourfile.latex Ö±˝ÓµĽČëµ˝ LaTeX ÖСà %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ÍĽĘľ (1) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfile.latex} \caption{ÄúµÄÍĽĘľ±ęĚâ} \label{figure:yourreferencename} \end{center} \end{figure} ·˝·¨(B) - ͼƬ±Ł´ćÎŞ EPS ¸ńĘ˝ --------------------------------------------- ÔÚ±ľ·¨ÖĐŁ¬łýÁ˲»ÄÜÔڴ˸ńʽʹÓĂ LaTeX ĂüÁî´®Í⣬ͼƬµÄ»ćÖƲ»´ćÔÚČÎşÎĆäËű µÄĎŢÖÎٶřĐí¶ŕµÄ PS ×ÖĚĺÔňżÉČ«˛żÔÚŐâÖÖ¸ńĘ˝ĎÂŔűÓĂĆđŔ´ˇŁŇ»µ©ÄúÍęłÉ»ćÖĆÄúµÄ ÍĽĆ¬Ł¬Ö»ĐčŇŞ´Ó xfig Ö÷˛ËµĄÖĐѡÔńĘäłö˛ËµĄŁ¬Č»şóѡ¶¨Ęäłö EPS ¸ńĘ˝ˇŁČç´Ë˝« ĘäłöŔ©ŐąĂűÎŞ .eps µÄÎÄĽţ٬¶ř¸ĂÎÄĽţżÉŇÔ°´ŐŐŇÔĎ·˝Ę˝°üş¬˝ř LaTeX ÎĵµÖСà %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ÍĽĘľ (2) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \ \includegraphics[width=4in]{yourfile.eps} \end{center} \caption{ÄúµÄ±ęĚâ} \label{figure:yourreference} \end{figure} ·˝·¨(C) - PS/LaTeXͬÎÄą˛´ć -------------------------------- ÔÚŐâÖÖ¸ńĘ˝ĎÂŁ¬ÄúżÉŇÔČÎŇâ»ćÖĆĎßĚő»ňŐßÇúĎߡŁÔÚ±Ł´ćŐâÖÖ¸ńĘ˝Ę±Ł¬LaTeX ×Ö´®»á ĎŢÖĆÄú˛»ÄÜͬʱʹÓĂŇŃÓĐµÄ PS ×ÖĚ塣ÄúČÔČ»żÉŇÔĘäČë×Ö´®Ł¬ľÍĎó $\int_0^9 f(x) dx$ ŐâÖÖ×Ö´®żÉŇÔ±» LaTeX ´¦ŔíˇŁµ«ĘÇĘąÓĂŐâÖÖ¸ńĘ˝µÄĘÂşó٬ÄúµĂ±Ł´ćÎÄĽţÁ˝´ÎˇĂŇ»´Î ĘǺϲ˘ ps/latex (PS˛ż·Ö) ¸ńĘ˝Ł¬ÁíÍâŇ»´ÎÔňĘǺϲ˘ ps/latex (LaTeX˛ż·Ö)¸ńĘ˝ˇŁ µÚŇ»´ÎÉúłÉµÄĘÇŇ»¸ö .pstex ÎÄĽţ٬µÚ¶ţ´ÎÉúłÉµÄÔňĘÇŇ»¸ö .pstex_t ÎÄĽţˇŁÄǸö .pstex_t »á×Ô¶Żµ÷ÓĂ .pstex ÎÄĽţ٬ŐâŃůÄúľÍÎŢĐčÔÚÄúµÄ TeX ÎĵµÖĐĎÔĘ˝µŘ°üş¬ Őâ¸ö .pstex ÎÄĽţÁˡŁŇŞÔÚÎĵµÖаüş¬˝řČĄÄúµÄÍĽĆ¬Ł¬ÇëĘąÓĂŔŕËĆŇÔϵÄÓďľä´úÂëˇĂ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ÍĽĘľ (3) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfigure.pstex_t} \caption{ÄúµÄÍĽĘľ} \label{figure:example} \end{center} \end{figure} N.B. ÄúżÉÄÜĎëŇŞ±ŕĽ­ÓĂ xfig ÉúłÉµÄ .pstex_t ÎÄĽţˇŁČçąűÖ¸¶¨ÎŞĆäËűÎÄĽţ±ČČç .pstex٬xfig ˝«×Ô¶Ż¸řłöÖ¸Ďň .pstex ÎÄĽţµÄ·ľ¶ˇŁŐâÓĐʱ˛»ą»·˝±ă٬ÓČĆä ĘÇÔÚÄúŇňÎŞ LaTeX Îĵµ´¦Ŕíłö´í٬¶ř˛»µĂ˛»ŇƶŻÎÄĽţµ˝ÁíÍâŇ»¸öĿ¼µÄʱşňˇŁ ÎҸöČËÇăĎňÓÚČĄµôČ«˛żÂ·ľ¶¶řÖ»±ŁÁôÎÄĽţĂűˇŁ ĆäËűŇŞµă -------- xfig ---- ÄúżÉŇÔÔÚ LaTeX ÎÄĽţÖеĽČë EPS ÎÄĽţˇŁČçąűÄú׼±¸ÔÚĆäËűłĚĐňµÄĘäłö˝áąűÉĎͿѻ µÄʱşň٬ŐâľÍşÜÓĐÓĂÁËˇŁ±ČČçËµŁ¬ÄúżÉŇÔ°üş¬˝řŔ´Ň»¸öŔ´×Ô MATLAB µÄͼƬ˛˘¸ůľÝ ¸öČËĐËȤ±ęʶŇÔ×Ö·ű´®Ł¬ĎßĚő٬ȦżňµČµČˇŁ×Ô xfig 2.1.7 żŞĘĽŁ¬ľÍÓĐÁËŇ»ĎîÄżą¦ ÄÜŁ¬ÔĘĐíÄúÔÚÄúµÄ»ćÍĽÖв鿴 PSˇŁŐâ¸öą¦ÄÜşÜşĂˇŁ ČçąűÄúÖ»ÓĐ .ps ÎÄĽţ٬ÄÇĂ´ÇëĘąÓĂŔ´×Ô ghostscript ČíĽţ°üµÄ ps2epsi Ŕ´·â×°Äú µÄ PS ÎÄĽţˇŁ -- ================================================================= Eric Masson - ericm@finnegan.ee.mcgill.ca - FAX: 514 398 4470 ================================================================= ================================================================= »ąÓĐһЩҪµă٬Ŕ´×Ô Stephen Eglen * ¸Ä±ä pstext_t ÖеÄͼƬ´óС ČçąűÄúͨąýĘąÓĂ \input{file.psttext_t} Ŕ´ĘąÓĂÍĽĆ¬Ł¬ÄÇĂ´ÄúľÍÎŢ·¨Ö¸¶¨ÍĽĆ¬µÄ´ó СÁËˇŁ¶Ô´ËÎŇÓĐÁ˝ÖÖ˝âľö·˝°¸ˇŁ 1. ÔÚ xfig ÖоͻćÖƳɺĎĘʵĴóСˇŁŇŞĂ´ÔÚÄú±Ł´ćÍĽĆ¬Ę±Ł¬ľÍÔÚ±Ł´ć´°żÚÄÇŔď¸Ä±ä ͼƬµÄ±ČŔýˇŁČçąűÄúÔÚ LaTeX ÎĵµÖĐ·˘ĎÖͼƬ´óС˛»şĎĘĘŁ¬ÄÇĂ´ŐâÁ˝ÖÖ·˝·¨¶ĽµĂ ˝řČë xfig ÖŘĐ½řĐĐ»ćÍĽˇŁ 2. ÔÚ LaTeX ÖĐͨąýĘąÓĂ \scalebox »ňŐß \resizebox Ŕ´¸Ä±äͼƬµÄ´óСˇŁŐâĘÇÔÚ ÍĽĎńÍĽĐδ¦Ŕí°ü graphics ÖĐÓĂÓÚËő·ĹÎıľ»ňŐßͼƬµÄłŁĽűą¦ÄܡŁĘąÓĂÓďľä \scalebox{factor}{object} żÉŇÔŇÔČκαČŔý factor Ëő·Ĺ objectˇŁfactor ĘÇŇ»¸ö±ČŔýĘý×Ö(СÓÚ1´ú±íËőĐˇŁ¬ ´óÓÚ1´ú±í·Ĺ´ó)Ł»¶ř object ÔňĘÇĆ˝łŁŇŞËő·ĹµÄÎıľ»ňŐßͼƬ¶ÔĎ󡣱ČČçÓďľä \scalebox{2}{ \input{file.pstex_t} } ľÍÄÜą»˝«ÍĽĆ¬·Ĺ´ó¶ţ±¶Ł¬ŐâÓëÇý¶ŻÓĐąŘ( .ps żÉŇÔż´µ˝Ł¬¶ř xdvi Ôňż´˛»µ˝Đ§ąű)ˇŁ Ëő·ĹµăŐó×ÖĚĺżÉÄܻᵼÖÂÄŃż´µÄ˝áąű٬ËůŇÔ×îşĂ±ÜĂâĘąÓõăŐó×ÖĚ塣Óďľä \resizebox{width}{ht} {stuff} ÔňÄÜą»ÖŘе÷Őű¶ÔĎó stuff ´óСΪ widthx htˇŁČçąűĘąÓĂ "!" ×÷ÎŞ˛ÎĘý٬ÄÇĂ´ ľÍÄÜą»±ŁłÖşĐżň(box)żňĽÜ±ČŔý˛»±ä٬±ČČçÓďľä \resizebox{5cm}{!}{fat cat} ľÍÄÜą»ĘąµĂ fat cat ±ŁłÖ 5cm żíşÍĎŕÓ¦±ČŔýµÄ¸ß¶ČˇŁ (ŐŞ×Ô Lamport µÄµÚ129Ňł) ============= >8 END of LATEX.AND.XFIG.zh_CN 8<====================== xfig.3.2.5c/LATEX.AND.XFIG.zh_TW0000700002656300244210000002026207573725302016356 0ustar bvsmithDomain UsersThis is a Traditional Chinese(Big5) version of LATEX.AND.XFIG converted from Simplified Chinese(GB2312) translated by Mendel L Chan(could be touched by beos@turbolinux.com.cn or linuxrat@gnuchina.org) on Nov 13, 2001. The encoding-converting utility is the (zh-)autoconvert written by YU GuangHui , a Chinese freesoftware developer. ============= >8 BEGIN OF LATEX.AND.XFIG.zh_TW 8< =================== Ą»¤ĺ§@ŞĚ¬O Eri Masson (ericm@kirk.ee.mcgill.ca) ¤U¤ĺÁż¸ŃŞş¬O¦V LaTeX ±ĆŞ©¨t˛ÎŞşľÉ¤JxfigąĎ¤ůŞş¤čŞkˇA¨ä¤¤Á٦ł¤@¨Ç¤płZ¬ˇA ŻŕĹý±z§ó»´©öąF¨ěĄŘĽĐˇC§ÚĽgŞşŞF¦čĄiŻŕ¦łÂIłŻÂ¡A¦ý¬OÁ٬OąęĄÎŞşˇC ݬ±z°·±d¦p·N! Eric ·q¤W ¦p¦ó¦b±zŞş LaTeX ¤ĺŔɤ¤ľÉ¤J xfig ąĎ¤ůˇJ -------------------------------------------------------------- ·ÇłĆ¶}©l -------- ±zĄiĄH°ő¦ć¦p¤U©RĄO±Ň°Ę xfig µ{§ÇˇJ xfig -specialtext -latexfonts -startlatexFont default ¦pŞG±z·QĹý±z©Ň¦łŞşąĎ¤ů¦b˝sżč®É´N±a¦łŻS®í¤ĺĄ»©M LaTeX ¦rĹéˇA±zĄiĄH¦b±zŞş .Xresources ©ÎŞĚ¨äĄL±z©Ň¨ĎĄÎŞşĂţ¦ü¸ę·˝¤ĺĄó­×§ď¦p¤Uł]¸mˇJ Fig.latexfonts: true Fig.specialtext: true xfig ĄiĄHżéĄX LaTeX ĄiĄHĹŞ¨úŞş´XşŘ®ć¦ˇˇC¦ý¬O§Ú¦bĄ»¤ĺĄu°Q˝×¤TşŘ¤čŞkˇJ (A) ąĎ¤ůŞ˝±µ¦s¦¨ LaTeX ®ć¦ˇˇC (B) ąĎ¤ů¦s¦¨ EPS ¨Ă¦b LaTeX ¤ĺŔɤ¤ľÉ¤J PSˇC (C) ąĎ¤ů¦s¦¨łˇ¤ŔŞş PSˇAłˇ¤ŔŞş LaTeX ®ć¦ˇˇC¤GŞĚłq®ÉĄÎ¤_±zŞş¤ĺŔɡC ło¤TşŘ¤čŞkłŁ¦ł¦U¦ŰŞşŔu¶ŐˇA¦P®ÉłŁ¤@ĽË²łć©ö¦ćˇC¤čŞk(A)ŞşŔu¶Ő¦b¤_±zŞş©Ň¦ł ¦¨«~łŁ¬O LaTeX ®ć¦ˇˇAłoĽË¤@¨Ó¦b .dvi ¤ĺĄó¤¤´NŻŕ°÷Ą]§t©Ň¦łĄ˛­nŞş«H®§ˇC¤č Şk(B)ŞşŔu¶Ő¦b¤_±z¦ł¨¬°÷Şş¦ŰĄŃŔH·NłB˛z PS ¦rĹéˇC¤čŞk(C)ŞşŔu¶Ő«h¦b¤_±zĄiĄH ¦ŰĄŃµo´§PSŞşĂ¸ąĎŻS©ĘˇAÁ٦ł LaTeX Şş¤ĺ¦r±ĆŞ©ˇC --- ¦b±zŞş LaTeX ľÉ¨Ąłˇ¤Ŕ(¤]´N¬O¤ĺŔɤ¤ \begin{document} »yĄy«e­±Şşłˇ¤Ŕ)ˇA ˝ĐĄ[¤JĄH¤U¤ş®eˇJ \usepackage{graphicx} łoĽËˇA±zŞşľÉ¨Ąłˇ¤Ŕ¬Ý°_¨Ó´N®t¤Ł¦h¬OłoşŘĽË¤lŞş¤FˇJ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LaTeX Preamble %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentstyle[12pt,bezier,amstex]{article} % Ą]§t¶i¨©ÁÉş¸¦±˝uø¨îĄ] \renewcommand\baselinestretch{1.0} % łćŞĹ®ć \pagestyle{empty} % ¤Ł»Ý­¶¬Ü©M­¶¸}­¶˝X \oddsidemargin -10 true pt % ©_ĽĆ­¶˝X­¶­±ŞşĄŞĂäĽe«× \evensidemargin 10 true pt % °¸ĽĆ­¶˝X­¶­±ŞşĄŞĂäĽe«× \marginparwidth 0.75 true in % ®ÇŞ`Ľe«× \oddsidemargin 0 true in % ˝ĐŞ`·NˇJ\oddsidemargin=\evensidemargin \evensidemargin 0 true in \topmargin -0.75 true in % «ü©w­¶­±ł»şÝ¨ě¤ĺĄ»¶ˇ¶Z \textheight 9.5 true in % ¤ĺĄ»¦ć°Ş«×(Ą]¬A¸}Ş`©MąĎĄÜ) \textwidth 6.375 true in % ¤ĺĄ»¦ćĽe«× \parindent=0pt % µL»Ý¬q¸¨ÁY¶i \parskip=0.15 true in \usepackage{graphicx} % ¤ął\©ń¸mPSøąĎ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Document Beginning %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \end{document} ¤čŞk(A)ˇJ- ąĎ¤ůŞ˝±µ¦s¦¨LaTeX®ć¦ˇ ----------------------------------------- ±qøąĎ§ŢłNŞş¨¤«×¨Ó¬ÝˇAło¬O±zŻŕĄÎ¤WŞşłĚ®z´ĽŞş¤č¦ˇ¤FˇCLaTeX ¤¤Şş˝u±řĄuŻŕĄH ¦h­Ó 30 ©M 45 «×¨¤¶i¦ćø¨îˇC¦Ó±a¦ł˝bŔYŞş˝u±řĄuŻŕĄH¦h­Ó 45 «×¨¤¶i¦ćø¨îˇC Á٦ł´N¬O¨äĄL´X­ÓŻS©ĘˇA¤ń¦pľň¶ęˇBĽË±řµĄµĄˇAłŁ¤Ł¤ä«ůˇCąę»Ú¤WˇAxfig ¨Ă¨S¦ł ął§QĄÎ¨©ÁÉş¸¦±˝uĄ]¨şĽË¦n¦n§QĄÎ¤w¸g¦s¦bŞş LaTeX §»Ą]ˇC¦b¤čŞk(A)©ŇĄÎąĎ¤ů®ć ¦ˇ¤¤ĄÎ xfig ¶i¦ć˝u±řø¨îˇA±N­­¨î±zĄuŻŕ¨ĎĄÎŻS©wŞş¨¤«×ˇC­Y«D¦p¦ąˇA¦b±z«O¦s ąĎ¤ů¦¨ latex ®ć¦ˇ®ÉˇAxfig ·|ł]Şk§â±z©Ňø¨îŞş˝u±ř®ÚľÚ latex ĄiĄÎŞş¦ł®Ä¨¤ «×¶i¦ćŞń¦üŔŔ¦XˇCłq±`łoĽË©Ň±oŞş®ÄŞGÁ`¬O¤Ł·|ĄO¤Hşˇ·NŞşˇC ¦błoşŘĽŇ¦ˇ¤§¤UˇA±zĄiĄH¦b±zŞşąĎ¤ů¤¤żé¤JĄô¦óŞş LaTeX ¦r¦ęˇC¤@ĄąľÉ¤J¨ě LaTeX ¤¤ˇA¦r¦ę·|łQĄż˝T¦a¸ŃÄŔŞşˇC¤ń¦p»ˇ»yĄyˇJ $\int_0^9 f(x) dx$ ´NŻŕ°÷¸ŃÄŔ¦¨¨çĽĆ f(x) Şş±q 0 ¨ě 9 Şş¨D©MŞíąF¦ˇˇC ¬°¤FłĐ«Ř LaTeX ¤ĺĄóˇA±zĄu»Ý­n±q xfig ĄDµćłć¤¤żď«hżéĄXµćłćˇAµM«áżď©wLaTeX ąĎ¤ů§@¬°żéĄX®ć¦ˇˇC¦p¦ą¤@¨ÓˇA´NŻŕ°÷łĐ«Ř¤@­ÓÂX®i¦W¬° .latex Şş¤ĺĄóˇC¸Ó¤ĺĄó ĄiĄH¦b±zŞş LaTeX ¤ĺŔɤ¤Ş˝±µ˝ŐĄÎˇC¤ń¦pĄH¤UŞş»yĄyĄN˝X´NŻŕ±N yourfile.latex Ş˝±µľÉ¤J¨ě LaTeX ¤¤ˇJ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfile.latex} \caption{±zŞşąĎĄÜĽĐĂD} \label{figure:yourreferencename} \end{center} \end{figure} ¤čŞk(B) - ąĎ¤ů«O¦s¬° EPS ®ć¦ˇ --------------------------------------------- ¦bĄ»Şk¤¤ˇA°Ł¤F¤ŁŻŕ¦b¦ą®ć¦ˇ¨ĎĄÎ LaTeX ©RĄO¦ęĄ~ˇAąĎ¤ůŞşĂ¸¨î¤Ł¦s¦bĄô¦ó¨äĄL Şş­­¨îˇC¦Ół\¦hŞş PS ¦rĹé«hĄiĄţłˇ¦błoşŘ®ć¦ˇ¤U§QĄÎ°_¨ÓˇC¤@Ąą±z§ą¦¨Ă¸¨î±zŞş ąĎ¤ůˇAĄu»Ý­n±q xfig ĄDµćłć¤¤żďľÜżéĄXµćłćˇAµM«áżď©wżéĄX EPS ®ć¦ˇˇC¦p¦ą±N żéĄXÂX®i¦W¬° .eps Şş¤ĺĄóˇA¦Ó¸Ó¤ĺĄóĄiĄH«ö·ÓĄH¤U¤č¦ˇĄ]§t¶i LaTeX ¤ĺŔɤ¤ˇJ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \ \includegraphics[width=4in]{yourfile.eps} \end{center} \caption{±zŞşĽĐĂD} \label{figure:yourreference} \end{figure} ¤čŞk(C) - PS/LaTeX¦P¤ĺ¦@¦s -------------------------------- ¦błoşŘ®ć¦ˇ¤UˇA±zĄiĄHĄô·Nø¨î˝u±ř©ÎŞĚ¦±˝uˇC¦b«O¦słoşŘ®ć¦ˇ®ÉˇALaTeX ¦r¦ę·| ­­¨î±z¤ŁŻŕ¦P®É¨ĎĄÎ¤w¦łŞş PS ¦rĹéˇC±z¤´µMĄiĄHżé¤J¦r¦ęˇA´N¶H $\int_0^9 f(x) dx$ łoşŘ¦r¦ęĄiĄHłQ LaTeX łB˛zˇC¦ý¬O¨ĎĄÎłoşŘ®ć¦ˇŞş¨Ć«áˇA±z±o«O¦s¤ĺĄó¨â¦¸ˇJ¤@¦¸ ¬O¦X¨Ă ps/latex (PSłˇ¤Ŕ) ®ć¦ˇˇAĄtĄ~¤@¦¸«h¬O¦X¨Ă ps/latex (LaTeXłˇ¤Ŕ)®ć¦ˇˇC ˛Ä¤@¦¸ĄÍ¦¨Şş¬O¤@­Ó .pstex ¤ĺĄóˇA˛Ä¤G¦¸ĄÍ¦¨Şş«h¬O¤@­Ó .pstex_t ¤ĺĄóˇC¨ş­Ó .pstex_t ·|¦Ű°Ę˝ŐĄÎ .pstex ¤ĺĄóˇAłoĽË±z´NµL»Ý¦b±zŞş TeX ¤ĺŔɤ¤Ĺ㦡¦aĄ]§t ło­Ó .pstex ¤ĺĄó¤FˇC­n¦b¤ĺŔɤ¤Ą]§t¶iĄh±zŞşąĎ¤ůˇA˝Đ¨ĎĄÎĂţ¦üĄH¤UŞş»yĄyĄN˝XˇJ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Figure 3 of Lecture %%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{figure}[htbp] \begin{center} \input{yourfigure.pstex_t} \caption{±zŞşąĎĄÜ} \label{figure:example} \end{center} \end{figure} N.B. ±zĄiŻŕ·Q­n˝sżčĄÎ xfig ĄÍ¦¨Şş .pstex_t ¤ĺĄóˇC¦pŞG«ü©w¬°¨äĄL¤ĺĄó¤ń¦p .pstexˇAxfig ±N¦Ű°ĘµąĄX«ü¦V .pstex ¤ĺĄóŞş¸ô®|ˇCło¦ł®É¤Ł°÷¤č«KˇA¤×¨ä ¬O¦b±z¦]¬° LaTeX ¤ĺŔÉłB˛zĄXżůˇA¦Ó¤Ł±o¤Ł˛ľ°Ę¤ĺĄó¨ěĄtĄ~¤@­ÓĄŘżýŞş®É­ÔˇC §Ú­Ó¤H¶É¦V¤_Ąh±ĽĄţłˇ¸ô®|¦ÓĄu«OŻd¤ĺĄó¦WˇC ¨äĄL­nÂI -------- xfig ---- ±zĄiĄH¦b LaTeX ¤ĺĄó¤¤ľÉ¤J EPS ¤ĺĄóˇC¦pŞG±z·ÇłĆ¦b¨äĄLµ{§ÇŞşżéĄXµ˛ŞG¤W¶îľ~ Şş®É­ÔˇAło´N«Ü¦łĄÎ¤FˇC¤ń¦p»ˇˇA±zĄiĄHĄ]§t¶i¨Ó¤@­Ó¨Ó¦Ű MATLAB ŞşąĎ¤ů¨Ă®ÚľÚ ­Ó¤Hżł˝ěĽĐĂŃĄH¦r˛Ĺ¦ęˇA˝u±řˇA°é®ŘµĄµĄˇC¦Ű xfig 2.1.7 ¶}©lˇA´N¦ł¤F¤@¶µĄŘĄ\ ŻŕˇA¤ął\±z¦b±zŞşĂ¸ąĎ¤¤¬d¬Ý PSˇCło­ÓĄ\Żŕ«Ü¦nˇC ¦pŞG±zĄu¦ł .ps ¤ĺĄóˇA¨ş»ň˝Đ¨ĎĄÎ¨Ó¦Ű ghostscript łnĄóĄ]Şş ps2epsi ¨Ó«Ę¸Ë±z Şş PS ¤ĺĄóˇC -- ================================================================= Eric Masson - ericm@finnegan.ee.mcgill.ca - FAX: 514 398 4470 ================================================================= ================================================================= Á٦ł¤@¨Ç­nÂIˇA¨Ó¦Ű Stephen Eglen * §ďĹÜ pstext_t ¤¤ŞşąĎ¤ů¤j¤p ¦pŞG±złqąL¨ĎĄÎ \input{file.psttext_t} ¨Ó¨ĎĄÎąĎ¤ůˇA¨ş»ň±z´NµLŞk«ü©wąĎ¤ůŞş¤j ¤p¤FˇCąď¦ą§Ú¦ł¨âşŘ¸Ń¨M¤č®×ˇC 1. ¦b xfig ¤¤´Nø¨î¦¨¦XľAŞş¤j¤pˇC­n»ň¦b±z«O¦sąĎ¤ů®ÉˇA´N¦b«O¦sµˇ¤f¨ş¸Ě§ďĹÜ ąĎ¤ůŞş¤ń¨ŇˇC¦pŞG±z¦b LaTeX ¤ĺŔɤ¤µo˛{ąĎ¤ů¤j¤p¤Ł¦XľAˇA¨ş»ňło¨âşŘ¤čŞkłŁ±o ¶i¤J xfig ­«·s¶i¦ćøąĎˇC 2. ¦b LaTeX ¤¤łqąL¨ĎĄÎ \scalebox ©ÎŞĚ \resizebox ¨Ó§ďĹܹϤůŞş¤j¤pˇCło¬O¦b ąĎąłąĎ§ÎłB˛zĄ] graphics ¤¤ĄÎ¤_ÁY©ń¤ĺĄ»©ÎŞĚąĎ¤ůŞş±`¨ŁĄ\ŻŕˇC¨ĎĄÎ»yĄy \scalebox{factor}{object} ĄiĄHĄHĄô¦ó¤ń¨Ň factor ÁY©ń objectˇCfactor ¬O¤@­Ó¤ń¨ŇĽĆ¦r(¤p¤_1ĄNŞíÁY¤pˇA ¤j¤_1ĄNŞí©ń¤j)ˇF¦Ó object «h¬OĄ­±`­nÁY©ńŞş¤ĺĄ»©ÎŞĚąĎ¤ůąď¶HˇC¤ń¦p»yĄy \scalebox{2}{ \input{file.pstex_t} } ´NŻŕ°÷±NąĎ¤ů©ń¤j¤G­żˇAło»PĹX°Ę¦łĂö( .ps ĄiĄH¬Ý¨ěˇA¦Ó xdvi «h¬Ý¤Ł¨ě®ÄŞG)ˇC ÁY©ńÂI°}¦rĹéĄiŻŕ·|ľÉ­PĂř¬ÝŞşµ˛ŞGˇA©ŇĄHłĚ¦nÁ×§K¨ĎĄÎÂI°}¦rĹéˇC»yĄy \resizebox{width}{ht} {stuff} «hŻŕ°÷­«·s˝Őľăąď¶H stuff ¤j¤p¬° widthx htˇC¦pŞG¨ĎĄÎ "!" §@¬°°ŃĽĆˇA¨ş»ň ´NŻŕ°÷«O«ů˛°®Ř(box)®Ř¬[¤ń¨Ň¤ŁĹܡA¤ń¦p»yĄy \resizebox{5cm}{!}{fat cat} ´NŻŕ°÷¨Ď±o fat cat «O«ů 5cm Ľe©M¬ŰŔł¤ń¨ŇŞş°Ş«×ˇC (şK¦Ű Lamport Şş˛Ä129­¶) ============= >8 END of LATEX.AND.XFIG.zh_TW 8<====================== ×}9ëŤ8ó­uß­ô÷˝v×M9ó^8ă xfig.3.2.5c/CompKeyDB0000700002656300244210000002027507736126100015063 0ustar bvsmithDomain Users:~Ctrl1: insert-string(1) :~Ctrl2: insert-string(2) :~Ctrl3: insert-string(3) :~Ctrl4: insert-string(4) :~Ctrla: insert-string(a) :~Ctrlc: insert-string(c) :~Ctrld: insert-string(d) :~Ctrle: insert-string(e) :~Ctrli: insert-string(i) :~Ctrln: insert-string(n) :~Ctrlo: insert-string(o) :~Ctrlp: insert-string(p) :~Ctrls: insert-string(s) :~Ctrlu: insert-string(u) :~Ctrl~Metay: insert-string(y) :~CtrlA: insert-string(A) :~CtrlC: insert-string(C) :~CtrlE: insert-string(E) :~CtrlD: insert-string(D) :~CtrlI: insert-string(I) :~CtrlL: insert-string(L) :~CtrlN: insert-string(N) :~CtrlO: insert-string(O) :~CtrlP: insert-string(P) :~CtrlR: insert-string(R) :~CtrlS: insert-string(S) :~CtrlU: insert-string(U) :~CtrlX: insert-string(X) :~CtrlY: insert-string(Y) :quotedbl: insert-string(0x22) :bar: insert-string(|) :exclam: insert-string(!) :underscore: insert-string(_) :less: insert-string(<) :minus: insert-string(-) :asciicircum: insert-string(^) :plus: insert-string(+) :backslash: insert-string(\) :slash: insert-string(/) :greater: insert-string(>) :question: insert-string(?) :asterisk: insert-string(*) :grave: insert-string(`) :apostrophe: insert-string(') :asciitilde: insert-string(~) :period: insert-string(.) :comma: insert-string(0x2c) :colon: insert-string(:) :Ctrla: beginning-of-line() :Ctrle: end-of-line() :Ctrlf: forward-character() :Metaf: forward-word() :Ctrlb: backward-character() :Metab: backward-word() :Meta]: forward-paragraph() :Meta[: backward-paragraph() :Ctrld: delete-next-character() :Ctrlh: delete-previous-character() :Metad: delete-next-word() :Metah: delete-previous-word() :MetaD: kill-word() :MetaH: backward-kill-word() :Ctrlw: kill-selection() :Ctrlk: kill-to-end-of-line() :Metak: kill-to-end-of-paragraph() :Metay: insert-selection(PRIMARY,CUT_BUFFER0) :Ctrll: redraw-display() :Metai: insert-file() :Ctrlr: search(backward) :Ctrls: search(forward) :Ctrlu: multiply(4) :Ctrlg: multiply(Reset) :Metaq: form-paragraph() :Ctrlt: transpose-characters() :Ctrly: insert-selection(CUT_BUFFER1) :Multi_key,:o,:e: insert-string(0x98) :Multi_key,:O,:E: insert-string(0x99) :Multi_key,:exclam,:exclam: insert-string(0xA1) :Multi_key,:C,:slash: insert-string(0xA2) :Multi_key,:L,:minus: insert-string(0xA3) :Multi_key,:O,:X: insert-string(0xA4) :Multi_key,:Y,:minus: insert-string(0xA5) :Multi_key,:bar,:bar: insert-string(0xA6) :Multi_key,:S,:O: insert-string(0xA7) :Multi_key,:quotedbl,:quotedbl: insert-string(0xA8) :Multi_key,:C,:O: insert-string(0xA9) :Multi_key,:underscore,:a: insert-string(0xAA) :Multi_key,:less,:less: insert-string(0xAB) :Multi_key,:minus,:bar: insert-string(0xAC) :Multi_key,:minus,:minus: insert-string(0xAD) :Multi_key,:R,:O: insert-string(0xAE) :Multi_key,:asciicircum,:minus: insert-string(0xAF) :Multi_key,:asciicircum,:asterisk: insert-string(0xB0) :Multi_key,:plus,:minus: insert-string(0xB1) :Multi_key,:asciicircum,:2: insert-string(0xB2) :Multi_key,:asciicircum,:3: insert-string(0xB3) :Multi_key,:backslash,:backslash: insert-string(0xB4) :Multi_key,:slash,:u: insert-string(0xB5) :Multi_key,:P,:exclam: insert-string(0xB6) :Multi_key,:asciicircum,:period: insert-string(0xB7) :Multi_key,:comma,:comma: insert-string(0xB8) :Multi_key,:asciicircum,:1: insert-string(0xB9) :Multi_key,:underscore,:o: insert-string(0xBA) :Multi_key,:greater,:greater: insert-string(0xBB) :Multi_key,:1,:4: insert-string(0xBC) :Multi_key,:1,:2: insert-string(0xBD) :Multi_key,:3,:4: insert-string(0xBE) :Multi_key,:question,:question: insert-string(0xBF) :Multi_key,:A,:grave: insert-string(0xC0) :Multi_key,:A,:apostrophe: insert-string(0xC1) :Multi_key,:A,:asciicircum: insert-string(0xC2) :Multi_key,:A,:asciitilde: insert-string(0xC3) :Multi_key,:A,:quotedbl: insert-string(0xC4) :Multi_key,:A,:asterisk: insert-string(0xC5) :Multi_key,:A,:E: insert-string(0xC6) :Multi_key,:C,:comma: insert-string(0xC7) :Multi_key,:E,:grave: insert-string(0xC8) :Multi_key,:E,:apostrophe: insert-string(0xC9) :Multi_key,:E,:asciicircum: insert-string(0xCA) :Multi_key,:E,:quotedbl: insert-string(0xCB) :Multi_key,:I,:grave: insert-string(0xCC) :Multi_key,:I,:apostrophe: insert-string(0xCD) :Multi_key,:I,:asciicircum: insert-string(0xCE) :Multi_key,:I,:quotedbl: insert-string(0xCF) :Multi_key,:D,:minus: insert-string(0xD0) :Multi_key,:N,:asciitilde: insert-string(0xD1) :Multi_key,:O,:grave: insert-string(0xD2) :Multi_key,:O,:apostrophe: insert-string(0xD3) :Multi_key,:O,:asciicircum: insert-string(0xD4) :Multi_key,:O,:asciitilde: insert-string(0xD5) :Multi_key,:O,:quotedbl: insert-string(0xD6) :Multi_key,:asterisk,:asterisk: insert-string(0xD7) :Multi_key,:O,:slash: insert-string(0xD8) :Multi_key,:U,:grave: insert-string(0xD9) :Multi_key,:U,:apostrophe: insert-string(0xDA) :Multi_key,:U,:asciicircum: insert-string(0xDB) :Multi_key,:U,:quotedbl: insert-string(0xDC) :Multi_key,:Y,:apostrophe: insert-string(0xDD) :Multi_key,:P,:bar: insert-string(0xDE) :Multi_key,:s,:s: insert-string(0xDF) :Multi_key,:a,:grave: insert-string(0xE0) :Multi_key,:a,:apostrophe: insert-string(0xE1) :Multi_key,:a,:asciicircum: insert-string(0xE2) :Multi_key,:a,:asciitilde: insert-string(0xE3) :Multi_key,:a,:quotedbl: insert-string(0xE4) :Multi_key,:a,:asterisk: insert-string(0xE5) :Multi_key,:a,:e: insert-string(0xE6) :Multi_key,:c,:comma: insert-string(0xE7) :Multi_key,:e,:grave: insert-string(0xE8) :Multi_key,:e,:apostrophe: insert-string(0xE9) :Multi_key,:e,:asciicircum: insert-string(0xEA) :Multi_key,:e,:quotedbl: insert-string(0xEB) :Multi_key,:i,:grave: insert-string(0xEC) :Multi_key,:i,:apostrophe: insert-string(0xED) :Multi_key,:i,:asciicircum: insert-string(0xEE) :Multi_key,:i,:quotedbl: insert-string(0xEF) :Multi_key,:d,:minus: insert-string(0xF0) :Multi_key,:n,:asciitilde: insert-string(0xF1) :Multi_key,:o,:grave: insert-string(0xF2) :Multi_key,:o,:apostrophe: insert-string(0xF3) :Multi_key,:o,:asciicircum: insert-string(0xF4) :Multi_key,:o,:asciitilde: insert-string(0xF5) :Multi_key,:o,:quotedbl: insert-string(0xF6) :Multi_key,:minus,:colon: insert-string(0xF7) :Multi_key,:o,:slash: insert-string(0xF8) :Multi_key,:u,:grave: insert-string(0xF9) :Multi_key,:u,:apostrophe: insert-string(0xFA) :Multi_key,:u,:asciicircum: insert-string(0xFB) :Multi_key,:u,:quotedbl: insert-string(0xFC) :Multi_key,:y,:apostrophe: insert-string(0xFD) :Multi_key,:p,:bar: insert-string(0xFE) :Multi_key,:y,:quotedbl: insert-string(0xFF) xfig.3.2.5c/d_arc.h0000700002656300244210000000167410602603366014606 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern F_pos point[3]; extern F_pos center_point; extern Boolean center_marked; extern void elastic_arc(void); extern void arc_drawing_selected (void); xfig.3.2.5c/d_arcbox.h0000700002656300244210000000005510602603366015307 0ustar bvsmithDomain Usersextern void arcbox_drawing_selected (void); xfig.3.2.5c/d_box.h0000700002656300244210000000141510602603366014622 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ void init_box_drawing(int x, int y); extern void box_drawing_selected (void); xfig.3.2.5c/d_ellipse.h0000700002656300244210000000017610602603366015472 0ustar bvsmithDomain Usersextern void circle_ellipse_bydiameter_drawing_selected (void); extern void circle_ellipse_byradius_drawing_selected (void); xfig.3.2.5c/d_line.h0000700002656300244210000000176010602603366014764 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ void init_trace_drawing(int x, int y); void create_lineobject(int x, int y); void get_intermediatepoint(int x, int y, int shift); void freehand_get_intermediatepoint(int x, int y); extern Boolean freehand_line; extern void line_drawing_selected (void); extern void line_drawing_selected (void); xfig.3.2.5c/d_picobj.h0000700002656300244210000000005510602603366015277 0ustar bvsmithDomain Usersextern void picobj_drawing_selected (void); xfig.3.2.5c/d_regpoly.h0000700002656300244210000000005610602603366015513 0ustar bvsmithDomain Usersextern void regpoly_drawing_selected (void); xfig.3.2.5c/d_spline.h0000700002656300244210000000201510602603366015321 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef D_SPLINE_H #define D_SPLINE_H #define OPEN_SPLINE_MIN_NUM_POINTS 2 #define CLOSED_SPLINE_MIN_NUM_POINTS 3 extern void spline_drawing_selected(void); extern int make_sfactors(F_spline *spl); #endif xfig.3.2.5c/d_subspline.h0000700002656300244210000000221310602603366016033 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef D_SUBSPLINE_H #define D_SUBSPLINE_H extern F_spline *create_subspline(int *num_pts, F_spline *spline, F_point *point, F_sfactor **sfactor, F_sfactor **sub_sfactor); extern void free_subspline(int num_pts, F_spline **spline); extern void draw_subspline(int num_pts, F_spline *spline, int op); #endif /* D_SUBSPLINE_H */ xfig.3.2.5c/d_text.h0000700002656300244210000000275210602603366015023 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void char_handler(XKeyEvent *kpe, unsigned char c, KeySym keysym); extern void draw_char_string(void); extern void erase_char_string(void); extern void finish_text_input(int x, int y, int shift); extern void reload_text_fstruct(F_text *t); extern void reload_text_fstructs(void); extern Boolean text_selection_active; extern Boolean ConvertSelection(); extern void LoseSelection(), TransferSelectionDone(); extern int work_font; #ifdef I18N extern XIC xim_ic; extern Boolean xim_active; extern i18n_char_handler(); extern prefix_append_char(); #ifdef I18N_USE_PREEDIT extern kill_preedit(); #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ extern void text_drawing_selected (void); xfig.3.2.5c/e_addpt.h0000700002656300244210000000217110602603366015127 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void splinepoint_adding(F_spline *spline, F_point *left_point, F_point *added_point, F_point *right_point, double sfactor); extern void linepoint_adding(F_line *line, F_point *left_point, F_point *added_point); extern void find_endpoints(F_point *p, int x, int y, F_point **fp, F_point **sp); extern void point_adding_selected (void); xfig.3.2.5c/e_align.h0000700002656300244210000000004410602603366015122 0ustar bvsmithDomain Usersextern void align_selected (void); xfig.3.2.5c/e_arrow.h0000700002656300244210000000207710602603366015172 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void delete_linearrow(F_line *line, F_point *prev_point, F_point *selected_point); extern void delete_arcarrow(F_arc *arc, int point_num); extern void delete_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point); extern void arrow_head_selected (void); xfig.3.2.5c/e_break.h0000700002656300244210000000004410602603366015114 0ustar bvsmithDomain Usersextern void break_selected (void); xfig.3.2.5c/e_chop.h0000700002656300244210000000155710602603366014773 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef C_CHOP_H #define C_CHOP_H extern void chop_selected(void); #endif xfig.3.2.5c/e_compound.h0000700002656300244210000000012510602603366015654 0ustar bvsmithDomain Usersextern void close_all_compounds (void); extern void open_compound_selected (void); xfig.3.2.5c/e_convert.h0000700002656300244210000000240010602603366015506 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef E_CONVERT_H #define E_CONVERT_H extern void spline_line(F_spline *s); extern void line_spline(F_line *l, int type_value); extern void toggle_polyline_polygon(F_line *line, F_point *previous_point, F_point *selected_point); extern void toggle_open_closed_spline(F_spline *spline, F_point *previous_point, F_point *selected_point); extern void box_2_box(F_line *old_l); extern void convert_selected (void); #endif /* E_CONVERT_H */ xfig.3.2.5c/e_copy.h0000700002656300244210000000150310602603366015003 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void copy_selected(void); xfig.3.2.5c/e_delete.h0000700002656300244210000000010410602603366015267 0ustar bvsmithDomain Usersextern int delete_all (void); extern void delete_selected (void); xfig.3.2.5c/e_deletept.h0000700002656300244210000000201610602603366015637 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void splinepoint_deleting(F_spline *spline, F_point *previous_point, F_point *selected_point); extern void linepoint_deleting(F_line *line, F_point *prev_point, F_point *selected_point); extern void delete_point_selected (void); xfig.3.2.5c/e_edit.h0000700002656300244210000000317010604747730014766 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef E_EDIT_H #define E_EDIT_H extern void change_sfactor(int x, int y, unsigned int button); extern void Quit(void); extern void clear_text_key(Widget w); extern void paste_panel_key(Widget w, XKeyEvent *event); extern Widget color_selection_panel(char *label, char *wname, char *name, Widget parent, Widget below, Widget beside, Widget *button, Widget *popup, int color, XtCallbackProc callback); extern void color_select(Widget w, Color color); extern void edit_item (void *p, int type, int x, int y); extern void edit_item_selected (void); extern void push_apply_button (void); extern Boolean edit_remember_lib_mode; /* Remember that we were in library mode */ extern Boolean edit_remember_dimline_mode; /* Remember that we were in dimension line mode */ extern Widget pic_name_panel; #endif /* E_EDIT_H */ xfig.3.2.5c/e_flip.h0000700002656300244210000000177610602603370014772 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern int setanchor; extern int setanchor_x; extern int setanchor_y; extern int flip_compound (F_compound *c, int x, int y, int flip_axis); extern void flip_lr_selected (void); extern void flip_ud_selected (void); xfig.3.2.5c/e_glue.h0000700002656300244210000000023510602603370014761 0ustar bvsmithDomain Usersextern int compose_compound (F_compound *c); extern int tag_obj_in_region (int xmin, int ymin, int xmax, int ymax); extern void compound_selected (void); xfig.3.2.5c/e_joinsplit.h0000700002656300244210000000005110602603370016034 0ustar bvsmithDomain Usersextern void join_split_selected (void); xfig.3.2.5c/e_measure.h0000700002656300244210000000016510602603370015470 0ustar bvsmithDomain Usersextern void anglemeas_selected (void); extern void areameas_selected (void); extern void lenmeas_selected (void); xfig.3.2.5c/e_move.h0000700002656300244210000000004310602603370014770 0ustar bvsmithDomain Usersextern void move_selected (void); xfig.3.2.5c/e_movept.h0000700002656300244210000000016510602603370015341 0ustar bvsmithDomain Usersextern int assign_newboxpoint (F_line *b, int x1, int y1, int x2, int y2); extern void move_point_selected (void); xfig.3.2.5c/e_placelib.h0000700002656300244210000000201710602603370015600 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1998 by Stephane Mancini * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern int cur_library_object; extern int old_library_object; extern void cancel_place_lib_obj(int x, int y, int shift); extern void sel_place_lib_obj(void); extern void put_noobj_selected(); extern void put_selected (void); xfig.3.2.5c/e_rotate.h0000700002656300244210000000213510602603370015324 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern int setcenter; extern int setcenter_x; extern int setcenter_y; extern int rotn_dirn; extern float act_rotnangle; extern int rotate_compound (F_compound *c, int x, int y); extern int rotate_line (F_line *l, int x, int y); extern void rotate_ccw_selected (void); extern void rotate_cw_selected (void); xfig.3.2.5c/e_scale.h0000700002656300244210000000214110602603370015112 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void scale_compound(F_compound *c, double sx, double sy, int refx, int refy); extern void scale_radius(F_line *old, F_line *new, int owd, int oht, int nwd, int nht); extern Boolean rescale_dimension_line(F_compound *dimline, float scalex, float scaley, int refx, int refy); extern void scale_selected (void); xfig.3.2.5c/e_tangent.h0000700002656300244210000000004610602603370015465 0ustar bvsmithDomain Usersextern void tangent_selected (void); xfig.3.2.5c/e_update.h0000700002656300244210000000154210604747730015324 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Parts Copyright (c) 1997 by T. Sato * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void update_text(F_text *text); extern void fix_fillstyle (void *object); extern void update_selected (void); xfig.3.2.5c/f_load.h0000700002656300244210000000023610602603370014746 0ustar bvsmithDomain Usersextern int load_file (char *file, int xoff, int yoff); extern int update_recent_list (char *file); extern void merge_file(char *file, int xoff, int yoff); xfig.3.2.5c/f_neuclrtab.h0000700002656300244210000000334110602603370016006 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1994 Anthony Dekker * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef F_NEUCLRTAB_H #define F_NEUCLRTAB_H /* * Neural-Net quantization algorithm based on work of Anthony Dekker */ /* * color.h - header for routines using pixel color values. * * 12/31/85 * * Two color representations are used, one for calculation and * another for storage. Calculation is done with three floats * for speed. Stored color values use 4 bytes which contain * three single byte mantissas and a common exponent. */ #define N_RED 0 #define N_GRN 1 #define N_BLU 2 typedef unsigned char BYTE; /* 8-bit unsigned integer */ typedef BYTE COLR[4]; /* red, green, blue, exponent */ extern BYTE clrtab[][3]; extern int neu_init(long int npixels); extern int neu_init2 (long int npixels); extern int neu_clrtab(int ncolors); extern void neu_pixel(register BYTE *col); extern int neu_map_pixel(register BYTE *col); #define MIN_NEU_SAMPLES 600 /* min number of samples (npixels/samplefac) needed for network */ #endif /* F_NEUCLRTAB_H */ xfig.3.2.5c/f_picobj.h0000700002656300244210000000212710602603370015276 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1992 by Brian Boyter * DPS option Copyright 1992 by Dave Hale * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern FILE *open_picfile(char *name, int *type, Boolean pipeok, char *retname); extern void close_picfile(FILE *file, int type); #define PIPEOK True #define PIPE_NOTOK False extern void read_picobj (F_pic *pic, char *file, int color, Boolean force, Boolean *existing); xfig.3.2.5c/f_read.h0000700002656300244210000000356210602603370014747 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* errors from read_figc in addition to those in errno.h (e.g. ENOENT) */ #define BAD_FORMAT -1 #define EMPTY_FILE -2 #define NO_VERSION -3 #define MERGE True #define DONT_MERGE False #define REMAP_IMAGES True #define DONT_REMAP_IMAGES False extern int defer_update_layers; /* if != 0, update_layers() doesn't update */ extern int line_no; extern int num_object; extern char *read_file_name; /* structure which is filled by readfp_fig */ typedef struct { Boolean landscape; Boolean flushleft; Boolean units; int grid_unit; int papersize; float magnification; Boolean multiple; int transparent; } fig_settings; extern Boolean uncompress_file(char *name); extern int read_figc(char *file_name, F_compound *obj, Boolean merge, Boolean remapimages, int xoff, int yoff, fig_settings *settings); extern int read_fig(char *file_name, F_compound *obj, Boolean merge, int xoff, int yoff, fig_settings *settings); extern int parse_papersize(char *size); extern void fix_angle (float *angle); extern void swap_colors (void); xfig.3.2.5c/f_readeps.h0000700002656300244210000000007610602603370015454 0ustar bvsmithDomain Usersextern int read_epsf (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readgif.h0000700002656300244210000000007510602603370015431 0ustar bvsmithDomain Usersextern int read_gif (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readjpg.h0000700002656300244210000000003110602603370015434 0ustar bvsmithDomain Usersextern int read_jpg (); xfig.3.2.5c/f_readold.h0000700002656300244210000000010510602603370015434 0ustar bvsmithDomain Usersextern int read_1_3_objects (FILE *fp, char *buf, F_compound *obj); xfig.3.2.5c/f_readpcx.h0000700002656300244210000000017210602603370015454 0ustar bvsmithDomain Usersextern int read_pcx (FILE *file, int filetype, F_pic *pic); extern int read_pcx (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readpng.h0000700002656300244210000000007510602603370015450 0ustar bvsmithDomain Usersextern int read_png (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readppm.h0000700002656300244210000000007510602603370015460 0ustar bvsmithDomain Usersextern int read_ppm (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readtif.h0000700002656300244210000000010110602603370015434 0ustar bvsmithDomain Usersextern int read_tif (char *filename, int filetype, F_pic *pic); xfig.3.2.5c/f_readxbm.h0000700002656300244210000000007510602603370015452 0ustar bvsmithDomain Usersextern int read_xbm (FILE *file, int filetype, F_pic *pic); xfig.3.2.5c/f_readxpm.h0000700002656300244210000000003110602603370015460 0ustar bvsmithDomain Usersextern int read_xpm (); xfig.3.2.5c/f_save.h0000700002656300244210000000101510602603370014761 0ustar bvsmithDomain Usersextern int emergency_save (char *file_name); extern int write_arc (FILE *fp, F_arc *a); extern int write_compound (FILE *fp, F_compound *com); extern int write_ellipse (FILE *fp, F_ellipse *e); extern int write_fig_header (FILE *fp); extern int write_file (char *file_name, Boolean update_recent); extern int write_line (FILE *fp, F_line *l); extern int write_spline (FILE *fp, F_spline *s); extern int write_text (FILE *fp, F_text *t); extern void end_write_tmpfile (void); extern void init_write_tmpfile (void); xfig.3.2.5c/f_util.h0000700002656300244210000000416110602603370015005 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Change function implemented by Frank Schmuck (schmuck@svax.cs.cornell.edu) * X version by Jon Tombs * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern char *xf_basename(char *filename); extern int emptyfigure(void); extern char *safe_strcpy(char *p1, char *p2); extern Boolean uncompress_file(char *name); extern char *build_command(char *program, char *filename); extern Boolean map_to_palette(F_pic *pic); extern Boolean dimline_components(F_compound *dimline, F_line **line, F_line **tick1, F_line **tick2, F_line **poly); extern int find_largest_depth(F_compound *compound); extern int find_smallest_depth(F_compound *compound); extern void get_grid_spec(char *grid, Widget minor_grid_panel, Widget major_grid_panel); extern time_t file_timestamp(char *file); extern void map_to_mono(F_pic *pic); extern void read_xfigrc(void); extern void init_settings(void); extern int change_directory(char *path); extern void beep (void); extern int emptyfigure_msg (char *msg); extern int emptyname (char *name); extern int emptyname_msg (char *name, char *msg); extern int get_directory (char *direct); extern int ok_to_write (char *file_name, char *op_name); extern void remap_imagecolors (void); extern void update_recent_files (void); extern void update_xfigrc (char *name, char *string); xfig.3.2.5c/f_wrpng.h0000700002656300244210000000025210602603370015162 0ustar bvsmithDomain Usersextern Boolean write_png (FILE *file, unsigned char *data, int type, unsigned char *Red, unsigned char *Green, unsigned char *Blue, int numcols, int width, int height); xfig.3.2.5c/fig.h0000700002656300244210000002445111527545764014317 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef FIG_H #define FIG_H extern char *my_strdup(char *str); /* For the X stuff, include only Xlib.h and Intrinsic.h here - use figx.h for widget stuff */ #if defined(ultrix) || defined(__bsdi__) || defined(Mips) || defined(apollo) || defined(__hpux) #if defined(__hpux) #define _HPUX_SOURCE /* for typedef caddr_t :-(( */ #endif #include /* for stat structure */ #endif #include #if defined(__convex__) && defined(__STDC__) #define S_IFDIR _S_IFDIR #define S_IWRITE _S_IWRITE #endif #ifndef SYSV #ifndef SVR4 #include #endif #endif #include #include #include #include #include #include #ifdef NEED_STRERROR extern char *strerror(); # if !defined(__bsdi__) && !defined(__NetBSD__) && !defined(__GNU_LIBRARY__) extern int errno; extern int sys_nerr; # if ( !(defined(BSD) && (BSD - 0 >= 199306)) && !defined(__NetBSD__) && \ !defined(__GNU_LIBRARY__) && !defined(__FreeBSD__) && !defined(__GLIBC__)) extern char *sys_errlist[]; # endif # endif #endif /* NEED_STRERROR */ extern char *mktemp(char *); #include /* for sin(), cos() etc */ #include #include #include /* for those who have an older (R4) Xos.h, we need to include unistd.h here */ /* * Get open(2) constants */ #ifdef X_NOT_POSIX #include #ifdef USL #include #endif /* USL */ #ifdef CRAY #include #endif /* CRAY */ #ifdef MOTOROLA #include #endif /* MOTOROLA */ #ifdef SYSV386 #include #endif /* SYSV386 */ #include #else /* X_NOT_POSIX */ #if !defined(_POSIX_SOURCE) && defined(macII) #define _POSIX_SOURCE #include #undef _POSIX_SOURCE #else #include #endif #include #endif /* X_NOT_POSIX else */ #if XtSpecificationRelease > 4 #include #else /* The following is just a copy of X11/Xosdefs.h and X11/Xfuncs.h (and copyright notice). I include it here so xfig can still be compiled under X11R4, since these files only comes with R5, and I'd like people to still be able to compile xfig under R4. */ /* * O/S-dependent (mis)feature macro definitions * * $XConsortium: Xosdefs.h,v 1.7 91/07/19 23:22:19 rws Exp $ * * Copyright 1991 Massachusetts Institute of Technology * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and * documentation files (the "Software"), including without limitation the * rights to use, copy, modify, merge, publish and/or distribute copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that this copyright * notice remain intact. * * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _XOSDEFS_H_ #define _XOSDEFS_H_ /* * X_NOT_STDC_ENV means does not have ANSI C header files. Lack of this * symbol does NOT mean that the system has stdarg.h. * * X_NOT_POSIX means does not have POSIX header files. Lack of this * symbol does NOT mean that the POSIX environment is the default. * You may still have to define _POSIX_SOURCE to get it. */ #ifdef NOSTDHDRS #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #ifdef sony #ifndef SYSTYPE_SYSV #define X_NOT_POSIX #endif #endif #ifdef UTEK #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #ifdef CRAY #define X_NOT_POSIX #endif #ifdef vax #ifndef ultrix /* assume vanilla BSD */ #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #endif #ifdef luna #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #ifdef Mips #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #ifdef USL #ifdef SYSV /* (release 3.2) */ #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #endif #ifdef SYSV386 #ifdef SYSV #define X_NOT_POSIX #define X_NOT_STDC_ENV #endif #endif #ifdef MOTOROLA #ifdef SYSV #define X_NOT_STDC_ENV #endif #endif #endif /* _XOSDEFS_H_ */ /* * $XConsortium: Xfuncs.h,v 1.8 91/04/17 09:27:52 rws Exp $ * * Copyright 1990 by the Massachusetts Institute of Technology * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * */ #ifndef _XFUNCS_H_ #define _XFUNCS_H_ #ifdef X_USEBFUNCS void bcopy(); void bzero(); int bcmp(); #else #if (__STDC__ && !defined(X_NOT_STDC_ENV) && !defined(sun) && !defined(macII)) || defined(SVR4) || defined(hpux) || defined(_IBMR2) #include #define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) #define bzero(b,len) memset(b, 0, (size_t)(len)) #define bcmp(b1,b2,len) memcmp(b1, b2, (size_t)(len)) #else #ifdef sgi #include #else #ifdef SYSV #include #if defined(_XBCOPYFUNC) && !defined(macII) #define bcopy _XBCOPYFUNC #define _XNEEDBCOPYFUNC #endif void bcopy(); #define bzero(b,len) memset(b, 0, len) #define bcmp(b1,b2,len) memcmp(b1, b2, len) #else /* bsd */ void bcopy(); void bzero(); int bcmp(); #endif /* SYSV */ #endif /* sgi */ #endif /* __STDC__ and relatives */ #endif /* X_USEBFUNCS */ #endif /* _XFUNCS_H_ */ #endif /* XtSpecificationRelease > 4 */ #ifdef X_NOT_STDC_ENV #ifdef SYSV #include #else /* NOT SYSV */ #include #ifndef strchr #define strchr index #endif #ifndef strrchr #define strrchr rindex #endif #endif /* SYSV */ #endif /* X_NOT_STDC_ENV */ #if defined(SYSV) && defined(SYSV386) #if defined(__STDC__) #ifdef ISC extern double atof(char const *); #endif /* ISC */ #ifdef SCO #ifdef SCO324 #include /* for atof() and getenv(), maybe required for all SCO's ? */ #else /* NOT SCO 3.2r4 */ extern double atof(const char *); #endif /* SCO 3.2r4 */ #else /* NOT SCO */ extern double atof(); #endif /* SCO */ #else /* NOT __STDC__ */ extern double atof(); #endif /* __STDC__ */ #else /* NOT defined(SYSV) && defined(SYSV386) */ #ifdef X_NOT_STDC_ENV #if defined(ultrix) || defined(sun) && !defined(sparc) || defined(titan) || \ (defined(ibm032) && !defined(_AIX)) extern double atof(); extern char *getenv(); #endif /* (sun) !(sparc) (titan) */ #else /* NOT X_NOT_STDC_ENV */ #include /* for atof() and getenv() */ #endif /* X_NOT_STDC_ENV */ #endif /* defined(SYSV) && defined(SYSV386) */ #ifdef HAVE_NO_DIRENT #define DIRSTRUCT struct direct #else #define DIRSTRUCT struct dirent #endif /* taken from the X11R5 server/os/osfonts.c file */ #ifndef X_NOT_POSIX #ifdef _POSIX_SOURCE #include #else #if !defined(sun) || defined(sparc) || (defined(SVR4) && defined(i386)) #define _POSIX_SOURCE #include #undef _POSIX_SOURCE #endif /* !defined(sun) || defined(sparc) */ #endif /* _POSIX_SOURCE */ #endif /* X_NOT_POSIX */ /* define PATH_MAX if not already defined */ #ifndef PATH_MAX #include #ifdef MAXPATHLEN #define PATH_MAX MAXPATHLEN #else #define PATH_MAX 1024 #endif /* MAXPATHLEN */ #endif /* PATH_MAX */ /* use my own PI because GNUC has a long double and others have something else */ #undef M_PI #undef M_PI_2 #undef M_2PI #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #define M_2PI 6.28318530717958647692 #define min2(a, b) (((a) < (b)) ? (a) : (b)) #define max2(a, b) (((a) > (b)) ? (a) : (b)) #define min3(a,b,c) ((((ab)?a:b)>c)?((a>b)?a:b):c) #define round(a) (int)(((a)<0.0)?(a)-.5:(a)+.5) #define signof(a) (((a) < 0) ? -1 : 1) #ifdef USE_INLINE #define INLINE __inline #else #define INLINE #endif /* USE_INLINE */ #ifdef NOSTRSTR extern char *strstr(); #endif #if defined(SYSV) || defined(SVR4) extern void srand48(); extern long lrand48(); extern double drand48(); #define srandom(seed) srand48((seed)) #define random() lrand48() #define frandom() drand48() #elif defined(BSD) /* not SYSV/SVR4, check for BSD */ #define srandom(seed) srand48((long)(seed)) #define random() lrand48() #define frandom() drand48() #elif (defined(linux) && !defined(glibc) && !defined(__GLIBC__)) extern long random(); extern void srandom(unsigned int); #elif !defined(__osf__) && !defined(__CYGWIN__) && !defined(linux) && !defined(__FreeBSD__) && !defined(__GLIBC__) extern void srandom(int); #endif #ifndef frandom #define frandom() (random()*(1./2147483648.)) #endif #ifdef I18N #include #endif /* I18N */ #endif /* FIG_H */ xfig.3.2.5c/figx.h0000644002656300244210000000412612010762344014472 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef FIGX_H #define FIGX_H #include #include #include #include #ifdef XAW3D #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef XAW3D1_5E #include #endif /* XAW3D1_5E */ #include #include #include #include #include #else /* XAW3D */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SmeBSB.h" #endif /* XAW3D */ #endif /* FIGX_H */ xfig.3.2.5c/main.h0000700002656300244210000000171110602603370014445 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern Atom wm_protocols[]; extern Boolean geomspec; extern void toggle_refresh_mode(void); extern void cancel_autorefresh(void); extern void set_autorefresh(void); xfig.3.2.5c/mode.h0000700002656300244210000002106511026534616014460 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef MODE_H #define MODE_H #define F_NULL 0 #define FIRST_DRAW_MODE F_CIRCLE_BY_RAD #define F_CIRCLE_BY_RAD 1 #define F_CIRCLE_BY_DIA 2 #define F_ELLIPSE_BY_RAD 3 #define F_ELLIPSE_BY_DIA 4 #define F_CIRCULAR_ARC 5 #define F_POLYLINE 6 #define F_BOX 7 #define F_POLYGON 8 #define F_TEXT 9 #define F_APPROX_SPLINE 10 #define F_CLOSED_APPROX_SPLINE 11 #define F_INTERP_SPLINE 12 #define F_CLOSED_INTERP_SPLINE 13 #define F_ARCBOX 14 #define F_REGPOLY 15 #define F_PICOBJ 16 #define F_PLACE_LIB_OBJ 17 #define FIRST_EDIT_MODE F_GLUE #define F_GLUE 30 #define F_BREAK 31 #define F_SCALE 32 #define F_ADD 33 #define F_COPY 34 #define F_MOVE 35 #define F_DELETE 36 #define F_MOVE_POINT 37 #define F_DELETE_POINT 38 #define F_ADD_POINT 39 #define F_DELETE_ARROW_HEAD 40 #define F_ADD_ARROW_HEAD 41 #define F_FLIP 42 #define F_ROTATE 43 #define F_AUTOARROW 44 #define F_CONVERT 45 #define F_EDIT 46 #define F_UPDATE 47 #define F_ALIGN 48 #define F_ZOOM 49 #define F_LOAD 50 #define F_ENTER_COMP 51 #define F_EXIT_COMP 52 #define F_EXIT_ALL_COMP 53 #define F_OPEN_CLOSE 54 #define F_SPLIT 55 #define F_JOIN 56 #define F_TANGENT 57 #define F_ANGLEMEAS 58 #define F_LENMEAS 59 #define F_AREAMEAS 60 #define F_PASTE 61 #define F_CHOP 62 extern int cur_mode; /* alignment mode */ #define ALIGN_NONE 0 #define ALIGN_LEFT 1 #define ALIGN_TOP 1 #define ALIGN_CENTER 2 #define ALIGN_RIGHT 3 #define ALIGN_BOTTOM 3 #define ALIGN_DISTRIB_C 4 #define ALIGN_DISTRIB_E 5 #define ALIGN_ABUT 6 extern int cur_halign; extern int cur_valign; /* angle geometry */ #define L_UNCONSTRAINED 0 #define L_LATEXLINE 1 #define L_LATEXARROW 2 #define L_MOUNTHATTAN 3 #define L_MANHATTAN 4 #define L_MOUNTAIN 5 extern int manhattan_mode; extern int mountain_mode; extern int latexline_mode; extern int latexarrow_mode; /* arrow mode */ #define L_NOARROWS 0 #define L_FARROWS 1 #define L_FBARROWS 2 #define L_BARROWS 3 extern int autoforwardarrow_mode; extern int autobackwardarrow_mode; /* grid subunit modes (mm, 1/16", 1/10") */ #define NUM_GRID_UNITS 3 enum { MM_UNIT, FRACT_UNIT, TENTH_UNIT }; /* grid mode */ #define GRID_0 0 #define GRID_1 1 #define GRID_2 2 #define GRID_3 3 #define GRID_4 4 #define GRID_ISO_1 5 // isometric grid #define GRID_ISO_2 6 #define GRID_ISO_3 7 #define GRID_ISO_4 8 #define GRID_SQUARE 0 #define GRID_ISO 1 extern int cur_gridtype, cur_gridmode, cur_gridunit, old_gridunit, grid_unit; // isometric grid extern int grid_spacing[NUM_GRID_UNITS][GRID_4]; extern char *grid_name[NUM_GRID_UNITS][GRID_4+1]; /* point position */ #define P_ANY 0 #define P_MAGNET 1 #define P_GRID1 2 #define P_GRID2 3 #define P_GRID3 4 #define P_GRID4 5 extern int cur_pointposn; extern int posn_rnd[NUM_GRID_UNITS][P_GRID4+1]; extern int posn_hlf[NUM_GRID_UNITS][P_GRID4+1]; /* rotn axis */ #define UD_FLIP 1 #define LR_FLIP 2 extern float cur_rotnangle; /* smart link mode */ #define SMART_OFF 0 #define SMART_MOVE 1 #define SMART_SLIDE 2 extern int cur_linkmode; /* misc */ extern int action_on; extern int highlighting; extern int aborting; extern int anypointposn; extern int figure_modified; extern int cur_numsides; extern int cur_numcopies; extern int cur_numxcopies; extern int cur_numycopies; extern char cur_fig_units[200]; extern char cur_library_dir[PATH_MAX]; extern char cur_image_editor[PATH_MAX]; extern char cur_spellchk[PATH_MAX]; extern char cur_browser[PATH_MAX]; extern char cur_pdfviewer[PATH_MAX]; extern Boolean warnexist; extern void reset_modifiedflag(void); extern void set_modifiedflag(void); extern void reset_action_on(void); extern void set_action_on(void); /********************** global mode variables ************************/ extern int num_point; extern int min_num_points; /*************************** Export Settings ****************************/ /*********************************************************************/ /* If you change the order of the LANG_xxx you must change the order */ /* of the lang_texts[] and the LANG_items[] items in mode.c */ /*********************************************************************/ /* position of languages starting from 0 */ enum { LANG_PS, LANG_EPS, LANG_EPS_ASCII, LANG_EPS_MONO_TIFF, LANG_EPS_COLOR_TIFF, LANG_PDF, LANG_PSPDF, LANG_BOX, LANG_LATEX, LANG_EPIC, LANG_EEPIC, LANG_EEPICEMU, LANG_PSTEX, LANG_PDFTEX, LANG_PSPDFTEX, LANG_PICTEX, LANG_IBMGL, LANG_TEXTYL, LANG_TPIC, LANG_PIC, LANG_MAP, LANG_MF, LANG_MP, LANG_MMP, LANG_CGM, LANG_BCGM, /* binary cgm */ LANG_EMF, LANG_TK, LANG_SHAPE, /* ShapePar definition */ LANG_SVG, /* bitmap formats should follow here, starting with GIF */ LANG_GIF, LANG_JPEG, LANG_PCX, LANG_PNG, LANG_PPM, LANG_SLD, LANG_TIFF, LANG_XBM, #ifdef USE_XPM LANG_XPM, #endif END_OF_LANGS }; /* important for the menu dividing line */ #define FIRST_BITMAP_LANG LANG_GIF /* number of export languages */ #define NUM_EXP_LANG END_OF_LANGS extern int cur_exp_lang; extern char *lang_items[NUM_EXP_LANG]; extern char *lang_texts[NUM_EXP_LANG]; extern Boolean batch_exists; extern char batch_file[]; /*************************** Mode Settings ****************************/ extern int cur_objmask; extern int cur_updatemask; extern int new_objmask; extern int cur_depth; /*************************** Text Settings ****************************/ extern int hidden_text_length; extern float cur_textstep; extern int cur_fontsize; extern int cur_latex_font; extern int cur_ps_font; extern int cur_textjust; extern int cur_textflags; /******************************* Lines *********************************/ extern int cur_linewidth; extern int cur_linestyle; extern int cur_joinstyle; extern int cur_capstyle; extern float cur_dashlength; extern float cur_dotgap; extern float cur_styleval; extern Color cur_pencolor; extern Color cur_fillcolor; extern int cur_boxradius; extern int cur_fillstyle; extern int cur_arrowmode; extern int cur_arrowtype; extern float cur_arrowwidth; extern float cur_arrowheight; extern float cur_arrowthick; extern float cur_arrow_multwidth; extern float cur_arrow_multheight; extern float cur_arrow_multthick; extern Boolean use_abs_arrowvals; extern int cur_arctype; extern float cur_tangnormlen; /*************************** Dimension lines ****************************/ extern int cur_dimline_thick; extern int cur_dimline_style; extern int cur_dimline_color; extern int cur_dimline_leftarrow; extern int cur_dimline_rightarrow; extern float cur_dimline_arrowlength; extern float cur_dimline_arrowwidth; extern Boolean cur_dimline_ticks; extern int cur_dimline_tickthick; extern int cur_dimline_boxthick; extern int cur_dimline_boxcolor; extern int cur_dimline_textcolor; extern int cur_dimline_font; extern int cur_dimline_fontsize; extern int cur_dimline_psflag; extern Boolean cur_dimline_fixed; extern int cur_dimline_prec; /**************************** Miscellaneous *****************************/ extern float cur_elltextangle; /* text/ellipse input angle */ extern char EMPTY_PIC[8]; /*************************** File Settings ****************************/ extern char cur_file_dir[]; extern char cur_export_dir[]; extern char cur_filename[]; extern char save_filename[]; /* to undo load or "new" command */ extern char file_header[]; extern char cut_buf_name[]; /* path of .xfig cut buffer file */ extern char xfigrc_name[]; /* path of .xfigrc file */ #endif /* MODE_H */ xfig.3.2.5c/object.h0000700002656300244210000003633711641413606015010 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef OBJECT_H #define OBJECT_H /* values to signify color used for transparent GIF color */ #define CANVAS_BG -7 /* use canvas background color */ #define DARK_GRAY -6 /* pseudo color to Greek small text */ #define MED_GRAY -5 /* pseudo colors to gray out inactive layers */ #define LT_GRAY -4 #define TRANSP_BACKGROUND -3 /* use background of figure as transp color */ #define TRANSP_NONE -2 /* no transp color */ #define COLOR_NONE -2 /* no background color (exporting) */ /* DEFAULT is used for many things - font, color etc */ #define DEFAULT (-1) #define SOLID_LINE 0 #define DASH_LINE 1 #define DOTTED_LINE 2 #define DASH_DOT_LINE 3 #define DASH_2_DOTS_LINE 4 #define DASH_3_DOTS_LINE 5 #define RUBBER_LINE 11 #define PANEL_LINE 12 #define BLACK 0 #define BLUE 1 #define GREEN 2 #define CYAN 3 #define RED 4 #define MAGENTA 5 #define YELLOW 6 #define WHITE 7 #define GREEN4 12 /* defaults for line attributes */ #define DEF_BOXRADIUS 7 #define DEF_DASHLENGTH 4 #define DEF_DOTGAP 3 /* arrowhead defaults */ #define DEF_ARROW_WID 4.0 #define DEF_ARROW_HT 8.0 /** VERY IMPORTANT: The f_line, f_spline and f_arc objects all must have the components up to and including the arrows in the same order. This is for the get/put_generic_arrows() in e_edit.c. In addition, the f_line and f_spline objects must have the components up to and including the f_points in the same order. **/ /***********************************************************************/ /* NOTE: If you change this you must change _pic_names in e_edit.c too */ /***********************************************************************/ /* These values are used internally, so changing them doesn't affect any Fig files */ enum pictypes { T_PIC_NONE, T_PIC_EPS, T_PIC_GIF, #ifdef USE_JPEG T_PIC_JPEG, #endif /* USE_JPEG */ T_PIC_PCX, T_PIC_PNG, T_PIC_PPM, T_PIC_TIF, T_PIC_XBM, #ifdef USE_XPM T_PIC_XPM, #endif /* USE_XPM */ LAST_PIC } ; #define NUM_PIC_TYPES LAST_PIC-1 /* structure to contain a point */ typedef struct f_pos { int x, y; } F_pos; struct _pics { char *file; char *realname; /* in case the actual file is compressed (.gz, etc) */ time_t time_stamp; /* to see if the file has changed */ char *bitmap; enum pictypes subtype; int size_x, size_y; /* picture size (fig units) */ F_pos bit_size; /* size of bitmap in pixels */ struct Cmap cmap[MAX_COLORMAP_SIZE]; /* for GIF/XPM/JPEG files */ int numcols; /* number of colors in cmap */ int transp; /* transparent color (TRANSP_NONE if none) for GIFs */ int refcount; /* number of references to picture */ struct _pics *prev; struct _pics *next; }; /*******************/ /* point structure */ /*******************/ typedef struct f_point { int x, y; struct f_point *next; } F_point; /***********************/ /* Arrowhead structure */ /***********************/ typedef struct f_arrow { int type; int style; float thickness; float wd; float ht; } F_arrow; /******************/ /* Ellipse object */ /******************/ typedef struct f_ellipse { int tagged; int distrib; int type; #define T_ELLIPSE_BY_RAD 1 #define T_ELLIPSE_BY_DIA 2 #define T_CIRCLE_BY_RAD 3 #define T_CIRCLE_BY_DIA 4 int style; int thickness; Color pen_color; Color fill_color; int fill_style; int depth; int pen_style; float style_val; float angle; /* in radians */ int direction; #define UNFILLED -1 struct f_pos center; struct f_pos radiuses; struct f_pos start; struct f_pos end; char *comments; struct f_ellipse *next; } F_ellipse; /* SEE NOTE AT TOP BEFORE CHANGING ANYTHING IN THE f_arc STRUCTURE */ /**************/ /* Arc object */ /**************/ typedef struct f_arc { int tagged; int distrib; int type; /* note: these arc types are the internal values */ /* in the file, they are open=1, wedge=2, elliptical=3 */ #define T_OPEN_ARC 0 #define T_PIE_WEDGE_ARC 1 #define T_ELLIPTICAL 2 int style; int thickness; Color pen_color; Color fill_color; int fill_style; int depth; int pen_style; float style_val; struct f_arrow *for_arrow; struct f_arrow *back_arrow; int cap_style; #define CAP_BUTT 0 #define CAP_ROUND 1 #define CAP_PROJECT 2 /* THE PRECEDING VARS MUST BE IN THE SAME ORDER IN f_arc, f_line and f_spline */ float angle; /* for elliptical arcs, new for V4.0 */ int direction; struct { float x, y; } center; struct f_pos point[3]; char *comments; struct f_arc *next; } F_arc; #define PicSuccess 1 #define FileInvalid -2 /************************************/ /* Picture sub-type for Line object */ /************************************/ typedef struct f_pic { struct _pics *pic_cache; /* picture repository (bitmap, refcount etc) */ Boolean new; /* set when creating object, cleared when Done is clicked in edit operation */ int flipped; float hw_ratio; Pixmap mask; /* for GIF transparency */ Color color; /* only used for XBM */ Pixmap pixmap; /* pixmap created for canvas */ int pix_rotation, pix_width, /* current width of pixmap (pixels) */ pix_height, /* current height of pixmap (pixels) */ pix_flipped; } F_pic; extern char EMPTY_PIC[]; /* SEE NOTE AT TOP BEFORE CHANGING ANYTHING IN THE f_line STRUCTURE */ /***************/ /* Line object */ /***************/ typedef struct f_line { int tagged; int distrib; int type; #define T_POLYLINE 1 #define T_BOX 2 #define T_POLYGON 3 #define T_ARCBOX 4 #define T_PICTURE 5 int style; int thickness; Color pen_color; Color fill_color; int fill_style; int depth; int pen_style; float style_val; struct f_arrow *for_arrow; struct f_arrow *back_arrow; int cap_style; /* line cap style - Butt, Round, Bevel */ /* THE PRECEDING VARS MUST BE IN THE SAME ORDER IN f_arc, f_line and f_spline */ struct f_point *points; /* this must immediately follow cap_style */ /* THE PRECEDING VARS MUST BE IN THE SAME ORDER IN f_line and f_spline */ int join_style; /* join style - Miter, Round, Bevel */ #define JOIN_MITER 0 #define JOIN_ROUND 1 #define JOIN_BEVEL 2 int radius; /* corner radius for T_ARCBOX */ F_pic *pic; /* picture object, if type = T_PICTURE */ char *comments; struct f_line *next; } F_line; /***************/ /* Text object */ /***************/ typedef struct f_text { int tagged; int distrib; int type; #define T_LEFT_JUSTIFIED 0 #define T_CENTER_JUSTIFIED 1 #define T_RIGHT_JUSTIFIED 2 int font; XFontStruct *fontstruct; float zoom; /* to keep track of when it needs rescaling */ int size; /* point size */ Color color; int depth; float angle; /* in radians */ int flags; #define RIGID_TEXT 1 #define SPECIAL_TEXT 2 #define PSFONT_TEXT 4 #define HIDDEN_TEXT 8 int ascent; /* Fig units */ int length; /* Fig units */ int descent; /* from XTextExtents(), not in file */ int base_x; int base_y; int pen_style; char *cstring; char *comments; struct f_text *next; } F_text; /* text macros */ #define MAXFONT(T) (psfont_text(T) ? NUM_FONTS : NUM_LATEX_FONTS) #define rigid_text(t) \ (t->flags == DEFAULT \ || (t->flags & RIGID_TEXT)) #define special_text(t) \ ((t->flags != DEFAULT \ && (t->flags & SPECIAL_TEXT))) #define psfont_text(t) \ (t->flags != DEFAULT \ && (t->flags & PSFONT_TEXT)) #define hidden_text(t) \ (t->flags != DEFAULT \ && (t->flags & HIDDEN_TEXT)) #define text_length(t) \ (hidden_text(t) ? hidden_text_length : t->length) #define using_ps (cur_textflags & PSFONT_TEXT) /* SEE NOTE AT TOP BEFORE CHANGING ANYTHING IN THE f_spline STRUCTURE */ /*****************/ /* Spline object */ /*****************/ #define int_spline(s) (s->type & 0x2) #define x_spline(s) (s->type & 0x4) #define approx_spline(s) (!(int_spline(s)|x_spline(s))) #define closed_spline(s) (s->type & 0x1) #define open_spline(s) (!(s->type & 0x1)) #define S_SPLINE_ANGULAR 0.0 #define S_SPLINE_APPROX 1.0 #define S_SPLINE_INTERP (-1.0) typedef struct f_spline { int tagged; int distrib; int type; #define T_OPEN_APPROX 0 #define T_CLOSED_APPROX 1 #define T_OPEN_INTERP 2 #define T_CLOSED_INTERP 3 #define T_OPEN_XSPLINE 4 #define T_CLOSED_XSPLINE 5 int style; int thickness; Color pen_color; Color fill_color; int fill_style; int depth; int pen_style; float style_val; struct f_arrow *for_arrow; struct f_arrow *back_arrow; int cap_style; /* THE PRECEDING VARS MUST BE IN THE SAME ORDER IN f_arc, f_line and f_spline */ /* * "points" are control points. Shape factors are stored in "sfactors". */ struct f_point *points; /* this must immediately follow cap_style */ /* THE PRECEDING VARS MUST BE IN THE SAME ORDER IN f_line and f_spline */ struct f_shape *sfactors; char *comments; struct f_spline *next; } F_spline; /**************************************/ /* Shape factor structure for splines */ /**************************************/ typedef struct f_shape { double s; struct f_shape *next; } F_sfactor; /*******************/ /* Compound object */ /*******************/ typedef struct f_compound { int tagged; int distrib; struct f_pos nwcorner; struct f_pos secorner; struct f_line *lines; struct f_ellipse *ellipses; struct f_spline *splines; struct f_text *texts; struct f_arc *arcs; char *comments; struct f_compound *parent; /* for "open/close compound" */ struct f_compound *GABPtr; /* Where original compound came from */ Boolean draw_parent; struct f_compound *compounds; struct f_compound *next; } F_compound; typedef struct f_linkinfo { struct f_line *line; struct f_point *endpt; struct f_point *prevpt; int two_pts; struct f_linkinfo *next; } F_linkinfo; /* separate the "type" and the "style" from the cur_arrowtype */ #define ARROW_TYPE(x) ((x)==0? 0 : ((x)+1)/2) #define ARROW_STYLE(x) ((x)==0? 0 : ((x)+1)%2) #define ARROW_SIZE sizeof(struct f_arrow) #define POINT_SIZE sizeof(struct f_point) #define CONTROL_SIZE sizeof(struct f_shape) #define ELLOBJ_SIZE sizeof(struct f_ellipse) #define ARCOBJ_SIZE sizeof(struct f_arc) #define LINOBJ_SIZE sizeof(struct f_line) #define TEXOBJ_SIZE sizeof(struct f_text) #define SPLOBJ_SIZE sizeof(struct f_spline) #define COMOBJ_SIZE sizeof(struct f_compound) #define PIC_SIZE sizeof(struct f_pic) #define LINKINFO_SIZE sizeof(struct f_linkinfo) /********************** object codes **********************/ #define O_COLOR_DEF 0 #define O_ELLIPSE 1 #define O_POLYLINE 2 #define O_SPLINE 3 #define O_TXT 4 #define O_ARC 5 #define O_COMPOUND 6 #define O_END_COMPOUND -O_COMPOUND /* pseudo-object O_FIGURE only for edit panel */ #define O_FIGURE 17777 #define O_ALL_OBJECT 99 /********************* object masks for update ************************/ #define M_NONE 0x0000 #define M_POLYLINE_POLYGON 0x0001 #define M_POLYLINE_LINE 0x0002 #define M_POLYLINE_BOX 0x0004 /* includes ARCBOX */ #define M_SPLINE_O_APPROX 0x0008 #define M_SPLINE_C_APPROX 0x0010 #define M_SPLINE_O_INTERP 0x0020 #define M_SPLINE_C_INTERP 0x0040 #define M_SPLINE_O_XSPLINE 0x0080 #define M_SPLINE_C_XSPLINE 0x0100 #define M_TEXT_NORMAL 0x0200 #define M_TEXT_HIDDEN 0x0400 #define M_ARC 0x0800 #define M_ELLIPSE 0x1000 #define M_COMPOUND 0x2000 #define M_TEXT (M_TEXT_HIDDEN | M_TEXT_NORMAL) #define M_SPLINE_O (M_SPLINE_O_APPROX | M_SPLINE_O_INTERP | M_SPLINE_O_XSPLINE) #define M_SPLINE_C (M_SPLINE_C_APPROX | M_SPLINE_C_INTERP | M_SPLINE_C_XSPLINE) #define M_SPLINE_APPROX (M_SPLINE_O_APPROX | M_SPLINE_C_APPROX) #define M_SPLINE_INTERP (M_SPLINE_O_INTERP | M_SPLINE_C_INTERP) #define M_SPLINE_XSPLINE (M_SPLINE_O_XSPLINE | M_SPLINE_C_XSPLINE) #define M_SPLINE (M_SPLINE_APPROX | M_SPLINE_INTERP | M_SPLINE_XSPLINE) #define M_POLYLINE (M_POLYLINE_LINE | M_POLYLINE_POLYGON | M_POLYLINE_BOX) #define M_VARPTS_OBJECT (M_POLYLINE_LINE | M_POLYLINE_POLYGON | M_SPLINE) #define M_OPEN_OBJECT (M_POLYLINE_LINE | M_SPLINE_O | M_ARC) #define M_ROTATE_ANGLE (M_VARPTS_OBJECT | M_ARC | M_TEXT | M_COMPOUND | M_ELLIPSE) #define M_OBJECT (M_ELLIPSE | M_POLYLINE | M_SPLINE | M_TEXT | M_ARC) #define M_NO_TEXT (M_ELLIPSE | M_POLYLINE | M_SPLINE | M_COMPOUND | M_ARC) #define M_ALL (M_OBJECT | M_COMPOUND) #define M_ANGLEMEAS_OBJECT (M_POLYLINE_LINE | M_POLYLINE_POLYGON | M_ARC) #define M_LENMEAS_OBJECT (M_POLYLINE_LINE | M_POLYLINE_POLYGON | M_POLYLINE_BOX | M_ARC | M_ELLIPSE) #define M_AREAMEAS_OBJECT (M_POLYLINE_POLYGON | M_POLYLINE_BOX | M_ARC | M_ELLIPSE) #define M_TANGENT_OBJECT (M_VARPTS_OBJECT | M_POLYLINE_BOX | M_ARC | M_ELLIPSE) /************************ Objects **********************/ extern F_compound objects; /************ global working pointers ************/ extern F_line *cur_l, *new_l, *old_l; extern F_arc *cur_a, *new_a, *old_a; extern F_ellipse *cur_e, *new_e, *old_e; extern F_text *cur_t, *new_t, *old_t; extern F_spline *cur_s, *new_s, *old_s; extern F_compound *cur_c, *new_c, *old_c; extern F_point *first_point, *cur_point; extern F_linkinfo *cur_links; #endif /* OBJECT_H */ xfig.3.2.5c/paintop.h0000700002656300244210000000203410602603370015172 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef PAINTOP_H #define PAINTOP_H #define INV_PAINT 0 #define PAINT 1 #define ERASE 2 #define NUMOPS 3 /* size of markers for selected objects */ #define MARK_SIZ 5 #define SM_MARK 3 #define CENTER_MARK 8 #endif /* PAINTOP_H */ xfig.3.2.5c/patchlevel.h0000700002656300244210000000160111272607050015651 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef PATCHLEVEL_H #define PATCHLEVEL_H #define PATCHLEVEL "5c" #endif /* PATCHLEVEL_H */ xfig.3.2.5c/pcx.h0000700002656300244210000000331410602603370014314 0ustar bvsmithDomain Users/* * TransFig: Facility for Translating Fig code * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* structure of a PCX header */ typedef struct _pcxhead { unsigned char id; /* 00h Manufacturer ID */ unsigned char vers; /* 01h version */ unsigned char format; /* 02h Encoding Scheme */ unsigned char bppl; /* 03h Bits/Pixel/Plane */ unsigned short xmin; /* 04h X Start (upper left) */ unsigned short ymin; /* 06h Y Start (top) */ unsigned short xmax; /* 08h X End (lower right) */ unsigned short ymax; /* 0Ah Y End (bottom) */ unsigned short hdpi; /* 0Ch Horizontal Res. */ unsigned short vdpi; /* 0Eh Vertical Res. */ unsigned char egapal[48]; /* 10h 16-Color EGA Palette */ unsigned char reserv; /* 40h reserv */ unsigned char nplanes; /* 41h Number of Color Planes */ unsigned short blp; /* 42h Bytes/Line/Plane */ unsigned short palinfo; /* 44h Palette Interp. */ unsigned short hscrnsiz; /* 46h Horizontal Screen Size */ unsigned short vscrnsiz; /* 48h Vertical Screen Size */ unsigned char fill[54]; /* 4Ah reserv */ } pcxheadr; xfig.3.2.5c/resources.h0000700002656300244210000003604311527545016015552 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef RESOURCES_H #define RESOURCES_H #include "paintop.h" #define NUMSHADEPATS 21 #define NUMTINTPATS 20 #define NUMPATTERNS 22 #define NUMFILLPATS NUMSHADEPATS+NUMTINTPATS+NUMPATTERNS /* page sizes used when imported EPS has no bounding box or pdf has no /MediaBox */ #define LETTER_WIDTH 10200 #define LETTER_HEIGHT 13200 #define A4_WIDTH 9921 #define A4_HEIGHT 14031 /* min, max zoom allowed */ #define MIN_ZOOM 0.01 #define MAX_ZOOM 100 /* starting, min, max depth of objects on canvas */ #define DEF_DEPTH 50 #define MIN_DEPTH 0 #define MAX_DEPTH 999 /* min, max font size (points) */ #define MIN_FONT_SIZE 1 #define MAX_FONT_SIZE 500 /* min, max font size on the display (after zooming) */ /* this is necessary because some X servers crash completely when rendering very small fonts */ #define MIN_X_FONT_SIZE 5 #define MAX_X_FONT_SIZE MAX_FONT_SIZE /* maximum width of lines (Fig units) */ #define MAX_LINE_WIDTH 500 /* max number of sides for regular polygon */ #define MIN_POLY_SIDES 3 #define MAX_POLY_SIDES 200 /* min, max vertical spacing when entering text (fraction of font size) */ #define MIN_TEXT_STEP 0 #define MAX_TEXT_STEP 100 /* min, max arc-box corner radius (1/80 inch) */ #define MIN_BOX_RADIUS 2 #define MAX_BOX_RADIUS 1000 /* min, max tangent/normal line length */ #define MIN_TANGNORMLEN 0 #define MAX_TANGNORMLEN 20 /* number of standard colors */ #define NUM_STD_COLS 32 /* max number of user-defined colors */ #define MAX_USR_COLS 512 /* number of paper sizes (A4, B5, letter, etc. [see resources.c]) */ #define NUMPAPERSIZES 29 /* define these positions so we can start with default paper size */ #define PAPER_LETTER 0 #define PAPER_A4 13 #define Color int /* default number of colors to use for GIF/XPM */ /* this can be overridden in resources or command-line arg */ #define DEF_MAX_IMAGE_COLS 64 /* max and default number of recently used files for File menu */ #define MAX_RECENT_FILES 9 #define DEF_RECENT_FILES 5 /* for picture files */ #define MAX_COLORMAP_SIZE MAX_USR_COLS /* for JPEG export */ #define DEF_JPEG_QUALITY 75 /* default border margin for export */ #define DEF_EXPORT_MARGIN 0 /* how often to check for external file change, milliseconds (-autorefresh) */ #define CHECK_REFRESH_TIME 1000 /* for screen capture */ #define IMAGE_PALETTE 0 /* colormapped screen capture */ #define IMAGE_RGB 1 /* RGB (TrueColor) screen capture */ struct Cmap { unsigned short red, green, blue; unsigned long pixel; }; typedef struct { char *name, *rgb; } fig_colors ; /* for the xfig icon */ extern Pixmap fig_icon; /* version string for xfig (generated in main() )*/ extern char xfig_version[]; /* these are allocated in main() in case we aren't using default colormap (so we can't use BlackPixelOfScreen... */ extern XColor black_color, white_color; /* original directory where xfig started */ extern char orig_dir[PATH_MAX+2]; /* whether user is updating Fig files or loading one to view */ extern Boolean update_figs; #ifdef USE_XPM #include extern XpmAttributes xfig_icon_attr; #endif extern fig_colors colorNames[NUM_STD_COLS + 1]; extern char *short_clrNames[NUM_STD_COLS + 1]; extern Pixel colors[NUM_STD_COLS+MAX_USR_COLS]; extern XColor user_colors[MAX_USR_COLS]; extern XColor undel_user_color; extern XColor n_user_colors[MAX_USR_COLS]; extern XColor save_colors[MAX_USR_COLS]; extern int num_usr_cols, n_num_usr_cols; extern int current_memory; extern Boolean colorUsed[MAX_USR_COLS]; extern Boolean colorFree[MAX_USR_COLS]; extern Boolean n_colorFree[MAX_USR_COLS]; extern Boolean all_colors_available; extern Pixel dark_gray_color, med_gray_color, lt_gray_color; extern Pixel pageborder_color; extern Pixel axis_lines_color; extern int max_depth, min_depth; extern char tool_name[200]; extern int export_background_color; /* current export/print background color */ extern Boolean display_fractions; /* whether to display fractions in lengths */ extern char *userhome; /* user's home directory */ extern struct _pics *pictures; /* common repository to share imported pictures */ extern float scale_factor; /* scale drawing as it is read in */ extern char minor_grid[40], major_grid[40]; /* export/print grid values */ extern Boolean draw_parent_gray; /* in open compound, draw rest in gray */ /* number of colors we want to use for GIF/XPM images */ extern int avail_image_cols; /* colormap used for same */ extern XColor image_cells[MAX_COLORMAP_SIZE]; /* resources structure */ typedef struct _appres { Boolean write_v40; /* flag to save figure in V4.0 format */ Boolean allownegcoords; /* allow negative x/y coordinates for panning */ int balloon_delay; /* delay (ms) before balloon pops up on */ char *boldFont; char *browser; /* browser for viewing html docs */ int but_per_row; /* number of buttons wide for the mode panel */ char *buttonFont; char *canvasbackground; char *canvasforeground; Boolean DEBUG; Boolean dontswitchcmap; /* don't allow switching of colormap */ Boolean installowncmap; /* install our own private colormap */ Boolean showaxislines; /* draw axis lines through 0,0 (useful w/allow_neg_coords) */ Boolean smallicons; /* draw axis lines through 0,0 (useful w/allow_neg_coords) */ char *exportLanguage; Boolean flushleft; /* center/flush-left printing */ char *geometry; char *iconGeometry; char *image_editor; /* image editor (xv, etc) */ Boolean INCHES; int internalborderwidth; int jpeg_quality; /* jpeg image quality */ char *keyFile; Boolean landscape; Boolean latexfonts; char *library_dir; /* for object library path */ float magnification; /* export/print magnification */ int max_image_colors; /* max colors to use for GIF/XPM images */ Boolean monochrome; Boolean multiple; /* multiple/single page for export/print */ char *normalFont; char *pageborder; /* color of page border */ char *paper_size; /* ASCII size of paper (from command-line) */ int papersize; /* size of paper */ Boolean RHS_PANEL; char *pdf_viewer; /* viewer for pdf docs */ int rulerthick; /* thickness of rulers */ Boolean scalablefonts; /* whether user wants scalable fonts or not */ Boolean showallbuttons; Boolean showballoons; /* show popup messages when user passes over buttons */ Boolean showlengths; /* length/width lines when drawing or moving */ Boolean shownums; /* print vertex numbers above polyline points */ Boolean show_pageborder; /* show page border in color on canvas */ Boolean specialtext; char *spellcheckcommand; /* spell check command e.g. "spell %s" or "ispell -l < %s | sort -u" */ int spinner_delay; /* delay (ms) before spinner counts automatically */ int spinner_rate; /* rate (ms) at which spinner counts */ int startfillstyle; /* starting fill style */ float startfontsize; /* ges 6 Feb 91 */ int startgridmode; /* starting grid mode */ int startgridtype; /* starting grid type */ // isometric grid int startarrowtype; /* starting arrow type */ float startarrowthick; /* starting arrow thick */ float startarrowwidth; /* starting arrow width */ float startarrowlength; /* starting arrow length (height) */ char *startlatexFont; /* bab 11 Jan 92 */ int startlinewidth; /* starting line width */ int startposnmode; /* starting point position mode */ char *startpsFont; /* bab 11 Jan 92 */ float starttextstep; /* starting multi-line text spacing */ Boolean tablet; /* input tablet extension */ float tmp_height; float tmp_width; Boolean tracking; /* mouse tracking in rulers */ int transparent; /* transparent color for GIF export (-2=none, -1=background) */ float userscale; /* scale screen units to user units */ char *userunit; /* user defined unit name */ float zoom; /* starting zoom scale */ char *version; /* version of the app-defaults file (compared with the version/patchlevel of xfig when starting */ int export_margin; /* size of border around figure for export */ Boolean flipvisualhints; /* switch left/right mouse indicator messages */ Boolean rigidtext; Boolean hiddentext; Boolean showdepthmanager; /* whether or not to display the depth manager */ char *grid_color; /* color of grid (when on) */ int smooth_factor; /* smoothing factor when export to bitmap formats */ Boolean icon_view; /* icon or list view of library objects */ int library_icon_size; /* size of those icons */ Boolean splash; /* whether or not to show the splash screen on startup */ char *axislines; /* color of axis lines on canvas */ int freehand_resolution; /* minimum spacing of points when drawing freehand */ char *tgrid_unit; /* units of grid/point positioning (1/10" or 1/16") */ Boolean overlap; /* overlap/no-overlap multiple pages for export/print */ char *ghostscript; /* name of ghostscript (e.g. gs or gswin32) */ Boolean correct_font_size; /* adjust for difference in Fig screen res vs points (80/72) */ int encoding; /* encoding for latex escape translation */ Boolean crosshair; /* draw crosshair cursor wherever the pointer is */ Boolean autorefresh; /* automatically redraw figure when file has changed */ Boolean write_bak; /* automatically rename current to .bak when saving */ #ifdef I18N Boolean international; String font_menu_language; Boolean euc_encoding; Boolean locale_encoding; Boolean latin_keyboard; Boolean always_use_fontset; XFontSet fixed_fontset; int fontset_size; String xim_input_style; String fig2dev_localize_option; #ifdef I18N_USE_PREEDIT String text_preedit; #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ } appresStruct, *appresPtr; extern appresStruct appres; typedef struct { int length, ascent, descent; } pr_size; typedef struct { unsigned int r_width, r_height, r_left, r_top; } RectRec; typedef struct { int type; char *label; caddr_t info; } MenuItemRec; struct Menu { int m_imagetype; #define MENU_IMAGESTRING 0x00 /* imagedata is char * */ #define MENU_GRAPHIC 0x01 /* imagedata is pixrect * */ caddr_t m_imagedata; int m_itemcount; MenuItemRec *m_items; struct Menu *m_next; caddr_t m_data; }; /* def for paper size list */ struct paper_def { char *sname; /* short name e.g. 'A' */ char *fname; /* full name e.g. 'A (8.5" x 11")' */ int width,height; /* size in Fig units e.g. 10200 13200 */ }; typedef struct Menu MenuRec; typedef XImage *PIXRECT; typedef pr_size PR_SIZE; typedef RectRec RECT; extern float ZOOM_FACTOR; extern float PIC_FACTOR; extern Window main_canvas; /* main canvas window */ extern Window canvas_win; /* current canvas */ extern Window msg_win, sideruler_win, topruler_win; extern Cursor cur_cursor; extern Cursor arrow_cursor, bull_cursor, buster_cursor, crosshair_cursor, null_cursor, text_cursor, pick15_cursor, pick9_cursor, panel_cursor, l_arrow_cursor, lr_arrow_cursor, r_arrow_cursor, u_arrow_cursor, ud_arrow_cursor, d_arrow_cursor, wait_cursor, magnify_cursor; extern Widget tool; extern XtAppContext tool_app; extern Widget canvas_sw, ps_fontmenu, /* printer font menu tool */ latex_fontmenu, /* printer font menu tool */ msg_form, msg_panel, name_panel, cmd_form, mode_panel, d_label, e_label, mousefun, ind_panel, ind_box, upd_ctrl, /* indicator panel */ unitbox_sw, sideruler_sw, topruler_sw; extern Display *tool_d; extern Screen *tool_s; extern Window tool_w; extern Widget tool_form; extern int tool_sn; extern int tool_vclass; extern Visual *tool_v; extern int tool_dpth; extern int tool_cells; extern int image_bpp; /* # of bytes-per-pixel for images at this visual */ extern int screen_wd, screen_ht; /* width and height of screen */ extern Colormap tool_cm, newcmap; extern Boolean swapped_cmap; extern Atom wm_delete_window; extern int num_recent_files; /* number of recent files in list */ extern int max_recent_files; /* user max number of recent files */ extern int splash_onscreen; /* flag used to clear off splash graphic */ extern time_t figure_timestamp; /* last time file was written externally (for -autorefresh) */ extern GC border_gc, button_gc, ind_button_gc, mouse_button_gc, pic_gc, fill_color_gc, pen_color_gc, blank_gc, ind_blank_gc, mouse_blank_gc, gccache[NUMOPS], grid_gc, fillgc, fill_gc[NUMFILLPATS], /* fill style gc's */ tr_gc, tr_xor_gc, tr_erase_gc, /* for the rulers */ sr_gc, sr_xor_gc, sr_erase_gc; extern Color grid_color; extern Pixmap fill_pm[NUMFILLPATS],fill_but_pm[NUMPATTERNS]; extern float fill_pm_zoom[NUMFILLPATS],fill_but_pm_zoom[NUMFILLPATS]; extern XColor x_fg_color, x_bg_color; extern unsigned long but_fg, but_bg; extern unsigned long ind_but_fg, ind_but_bg; extern unsigned long mouse_but_fg, mouse_but_bg; /* will contain environment variable XFIGTMPDIR, if any */ extern char *TMPDIR; /* will contain environment variable FIG2DEV_DIR, if any */ extern char *fig2dev_path; extern char fig2dev_cmd[PATH_MAX]; extern String text_translations; /* for w_export.c and w_print.c */ extern char *orient_items[2]; extern char *just_items[2]; extern struct paper_def paper_sizes[NUMPAPERSIZES]; extern char *multiple_pages[2], *overlap_pages[2]; /* for w_file.c and w_export.c */ extern char *offset_unit_items[3]; extern int RULER_WD; /* environment variable name definition for image editor used for screen capture */ #define XFIG_ENV_GIF_EDITOR getenv("XFIG_GIF_EDITOR") /* flag for when picture object is read in merge_file to see if need to remap existing picture colors */ extern Boolean pic_obj_read; typedef struct _recent_file_struct { char *name; Widget menu; } _recent_files; extern _recent_files recent_files[]; #endif /* RESOURCES_H */ xfig.3.2.5c/SmeBSB.h0000700002656300244210000000725510602603366014612 0ustar bvsmithDomain Users/* * $XConsortium: SmeBSB.h,v 1.7 94/04/17 20:12:49 kaleb Exp $ * Copyright (c) 1989, 1994 X Consortium Any party obtaining a copy of these files is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish and/or distribute copies of the Software, and to permit persons who receive copies from any such party to do so, with the only requirement being that this copyright notice remain intact. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ /* * SmeBSB.h - Public Header file for SmeBSB object. * * This is the public header file for the Athena BSB Sme object. * It is intended to be used with the simple menu widget. This object * provides bitmap - string - bitmap style entries. * * Date: April 3, 1989 * * By: Chris D. Peterson * MIT X Consortium * kit@expo.lcs.mit.edu */ #ifndef _SmeBSB_h #define _SmeBSB_h #include #ifdef XAW3D #include #else #include #endif /* XAW3D */ /**************************************************************** * * SmeBSB object * ****************************************************************/ /* BSB Menu Entry Resources: Name Class RepType Default Value ---- ----- ------- ------------- callback Callback Callback NULL destroyCallback Callback Pointer NULL font Font XFontStruct * XtDefaultFont foreground Foreground Pixel XtDefaultForeground height Height Dimension 0 label Label String Name of entry leftBitmap LeftBitmap Pixmap None leftMargin HorizontalMargins Dimension 4 rightBitmap RightBitmap Pixmap None rightMargin HorizontalMargins Dimension 4 sensitive Sensitive Boolean True vertSpace VertSpace int 25 width Width Dimension 0 x Position Position 0n y Position Position 0 */ typedef struct _SmeBSBClassRec *SmeBSBObjectClass; typedef struct _SmeBSBRec *SmeBSBObject; extern WidgetClass smeBSBObjectClass; #define XtNleftBitmap "leftBitmap" #define XtNleftMargin "leftMargin" #define XtNrightBitmap "rightBitmap" #define XtNrightMargin "rightMargin" #define XtNvertSpace "vertSpace" #ifndef XtNfontSet #define XtNfontSet "fontSet" #endif #ifndef XtCFontSet #define XtCFontSet "FontSet" #endif #define XtCLeftBitmap "LeftBitmap" #define XtCHorizontalMargins "HorizontalMargins" #define XtCRightBitmap "RightBitmap" #define XtCVertSpace "VertSpace" #endif /* _SmeBSB_h */ xfig.3.2.5c/SmeBSBP.h0000700002656300244210000001011010602603366014712 0ustar bvsmithDomain Users/* * $XConsortium: SmeBSBP.h,v 1.8 94/04/17 21:44:11 rws Exp $ * Copyright (c) 1989, 1994 X Consortium Any party obtaining a copy of these files is granted, free of charge, a full and unrestricted irrevocable, world-wide, paid up, royalty-free, nonexclusive right and license to deal in this software and documentation files (the "Software"), including without limitation the rights to use, copy, modify, merge, publish and/or distribute copies of the Software, and to permit persons who receive copies from any such party to do so, with the only requirement being that this copyright notice remain intact. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. * * Author: Chris D. Peterson, MIT X Consortium */ /* * SmeP.h - Private definitions for Sme object * */ #ifndef _XawSmeBSBP_h #define _XawSmeBSBP_h /*********************************************************************** * * Sme Object Private Data * ***********************************************************************/ #ifdef XAW3D #include #else #include #endif /* XAW3D */ #include "SmeBSB.h" /************************************************************ * * New fields for the Sme Object class record. * ************************************************************/ typedef struct _SmeBSBClassPart { XtPointer extension; } SmeBSBClassPart; /* Full class record declaration */ typedef struct _SmeBSBClassRec { RectObjClassPart rect_class; SmeClassPart sme_class; #ifdef XAW3D SmeThreeDClassPart sme_threeD_class; #endif /* XAW3D */ SmeBSBClassPart sme_bsb_class; } SmeBSBClassRec; extern SmeBSBClassRec smeBSBClassRec; /* New fields for the Sme Object record */ typedef struct { /* resources */ String label; /* The entry label. */ int vert_space; /* extra vert space to leave, as a percentage of the font height of the label. */ Pixmap left_bitmap, right_bitmap; /* bitmaps to show. */ Dimension left_margin, right_margin; /* left and right margins. */ Pixel foreground; /* foreground color. */ XFontStruct * font; /* The font to show label in. */ XFontSet fontset; /* or fontset */ XtJustify justify; /* Justification for the label. */ /* private resources. */ Boolean set_values_area_cleared; /* Remember if we need to unhighlight. */ GC norm_gc; /* noral color gc. */ GC rev_gc; /* reverse color gc. */ GC norm_gray_gc; /* Normal color (grayed out) gc. */ GC invert_gc; /* gc for flipping colors. */ Dimension left_bitmap_width; /* size of each bitmap. */ Dimension left_bitmap_height; Dimension right_bitmap_width; Dimension right_bitmap_height; } SmeBSBPart; /**************************************************************** * * Full instance record declaration * ****************************************************************/ typedef struct _SmeBSBRec { ObjectPart object; RectObjPart rectangle; SmePart sme; #ifdef XAW3D SmeThreeDPart sme_threeD; #endif /* XAW3D */ SmeBSBPart sme_bsb; } SmeBSBRec; /************************************************************ * * Private declarations. * ************************************************************/ #endif /* _XawSmeBSBP_h */ xfig.3.2.5c/SmeCascade.h0000700002656300244210000000455110602603520015513 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and * documentation files (the "Software"), including without limitation the * rights to use, copy, modify, merge, publish and/or distribute copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that this copyright * notice remain intact. * */ /* This subclasses the SmeBSB object to make a cascade menu */ /* Public definitions for SmeCascade object */ #ifndef _SmeCascade_h #define _SmeCascade_h #include #ifdef XAW3D #include #else #include #endif #include "SmeBSB.h" /**************************************************************** * * SmeCascade object * ****************************************************************/ /* Cascade Menu Entry Resources: Name Class RepType Default Value ---- ----- ------- ------------- font Font XFontStruct * XtDefaultFont foreground Foreground Pixel XtDefaultForeground height Height Dimension 0 label Label String Name of entry leftBitmap LeftBitmap Pixmap None leftMargin HorizontalMargins Dimension 4 rightBitmap RightBitmap Pixmap None rightMargin HorizontalMargins Dimension 4 sensitive Sensitive Boolean True vertSpace VertSpace int 25 width Width Dimension 0 x Position Position 0n y Position Position 0 subMenu SubMenu Widget NULL selectCascade SelectCascade Boolean False */ typedef struct _SmeCascadeClassRec *SmeCascadeObjectClass; typedef struct _SmeCascadeRec *SmeCascadeObject; extern WidgetClass smeCascadeObjectClass; void popdown_subs(void); #define XtNsubMenu "subMenu" #define XtCSubMenu "SubMenu" #define XtNselectCascade "selectCascade" #define XtCSelectCascade "SelectCascade" #endif /* _SmeBSB_h */ xfig.3.2.5c/SmeCascadeP.h0000700002656300244210000000535310602603514015637 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and * documentation files (the "Software"), including without limitation the * rights to use, copy, modify, merge, publish and/or distribute copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that this copyright * notice remain intact. * */ /* This subclasses the SmeBSB object to make a cascade menu */ /* Private definitions for SmeCascade object */ #ifndef _XawSmeCascadeP_h #define _XawSmeCascadeP_h /*********************************************************************** * * Sme Cascade Object Private Data * ***********************************************************************/ #ifdef XAW3D #include #else #include #endif #include "SmeBSBP.h" #include "SmeCascade.h" /************************************************************ * * New fields for the Sme Cascade Object class record. * ************************************************************/ typedef struct _SmeCascadeClassPart { XtPointer extension; } SmeCascadeClassPart; /* Full class record declaration */ typedef struct _SmeCascadeClassRec { RectObjClassPart rect_class; SmeClassPart sme_class; #ifdef XAW3D SmeThreeDClassPart sme_threeD_class; #endif /* XAW3D */ SmeBSBClassPart sme_bsb_class; SmeCascadeClassPart sme_cascade_class; } SmeCascadeClassRec; extern SmeCascadeClassRec smeCascadeClassRec; /* New fields for the Sme Cascade Object record */ typedef struct { /* resources */ Widget subMenu; /* sub-menu that I post */ Boolean selectCascade; /* whether or not to make this cascade selectable (Notify) */ Boolean highlighted; /* holds the state of the entry */ /* private fields */ } SmeCascadePart; /**************************************************************** * * Full instance record declaration * ****************************************************************/ typedef struct _SmeCascadeRec { ObjectPart object; RectObjPart rectangle; SmePart sme; #ifdef XAW3D SmeThreeDPart sme_threeD; #endif /* XAW3D */ SmeBSBPart sme_bsb; SmeCascadePart sme_cascade; } SmeCascadeRec; /************************************************************ * * Private declarations. * ************************************************************/ #endif /* _XawSmeCascadeP_h */ xfig.3.2.5c/u_bound.h0000700002656300244210000000344611026534616015172 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_BOUND_H #define U_BOUND_H extern int overlapping(int xmin1, int ymin1, int xmax1, int ymax1, int xmin2, int ymin2, int xmax2, int ymax2); extern int floor_coords_x(); // isometric grid extern int floor_coords_y(); extern int ceil_coords_x(); extern int ceil_coords_y(); extern void arc_bound (F_arc *arc, int *xmin, int *ymin, int *xmax, int *ymax); extern void compound_bound (F_compound *compound, int *xmin, int *ymin, int *xmax, int *ymax); extern void active_compound_bound(F_compound *compound, int *xmin, int *ymin, int *xmax, int *ymax, Boolean active_only); extern void ellipse_bound (F_ellipse *e, int *xmin, int *ymin, int *xmax, int *ymax); extern void line_bound (F_line *l, int *xmin, int *ymin, int *xmax, int *ymax); extern void spline_bound (F_spline *s, int *xmin, int *ymin, int *xmax, int *ymax); extern void text_bound (F_text *t, int *xmin, int *ymin, int *xmax, int *ymax, int *rx1, int *ry1, int *rx2, int *ry2, int *rx3, int *ry3, int *rx4, int *ry4); #endif /* U_BOUND_H */ xfig.3.2.5c/u_create.h0000700002656300244210000000453510602603370015317 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_CREATE_H #define U_CREATE_H extern F_arc *create_arc(void); extern F_ellipse *create_ellipse(void); extern F_line *create_line(void); extern F_spline *create_spline(void); extern F_text *create_text(void); extern F_compound *create_compound(void); extern F_pic *create_pic(void); extern F_point *create_point(void); extern F_sfactor *create_sfactor(void); extern F_compound *create_dimension_line(F_line *line, Boolean add_to_figure); extern void create_dimline_ticks(F_line *line, F_line **tick1, F_line **tick2); extern struct _pics * create_picture_entry(void); extern F_arc *copy_arc(F_arc *a); extern F_ellipse *copy_ellipse(F_ellipse *e); extern F_line *copy_line(F_line *l); extern F_spline *copy_spline(F_spline *s); extern F_text *copy_text(F_text *t); extern F_compound *copy_compound(F_compound *c); extern void copy_comments(char **source, char **dest); extern F_point *copy_points(F_point *orig_pt); extern F_sfactor *copy_sfactors(F_sfactor *orig_sf); extern void reverse_points(F_point *orig_pt); extern void reverse_sfactors(F_sfactor *orig_sf); extern F_arrow *forward_arrow(void); extern F_arrow *backward_arrow(void); extern F_arrow *create_arrow(void); extern F_arrow *forward_dim_arrow(void); extern F_arrow *backward_dim_arrow(void); extern F_arrow *new_arrow(int type, int style, float thickness, float wd, float ht); extern char *new_string(int len); extern F_linkinfo *new_link(F_line *l, F_point *ep, F_point *pp); #endif /* U_CREATE_H */ xfig.3.2.5c/u_drag.h0000700002656300244210000000220510602603370014761 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void init_ellipsedragging(F_ellipse *e, int x, int y); extern void init_arcdragging(F_arc *a, int x, int y); extern void init_linedragging(F_line *l, int x, int y); extern void init_textdragging(F_text *t, int x, int y); extern void init_splinedragging(F_spline *s, int x, int y); extern void init_compounddragging(F_compound *c, int x, int y); xfig.3.2.5c/u_draw.h0000700002656300244210000000464610602603370015014 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_DRAW_H #define U_DRAW_H #include "w_drawprim.h" #define DRAW_POINTS True #define DONT_DRAW_POINTS False #define DRAW_CENTER True #define DONT_DRAW_CENTER False /* * declarations of routines for drawing objects */ /* compounds */ void draw_compoundelements(F_compound *c, int op); /* splines */ void draw_spline(F_spline *spline, int op); void quick_draw_spline(F_spline *spline, int operator); /* curve routine needed by arc() and show_boxradius() */ void curve(Window window, int depth, int xstart, int ystart, int xend, int yend, Boolean draw_points, Boolean draw_center, int direction, int a, int b, int xoff, int yoff, int op, int thick, int style, float style_val, int fill_style, Color pen_color, Color fill_color, int cap_style); extern void angle_ellipse (int center_x, int center_y, int radius_x, int radius_y, float angle, int op, int depth, int thickness, int style, float style_val, int fill_style, int pen_color, int fill_color); extern void calc_arrow (int x1, int y1, int x2, int y2, int linethick, F_arrow *arrow, zXPoint *points, int *npoints, zXPoint *fillpoints, int *nfillpoints, zXPoint *clippts, int *nclippts); extern void compute_arcarrow_angle (float x1, float y1, int x2, int y2, int direction, F_arrow *arrow, int *x, int *y); extern void draw_arc (F_arc *a, int op); extern void draw_ellipse (F_ellipse *e, int op); extern void draw_line (F_line *line, int op); extern void draw_text (F_text *text, int op); extern void redraw_images (F_compound *obj); extern void too_many_points (void); #endif /* U_DRAW_H */ xfig.3.2.5c/u_elastic.h0000700002656300244210000001003211527545764015510 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_ELASTIC_H #define U_ELASTIC_H #define MOVE_ARB 0 #define MOVE_HORIZ_VERT 1 #define BOX_SCALE 2 #define BOX_HSTRETCH 3 #define BOX_VSTRETCH 4 #define MSG_RADIUS 0 #define MSG_RADIUS2 1 #define MSG_DIAM 2 #define MSG_LENGTH 3 #define MSG_DIST 4 #define MSG_PNTS_LENGTH 5 #define MSG_DIAM_ANGLE 6 #define MSG_RADIUS_ANGLE 7 extern int constrained; extern float cur_angle; extern int work_numsides; extern int x1off, x2off, y1off, y2off; extern Cursor cur_latexcursor; extern int from_x, from_y; extern double cosa, sina; extern intptr_t movedpoint_num; extern F_point *left_point, *right_point; extern void elastic_box(int x1, int y1, int x2, int y2); extern void elastic_fixedbox(void); extern void elastic_movebox(void); extern void resizing_box(int x, int y); extern void elastic_box_constrained(); extern void constrained_resizing_box(int x, int y); extern void constrained_resizing_scale_box(int x, int y); extern void moving_box(int x, int y); extern void elastic_poly(int x1, int y1, int x2, int y2, int numsides); extern void resizing_poly(int x, int y); extern void scaling_compound(int x, int y); extern void elastic_scalecompound(F_compound *c); extern void elastic_scale_curcompound(void); extern void resizing_cbr(int x, int y), elastic_cbr(void), resizing_cbd(int x, int y), elastic_cbd(void); extern void resizing_ebr(int x, int y), elastic_ebr(void), resizing_ebd(int x, int y), elastic_ebd(void); extern void constrained_resizing_ebr(int x, int y), constrained_resizing_ebd(int x, int y); extern void constrained_resizing_cbd(int x, int y); extern void elastic_moveellipse(void); extern void moving_ellipse(int x, int y); extern void elastic_scaleellipse(F_ellipse *e); extern void scaling_ellipse(int x, int y); extern void elastic_scale_curellipse(void); extern void unconstrained_line(int x, int y); extern void latex_line(int x, int y); extern void constrainedangle_line(int x, int y); extern void elastic_moveline(F_point *pts); extern void elastic_movenewline(void); extern void elastic_line(void); extern void elastic_dimension_line(); extern void moving_line(int x, int y); extern void reshaping_line(int x, int y); extern void reshaping_latexline(); extern void elastic_linelink(void); extern void elastic_scalepts(F_point *pts); extern void scaling_line(int x, int y); extern void elastic_scale_curline(int x, int y); extern void arc_point(int x, int y, int numpoint); extern void moving_arc(int x, int y); extern void elastic_movearc(F_arc *a); extern void elastic_movenewarc(void); extern void reshaping_arc(int x, int y); extern void elastic_arclink(void); extern void scaling_arc(int x, int y); extern void elastic_scalearc(F_arc *a); extern void elastic_scale_curarc(void); extern void moving_text(int x, int y); extern void draw_movingtext(); extern void elastic_movetext(void); extern void moving_spline(int x, int y); extern void elastic_movenewspline(void); extern void scaling_spline(int x, int y); extern void elastic_scale_curspline(void); extern void adjust_box_pos(int curs_x, int curs_y, int orig_x, int orig_y, int *ret_x, int *ret_y); extern void adjust_pos(int curs_x, int curs_y, int orig_x, int orig_y, int *ret_x, int *ret_y); #endif /* U_ELASTIC_H */ xfig.3.2.5c/u_error.h0000700002656300244210000000173310604747730015215 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern int X_error_handler(Display *d, XErrorEvent *err_ev); extern void error_handler(int err_sig); extern void my_quit(Widget w, XEvent *event, String *params, Cardinal *num_params); xfig.3.2.5c/u_fonts.h0000700002656300244210000000440211527544310015203 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_FONTS_H #define U_FONTS_H #define DEF_FONTSIZE 12 /* default font size in pts */ #define DEF_PS_FONT 0 #define DEF_LATEX_FONT 0 #define PS_FONTPANE_WD 290 #define LATEX_FONTPANE_WD 112 #define PS_FONTPANE_HT 20 #define LATEX_FONTPANE_HT 20 #define NUM_FONTS 35 #define NUM_LATEX_FONTS 6 /* font number for the "nil" font (when user wants tiny text) */ #define NILL_FONT NUM_FONTS /* element of linked list for each font The head of list is for the different font NAMES, and the elements of this list are for each different point size of that font */ struct xfont { int size; /* size in points */ Font fid; /* X font id */ char *fname; /* actual name of X font found */ char *bname; /* name of backup X font to try if first doesn't exist */ XFontStruct *fstruct; /* X font structure */ XFontSet fset; /* X font set - used in international mode*/ struct xfont *next; /* next in the list */ }; struct _fstruct { char *name; /* Postscript font name */ int xfontnum; /* template for locating X fonts */ }; struct _xfstruct { char *template; /* template for locating X fonts */ struct xfont *xfontlist; /* linked list of X fonts for different point * sizes */ }; extern int psfontnum(char *font); extern int latexfontnum(char *font); extern struct _xfstruct x_fontinfo[], x_backup_fontinfo[]; extern struct _fstruct ps_fontinfo[]; extern struct _fstruct latex_fontinfo[]; int x_fontnum(int psflag, int fnum); #endif /* U_FONTS_H */ xfig.3.2.5c/u_free.h0000700002656300244210000000112010602603372014762 0ustar bvsmithDomain Usersextern int free_Fonts (void); extern int free_GCs (void); extern int free_arc (F_arc **list); extern int free_compound (F_compound **list); extern int free_ellipse (F_ellipse **list); extern int free_line (F_line **list); extern int free_linestorage (F_line *l); extern int free_linkinfo (F_linkinfo **list); extern int free_picture_entry (struct _pics *picture); extern int free_points (F_point *first_point); extern int free_sfactors (F_sfactor *sf); extern int free_spline (F_spline **list); extern int free_splinestorage (F_spline *s); extern int free_text (F_text **list); xfig.3.2.5c/u_geom.h0000700002656300244210000000452710602603372015006 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern double compute_angle(double dx, double dy); /* compute the angle between 0 to 2PI */ extern int close_to_arc (F_arc *a, int xp, int yp, int d, float *px, float *py); extern int close_to_ellipse (F_ellipse *e, int xp, int yp, int d, float *ex, float *ey, float *vx, float *vy); extern int close_to_polyline (F_line *l, int xp, int yp, int d, int sd, int *px, int *py, int *lx1, int *ly1, int *lx2, int *ly2); extern int close_to_spline (F_spline *spline, int xp, int yp, int d, int *px, int *py, int *lx1, int *ly1, int *lx2, int *ly2); extern int close_to_vector (int x1, int y1, int x2, int y2, int xp, int yp, int d, float dd, int *px, int *py); extern int compute_3p_angle (F_point *p1, F_point *p2, F_point *p3, double *alpha); extern int compute_arc_angle (F_arc *a, double *alpha); extern int compute_arc_area (F_arc *a, float *ap); extern int compute_arc_length (F_arc *a, float *lp); extern int compute_arccenter (F_pos p1, F_pos p2, F_pos p3, float *x, float *y); extern int compute_arcradius (int x1, int y1, int x2, int y2, int x3, int y3, float *r); extern int compute_direction (F_pos p1, F_pos p2, F_pos p3); extern int compute_ellipse_area (F_ellipse *e, float *ap); extern int compute_line_angle (F_line *l, F_point *p, double *alpha); extern void compute_normal (float x1, float y1, int x2, int y2, int direction, int *x, int *y); extern int compute_poly_length (F_line *l, float *lp); extern void latex_endpoint (int x1, int y1, int x2, int y2, int *xout, int *yout, int arrow, int magnet); extern void compute_poly_area (F_line *l, float *ap); xfig.3.2.5c/u_list.h0000700002656300244210000001074010602603372015024 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_LIST_H #define U_LIST_H void list_delete_arc(F_arc **arc_list, F_arc *arc); void list_delete_ellipse(F_ellipse **ellipse_list, F_ellipse *ellipse); void list_delete_line(F_line **line_list, F_line *line); void list_delete_spline(F_spline **spline_list, F_spline *spline); void list_delete_text(F_text **text_list, F_text *text); void list_delete_compound(F_compound **list, F_compound *compound); void remove_depth(int type, int depth); void remove_compound_depth(F_compound *comp); void list_add_arc(F_arc **list, F_arc *a); void list_add_ellipse(F_ellipse **list, F_ellipse *e); void list_add_line(F_line **list, F_line *l); void list_add_spline(F_spline **list, F_spline *s); void list_add_text(F_text **list, F_text *t); void list_add_compound(F_compound **list, F_compound *c); void add_depth(int type, int depth); void add_compound_depth(F_compound *comp); F_line *last_line(F_line *list); F_arc *last_arc(F_arc *list); F_ellipse *last_ellipse(F_ellipse *list); F_text *last_text(F_text *list); F_spline *last_spline(F_spline *list); F_compound *last_compound(F_compound *list); F_point *last_point(F_point *list); F_sfactor *last_sfactor(F_sfactor *list); Boolean first_spline_point(int x, int y, double s, F_spline *spline); Boolean append_sfactor(double s, F_sfactor *cpoint); F_point *search_spline_point(F_spline *spline, int x, int y); F_point *search_line_point(F_line *line, int x, int y); F_sfactor *search_sfactor(F_spline *spline, F_point *selected_point); Boolean insert_point(int x, int y, F_point *point); int num_points(F_point *points); F_line *prev_line(F_line *list, F_line *line); F_arc *prev_arc(F_arc *list, F_arc *arc); F_ellipse *prev_ellipse(F_ellipse *list, F_ellipse *ellipse); F_text *prev_text(F_text *list, F_text *text); F_spline *prev_spline(F_spline *list, F_spline *spline); F_compound *prev_compound(F_compound *list, F_compound *compound); F_point *prev_point(F_point *list, F_point *point); void delete_line(F_line *old_l); void delete_arc(F_arc *old_a); void delete_ellipse(F_ellipse *old_e); void delete_text(F_text *old_t); void delete_spline(F_spline *old_s); void delete_compound(F_compound *old_c); void add_line(F_line *new_l); void add_arc(F_arc *new_a); void add_ellipse(F_ellipse *new_e); void add_text(F_text *new_t); void add_spline(F_spline *new_s); void add_compound(F_compound *new_c); void change_line(F_line *old_l, F_line *new_l); void change_arc(F_arc *old_a, F_arc *new_a); void change_ellipse(F_ellipse *old_e, F_ellipse *new_e); void change_text(F_text *old_t, F_text *new_t); void change_spline(F_spline *old_s, F_spline *new_s); void change_compound(F_compound *old_c, F_compound *new_c); void get_links(int llx, int lly, int urx, int ury); void adjust_links(int mode, F_linkinfo *links, int dx, int dy, int cx, int cy, float sx, float sy, Boolean copying); extern void append_objects (F_compound *l1, F_compound *l2, F_compound *tails); extern void cut_objects (F_compound *objects, F_compound *tails); extern int object_count (F_compound *list); extern void set_tags (F_compound *list, int tag); extern void get_interior_links (int llx, int lly, int urx, int ury); extern void append_point(int x, int y, F_point **point); extern void remove_arc_depths (F_arc *a); extern void remove_ellipse_depths (F_ellipse *e); extern void remove_line_depths (F_line *l); extern void remove_spline_depths (F_spline *s); extern void remove_text_depths (F_text *t); extern void tail(F_compound *ob, F_compound *tails); #endif /* U_LIST_H */ xfig.3.2.5c/u_markers.h0000700002656300244210000000454410602603372015522 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_MARKERS_H #define U_MARKERS_H extern void toggle_pointmarker(int x, int y); extern int anyline_in_mask (void); extern int anyspline_in_mask (void); extern int anytext_in_mask (void); extern int arc_in_mask (void); extern void center_marker (int x, int y); extern int compound_in_mask (void); extern int ellipse_in_mask (void); extern void mask_toggle_arcmarker (F_arc *a); extern void mask_toggle_compoundmarker (F_compound *c); extern void mask_toggle_ellipsemarker (F_ellipse *e); extern void mask_toggle_linemarker (F_line *l); extern void mask_toggle_splinemarker (F_spline *s); extern void mask_toggle_textmarker (F_text *t); extern void toggle_all_compoundmarkers (void); extern void toggle_archighlight (F_arc *a); extern void toggle_arcmarker (F_arc *a); extern void toggle_compoundhighlight (F_compound *c); extern void toggle_compoundmarker (F_compound *c); extern void toggle_csrhighlight (int x, int y); extern void toggle_ellipsehighlight (F_ellipse *e); extern void toggle_ellipsemarker (F_ellipse *e); extern void toggle_linehighlight (F_line *l); extern void toggle_linemarker (F_line *l); extern void toggle_markers_in_compound (F_compound *cmpnd); extern void toggle_splinehighlight (F_spline *s); extern void toggle_splinemarker (F_spline *s); extern void toggle_texthighlight (F_text *t); extern void toggle_textmarker (F_text *t); extern void update_markers (int mask); extern int validline_in_mask (F_line *l); extern int validspline_in_mask (F_spline *s); extern int validtext_in_mask (F_text *t); #endif /* U_MARKERS_H */ xfig.3.2.5c/u_pan.h0000700002656300244210000000175610602603372014636 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Copyright (c) 1991 by Henning Spruth * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void pan_origin(void); extern int pan_down (int shift); extern int pan_left (int shift); extern int pan_right (int shift); extern int pan_up (int shift); xfig.3.2.5c/u_print.h0000700002656300244210000000271710661632674015226 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ char *shell_protect_string(char *string); extern Boolean print_hpgl_pcl_switch; extern Boolean hpgl_specified_font; extern void print_to_printer(char *printer, char *backgrnd, float mag, Boolean print_all_layers, Boolean bound_active_layers, char *grid, char *params); extern int print_to_file(char *file, char *lang, float mag, int xoff, int yoff, char *backgrnd, char *transparent, Boolean use_transp_backg, Boolean print_all_layers, Boolean bound_active_layers, int border, Boolean smooth, char *grid, Boolean overlap); extern void make_rgb_string (int color, char *rgb_string); extern void gen_print_cmd(char *cmd, char *file, char *printer, char *pr_params); xfig.3.2.5c/u_quartic.h0000700002656300244210000000170110602603372015516 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 2004 by Chris Moller * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_QUARTIC_H #define U_QUARTIC_H extern int quartic(double * dd, double * sol, double * soli); #endif xfig.3.2.5c/u_redraw.h0000700002656300244210000000657310602603372015346 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void redisplay_canvas(void); extern Boolean request_redraw; /* set in redisplay_region if called when preview_in_progress is true */ extern void clearcounts(void); /* clear object counters for each depth */ extern void clearallcounts(void); /* clear all object counters for each depth */ /* * Support for rendering based on correct object depth. A simple depth based * caching scheme; anything more will require major surgery on the object * data structures that will percolate throughout program. * * One ``counts'' structure for each object type at each nesting depth from 0 * to MAX_DEPTH - 1. We track both the number of objects per type per depth, * as well as the number of objects drawn so far per type per depth to cut * down on search loop overhead. */ struct counts { unsigned num_arcs; /* # arcs at this depth */ unsigned num_lines; /* # lines at this depth */ unsigned num_ellipses; /* # ellipses at this depth */ unsigned num_splines; /* # splines at this depth */ unsigned num_texts; /* # texts at this depth */ unsigned cnt_arcs; /* count of arcs drawn at this depth */ unsigned cnt_lines; /* count of lines drawn at this depth */ unsigned cnt_ellipses; /* count of ellipses drawn at this * depth */ unsigned cnt_splines; /* count of splines drawn at this depth */ unsigned cnt_texts; /* count of texts drawn at this depth */ }; extern struct counts counts[], saved_counts[]; extern void redisplay_arc (F_arc *a); extern void redisplay_arcs (F_arc *a1, F_arc *a2); extern void redisplay_compound (F_compound *c); extern void redisplay_compoundobject (F_compound *compounds, int depth); extern void redisplay_compounds (F_compound *c1, F_compound *c2); extern void redisplay_ellipse (F_ellipse *e); extern void redisplay_ellipses (F_ellipse *e1, F_ellipse *e2); extern void redisplay_line (F_line *l); extern void redisplay_lines (F_line *l1, F_line *l2); extern void redisplay_objects (F_compound *active_objects); extern void redisplay_pageborder (void); extern void redisplay_spline (F_spline *s); extern void redisplay_splines (F_spline *s1, F_spline *s2); extern void redisplay_text (F_text *t); extern void redisplay_texts (F_text *t1, F_text *t2); extern void redisplay_zoomed_region (int xmin, int ymin, int xmax, int ymax); extern void update_pageborder (void); extern void redisplay_region (int xmin, int ymin, int xmax, int ymax); extern void redisplay_regions (int xmin1, int ymin1, int xmax1, int ymax1, int xmin2, int ymin2, int xmax2, int ymax2); xfig.3.2.5c/u_scale.h0000700002656300244210000000100510602603372015132 0ustar bvsmithDomain Usersextern int read_scale_arcs (F_arc *arcs, float mul, int offset); extern int read_scale_compound (F_compound *compound, float mul, int offset); extern int read_scale_compounds (F_compound *compounds, float mul, int offset); extern int read_scale_ellipses (F_ellipse *ellipses, float mul, int offset); extern int read_scale_lines (F_line *lines, float mul, int offset); extern int read_scale_splines (F_spline *splines, float mul, int offset); extern int read_scale_texts (F_text *texts, float mul, int offset); xfig.3.2.5c/u_search.h0000700002656300244210000000350310604747730015326 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_SEARCH_H #define U_SEARCH_H Boolean in_text_bound(F_text *t, int x, int y, int *posn, Boolean extra); void init_searchproc_left(void (*handlerproc) (/* ??? */)); void init_searchproc_middle(void (*handlerproc) (/* ??? */)); void init_searchproc_right(void (*handlerproc) (/* ??? */)); void point_search_left(int x, int y, unsigned int shift); void point_search_middle(int x, int y, unsigned int shift); void point_search_right(int x, int y, unsigned int shift); void object_search_left(int x, int y, unsigned int shift); void object_search_middle(int x, int y, unsigned int shift); void object_search_right(int x, int y, unsigned int shift); void erase_objecthighlight(void); F_text *text_search(int x, int y, int *posn); F_compound *compound_search(int x, int y, int tolerance, int *px, int *py); F_compound *compound_point_search(int x, int y, int tol, int *cx, int *cy, int *fx, int *fy); F_spline *get_spline_point(int x, int y, F_point **p, F_point **q); #endif /* U_SEARCH_H */ xfig.3.2.5c/u_smartsearch.h0000700002656300244210000000237710604747730016405 0ustar bvsmithDomain Users#ifndef U_SMARTSEARCH_H #define U_SMARTSEARCH_H /* * FIG : Facility for Interactive Generation of figures * This part Copyright (c) 1999-2002 by A. Durner * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ void init_smart_searchproc_left(void (*handlerproc) (/* ??? */)); void init_smart_searchproc_middle(void (*handlerproc) (/* ??? */)); void init_smart_searchproc_right(void (*handlerproc) (/* ??? */)); void smart_object_search_left(int x, int y, unsigned int shift); void smart_object_search_middle(int x, int y, unsigned int shift); void smart_object_search_right(int x, int y, unsigned int shift); void smart_null_proc(void); extern F_point smart_point1, smart_point2; #endif /* U_SMARTSEARCH_H */ xfig.3.2.5c/u_translate.h0000700002656300244210000000057210602603372016050 0ustar bvsmithDomain Usersextern int translate_arc (F_arc *arc, int dx, int dy); extern int translate_compound (F_compound *compound, int dx, int dy); extern int translate_ellipse (F_ellipse *ellipse, int dx, int dy); extern int translate_line (F_line *line, int dx, int dy); extern int translate_spline (F_spline *spline, int dx, int dy); extern int translate_text (F_text *text, int dx, int dy); xfig.3.2.5c/u_undo.h0000700002656300244210000000431610602603372015020 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef U_UNDO_H #define U_UNDO_H /******************* DECLARE EXPORTS ********************/ extern F_compound saved_objects; extern F_compound object_tails; extern F_arrow *saved_for_arrow; extern F_arrow *saved_back_arrow; extern F_line *latest_line; /* for undo_join (line) */ extern F_spline *latest_spline; /* for undo_join (spline) */ extern void undo(void); extern void clean_up (void); extern void set_action (int action); extern void set_action_object (int action, int object); extern void set_last_arcpointnum (int num); extern void set_last_arrows (F_arrow *forward, F_arrow *backward); extern void set_last_nextpoint (F_point *next_point); extern void set_last_prevpoint (F_point *prev_point); extern void set_last_selectedpoint (F_point *selected_point); extern void set_last_selectedsfactor (F_sfactor *selected_sfactor); extern void set_last_tension (double origin, double extremity); extern void set_lastlinkinfo (int mode, F_linkinfo *links); extern void set_lastposition (int x, int y); extern void set_latestarc (F_arc *arc); extern void set_latestcompound (F_compound *compound); extern void set_latestellipse (F_ellipse *ellipse); extern void set_latestline (F_line *line); extern void set_latestobjects (F_compound *objects); extern void set_latestspline (F_spline *spline); extern void set_latesttext (F_text *text); extern void set_newposition (int x, int y); #endif /* U_UNDO_H */ xfig.3.2.5c/version.h0000700002656300244210000000160710602603372015214 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef VERSION_H #define VERSION_H #define FIG_VERSION "3.2" #define PROTOCOL_VERSION "3.2" /* file format */ #endif /* VERSION_H */ xfig.3.2.5c/w_browse.h0000700002656300244210000000175310602603372015360 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* This file is part of xdir, an X-based directory browser. */ extern Widget browse_selfile, browse_dir, browse_flist, browse_dlist, browse_mask; extern char cur_browse_dir[]; extern Boolean browse_up; extern void popup_browse_panel(Widget w); xfig.3.2.5c/w_canvas.h0000700002656300244210000000444311164165252015335 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_CANVAS_H #define W_CANVAS_H /************** DECLARE EXPORTS ***************/ extern void init_canvas(Widget tool); extern void add_canvas_actions(void); extern void (*canvas_kbd_proc) (); extern void (*canvas_locmove_proc) (); extern void (*canvas_ref_proc) (); extern void (*canvas_leftbut_proc) (); extern void (*canvas_middlebut_proc) (); extern void (*canvas_middlebut_save) (); extern void (*canvas_rightbut_proc) (); extern void (*return_proc) (); extern void null_proc(void); extern void toggle_show_balloons(void); extern void toggle_show_lengths(void); extern void toggle_show_vertexnums(void); extern void toggle_show_borders(void); extern void round_coords(int *x, int *y); // isometric grid extern void canvas_selected(Widget tool, XButtonEvent *event, String *params, Cardinal *nparams); extern void paste_primary_selection(void); extern void setup_canvas(void); extern void clear_region(int xmin, int ymin, int xmax, int ymax); extern void clear_canvas(void); extern int clip_xmin, clip_ymin, clip_xmax, clip_ymax; extern int clip_width, clip_height; extern int cur_x, cur_y; extern int fix_x, fix_y; extern int ignore_exp_cnt; extern int last_x, last_y; /* last position of mouse */ extern int shift; /* global state of shift key */ extern int pointer_click; /* for counting multiple clicks */ /* for Sun keyboard, define COMP_LED 2 */ extern void setCompLED(int on); extern String local_translations; #define LOC_OBJ "Locate Object" #endif /* W_CANVAS_H */ xfig.3.2.5c/w_capture.h0000700002656300244210000000165310602603372015521 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1995 Jim Daley (jdaley@cix.compulink.co.uk) * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ Boolean captureImage(Widget window, char *filename); /* returns True on success */ Boolean canHandleCapture(Display *d); /* returns True if image capture will works */ xfig.3.2.5c/w_cmdpanel.h0000700002656300244210000000524310602603372015640 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* width of a command button */ #define CMD_BUT_WD 60 #define CMD_BUT_HT 22 /* def for menu */ typedef struct { char *name; /* name e.g. 'Save' */ int u_line; /* which character to underline (-1 means none) */ void (*func)(); /* function that is called for menu choice */ Boolean checkmark; /* whether a checkmark is put in the left bitmap space */ } menu_def ; /* cmd panel menu definitions */ #define CMD_LABEL_LEN 16 typedef struct main_menu_struct { char label[CMD_LABEL_LEN]; /* label on the button */ char menu_name[CMD_LABEL_LEN]; /* command name for resources */ char hint[CMD_LABEL_LEN]; /* label for mouse func and balloon */ menu_def *menu; /* menu */ Widget widget; /* button widget */ Widget menuwidget; /* menu widget */ } main_menu_info; extern main_menu_info main_menus[]; extern void init_cmd_panel(); extern void add_cmd_actions(void); extern void quit(Widget w, XtPointer closure, XtPointer call_data); extern void new(Widget w, XtPointer closure, XtPointer call_data); extern void paste(Widget w, XtPointer closure, XtPointer call_data); extern void delete_all_cmd(Widget w, int closure, int call_data); extern void setup_cmd_panel(); extern void change_orient(); extern void setup_cmd_panel(); extern void show_global_settings(Widget w); extern void acc_load_recent_file(Widget w, XEvent *event, String *params, Cardinal *nparams); extern int num_main_menus(void); extern Widget create_menu_item(main_menu_info *menup); extern void refresh_view_menu(void); extern void popup_character_map(void); extern void refresh_character_panel(void); extern void init_main_menus(Widget tool, char *filename); extern void goodbye (Boolean abortflag); extern void update_cur_filename (char *newname); extern void rebuild_file_menu (Widget menu); void setup_main_menus(void); xfig.3.2.5c/w_color.h0000700002656300244210000000523610602603372015175 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1987 Christopher A. Kent * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_COLOR_H #define W_COLOR_H #define USE_EXISTING_COLOR True #define DONT_USE_EXISTING_COLOR False extern void show_pencolor(void), next_pencolor(ind_sw_info *sw), prev_pencolor(ind_sw_info *sw); extern void show_fillcolor(void), next_fillcolor(ind_sw_info *sw), prev_fillcolor(ind_sw_info *sw); extern void count_user_colors(void); extern void YStoreColors (Colormap colormap, XColor *color, int ncolors); extern int add_color_cell (Boolean use_exist, int indx, int r, int g, int b); extern void color_borders (void); extern void create_color_panel (Widget form, Widget label, Widget cancel, ind_sw_info *isw); extern void del_color_cell (int indx); extern void pen_fill_activate (int func); extern void pick_contrast (XColor color, Widget widget); extern void restore_mixed_colors (void); extern void set_cmap (Window window); extern Widget delunusedColors; /* * color.h - color definitions * * Author: Christopher A. Kent * Western Research Laboratory * Digital Equipment Corporation * Date: Sun Dec 13 1987 */ Boolean switch_colormap(void); Boolean alloc_color_cells(Pixel *pixels, int n); /* * $Log: w_color.h,v $ * Revision 1.1 1995/02/28 15:40:16 feuille * Initial revision * * Revision 1.2 90/06/30 14:33:12 rlh2 * patchlevel 1 * * Revision 1.1 90/05/10 11:16:54 rlh2 * Initial revision * * Revision 1.2 88/06/30 09:58:56 mikey * Handles CMY also. * * Revision 1.1 88/06/30 09:10:53 mikey * Initial revision * */ typedef struct _RGB { unsigned short r, g, b; } RGB; typedef struct _HSV { float h, s, v; /* [0, 1] */ } HSV; typedef struct _CMY { unsigned short c, m, y; } CMY; extern RGB RGBWhite, RGBBlack; RGB MixRGB(); RGB MixHSV(); RGB HSVToRGB(HSV hsv); HSV RGBToHSV(RGB rgb); float RGBDist(); RGB PctToRGB(float rr, float gg, float bb); HSV PctToHSV(); RGB CMYToRGB(); CMY RGBToCMY(); #endif /* W_COLOR_H */ xfig.3.2.5c/w_cursor.h0000700002656300244210000000174010602603372015370 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void set_cursor(Cursor cursor); extern void set_temp_cursor(Cursor cursor); extern void init_cursor(void); extern void recolor_cursors(void); extern void reset_cursor (void); xfig.3.2.5c/w_digitize.h0000700002656300244210000000135110602603372015661 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void popup_digitize_panel(Widget w); xfig.3.2.5c/w_dir.h0000700002656300244210000000626710602603372014642 0ustar bvsmithDomain Users/* This file is part of xdir, an X-based directory browser. */ /* * FIG : Facility for Interactive Generation of figures * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * * * Created: 13 Aug 88 * * Win Treese * Cambridge Research Lab * Digital Equipment Corporation * treese@crl.dec.com * * COPYRIGHT 1990 * DIGITAL EQUIPMENT CORPORATION * MAYNARD, MASSACHUSETTS * ALL RIGHTS RESERVED. * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE * FOR ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED * WARRANTY. * * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN * ADDITION TO THAT SET FORTH ABOVE. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Digital Equipment Corporation not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * */ #ifndef W_DIR_H #define W_DIR_H /* From the C library. */ char *re_comp(); /* Useful constants. */ #define EOS '\0' /* End-of-string. */ #define NENTRIES 100 /* chunk size for allocating filename space */ #define F_FILE_WIDTH 413 /* width of filename, etc widgets for FILE panel */ #define E_FILE_WIDTH 360 /* width of filename, etc widgets for EXPORT panel */ /* Useful macros. */ #define streq(a, b) (! strcmp((a), (b))) extern Widget popup_dir_text; extern void create_dirinfo(Boolean file_exp, Widget parent, Widget below, Widget *ret_beside, Widget *ret_below, Widget *mask_w, Widget *dir_w, Widget *flist_w, Widget *dlist_w, int file_width, Boolean file_panel); /* Xdir function declarations. */ extern Boolean MakeFileList(char *dir_name, char *mask, char ***dir_list, char ***file_list); extern char *SaveString(); extern void MakeFullPath(char *root, char *filename, char *pathname); extern Boolean IsDirectory(char *path, char *file); extern void parseuserpath (char *path, char *longpath); extern void Rescan (Widget widget, XEvent *event, String *params, Cardinal *num_params); #endif /* W_DIR_H */ xfig.3.2.5c/w_drawprim.h0000700002656300244210000001245710602603372015707 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_DRAWPRIM_H #define W_DRAWPRIM_H #include "w_zoom.h" /* our version of XPoint */ typedef struct { int x,y; } zXPoint ; /* function prototypes */ extern void pw_text(Window w, int x, int y, int op, int depth, XFontStruct *fstruct, float angle, char *string, Color color, Color background); extern void pw_vector(Window w, int x1, int y1, int x2, int y2, int op, int line_width, int line_style, float style_val, Color color); extern void pw_curve(Window w, int xstart, int ystart, int xend, int yend, int op, int depth, int linewidth, int style, float style_val, int fill_style, Color pen_color, Color fill_color, int cap_style); extern void pw_point(Window w, int x, int y, int op, int depth, int line_width, Color color, int cap_style); extern void pw_arcbox(Window w, int xmin, int ymin, int xmax, int ymax, int radius, int op, int depth, int line_width, int line_style, float style_val, int fill_style, Color pen_color, Color fill_color); extern void pw_lines(Window w, zXPoint *points, int npoints, int op, int depth, int line_width, int line_style, float style_val, int join_style, int cap_style, int fill_style, Color pen_color, Color fill_color); extern void init_font(void); extern void init_fill_gc (void); extern void init_fill_pm (void); extern void reset_clip_window (void); extern void set_clip_window (int xmin, int ymin, int xmax, int ymax); extern void set_fill_gc (int fill_style, int op, int pencolor, int fillcolor, int xorg, int yorg); extern void set_line_stuff (int width, int style, float style_val, int join_style, int cap_style, int op, int color); extern int x_color (int col); extern void init_gc(void); /* convert Fig units to pixels at current zoom */ #define ZOOMX(x) (int) round(zoomscale*((x)-zoomxoff)) #define ZOOMY(y) (int) round(zoomscale*((y)-zoomyoff)) /* convert pixels to Fig units at current zoom */ #define BACKX(x) round(x/zoomscale+zoomxoff) #define BACKY(y) round(y/zoomscale+zoomyoff) #define zXDrawArc(disp,win,gc,x,y,d1,d2,a1,a2)\ XDrawArc(disp,win,gc,ZOOMX(x),ZOOMY(y), \ (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\ a1,a2) #define zXFillArc(disp,win,gc,x,y,d1,d2,a1,a2)\ XFillArc(disp,win,gc,ZOOMX(x),ZOOMY(y), \ (short)round(zoomscale*(d1)),(short)round(zoomscale*(d2)),\ a1,a2) #define zXDrawLine(disp,win,gc,x1,y1,x2,y2)\ XDrawLine(disp,win,gc,ZOOMX(x1),ZOOMY(y1), \ ZOOMX(x2),ZOOMY(y2)) #define zXRotDrawString(disp,font,ang,win,gc,x,y,s)\ XRotDrawString(disp,font,ang,win,gc,ZOOMX(x),ZOOMY(y),s) #define zXRotDrawImageString(disp,font,ang,win,gc,x,y,s)\ XRotDrawImageString(disp,font,ang,win,gc,ZOOMX(x),ZOOMY(y),s) #define zXFillRectangle(disp,win,gc,x,y,w,h)\ XFillRectangle(disp,win,gc,ZOOMX(x),ZOOMY(y),\ (short)round(zoomscale*(w)),(short)round(zoomscale*(h))) #define zXDrawRectangle(disp,win,gc,x,y,w,h)\ XDrawRectangle(disp,win,gc,ZOOMX(x),ZOOMY(y),\ (short)round(zoomscale*(w)),(short)round(zoomscale*(h))) extern pr_size textsize(XFontStruct *fstruct, int n, char *s); extern XFontStruct *bold_font; extern XFontStruct *roman_font; extern XFontStruct *button_font; extern XFontStruct *canvas_font; extern XFontStruct *lookfont(int fnum, int size); extern GC makegc(int op, Pixel fg, Pixel bg); /* patterns like bricks, etc */ typedef struct _patrn_strct { int owidth,oheight; /* original width/height */ char *odata; /* original bytes */ int cwidth,cheight; /* current width/height */ char *cdata; /* bytes at current zoom */ } patrn_strct; #define SHADE_IM_SIZE 32 /* fixed by literal patterns in w_drawprim.c */ extern patrn_strct pattern_images[NUMPATTERNS]; extern unsigned char shade_images[NUMSHADEPATS][128]; /* Maximum number of points for polygons etc */ /* This may be overridden by adding -DMAXNUMPTS=xxxx in the Imakefile/Makefile */ #ifndef MAXNUMPTS #define MAXNUMPTS 25000 #endif /* MAXNUMPTS */ #define NORMAL_FONT "fixed" #define BOLD_FONT "8x13bold" #define BUTTON_FONT "6x13" #define max_char_height(font) \ ((font)->max_bounds.ascent + (font)->max_bounds.descent) #define char_width(font) ((font)->max_bounds.width) #define char_advance(font,char) \ (((font)->per_char)?\ ((font)->per_char[(char)-(font)->min_char_or_byte2].width):\ ((font)->max_bounds.width)) #define set_x_fg_color(gc,col) XSetForeground(tool_d,gc, x_color(col)) #define set_x_bg_color(gc,col) XSetBackground(tool_d,gc, x_color(col)) #endif /* W_DRAWPRIM_H */ xfig.3.2.5c/w_export.h0000700002656300244210000000375110602603372015400 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern Widget export_popup; /* the main export popup */ extern Widget export_panel; /* the form it's in */ extern Widget exp_selfile, /* output (selected) file widget */ exp_mask, /* mask widget */ exp_dir, /* current directory widget */ exp_flist, /* file list widget */ exp_dlist; /* dir list widget */ extern Boolean export_up; extern char default_export_file[]; extern Widget export_orient_panel; extern Widget export_just_panel; extern Widget export_papersize_panel; extern Widget export_multiple_panel; extern Widget export_overlap_panel; extern Widget export_mag_text; extern void export_update_figure_size(void); extern Widget export_transp_panel; extern Widget export_background_panel; extern Widget export_grid_minor_text, export_grid_major_text; extern Widget export_grid_minor_menu_button, export_grid_minor_menu; extern Widget export_grid_major_menu_button, export_grid_major_menu; extern Widget export_grid_unit_label; extern void export_grid_minor_select(Widget w, XtPointer new_grid_choice, XtPointer call_data); extern void export_grid_major_select(Widget w, XtPointer new_grid_choice, XtPointer call_data); extern void popup_export_panel(Widget w); extern void do_export(Widget w); extern void update_def_filename (void); xfig.3.2.5c/w_file.h0000700002656300244210000000326410602603372014775 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern Boolean colors_are_swapped; extern void load_request(Widget w, XButtonEvent *ev); extern void do_save(Widget w, XButtonEvent *ev); extern void popup_open_panel(void); extern void popup_merge_panel(void); extern void popup_saveas_panel(void); extern Boolean query_save(char *msg); extern Widget preview_size, preview_widget, preview_name; extern Pixmap preview_land_pixmap, preview_port_pixmap; extern Widget file_panel; extern Boolean file_up; extern Widget cfile_text; extern Widget file_selfile; extern Widget file_mask; extern Widget file_dir; extern Widget file_flist; extern Widget file_dlist; extern Widget file_popup; extern Boolean check_cancel(void); extern Boolean cancel_preview; extern Boolean preview_in_progress; extern void preview_figure (char *filename, Widget parent, Widget canvas, Widget size_widget, Pixmap port_pixmap, Pixmap land_pixmap); extern int renamefile (char *file); extern void file_panel_dismiss (void); xfig.3.2.5c/w_fontbits.h0000700002656300244210000000167710602603372015714 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* width of widest font image plus a small border */ #define MAX_FONTIMAGE_WIDTH 296 extern Pixmap psfont_menu_bitmaps[]; extern Pixmap latexfont_menu_bitmaps[]; extern unsigned char *psfont_menu_bits[]; extern unsigned char *latexfont_menu_bits[]; xfig.3.2.5c/w_fontpanel.h0000700002656300244210000000011410602603372016033 0ustar bvsmithDomain Usersextern void init_fontmenu(Widget tool); extern void setup_fontmenu(void); xfig.3.2.5c/w_grid.h0000700002656300244210000000007711026525374015010 0ustar bvsmithDomain Usersextern void init_grid (void); extern void setup_grid (void); xfig.3.2.5c/w_help.h0000700002656300244210000000153110602603372015001 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void launch_refman(), launch_refpdf_en(), launch_refpdf_jp(); extern void launch_man(); extern void launch_howto(); extern void launch_about(); xfig.3.2.5c/w_i18n.h0000700002656300244210000000025710602603372014634 0ustar bvsmithDomain Usersextern Boolean is_i18n_font (); extern Boolean is_i18n_font (); extern void i18n_draw_image_string (); extern void i18n_draw_string (); extern void i18n_text_extents (); xfig.3.2.5c/w_icons.h0000700002656300244210000001364011475521324015175 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_ICONS_H #define W_ICONS_H extern int mode_sw_ht; extern int mode_sw_wd; void setup_icons_small(); void setup_icons_big(); typedef struct _icon_struct { int width, height; char *bits; } icon_struct; extern icon_struct addpt_ic; extern icon_struct figure_ic; extern char *fig_full_c_icon_X[], *fig_reduced_c_icon_X[]; extern icon_struct smartoff_ic; extern icon_struct smartmove_ic; extern icon_struct smartslide_ic; extern icon_struct arc_ic; extern icon_struct autoarrow_ic; extern icon_struct backarrow_ic; extern icon_struct box_ic; extern icon_struct regpoly_ic; extern icon_struct picobj_ic; extern icon_struct arc_box_ic; extern icon_struct cirrad_ic; extern icon_struct cirdia_ic; extern icon_struct c_spl_ic; extern icon_struct c_xspl_ic; extern icon_struct copy_ic; extern icon_struct glue_ic; extern icon_struct break_ic; extern icon_struct library_ic; extern icon_struct open_comp_ic; extern icon_struct join_split_ic; extern icon_struct chop_ic; extern icon_struct joinmiter_ic; extern icon_struct joinround_ic; extern icon_struct joinbevel_ic; extern icon_struct capbutt_ic; extern icon_struct capround_ic; extern icon_struct capproject_ic; extern icon_struct solidline_ic; extern icon_struct dashline_ic; extern icon_struct dottedline_ic; extern icon_struct dashdotline_ic; extern icon_struct dash2dotsline_ic; extern icon_struct dash3dotsline_ic; extern icon_struct deletept_ic; extern icon_struct ellrad_ic; extern icon_struct elldia_ic; extern icon_struct flip_x_ic; extern icon_struct flip_y_ic; extern icon_struct forarrow_ic; extern icon_struct grid1_ic, grid2_ic, grid3_ic, grid3_ic, grid4_ic; extern icon_struct grid_iso1_ic, grid_iso2_ic, grid_iso3_ic, grid_iso4_ic; // isometric grid extern icon_struct intspl_ic; extern icon_struct c_intspl_ic; extern icon_struct line_ic; extern icon_struct fine_grid_ic; extern icon_struct unconstrained_ic; extern icon_struct latexline_ic; extern icon_struct latexarrow_ic; extern icon_struct mounthattan_ic; extern icon_struct manhattan_ic; extern icon_struct mountain_ic; extern icon_struct move_ic; extern icon_struct movept_ic; extern icon_struct polygon_ic; extern icon_struct delete_ic; extern icon_struct rotCW_ic; extern icon_struct rotCCW_ic; extern icon_struct scale_ic; extern icon_struct convert_ic; extern icon_struct spl_ic; extern icon_struct text_ic; extern icon_struct update_ic; extern icon_struct edit_ic; extern icon_struct halignl_ic; extern icon_struct halignr_ic; extern icon_struct halignc_ic; extern icon_struct haligndc_ic; extern icon_struct halignde_ic; extern icon_struct haligna_ic; extern icon_struct valignt_ic; extern icon_struct valignb_ic; extern icon_struct valignc_ic; extern icon_struct valigndc_ic; extern icon_struct valignde_ic; extern icon_struct valigna_ic; extern icon_struct align_ic; extern icon_struct any_ic; extern icon_struct none_ic; extern icon_struct fill_ic; extern icon_struct blank_ic; extern icon_struct textL_ic; extern icon_struct textC_ic; extern icon_struct textR_ic; extern icon_struct noarrows_ic; extern icon_struct farrows_ic; extern icon_struct barrows_ic; extern icon_struct fbarrows_ic; extern icon_struct open_arc_ic; extern icon_struct pie_wedge_arc_ic; extern icon_struct xspl_ic; extern icon_struct tangent_ic; extern icon_struct anglemeas_ic; extern icon_struct lenmeas_ic; extern icon_struct areameas_ic; /* misc icons */ extern icon_struct kbd_ic; extern icon_struct printer_ic; extern icon_struct no_arrow_ic; extern icon_struct arrow0_ic; extern icon_struct arrow1o_ic, arrow1f_ic; extern icon_struct arrow2o_ic, arrow2f_ic; extern icon_struct arrow3o_ic, arrow3f_ic; extern icon_struct arrow4o_ic, arrow4f_ic; extern icon_struct arrow5o_ic, arrow5f_ic; extern icon_struct arrow6o_ic, arrow6f_ic; extern icon_struct arrow7o_ic, arrow7f_ic; extern icon_struct arrow8o_ic, arrow8f_ic; extern icon_struct arrow9a_ic, arrow9b_ic; extern icon_struct arrow10o_ic, arrow10f_ic; extern icon_struct arrow11o_ic, arrow11f_ic; extern icon_struct arrow12o_ic, arrow12f_ic; extern icon_struct arrow13a_ic, arrow13b_ic; extern icon_struct arrow14a_ic, arrow14b_ic; extern unsigned char no_arrow_bits[]; extern unsigned char arrow0_bits[]; extern unsigned char arrow1o_bits[], arrow1f_bits[]; extern unsigned char arrow2o_bits[], arrow2f_bits[]; extern unsigned char arrow3o_bits[], arrow3f_bits[]; extern unsigned char arrow4o_bits[], arrow4f_bits[]; extern unsigned char arrow5o_bits[], arrow5f_bits[]; extern unsigned char arrow6o_bits[], arrow6f_bits[]; extern unsigned char arrow7o_bits[], arrow7f_bits[]; extern unsigned char arrow8o_bits[], arrow8f_bits[]; extern unsigned char arrow9a_bits[], arrow9b_bits[]; extern unsigned char arrow10o_bits[], arrow10f_bits[]; extern unsigned char arrow11o_bits[], arrow11f_bits[]; extern unsigned char arrow12o_bits[], arrow12f_bits[]; extern unsigned char arrow13a_bits[], arrow13b_bits[]; extern unsigned char arrow14a_bits[], arrow14b_bits[]; /* for splash screen */ #ifdef USE_XPM extern char *spl_bckgnd_xpm[]; #endif /* USE_XPM */ extern icon_struct letters_ic; extern icon_struct spl_bckgnd_ic; #endif /* W_ICONS_H */ xfig.3.2.5c/w_indpanel.h0000700002656300244210000001640110604747730015656 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_INDPANEL_H #define W_INDPANEL_H #include "w_icons.h" /* size of buttons in indicator panel */ #define DEF_IND_SW_HT 34 #define DEF_IND_SW_WD 64 #define FONT_IND_SW_WD (40+PS_FONTPANE_WD) #define NARROW_IND_SW_WD 56 #define WIDE_IND_SW_WD 76 #define XWIDE_IND_SW_WD 90 /* size of update control panel */ #define UPD_BITS 10 /* bits wide and high */ #define UPD_BORD 1 /* border width for update squares */ #define UPD_INT 2 /* internal spacing */ #define UPD_CTRL_HT 40 + UPD_BITS + 2*UPD_BORD + 2*UPD_INT extern Dimension UPD_CTRL_WD; /* actual width is det. in setup_ind_panel */ #define NUM_CAPSTYLE_TYPES 3 #define NUM_JOINSTYLE_TYPES 3 #define NUM_LINESTYLE_TYPES 6 /* indicator button selection */ #define I_ANGLEGEOM 0x00000001 #define I_VALIGN 0x00000002 #define I_HALIGN 0x00000004 #define I_ARROWSIZE 0x00000008 #define I_POINTPOSN 0x00000010 #define I_FILLSTYLE 0x00000020 #define I_BOXRADIUS 0x00000040 #define I_LINEWIDTH 0x00000080 #define I_LINESTYLE 0x00000100 #define I_ARROWMODE 0x00000200 #define I_TEXTJUST 0x00000400 #define I_FONTSIZE 0x00000800 #define I_FONT 0x00001000 #define I_TEXTSTEP 0x00002000 #define I_DIMLINE 0x00004000 #define I_ROTNANGLE 0x00008000 #define I_NUMSIDES 0x00010000 #define I_PEN_COLOR 0x00020000 #define I_FILL_COLOR 0x00040000 #define I_LINKMODE 0x00080000 #define I_DEPTH 0x00100000 #define I_ELLTEXTANGLE 0x00200000 #define I_TEXTFLAGS 0x00400000 #define I_JOINSTYLE 0x00800000 #define I_ARROWTYPE 0x01000000 #define I_CAPSTYLE 0x02000000 #define I_ARCTYPE 0x04000000 #define I_NUMCOPIES 0x08000000 #define I_NUMXCOPIES 0x10000000 #define I_NUMYCOPIES 0x20000000 #define I_TANGNORMLEN 0x40000000 #define I_free1_____ 0x80000000 /* this one is free for another ind */ #define I_NONE 0x00000000 /* be sure to update I_ALL if more buttons are added */ #define I_ALL 0xffffffff & ~I_free1_____ #define I_MIN2 (I_POINTPOSN) #define I_MIN3 (I_MIN2 | I_LINKMODE) #define I_ADDMOVPT (I_MIN2 | I_ANGLEGEOM) #define I_TEXT0 (I_TEXTJUST | I_FONT | I_FONTSIZE | I_PEN_COLOR | \ I_DEPTH | I_ELLTEXTANGLE | I_TEXTFLAGS) #define I_TEXT (I_MIN2 | I_TEXTSTEP | I_TEXT0) #define I_LINE0 (I_FILLSTYLE | I_LINESTYLE | I_LINEWIDTH | \ I_PEN_COLOR | I_FILL_COLOR | I_DEPTH) #define I_LINE1 (I_FILLSTYLE | I_LINESTYLE | I_JOINSTYLE | I_LINEWIDTH | \ I_PEN_COLOR | I_FILL_COLOR | I_DEPTH | I_CAPSTYLE) #define I_LINE (I_MIN2 | I_LINE1 | I_DEPTH | I_ANGLEGEOM | I_DIMLINE | \ I_ARROWMODE | I_ARROWTYPE | I_ARROWSIZE) #define I_BOX (I_MIN2 | I_LINE1 | I_DEPTH) #define I_CIRCLE (I_MIN2 | I_LINE0 | I_DEPTH) #define I_ELLIPSE (I_MIN2 | I_LINE0 | I_DEPTH | I_ELLTEXTANGLE) #define I_ARC (I_BOX | I_ARROWMODE | I_ARROWTYPE | I_ARROWSIZE | \ I_CAPSTYLE | I_ARCTYPE) #define I_CHOP (I_ARCTYPE) #define I_REGPOLY (I_BOX | I_NUMSIDES) #define I_CLOSED (I_BOX | I_ANGLEGEOM) #define I_OPEN (I_CLOSED | I_ARROWMODE | I_ARROWTYPE | I_ARROWSIZE | I_CAPSTYLE) #define I_ARCBOX (I_BOX | I_BOXRADIUS) #define I_PICOBJ (I_MIN2 | I_DEPTH | I_PEN_COLOR) #define I_OBJECT (I_TEXT0 | I_LINE1 | I_ARROWMODE | I_ARROWTYPE | I_ARROWSIZE | \ I_BOXRADIUS | I_DEPTH | I_ARCTYPE | I_DIMLINE) #define I_ALIGN (I_HALIGN | I_VALIGN) #define I_ROTATE (I_MIN2 | I_ROTNANGLE | I_NUMCOPIES) #define I_COPY (I_MIN3 | I_NUMXCOPIES | I_NUMYCOPIES) #define I_ADD_DEL_ARROW (I_LINEWIDTH | I_ARROWTYPE | I_ARROWSIZE) #define I_TANGENT (I_MIN2 | I_LINE1 | I_DEPTH | I_ARROWTYPE | I_ARROWMODE | I_TANGNORMLEN) /* for checking which parts to update */ #define I_UPDATEMASK (I_OBJECT) typedef struct choice_struct { int value; icon_struct *icon; Pixmap pixmap; } choice_info; extern choice_info arrowtype_choices[]; extern choice_info dim_arrowtype_choices[]; extern choice_info fillstyle_choices[]; extern choice_info capstyle_choices[]; extern choice_info joinstyle_choices[]; extern choice_info linestyle_choices[]; typedef struct ind_sw_struct { int type; /* one of I_CHOICE .. I_FVAL */ unsigned long func; char line1[38], line2[8]; int sw_width; int *i_varadr; float *f_varadr; void (*inc_func) (); void (*dec_func) (); void (*show_func) (); int min, max; /* min, max values allowable */ float inc; /* increment for spinner */ choice_info *choices; /* specific to I_CHOICE */ int numchoices; /* specific to I_CHOICE */ int sw_per_row; /* specific to I_CHOICE */ Bool update; /* whether this object component is updated by update */ Widget button; Widget formw; Widget updbut; Pixmap pixmap; Widget panel; /* to keep track if already created */ } ind_sw_info; extern ind_sw_info ind_switches[]; extern ind_sw_info *fill_style_sw; extern ind_sw_info *pen_color_button, *fill_color_button, *depth_button; #define ZOOM_SWITCH_INDEX 0 /* used by w_zoom.c */ /* EXPORTS */ extern void init_ind_panel(Widget tool); extern void add_ind_actions(void); extern Boolean update_buts_managed; extern Widget choice_popup; extern void show_depth(ind_sw_info *sw), show_zoom(ind_sw_info *sw); extern void show_fillstyle(ind_sw_info *sw); extern void fontpane_popup(int *psfont_adr, int *latexfont_adr, int *psflag_adr, void (*showfont_fn) (/* ??? */), Widget show_widget); extern void make_pulldown_menu_images(choice_info *entries, Cardinal nent, Pixmap *images, char **texts, Widget parent, XtCallbackProc callback); extern void tog_selective_update(long unsigned int mask); extern unsigned long cur_indmask; /* mask showing which indicator buttons are mapped */ extern void inc_zoom(ind_sw_info *sw), dec_zoom(ind_sw_info *sw), fit_zoom(ind_sw_info *sw); extern void wheel_inc_zoom(), wheel_dec_zoom(); extern void update_current_settings(void); extern void setup_ind_panel(void); extern void manage_update_buts (void); extern void recolor_fillstyles (void); extern void unmanage_update_buts (void); extern void update_indpanel (long unsigned int mask); extern void choice_panel_dismiss (void); extern void set_and_show_rotnangle (float value); extern void generate_choice_pixmaps(ind_sw_info *isw); extern void draw_cur_dimline(void); extern void get_dimline_values(void); extern void popup_arrowsize_panel(ind_sw_info *isw); extern void popup_flags_panel(ind_sw_info *isw); extern void popup_nval_panel(ind_sw_info *isw); extern void popup_dimline_panel(ind_sw_info *isw); extern void popup_choice_panel(ind_sw_info *isw); #endif /* W_INDPANEL_H */ xfig.3.2.5c/w_intersect.h0000700002656300244210000000413511164165252016060 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 2004 by Chris Moller * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_INTERSECT_H #define W_INTERSECT_H typedef struct { int seg_idx; int x; int y; } isects_s; typedef struct { isects_s * isects; int nr_isects; int max_isects; } isect_cb_s; /* MUST BE >= 2 */ #define ISECTS_INCR 8 extern void insert_isect(isect_cb_s * isect_cb, double ix, double iy, int seg_idx); extern void intersect_ellipse_ellipse_handler(F_ellipse * e1, F_ellipse * e2, int x, int y, isect_cb_s * isect_cb ); extern void intersect_ellipse_arc_handler(F_ellipse * e, F_arc * a, int x, int y, isect_cb_s * isect_cb); extern void intersect_ellipse_polyline_handler(F_ellipse * e, F_line * l, int x, int y, isect_cb_s * isect_cb); extern void intersect_arc_arc_handler(F_arc * a1, F_arc * a2, int x, int y, isect_cb_s * isect_cb); extern void intersect_polyline_arc_handler(F_line * l, F_arc *a, int x, int y, isect_cb_s * isect_cb); extern void intersect_polyline_polyline_handler(F_line * l1, F_line * l2, int x, int y, isect_cb_s * isect_cb); extern void snap_intersect_handler(void * obj1, int type1, void * obj2, int type2, int x, int y); extern F_line * build_text_bounding_box(F_text * t); extern void delete_text_bounding_box(F_line * l); #endif xfig.3.2.5c/w_keyboard.h0000700002656300244210000000224710602603372015656 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 2004 by Chris Moller * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_KEYBOARD_H #define W_KEYBOARD_H extern void popup_keyboard_panel(Widget widget, XButtonEvent * event, String * params, Cardinal * num_params); extern void popdown_keyboard_panel(); extern Boolean keyboard_input_available; extern int keyboard_state; extern int keyboard_x; extern int keyboard_y; #endif xfig.3.2.5c/w_layers.h0000700002656300244210000000332410602603372015352 0ustar bvsmithDomain Users/* * This layer code written by Tim Love June 25, 1998 * * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern Boolean active_layers[MAX_DEPTH +1]; extern int object_depths[MAX_DEPTH +1], saved_depths[MAX_DEPTH +1]; extern int saved_min_depth, saved_max_depth; extern Boolean save_layers[MAX_DEPTH+1]; extern Widget layer_form; extern Boolean gray_layers; #define active_layer(layer) active_layers[layer] extern void init_depth_panel(Widget parent); extern void setup_depth_panel(void); extern void update_layers(void); extern void toggle_show_depths(void); extern void save_active_layers(void), restore_active_layers(void); extern void save_counts(void), save_counts_and_clear(void), restore_counts(void); extern void save_depths(void), restore_depths(void); extern Boolean any_active_in_compound(F_compound *cmpnd); extern void reset_layers(void); extern void reset_depths(void); extern int LAYER_WD, LAYER_HT; extern void update_layerpanel (); xfig.3.2.5c/w_library.h0000700002656300244210000000220110602603372015510 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #define DEF_ICON_SIZE 60 /* size (square) of object icon */ typedef struct f_libobj { struct { int x, y; } corner; struct f_compound *compound; } F_libobject; extern F_libobject **lib_compounds; extern char **library_objects_texts; extern void popup_library_panel(void); extern void set_comments(char *comments); xfig.3.2.5c/w_listwidget.h0000700002656300244210000000216710602603372016236 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* FigList widget public header file */ #ifndef _FigList_h #define _FigList_h #ifdef XAW3D #include #else /* XAW3D */ #include #endif /* XAW3D */ #include extern WidgetClass figListWidgetClass; typedef struct _FigListClassRec *FigListWidgetClass; typedef struct _FigListRec *FigListWidget; #endif /* _FigList_h */ /* DON'T ADD ANYTHING AFTER THIS #endif */ xfig.3.2.5c/w_listwidgetP.h0000700002656300244210000000373010602603372016353 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* w_listwidgetP.h - FigList - This is an attempt to subclass the listWidgetClass to add the functionality of up/down arrows to scroll up/down in the list */ /* protect again multiple includes */ #ifndef _FigListP_h #define _FigListP_h /* get the superclass private header */ #ifdef XAW3D #include #else /* XAW3D */ #include #endif /* XAW3D */ /* our header file */ #include "w_listwidget.h" /* New fields we need for the class record */ typedef struct { int make_compiler_happy; /* just so it's not empty */ } FigListClassPart; /* Full class record declaration */ typedef struct _FigListClassRec { CoreClassPart core_class; SimpleClassPart simple_class; ListClassPart list_class; FigListClassPart figList_class; } FigListClassRec; extern FigListClassRec figListClassRec; /* New fields for the FigList widget record */ typedef struct { /* resources */ /* (none) */ /* private state */ /* (none) */ int make_compiler_happy; } FigListPart; /* Full instance record declaration */ typedef struct _FigListRec { CorePart core; SimplePart simple; ListPart list; FigListPart figlist; } FigListRec; #endif /* _FigListP_h */ xfig.3.2.5c/w_menuentry.h0000700002656300244210000000312010602603372016073 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* w_menuentry.h - Public Header file for subclassed BSB Menu Entry object This adds the underline resource to underline one character of the label */ #ifndef _FigSmeBSB_h #define _FigSmeBSB_h #include #ifdef XAW3D #include #else #include #endif #include "SmeBSB.h" /**************************************************************** * * FigSmeBSB object * ****************************************************************/ /* FigBSB Menu Entry Resources: Name Class RepType Default Value ---- ----- ------- ------------- underline Index int -1 */ typedef struct _FigSmeBSBClassRec *FigSmeBSBObjectClass; typedef struct _FigSmeBSBRec *FigSmeBSBObject; extern WidgetClass figSmeBSBObjectClass; #define XtNunderline "underline" #endif /* Fig_SmeBSB_h */ xfig.3.2.5c/w_menuentryP.h0000700002656300244210000000540210602603372016220 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* w_menuentryP.h - Private Header file for subclassed BSB Menu Entry object This adds the underline resource to underline one character of the label */ #ifndef _FigSmeBSBP_h #define _FigSmeBSBP_h /*********************************************************************** * * Sme Object Private Data * ***********************************************************************/ #ifdef XAW3D #include #else #include #endif /* XAW3D */ #include "SmeBSBP.h" /* our header file */ #include "w_menuentry.h" /************************************************************ * * New fields for the Fig Sme Object class record. * ************************************************************/ typedef struct { int make_compiler_happy; /* just so it's not empty */ } FigSmeBSBClassPart; /* Full class record declaration */ typedef struct _FigSmeBSBClassRec { RectObjClassPart rect_class; SmeClassPart sme_class; #ifdef XAW3D SmeThreeDClassPart sme_threeD_class; #endif /* XAW3D */ SmeBSBClassPart sme_bsb_class; FigSmeBSBClassPart figSme_bsb_class; } FigSmeBSBClassRec; extern FigSmeBSBClassRec figSmeBSBClassRec; /* New fields for the FigSme Object record */ typedef struct { /* resources */ int underline; /* which letter of the label to underline */ /* private resources. */ int make_compiler_happy; /* just so it's not empty */ } FigSmeBSBPart; /**************************************************************** * * Full instance record declaration * ****************************************************************/ typedef struct _FigSmeBSBRec { ObjectPart object; RectObjPart rectangle; SmePart sme; #ifdef XAW3D SmeThreeDPart sme_threeD; #endif /* XAW3D */ SmeBSBPart sme_bsb; FigSmeBSBPart figSme_bsb; } FigSmeBSBRec; /************************************************************ * * Private declarations. * ************************************************************/ #endif /* _FigSmeBSBP_h */ xfig.3.2.5c/w_modepanel.h0000700002656300244210000000342710602603372016023 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void force_positioning(void); extern void force_nopositioning(void); extern void force_anglegeom(void); extern void force_noanglegeom(void); extern void init_mode_panel(Widget tool); #include "w_icons.h" #define MAX_MODEMSG_LEN 80 typedef struct mode_switch_struct { icon_struct *icon; /* icon (xxx_ic struct) */ int mode; /* mode (e.g. F_CIRCLE_BY_RAD) */ void (*setmode_func) (); /* function called when button is released */ int objmask; /* mask of objects that may be affected by this */ unsigned long indmask; /* mask to display indicators for this func */ char modemsg[MAX_MODEMSG_LEN]; /* message for function */ Boolean popup; /* true for commands that popup something */ Widget widget; Pixmap pixmap, reversePM; } mode_sw_info; extern void change_mode (icon_struct *icon); extern void turn_off_current (void); extern void update_modepanel (); extern void setup_mode_panel(void); xfig.3.2.5c/w_mousefun.h0000700002656300244210000000364210602603374015721 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_MOUSEFUN_H #define W_MOUSEFUN_H void init_mousefun(Widget tool); void setup_mousefun(void); void set_mousefun(char *left, char *middle, char *right, char *sh_left, char *sh_middle, char *sh_right); void draw_mousefun_mode(void); void draw_mousefun_ind(void); void draw_mousefun_unitbox(void); void shift_top_mousfun(); void draw_mousefun_topruler(Widget w, XEvent *event, String *params, Cardinal *num_params); void shift_side_mousfun(); void draw_mousefun_sideruler(Widget w, XEvent *event, String *params, Cardinal *num_params); void draw_mousefun_canvas(void); void draw_mousefun(char *left, char *middle, char *right); void draw_mousefn2(char *left, char *middle, char *right); void clear_mousefun(void); void notused_middle(void); void clear_middle(void); void notused_right(void); void clear_right(void); void draw_mousefun_kbd(void); void clear_mousefun_kbd(void); void init_mousefun_actions(); extern String kbd_translations; extern void init_kbd_actions (void); extern void update_mousepanel (); extern void draw_shift_mousefun_canvas(void); extern void draw_shift_mousefun_canvas2(char *tl, char *tm, char *tr); #endif /* W_MOUSEFUN_H */ xfig.3.2.5c/w_msgpanel.h0000700002656300244210000000333110602603374015661 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void init_msg(Widget tool); extern void put_msg(char *format, ...); extern void file_msg(char *format, ...); extern void boxsize_msg(int fact); extern void length_msg(int type); extern void altlength_msg(int type, int fx, int fy); extern void length_msg2(int x1, int y1, int x2, int y2, int x3, int y3); extern void popup_file_msg(void); extern void make_dimension_string(float length, char *str, Boolean square); extern Boolean popup_up; extern Boolean first_file_msg; extern Boolean file_msg_is_popped; extern Widget file_msg_popup; extern Boolean first_lenmsg; extern void boxsize_scale_msg (int fact); extern void erase_box_lengths (void); extern void erase_lengths (void); extern void arc_msg (int x1, int y1, int x2, int y2, int x3, int y3); extern void areameas_msg (char *msgtext, float area, float totarea, int flag); extern void lenmeas_msg (char *msgtext, float len, float totlen); extern void setup_msg(void); xfig.3.2.5c/w_print.h0000700002656300244210000000363410661632676015231 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern Widget print_popup; /* the main print popup */ extern Widget print_panel; /* the form it's in */ extern Widget print_orient_panel; extern Widget print_just_panel; extern Widget print_papersize_panel; extern Widget print_multiple_panel; extern Widget print_overlap_panel; extern Widget print_mag_text; extern Widget print_background_panel; extern Widget make_layer_choice(char *label_all, char *label_active, Widget parent, Widget below, Widget beside, int hdist, int vdist); extern void print_update_figure_size(void); extern void popup_print_panel(Widget w); extern void do_print(Widget w); extern void do_print_batch(Widget w); extern Boolean print_all_layers; extern Boolean bound_active_layers; extern Widget print_grid_minor_text, print_grid_major_text; extern Widget print_grid_minor_menu_button, print_grid_minor_menu; extern Widget print_grid_major_menu_button, print_grid_major_menu; extern Widget print_grid_unit_label; extern void print_grid_minor_select(Widget w, XtPointer new_grid_choice, XtPointer garbage); extern void print_grid_major_select(Widget w, XtPointer new_grid_choice, XtPointer garbage); xfig.3.2.5c/w_rottext.h0000700002656300244210000000652510602603374015574 0ustar bvsmithDomain Users/* ************************************************************************ */ /* Header file for the `xvertext 5.0' routines. * * Copyright (c) 1993 Alan Richardson (mppa3@uk.ac.sussex.syma) * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* ************************************************************************ */ #ifndef W_ROTTEXT_H #define W_ROTTEXT_H #ifndef _XVERTEXT_INCLUDED_ #define _XVERTEXT_INCLUDED_ #define XV_VERSION 5.0 #define XV_COPYRIGHT \ "xvertext routines Copyright (c) 1993 Alan Richardson" /* ---------------------------------------------------------------------- */ /* text alignment */ #define NONE 0 #define TLEFT 1 #define TCENTRE 2 #define TRIGHT 3 #define MLEFT 4 #define MCENTRE 5 #define MRIGHT 6 #define BLEFT 7 #define BCENTRE 8 #define BRIGHT 9 /* ---------------------------------------------------------------------- */ /* this shoulf be C++ compliant, thanks to vlp@latina.inesc.pt (Vasco Lopes Paulo) */ #if defined(__cplusplus) || defined(c_plusplus) extern "C" { float XRotVersion(char*, int); void XRotSetMagnification(float); void XRotSetBoundingBoxPad(int); int XRotDrawString(Display*, XFontStruct*, float, Drawable, GC, int, int, char*); int XRotDrawImageString(Display*, XFontStruct*, float, Drawable, GC, int, int, char*); int XRotDrawAlignedString(Display*, XFontStruct*, float, Drawable, GC, int, int, char*, int); int XRotDrawAlignedImageString(Display*, XFontStruct*, float, Drawable, GC, int, int, char*, int); XPoint *XRotTextExtents(XFontStruct*, float, int, int, char*, int); } #else extern float XRotVersion(char *str, int n); extern void XRotSetMagnification(float m); extern void XRotSetBoundingBoxPad(int p); extern int XRotDrawString(Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *str); extern int XRotDrawImageString(Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *str); extern int XRotDrawAlignedString(Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *text, int align); extern int XRotDrawAlignedImageString(Display *dpy, XFontStruct *font, float angle, Drawable drawable, GC gc, int x, int y, char *text, int align); extern XPoint *XRotTextExtents(XFontStruct *font, float angle, int x, int y, char *text, int align); #endif /* __cplusplus */ /* ---------------------------------------------------------------------- */ #endif /* _XVERTEXT_INCLUDED_ */ #endif /* W_ROTTEXT_H */ xfig.3.2.5c/w_rulers.h0000700002656300244210000000323610602603374015373 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void init_topruler(Widget tool); extern void popup_unit_panel(void); extern void erase_rulermark(void); extern void set_unit_indicator(Boolean use_userscale); extern void init_unitbox(Widget tool); extern void init_sideruler(Widget tool); extern void redisplay_sideruler (void); extern void redisplay_topruler (void); extern void reset_sideruler (void); extern void reset_topruler (void); extern void resize_sideruler (void); extern void resize_topruler (void); extern void setup_sideruler (void); extern void reset_rulers (void); extern void update_rulerpanel (); extern void setup_rulers(void); extern void set_rulermark(int x, int y); extern void erase_siderulermark(void); extern void erase_toprulermark(void); extern void set_rulermark(int x, int y); extern void set_siderulermark(int y); extern void set_toprulermark(int x); extern void setup_topruler(void); xfig.3.2.5c/w_setup.h0000644002656300244210000000462412207700756015235 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_SETUP_H #define W_SETUP_H #define PIX_PER_INCH 1200 #define PIX_PER_CM 450 /* closest to correct (472.4) and still have the rulers look good */ /* shorthand */ #define PPI PIX_PER_INCH #define PPCM PIX_PER_CM #define DISPLAY_PIX_PER_INCH 80 /* Portrait dimensions */ #define DEF_CANVAS_HT_PORT 9.5*DISPLAY_PIX_PER_INCH+1 #define DEF_CANVAS_WD_PORT 8.5*DISPLAY_PIX_PER_INCH+1 /* Landscape dimensions (allow enough height for the mode panel) */ #define DEF_CANVAS_HT_LAND 9.0*DISPLAY_PIX_PER_INCH+1 #define DEF_CANVAS_WD_LAND 11*DISPLAY_PIX_PER_INCH+1 #define DEF_RULER_WD 24 #define UNITBOX_WD 95 #ifndef MAX_TOPRULER_WD #define MAX_TOPRULER_WD 1600 #endif #ifndef MAX_SIDERULER_HT #define MAX_SIDERULER_HT 1280 #endif #define MOUSEFUN_WD 275 #define DEF_SW_PER_ROW 2 /* def num of buttons per row in mode panel */ #define DEF_INTERNAL_BW 1 #define POPUP_BW 2 #define DEF_LAYER_WD 64 /* default width of the depth panel */ extern int TOOL_WD, TOOL_HT; extern int CMDFORM_WD, CMDFORM_HT; extern int NAMEPANEL_WD; extern int MODEPANEL_WD; extern int MODEPANEL_SPACE; extern int MSGPANEL_WD, MSGPANEL_HT; extern int MOUSEFUN_HT; extern int INDPANEL_WD; extern int CANVAS_WD, CANVAS_HT; extern int CANVAS_WD_LAND, CANVAS_HT_LAND; extern int CANVAS_WD_PORT, CANVAS_HT_PORT; extern int INTERNAL_BW; extern int TOPRULER_WD, TOPRULER_HT; extern int SIDERULER_WD, SIDERULER_HT; extern int LAYER_WD, LAYER_HT; extern int SW_PER_ROW; extern int NUM_MODE_SW; extern void setup_sizes (int new_canv_wd, int new_canv_ht); #endif /* W_SETUP_H */ xfig.3.2.5c/w_snap.h0000700002656300244210000000522710604747764015040 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 2004 by Chris Moller * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_SNAP_H #define W_SNAP_H extern void snap_hold(Widget w, XtPointer closure, XtPointer call_data); extern void snap_release(Widget w, XtPointer closure, XtPointer call_data); extern void snap_endpoint(Widget w, XtPointer closure, XtPointer call_data); extern void snap_midpoint(Widget w, XtPointer closure, XtPointer call_data); extern void snap_nearest(Widget w, XtPointer closure, XtPointer call_data); extern void snap_focus(Widget w, XtPointer closure, XtPointer call_data); extern void snap_diameter(Widget w, XtPointer closure, XtPointer call_data); extern void snap_normal(Widget w, XtPointer closure, XtPointer call_data); extern void snap_tangent(Widget w, XtPointer closure, XtPointer call_data); extern void snap_intersect(Widget w, XtPointer closure, XtPointer call_data); extern Boolean snap_process(int * px, int *py, unsigned int state); extern void get_line_from_points(double * c, struct f_point * s1, struct f_point * s2); extern void snap_rotate_vector(double * dx, double * dy, double x, double y, double theta); extern Boolean is_point_on_arc(F_arc * a, int x, int y); extern void snap_polyline_focus_handler(F_line * a, int x, int y); extern void init_snap_panel(Widget parent); typedef enum { SNAP_MODE_NONE, SNAP_MODE_ENDPOINT, SNAP_MODE_MIDPOINT, SNAP_MODE_NEAREST, SNAP_MODE_FOCUS, SNAP_MODE_DIAMETER, SNAP_MODE_NORMAL, SNAP_MODE_TANGENT, SNAP_MODE_INTERSECT } snap_mode_e; typedef enum { INTERSECT_INITIAL, INTERSECT_FIRST_FOUND } intersect_state_e; extern intersect_state_e intersect_state; extern snap_mode_e snap_mode; extern Boolean snap_msg_set; extern int snap_gx; extern int snap_gy; extern Boolean snap_found; extern Widget snap_indicator_panel; extern Widget snap_indicator_label; # define signbit_(x) \ ((0.0 > (x)) ? 1 : 0) #endif xfig.3.2.5c/w_srchrepl.h0000700002656300244210000000164510602603374015703 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void popup_search_panel(void); extern void popup_spell_check_panel(char **list, int nitems); extern void spell_check(void); xfig.3.2.5c/w_style.h0000700002656300244210000000314210602603374015213 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * This file Copyright (c) 2002 Stephane Mancini * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ extern void init_manage_style_panel(void); extern void setup_manage_style_panel(void); extern void add_style_actions(void); extern void popup_manage_style_panel(void); extern int confirm_close_style(void); extern void add_style_actions(void); extern void init_manage_style_panel (void); extern void setup_manage_style_panel (void); extern Boolean style_dirty_flag; #define MAX_STYLE_ELEMENT 30 #define MAX_STYLE_FAMILY 16 #define MAX_STYLE_FAMILY_SET 16 typedef enum Element_type { Tint, Tfloat, TColor } Element_type; typedef struct Element { char *name; Element_type type; void *value,* toset; unsigned long flag; } Element; typedef struct Style { char *name; Element element[MAX_STYLE_ELEMENT]; } Style; typedef struct Style_family { char *name; Style style[MAX_STYLE_FAMILY]; } Style_family; #include "fig.h" xfig.3.2.5c/w_util.h0000700002656300244210000001555110662115656015046 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_UTIL_H #define W_UTIL_H #include "w_indpanel.h" /* constant values used for popup_query */ #define QUERY_YESCAN 0 #define QUERY_YESNO 1 #define QUERY_YESNOCAN 2 #define QUERY_ALLPARTCAN 3 #define QUERY_OK 4 #define RESULT_CANCEL -1 #define RESULT_NO 0 #define RESULT_YES 1 #define RESULT_ALL 2 #define RESULT_PART 3 /* some consts used by both w_indpanel.c, w_export.c and w_print.c */ #define I_CHOICE 0 #define I_IVAL 1 #define I_FVAL 2 /* width/height of the color buttons */ #define COLOR_BUT_WID 82 #define COLOR_BUT_HT 18 #define COLOR_BUT_BD_WID 1 /* border width */ /* true/false consts for make_color_popup_menu */ #define INCL_TRANSP True /* include transparent color button */ #define NO_TRANSP False /* don't ... */ #define INCL_BACKG True /* include background color button */ #define NO_BACKG False /* don't ... */ #define MANAGE True /* manage checkbox after creating */ #define DONT_MANAGE False /* don't ... */ #define LARGE_CHK True /* use large checkmark */ #define SMALL_CHK False /* use small checkmark (don't use large) */ /* number of arrow types */ #define NUM_ARROW_TYPES 30 /* EXPORTS */ extern char *grid_inch_choices[], *grid_tenth_inch_choices[]; extern char *grid_cm_choices[]; extern int num_grid_inch_choices, num_grid_tenth_inch_choices, num_grid_cm_choices; extern char **grid_choices; extern int n_grid_choices, grid_minor, grid_major; extern Widget make_grid_options(Widget parent, Widget put_below, Widget put_beside, char *minor_grid_value, char *major_grid_value, Widget *grid_minor_menu_button, Widget *grid_major_menu_button, Widget *grid_minor_menu, Widget *grid_major_menu, Widget *print_grid_minor_text, Widget *print_grid_major_text, Widget *grid_unit_label, void (*grid_major_select) (/* ??? */), void (*grid_minor_select) (/* ??? */)); extern void reset_grid_menus(Boolean inches); extern Boolean check_action_on(void); extern void check_for_resize(Widget tool, XButtonEvent *event, String *params, Cardinal *nparams); extern void check_colors(void); extern Widget make_pulldown_menu(char **entries, Cardinal nent, int divide_line, char *divide_message, Widget parent, XtCallbackProc callback); extern Widget make_color_popup_menu(Widget parent, char *name, XtCallbackProc callback, Boolean include_transp, Boolean include_backg); extern void set_color_name(int color, char *buf); extern void set_but_col(Widget widget, Pixel color); extern Widget MakeIntSpinnerEntry(Widget parent, Widget *text, char *name, Widget below, Widget beside, XtCallbackProc callback, char *string, int min, int max, int inc, int width); extern Widget MakeFloatSpinnerEntry(Widget parent, Widget *text, char *name, Widget below, Widget beside, XtCallbackProc callback, char *string, float min, float max, float inc, int width); extern Widget CreateCheckbutton(char *label, char *widget_name, Widget parent, Widget below, Widget beside, Boolean manage, Boolean large, Boolean *value, XtCallbackProc user_callback, Widget *togwidg); extern XtCallbackProc toggle_checkbutton(Widget w, XtPointer data, XtPointer garbage); extern Pixmap mouse_l, mouse_r; extern Pixmap check_pm, null_check_pm; extern Pixmap sm_check_pm, sm_null_check_pm; /* put these here so w_layers.c can get to them too */ #define check_width 16 #define check_height 16 #define sm_check_width 10 #define sm_check_height 10 extern Pixmap balloons_on_bitmap; extern Pixmap balloons_off_bitmap; extern Pixmap menu_arrow, menu_cascade_arrow; extern Pixmap arrow_pixmaps[NUM_ARROW_TYPES+1]; extern Pixmap diamond_pixmap; extern Pixmap linestyle_pixmaps[NUM_LINESTYLE_TYPES]; extern char *panel_get_value(Widget widg); extern void panel_set_value(Widget widg, char *val); extern void panel_set_int(Widget widg, int intval), panel_set_float(Widget widg, float floatval, char *format); extern void update_wm_title(char *name); extern void get_pointer_win_xy(int *xposn, int *yposn); extern void get_pointer_root_xy(int *xposn, int *yposn); extern void spinner_up_down(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params); extern void clear_splash(void); extern void InstallScroll(Widget widget); extern void InstallScrollParent(Widget widget); extern void fix_converters(void); extern Boolean user_colors_saved; extern Boolean nuser_colors_saved; /* * Author: Doyle C. Davidson * Intergraph Corporation * One Madison Industrial Park * Huntsville, Al. 35894-0001 * * Modification history: * 11 May 91 - added SetValues and GetValues - Paul King * * My macros for using XtSetArg easily: * Usage: * * blah() * { * DeclareArgs(2); * ... * FirstArg(XmNx, 100); * NextArg(XmNy, 80); * button = XmCreatePushButton(parent, name, Args, ArgCount); * } */ #include #define ArgCount _ArgCount #define Args _ArgList #define ArgCountMax _ArgCountMax #define DeclareArgs(n) Arg Args[n]; int ArgCountMax = n; int ArgCount #define DeclareStaticArgs(n) static Arg Args[n]; static int ArgCountMax = n; static int ArgCount #define FirstArg(name, val) \ { XtSetArg(Args[0], (name), (val)); ArgCount=1;} #define NextArg(name, val) \ { assert(ArgCount < ArgCountMax); \ XtSetArg(Args[ArgCount], (name), (val)); ArgCount++;} #define GetValues(n) XtGetValues(n, Args, ArgCount) #define SetValues(n) XtSetValues(n, Args, ArgCount) /* data structure passed to SpinnerEntry callback */ typedef struct { Widget widget; /* text widget inside spinner */ float min, max; /* min, max values allowed */ float inc; /* how much to inc/dec spinner with each click */ } spin_struct; extern void app_flush (void); extern void file_msg_add_grab (void); extern void process_pending (void); extern void resize_all (int width, int height); extern void restore_nuser_colors (void); extern void restore_user_colors (void); extern void save_nuser_colors (void); extern void save_user_colors (void); extern int popup_query(int query_type, char *message); extern void create_bitmaps(void); extern void splash_screen(void); extern int xallncol(char *name, XColor *color, XColor *exact); #endif /* W_UTIL_H */ xfig.3.2.5c/w_zoom.h0000700002656300244210000000205510602603374015041 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Henning Spruth * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #ifndef W_ZOOM_H #define W_ZOOM_H extern float zoomscale; extern float display_zoomscale; extern int zoomxoff; extern int zoomyoff; extern Boolean zoom_in_progress; extern Boolean integral_zoom; extern void unzoom(void); extern void zoom_selected(int x, int y, unsigned int button); #endif /* W_ZOOM_H */ xfig.3.2.5c/d_arc.c0000700002656300244210000002230511641414046014572 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. */ /********************** DECLARATIONS ********************/ /* IMPORTS */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_arc.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_cursor.h" #include "w_drawprim.h" #include "w_msgpanel.h" #include "w_mousefun.h" #include "u_geom.h" #include "f_util.h" #include "u_draw.h" #include "u_free.h" #include "u_markers.h" #include "u_redraw.h" /* EXPORT */ F_pos point[3]; F_pos center_point; Boolean center_marked; /* LOCAL */ static void create_arcobject(int lx, int ly); static void get_arcpoint(int x, int y); static void init_arc_drawing(int x, int y); static void cancel_arc(void); static void init_arc_c_drawing(int x, int y); static void resizing_arc(int x, int y); static F_arc *tmparc = 0; static F_pos tpoint[3]; static Boolean save_shownums; void arc_drawing_selected(void) { center_marked = FALSE; set_mousefun("first point", "center point", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_arc_drawing; canvas_middlebut_proc = init_arc_c_drawing; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_arc_drawing(int x, int y) { int i; if (center_marked) { /* erase the circle */ elastic_cbr(); /* save and turn off showing vertex numbers */ save_shownums = appres.shownums; appres.shownums = False; set_mousefun("direction", "", "cancel", "", "", ""); tmparc = create_arc(); tmparc->thickness = 1; tmparc->center.x = center_point.x; tmparc->center.y = center_point.y; /* initialize points in elastic arc */ for (i=0; i<3; i++) { tpoint[i].x = x; tpoint[i].y = y; } /* start the arc */ elastic_arc(); canvas_locmove_proc = resizing_arc; } else { set_mousefun("mid point", "", "cancel", "", "", ""); } draw_mousefun_canvas(); canvas_rightbut_proc = cancel_arc; point[0].x = fix_x = cur_x = x; point[0].y = fix_y = cur_y = y; num_point = 1; if (!center_marked) { canvas_locmove_proc = unconstrained_line; elastic_line(); } canvas_leftbut_proc = get_arcpoint; canvas_middlebut_proc = null_proc; set_cursor(null_cursor); set_action_on(); } static void init_arc_c_drawing(int x, int y) { set_mousefun("first point", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_cbr; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_arc; center_point.x = fix_x = cur_x = x; center_point.y = fix_y = cur_y = y; center_marked = TRUE; center_marker(center_point.x, center_point.y); set_action_on(); num_point = 0; } static void cancel_arc(void) { if (center_marked) { /* erase circle */ if (num_point == 0) elastic_cbr(); else elastic_arc(); /* free the temporary arc */ if (tmparc) { free_arc(&tmparc); tmparc = (F_arc *) 0; } center_marked = FALSE; center_marker(center_point.x, center_point.y); /* clear center marker */ /* restore shownums */ appres.shownums = save_shownums; } else { /* erase any length info if appres.showlengths is true */ erase_lengths(); elastic_line(); if (num_point == 2) { /* erase initial part of line */ cur_x = point[0].x; cur_y = point[0].y; elastic_line(); } } arc_drawing_selected(); draw_mousefun_canvas(); } static void get_arcpoint(int x, int y) { if (x == fix_x && y == fix_y) return; if (num_point == 1) { if (center_marked) { set_mousefun("final angle", "", "cancel", "", "", ""); } else { set_mousefun("final point", "", "cancel", "", "", ""); } draw_mousefun_canvas(); canvas_leftbut_proc = create_arcobject; } if (!center_marked) elastic_line(); cur_x = x; cur_y = y; if (!center_marked) elastic_line(); point[num_point].x = fix_x = x; point[num_point++].y = fix_y = y; if (!center_marked) elastic_line(); } static void create_arcobject(int lx, int ly) { F_arc *arc; int x, y; float xx, yy; /* erase last line segment */ if (!center_marked) elastic_line(); else /* restore shownums */ appres.shownums = save_shownums; /* erase any length info if appres.showlengths is true */ erase_lengths(); point[num_point].x = lx; point[num_point++].y = ly; x = point[0].x; y = point[0].y; if (center_marked) { double theta, r; /* erase the center marker */ center_marker(center_point.x, center_point.y); /* free the temporary arc */ free_arc(&tmparc); /* recompute the second and last points to put them on the arc */ r = sqrt((double)(point[0].x - center_point.x) * (point[0].x - center_point.x) + (double)(point[0].y - center_point.y) * (point[0].y - center_point.y)); theta = compute_angle((double)(point[1].x - center_point.x), (double)(point[1].y - center_point.y)); point[1].x = center_point.x + r * cos(theta); point[1].y = center_point.y + r * sin(theta); theta = compute_angle((double)(point[2].x - center_point.x), (double)(point[2].y - center_point.y)); point[2].x = center_point.x + r * cos(theta); point[2].y = center_point.y + r * sin(theta); } else { /* erase previous line segment */ pw_vector(canvas_win, x, y, point[1].x, point[1].y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); } if (!compute_arccenter(point[0], point[1], point[2], &xx, &yy)) { put_msg("Invalid ARC geometry"); beep(); arc_drawing_selected(); draw_mousefun_canvas(); return; } if ((arc = create_arc()) == NULL) { arc_drawing_selected(); draw_mousefun_canvas(); return; } arc->type = cur_arctype; arc->style = cur_linestyle; arc->thickness = cur_linewidth; /* scale dash length according to linethickness */ arc->style_val = cur_styleval * (cur_linewidth + 1) / 2; arc->pen_style = -1; arc->fill_style = cur_fillstyle; arc->pen_color = cur_pencolor; arc->fill_color = cur_fillcolor; arc->cap_style = cur_capstyle; arc->depth = cur_depth; arc->direction = compute_direction(point[0], point[1], point[2]); /* only allow arrowheads for open arc */ if (arc->type == T_PIE_WEDGE_ARC) { arc->for_arrow = NULL; arc->back_arrow = NULL; } else { if (autoforwardarrow_mode) arc->for_arrow = forward_arrow(); else arc->for_arrow = NULL; if (autobackwardarrow_mode) arc->back_arrow = backward_arrow(); else arc->back_arrow = NULL; } arc->center.x = xx; arc->center.y = yy; arc->point[0].x = point[0].x; arc->point[0].y = point[0].y; arc->point[1].x = point[1].x; arc->point[1].y = point[1].y; arc->point[2].x = point[2].x; arc->point[2].y = point[2].y; arc->next = NULL; add_arc(arc); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_arc(arc); arc_drawing_selected(); draw_mousefun_canvas(); } static void resizing_arc(int x, int y) { F_point p3; double alpha; elastic_arc(); cur_x = x; cur_y = y; p3.x = x; p3.y = y; if (num_point == 0) length_msg(MSG_RADIUS); else { compute_3p_angle((F_point *)&tpoint[0], (F_point *)¢er_point, &p3, &alpha); put_msg("1st angle = %.2f degrees", (float) alpha*180.0/M_PI); } elastic_arc(); } void elastic_arc(void) { register int i; register double r, theta1, theta2; tpoint[2].x = cur_x; tpoint[2].y = cur_y; /* if user hasn't entered second point yet, make it average of endpoints */ if (num_point <= 1) { tpoint[1].x = (tpoint[0].x + cur_x)/2; tpoint[1].y = (tpoint[0].y + cur_y)/2; } if (tpoint[0].x == tpoint[2].x && tpoint[0].y == tpoint[2].y) return; r = sqrt((double)(tpoint[0].x - center_point.x) * (tpoint[0].x - center_point.x) + (double)(tpoint[0].y - center_point.y) * (tpoint[0].y - center_point.y)); theta1 = compute_angle((double)(tpoint[1].x - center_point.x), (double)(tpoint[1].y - center_point.y)); tpoint[1].x = center_point.x + r * cos(theta1); tpoint[1].y = center_point.y + r * sin(theta1); theta2 = compute_angle((double)(tpoint[2].x - center_point.x), (double)(tpoint[2].y - center_point.y)); tpoint[2].x = center_point.x + r * cos(theta2); tpoint[2].y = center_point.y + r * sin(theta2); for (i=0; i<3; i++) tmparc->point[i] = tpoint[i]; tmparc->direction = compute_direction(tpoint[0], tpoint[1], tpoint[2]); draw_arc(tmparc, INV_PAINT); } xfig.3.2.5c/d_arcbox.c0000700002656300244210000000715311641414046015307 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_cursor.h" #include "w_msgpanel.h" #include "w_mousefun.h" #include "f_util.h" #include "u_redraw.h" /*************************** local procedures *********************/ static void create_arc_boxobject(int x, int y); static void cancel_arc_boxobject(void); static void init_arc_box_drawing(int x, int y); void arcbox_drawing_selected(void) { set_mousefun("corner point", "", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_arc_box_drawing; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_arc_box_drawing(int x, int y) { cur_x = fix_x = x; cur_y = fix_y = y; set_mousefun("final point", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_box; canvas_leftbut_proc = create_arc_boxobject; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_arc_boxobject; elastic_box(fix_x, fix_y, cur_x, cur_y); set_cursor(null_cursor); set_action_on(); } static void cancel_arc_boxobject(void) { elastic_box(fix_x, fix_y, cur_x, cur_y); arcbox_drawing_selected(); draw_mousefun_canvas(); } static void create_arc_boxobject(int x, int y) { F_line *box; F_point *point; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); if (fix_x == x || fix_y == y) { beep(); put_msg("Arc box must have area"); arcbox_drawing_selected(); draw_mousefun_canvas(); return; } if ((point = create_point()) == NULL) return; point->x = x; point->y = y; point->next = NULL; if ((box = create_line()) == NULL) { free((char *) point); return; } box->type = T_ARCBOX; box->style = cur_linestyle; box->thickness = cur_linewidth; box->pen_color = cur_pencolor; box->fill_color = cur_fillcolor; box->depth = cur_depth; box->pen_style = -1; box->join_style = cur_joinstyle; box->cap_style = cur_capstyle; box->fill_style = cur_fillstyle; /* multiply dash length by line thickness */ box->style_val = cur_styleval * (cur_linewidth + 1) / 2; box->radius = cur_boxradius;/* corner radius */ box->points = point; append_point(x, fix_y, &point); append_point(fix_x, fix_y, &point); append_point(fix_x, y, &point); append_point(x, y, &point); add_line(box); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_line(box); arcbox_drawing_selected(); draw_mousefun_canvas(); } xfig.3.2.5c/d_box.c0000700002656300244210000000705011641414046014615 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_box.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "f_util.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_msgpanel.h" /*************************** local declarations *********************/ static void create_boxobject(int x, int y); static void cancel_box(void); void box_drawing_selected(void) { set_mousefun("corner point", "", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_box_drawing; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } void init_box_drawing(int x, int y) { cur_x = fix_x = x; cur_y = fix_y = y; set_mousefun("final point", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_box; canvas_leftbut_proc = create_boxobject; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_box; elastic_box(fix_x, fix_y, cur_x, cur_y); set_cursor(null_cursor); set_action_on(); } static void cancel_box(void) { elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); box_drawing_selected(); draw_mousefun_canvas(); } static void create_boxobject(int x, int y) { F_line *box; F_point *point; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); if (fix_x == x || fix_y == y) { beep(); put_msg("Box must have area"); box_drawing_selected(); draw_mousefun_canvas(); return; } if ((point = create_point()) == NULL) return; point->x = fix_x; point->y = fix_y; point->next = NULL; if ((box = create_line()) == NULL) { free((char *) point); return; } box->type = T_BOX; box->style = cur_linestyle; box->thickness = cur_linewidth; box->pen_color = cur_pencolor; box->fill_color = cur_fillcolor; box->depth = cur_depth; box->pen_style = -1; box->join_style = cur_joinstyle; box->cap_style = cur_capstyle; box->fill_style = cur_fillstyle; /* scale dash length by line thickness */ box->style_val = cur_styleval * (cur_linewidth + 1) / 2; box->points = point; append_point(x, fix_y, &point); append_point(x, y, &point); append_point(fix_x, y, &point); append_point(fix_x, fix_y, &point); add_line(box); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_line(box); box_drawing_selected(); draw_mousefun_canvas(); } xfig.3.2.5c/d_ellipse.c0000700002656300244210000002340311641414046015462 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" /************************* local procedures ********************/ static void init_ellipsebyradius_drawing(int x, int y); static void init_ellipsebydiameter_drawing(int x, int y); static void init_circlebyradius_drawing(int x, int y); static void init_circlebydiameter_drawing(int x, int y); static void create_ellipsebydia(int x, int y); static void create_ellipsebyrad(int x, int y); static void create_circlebyrad(int x, int y); static void create_circlebydia(int x, int y); static void cancel_ellipsebydia(void); static void cancel_ellipsebyrad(void); static void cancel_circlebyrad(void); static void cancel_circlebydia(void); void circle_ellipse_byradius_drawing_selected(void) { canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_circlebyradius_drawing; canvas_middlebut_proc = init_ellipsebyradius_drawing; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); set_mousefun("Circle center", "Ellipse center", "", "", "", ""); reset_action_on(); } static void init_ellipsebyradius_drawing(int x, int y) { cur_mode = F_ELLIPSE_BY_RAD; cur_x = fix_x = x; cur_y = fix_y = y; cur_angle = cur_elltextangle/180.0*M_PI; center_marker(fix_x, fix_y); set_mousefun("Ellipse corner", "Ellipse corner", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_ebr; canvas_leftbut_proc = create_ellipsebyrad; canvas_middlebut_proc = create_ellipsebyrad; canvas_rightbut_proc = cancel_ellipsebyrad; set_cursor(null_cursor); elastic_ebr(); set_action_on(); } static void cancel_ellipsebyrad(void) { elastic_ebr(); center_marker(fix_x, fix_y); circle_ellipse_byradius_drawing_selected(); draw_mousefun_canvas(); } static void create_ellipsebyrad(int x, int y) { F_ellipse *ellipse; elastic_ebr(); center_marker(fix_x, fix_y); if ((ellipse = create_ellipse()) == NULL) return; ellipse->type = T_ELLIPSE_BY_RAD; ellipse->style = cur_linestyle; ellipse->thickness = cur_linewidth; ellipse->style_val = cur_styleval * (cur_linewidth + 1) / 2; ellipse->angle = cur_elltextangle/180.0*M_PI; /* convert to radians */ ellipse->pen_color = cur_pencolor; ellipse->fill_color = cur_fillcolor; ellipse->depth = cur_depth; ellipse->pen_style = -1; ellipse->fill_style = cur_fillstyle; ellipse->direction = 1; ellipse->center.x = fix_x; ellipse->center.y = fix_y; ellipse->radiuses.x = abs(x - fix_x); ellipse->radiuses.y = abs(y - fix_y); ellipse->start.x = fix_x; ellipse->start.y = fix_y; ellipse->end.x = x; ellipse->end.y = y; ellipse->next = NULL; add_ellipse(ellipse); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_ellipse(ellipse); circle_ellipse_byradius_drawing_selected(); draw_mousefun_canvas(); } void circle_ellipse_bydiameter_drawing_selected(void) { set_mousefun("Circle diameter", "Ellipse corner", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_circlebydiameter_drawing; canvas_middlebut_proc = init_ellipsebydiameter_drawing; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_ellipsebydiameter_drawing(int x, int y) { cur_mode = F_ELLIPSE_BY_DIA; cur_x = fix_x = x; cur_y = fix_y = y; cur_angle = cur_elltextangle/180.0*M_PI; center_marker(fix_x, fix_y); set_mousefun("final corner", "final corner", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_ebd; canvas_leftbut_proc = create_ellipsebydia; canvas_middlebut_proc = create_ellipsebydia; canvas_rightbut_proc = cancel_ellipsebydia; set_cursor(null_cursor); elastic_ebd(); set_action_on(); } static void cancel_ellipsebydia(void) { elastic_ebd(); center_marker(fix_x, fix_y); circle_ellipse_bydiameter_drawing_selected(); draw_mousefun_canvas(); } static void create_ellipsebydia(int x, int y) { F_ellipse *ellipse; elastic_ebd(); center_marker(fix_x, fix_y); if ((ellipse = create_ellipse()) == NULL) return; ellipse->type = T_ELLIPSE_BY_DIA; ellipse->style = cur_linestyle; ellipse->thickness = cur_linewidth; ellipse->style_val = cur_styleval * (cur_linewidth + 1) / 2; ellipse->angle = cur_elltextangle/180.0*M_PI; /* convert to radians */ ellipse->pen_color = cur_pencolor; ellipse->fill_color = cur_fillcolor; ellipse->depth = cur_depth; ellipse->pen_style = -1; ellipse->fill_style = cur_fillstyle; ellipse->direction = 1; ellipse->center.x = (fix_x + x) / 2; ellipse->center.y = (fix_y + y) / 2; ellipse->radiuses.x = abs(ellipse->center.x - fix_x); ellipse->radiuses.y = abs(ellipse->center.y - fix_y); ellipse->start.x = fix_x; ellipse->start.y = fix_y; ellipse->end.x = x; ellipse->end.y = y; ellipse->next = NULL; add_ellipse(ellipse); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_ellipse(ellipse); circle_ellipse_bydiameter_drawing_selected(); draw_mousefun_canvas(); } /*************************** circle section ************************/ static void init_circlebyradius_drawing(int x, int y) { cur_mode = F_CIRCLE_BY_RAD; cur_x = fix_x = x; cur_y = fix_y = y; center_marker(fix_x, fix_y); set_mousefun("set radius", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_cbr; canvas_leftbut_proc = create_circlebyrad; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_circlebyrad; set_cursor(null_cursor); elastic_cbr(); set_action_on(); } static void cancel_circlebyrad(void) { elastic_cbr(); center_marker(fix_x, fix_y); circle_ellipse_byradius_drawing_selected(); draw_mousefun_canvas(); } static void create_circlebyrad(int x, int y) { F_ellipse *c; double rx, ry; elastic_cbr(); center_marker(fix_x, fix_y); if ((c = create_ellipse()) == NULL) return; c->type = T_CIRCLE_BY_RAD; c->style = cur_linestyle; c->thickness = cur_linewidth; c->style_val = cur_styleval * (cur_linewidth + 1) / 2; c->angle = 0.0; c->pen_color = cur_pencolor; c->fill_color = cur_fillcolor; c->depth = cur_depth; c->pen_style = -1; c->fill_style = cur_fillstyle; c->direction = 1; c->center.x = fix_x; c->center.y = fix_y; rx = fix_x - x; ry = fix_y - y; c->radiuses.x = c->radiuses.y = round(sqrt(rx * rx + ry * ry)); c->start.x = fix_x; c->start.y = fix_y; c->end.x = x; c->end.y = y; c->next = NULL; add_ellipse(c); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_ellipse(c); circle_ellipse_byradius_drawing_selected(); draw_mousefun_canvas(); } static void init_circlebydiameter_drawing(int x, int y) { cur_mode = F_CIRCLE_BY_DIA; cur_x = fix_x = x; cur_y = fix_y = y; center_marker(fix_x, fix_y); set_mousefun("final point", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_cbd; canvas_leftbut_proc = create_circlebydia; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_circlebydia; set_cursor(null_cursor); elastic_cbd(); set_action_on(); } static void cancel_circlebydia(void) { elastic_cbd(); center_marker(fix_x, fix_y); circle_ellipse_bydiameter_drawing_selected(); draw_mousefun_canvas(); } static void create_circlebydia(int x, int y) { F_ellipse *c; double rx, ry; elastic_cbd(); center_marker(fix_x, fix_y); if ((c = create_ellipse()) == NULL) return; c->type = T_CIRCLE_BY_DIA; c->style = cur_linestyle; c->thickness = cur_linewidth; c->style_val = cur_styleval * (cur_linewidth + 1) / 2; c->angle = 0.0; c->pen_color = cur_pencolor; c->fill_color = cur_fillcolor; c->depth = cur_depth; c->pen_style = -1; c->fill_style = cur_fillstyle; c->direction = 1; c->center.x = round((fix_x + x) / 2); c->center.y = round((fix_y + y) / 2); rx = x - c->center.x; ry = y - c->center.y; c->radiuses.x = c->radiuses.y = round(sqrt(rx * rx + ry * ry)); c->start.x = fix_x; c->start.y = fix_y; c->end.x = x; c->end.y = y; c->next = NULL; add_ellipse(c); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_ellipse(c); circle_ellipse_bydiameter_drawing_selected(); draw_mousefun_canvas(); } xfig.3.2.5c/d_line.c0000700002656300244210000002146311641414046014760 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_line.h" #include "e_edit.h" #include "e_scale.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_setup.h" #include "u_free.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_drawprim.h" #include "w_msgpanel.h" Boolean freehand_line; Boolean dimension_line; /* LOCAL */ static void init_line_drawing(int x, int y, int shift); static void init_line_freehand_drawing(int x, int y); /********************** polyline and polygon section **********************/ void line_drawing_selected(void) { canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_line_drawing; canvas_middlebut_proc = init_line_freehand_drawing; set_cursor(crosshair_cursor); reset_action_on(); if (cur_mode == F_POLYGON) { set_mousefun("first point", "freehand", "", "", "", ""); min_num_points = 3; canvas_rightbut_proc = null_proc; } else { set_mousefun("first point", "freehand", "single point", "dimension line", "", ""); min_num_points = 1; num_point = 0; fix_x = fix_y = -1; canvas_rightbut_proc = create_lineobject; } } static void init_line_freehand_drawing(int x, int y) { freehand_line = True; /* not a dimension line */ dimension_line = False; init_trace_drawing(x, y); } static void init_line_drawing(int x, int y, int shift) { freehand_line = False; /* if the user pressed shift then make a dimension line */ dimension_line = shift; if (shift) { min_num_points = 2; } canvas_middlebut_proc = null_proc; init_trace_drawing(x, y); } void cancel_line_drawing(void) { elastic_line(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); cur_x = fix_x; cur_y = fix_y; if (cur_point != first_point) elastic_moveline(first_point); /* erase control vector */ free_points(first_point); first_point = NULL; return_proc(); draw_mousefun_canvas(); } void init_trace_drawing(int x, int y) { if ((first_point = create_point()) == NULL) return; cur_point = first_point; set_action_on(); cur_point->x = fix_x = cur_x = x; cur_point->y = fix_y = cur_y = y; cur_point->next = NULL; canvas_leftbut_proc = get_intermediatepoint; if (freehand_line) { canvas_locmove_proc = freehand_get_intermediatepoint; } else { /* only two points in a dimension line */ if (dimension_line) canvas_leftbut_proc = create_lineobject; if (latexline_mode || latexarrow_mode) { canvas_locmove_proc = latex_line; } else if (manhattan_mode || mountain_mode) { canvas_locmove_proc = constrainedangle_line; } else { canvas_locmove_proc = unconstrained_line; } } canvas_middlebut_save = create_lineobject; canvas_rightbut_proc = cancel_line_drawing; return_proc = line_drawing_selected; num_point = 1; set_mousefun("next point", "", "cancel", "del point", "", ""); if (dimension_line) { set_mousefun("final point", "", "cancel", "del point", "", ""); canvas_middlebut_proc = null_proc; } else if (num_point >= min_num_points - 1) { set_mousefun("next point", "final point", "cancel", "del point", "", ""); canvas_middlebut_proc = canvas_middlebut_save; } draw_mousefun_canvas(); set_cursor(null_cursor); elastic_line(); } /* we have this extra proc to call get_intermediatepoint() because we come here from a canvas_locmove_proc which doesn't have a shift value (its not a keypress event) */ void freehand_get_intermediatepoint(int x, int y) { /* if shift key is pressed user wants to delete points with left button press, return now */ if (shift) { unconstrained_line(x,y); return; } get_intermediatepoint(x, y, 0); } void get_intermediatepoint(int x, int y, int shift) { /* in freehand mode call unconstrained_line explicitely to move the mouse */ if (freehand_line) { unconstrained_line(x,y); /* pointer must move by at least freehand_resolution in any direction */ if (abs(fix_x-cur_x) < appres.freehand_resolution && (abs(fix_y-cur_y) < appres.freehand_resolution)) return; } else { /* otherwise call the (possibly) constrained movement procedure */ (*canvas_locmove_proc) (x, y); } /* don't allow coincident consecutive points */ if (fix_x == cur_x && fix_y == cur_y) return; num_point++; fix_x = cur_x; fix_y = cur_y; elastic_line(); if (cur_cursor != null_cursor) { set_cursor(null_cursor); } if (shift && num_point > 2) { F_point *p; num_point -= 2; p = prev_point(first_point, cur_point); p->next = NULL; /* erase the newest segment */ pw_vector(canvas_win, fix_x, fix_y, cur_point->x, cur_point->y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); /* and segment drawn before */ pw_vector(canvas_win, p->x, p->y, cur_point->x, cur_point->y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); /* and draw new elastic segment */ pw_vector(canvas_win, fix_x, fix_y, p->x, p->y, PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); fix_x = p->x; fix_y = p->y; free_points(cur_point); cur_point = p; } else { append_point(fix_x, fix_y, &cur_point); } if (num_point == min_num_points - 1) { if (freehand_line) set_mousefun("", "final point", "cancel", "del point", "", ""); else set_mousefun("next point", "final point", "cancel", "del point", "", ""); draw_mousefun_canvas(); canvas_middlebut_proc = canvas_middlebut_save; } } /* come here upon pressing middle button (last point of lineobject) */ /* or the second point of a dimension line */ void create_lineobject(int x, int y) { F_line *line; F_compound *comp; int dot; if (num_point == 0) { if ((first_point = create_point()) == NULL) { line_drawing_selected(); draw_mousefun_canvas(); return; } cur_point = first_point; first_point->x = fix_x = cur_x = x; first_point->y = fix_y = cur_y = y; first_point->next = NULL; num_point++; } else if (x != fix_x || y != fix_y) { get_intermediatepoint(x, y, 0); } /* dimension line must have 2 different points */ if (dimension_line && first_point->x == x && first_point->y == y) return; dot = (num_point == 1); elastic_line(); /* erase any length info if appres.showlengths is true */ erase_lengths(); if ((line = create_line()) == NULL) { line_drawing_selected(); draw_mousefun_canvas(); return; } line->type = T_POLYLINE; line->style = cur_linestyle; line->thickness = cur_linewidth; line->pen_color = cur_pencolor; line->fill_color = cur_fillcolor; line->depth = cur_depth; line->pen_style = -1; line->join_style = cur_joinstyle; line->cap_style = cur_capstyle; line->fill_style = cur_fillstyle; line->style_val = cur_styleval * (cur_linewidth + 1) / 2; line->points = first_point; if (!dot) { if (cur_mode == F_POLYGON) { /* close off polygon */ line->type = T_POLYGON; num_point++; append_point(first_point->x, first_point->y, &cur_point); elastic_line(); fix_x = first_point->x; fix_y = first_point->y; elastic_line(); /* fix last elastic line */ } else { /* polyline; draw any arrows */ if (autoforwardarrow_mode && !dimension_line) line->for_arrow = forward_arrow(); /* arrow will be drawn in draw_line below */ if (autobackwardarrow_mode && !dimension_line) line->back_arrow = backward_arrow(); /* arrow will be drawn in draw_line below */ } cur_x = fix_x; cur_y = fix_y; elastic_moveline(first_point); /* erase temporary outline */ } if (dimension_line) { comp = create_dimension_line(line, True); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_compound(comp); } else { add_line(line); reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_line(line); } line_drawing_selected(); if (!edit_remember_dimline_mode) draw_mousefun_canvas(); } xfig.3.2.5c/d_picobj.c0000700002656300244210000000703211641414046015273 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_line.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "d_box.h" #include "e_edit.h" #include "u_redraw.h" #include "w_cursor.h" /*************************** local declarations *********************/ static void init_picobj_drawing(int x, int y); static void create_picobj(int x, int y); static void cancel_picobj(void); void picobj_drawing_selected(void) { set_mousefun("corner point", "", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_picobj_drawing; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_picobj_drawing(int x, int y) { init_box_drawing(x, y); canvas_leftbut_proc = create_picobj; canvas_rightbut_proc = cancel_picobj; } static void cancel_picobj(void) { elastic_box(fix_x, fix_y, cur_x, cur_y); picobj_drawing_selected(); draw_mousefun_canvas(); } static void create_picobj(int x, int y) { F_line *box; F_point *point; /* erase last lengths if appres.showlengths is true */ erase_lengths(); elastic_box(fix_x, fix_y, cur_x, cur_y); canvas_locmove_proc = null_proc; if ((point = create_point()) == NULL) return; point->x = fix_x; point->y = fix_y; point->next = NULL; if ((box = create_line()) == NULL) { free((char *) point); return; } box->type = T_PICTURE; box->style = SOLID_LINE; box->thickness = 1; box->pen_color = cur_pencolor; box->fill_color = DEFAULT; box->depth = cur_depth; box->pen_style = -1; box->join_style = 0; /* not used */ box->cap_style = 0; /* not used */ box->fill_style = UNFILLED; box->style_val = 0; if ((box->pic = create_pic()) == NULL) { free((char *) point); free((char *) box); return; } box->pic->new = True; /* set new flag to delete if it user cancels edit operation */ box->pic->pic_cache = NULL; box->pic->flipped = 0; box->pic->hw_ratio = 0.0; box->pic->pixmap = 0; box->pic->pix_width = 0; box->pic->pix_height = 0; box->pic->pix_rotation = 0; box->pic->pix_flipped = 0; box->points = point; append_point(fix_x, y, &point); append_point(x, y, &point); append_point(x, fix_y, &point); append_point(fix_x, fix_y, &point); add_line(box); /* draw it and anything on top of it */ redisplay_line(box); put_msg("Please enter name of Picture Object file in EDIT window"); edit_item(box, O_POLYLINE, 0, 0); picobj_drawing_selected(); draw_mousefun_canvas(); } xfig.3.2.5c/d_regpoly.c0000700002656300244210000000764311641414046015516 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_create.h" #include "u_elastic.h" #include "u_geom.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_msgpanel.h" /*************************** local declarations *********************/ static void init_regpoly_drawing(int x, int y); static void create_regpoly(int x, int y); static void cancel_regpoly(void); void regpoly_drawing_selected(void) { set_mousefun("center point", "", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_regpoly_drawing; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_regpoly_drawing(int x, int y) { cur_x = fix_x = x; cur_y = fix_y = y; work_numsides = cur_numsides; set_mousefun("final point", "", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_locmove_proc = resizing_poly; canvas_leftbut_proc = create_regpoly; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_regpoly; elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides); set_cursor(null_cursor); set_action_on(); } static void cancel_regpoly(void) { elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides); /* erase any length info if appres.showlengths is true */ erase_lengths(); regpoly_drawing_selected(); draw_mousefun_canvas(); } static void create_regpoly(int x, int y) { register float angle; register int nx, ny, i; double dx, dy; double init_angle, mag; F_line *poly; F_point *point; elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides); /* erase any length info if appres.showlengths is true */ erase_lengths(); if (fix_x == x && fix_y == y) return; /* 0 size */ if ((point = create_point()) == NULL) return; point->x = x; point->y = y; point->next = NULL; if ((poly = create_line()) == NULL) { free((char *) point); return; } poly->type = T_POLYGON; poly->style = cur_linestyle; poly->thickness = cur_linewidth; poly->pen_color = cur_pencolor; poly->fill_color = cur_fillcolor; poly->depth = cur_depth; poly->pen_style = -1; poly->join_style = cur_joinstyle; poly->cap_style = cur_capstyle; poly->fill_style = cur_fillstyle; /* scale dash length by line thickness */ poly->style_val = cur_styleval * (cur_linewidth + 1) / 2; poly->radius = 0; poly->points = point; dx = x - fix_x; dy = y - fix_y; mag = sqrt(dx * dx + dy * dy); init_angle = compute_angle(dx, dy); /* now append cur_numsides points */ for (i = 1; i < cur_numsides; i++) { angle = init_angle - M_2PI * (double) i / (double) cur_numsides; if (angle < 0) angle += M_2PI; nx = fix_x + round(mag * cos(angle)); ny = fix_y + round(mag * sin(angle)); append_point(nx, ny, &point); } append_point(x, y, &point); add_line(poly); /* draw it and anything on top of it */ redisplay_line(poly); regpoly_drawing_selected(); draw_mousefun_canvas(); } xfig.3.2.5c/d_spline.c0000700002656300244210000001232311641414046015316 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_line.h" #include "d_spline.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "u_draw.h" #include "w_canvas.h" #include "w_mousefun.h" #include "f_util.h" #include "u_free.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_msgpanel.h" /*************************** local declarations *********************/ static void init_spline_drawing(int x, int y); static void create_splineobject(int x, int y); static void init_spline_freehand_drawing(int x, int y); static void init_spline_drawing2(int x, int y); void spline_drawing_selected(void) { set_mousefun("first point", "freehand", "", "", "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_leftbut_proc = init_spline_drawing; canvas_middlebut_proc = init_spline_freehand_drawing; canvas_rightbut_proc = null_proc; set_cursor(crosshair_cursor); reset_action_on(); } static void init_spline_freehand_drawing(int x, int y) { freehand_line = True; init_spline_drawing2(x, y); } static void init_spline_drawing(int x, int y) { freehand_line = False; init_spline_drawing2(x, y); } static void init_spline_drawing2(int x, int y) { if ((cur_mode == F_APPROX_SPLINE) || (cur_mode == F_INTERP_SPLINE)) { min_num_points = OPEN_SPLINE_MIN_NUM_POINTS; init_trace_drawing(x, y); canvas_middlebut_proc = create_splineobject; } else { min_num_points = CLOSED_SPLINE_MIN_NUM_POINTS; init_trace_drawing(x, y); canvas_middlebut_save = create_splineobject; canvas_middlebut_proc = null_proc; } return_proc = spline_drawing_selected; } static void create_splineobject(int x, int y) { F_spline *spline; if (x != fix_x || y != fix_y) get_intermediatepoint(x, y, 0); if (num_point < min_num_points) { /* too few points */ put_msg("Not enough points for spline"); beep(); return; } elastic_line(); /* erase any length info if appres.showlengths is true */ erase_lengths(); if ((spline = create_spline()) == NULL) { if (num_point == 1) { free((char *) cur_point); cur_point = NULL; } free((char *) first_point); first_point = NULL; return; } spline->style = cur_linestyle; spline->thickness = cur_linewidth; spline->style_val = cur_styleval * (cur_linewidth + 1) / 2; spline->pen_color = cur_pencolor; spline->fill_color = cur_fillcolor; spline->cap_style = cur_capstyle; spline->depth = cur_depth; spline->pen_style = -1; spline->fill_style = cur_fillstyle; /* * The current fill style is saved in all spline objects (but support for * filling may not be available in all fig2dev languages). */ spline->points = first_point; spline->sfactors = NULL; spline->next = NULL; /* initialize for no arrows - changed below if necessary */ spline->for_arrow = NULL; spline->back_arrow = NULL; cur_x = cur_y = fix_x = fix_y = 0; /* used in elastic_moveline */ elastic_moveline(spline->points); /* erase control vector */ if (cur_mode == F_CLOSED_APPROX_SPLINE) { spline->type = T_CLOSED_APPROX; } else if (cur_mode == F_CLOSED_INTERP_SPLINE) { spline->type = T_CLOSED_INTERP; } else { /* It must be F_SPLINE */ if (autoforwardarrow_mode) spline->for_arrow = forward_arrow(); if (autobackwardarrow_mode) spline->back_arrow = backward_arrow(); spline->type = (cur_mode == F_APPROX_SPLINE) ? T_OPEN_APPROX : T_OPEN_INTERP; } if (!make_sfactors(spline)) { free_spline(&spline); } else { add_spline(spline); } reset_action_on(); /* this signals redisplay_curobj() not to refresh */ /* draw it and anything on top of it */ redisplay_spline(spline); spline_drawing_selected(); draw_mousefun_canvas(); } int make_sfactors(F_spline *spl) { F_point *p = spl->points; F_sfactor *sp, *cur_sp; int type_s = approx_spline(spl) ? S_SPLINE_APPROX : S_SPLINE_INTERP; spl->sfactors = NULL; if ((sp = create_sfactor()) == NULL) return 0; spl->sfactors = cur_sp = sp; sp->s = closed_spline(spl) ? type_s : S_SPLINE_ANGULAR; p = p->next; for(; p!=NULL ; p=p->next) { if ((sp = create_sfactor()) == NULL) return 0; cur_sp->next = sp; sp->s = type_s; cur_sp = cur_sp->next; } cur_sp->s = spl->sfactors->s; cur_sp->next = NULL; return 1; } xfig.3.2.5c/d_subspline.c0000700002656300244210000001107611641414046016034 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1992 by James Tough * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "d_subspline.h" #include "u_create.h" #include "u_draw.h" #include "u_list.h" #include "u_free.h" /*************************** local declarations *********************/ #define MIN_NUMPOINTS_FOR_QUICK_REDRAW 2 static INLINE Boolean add_subspline_point(F_spline *spline, F_point **last_point, F_sfactor **last_sfactor, F_point *point); static F_spline *extract_subspline(F_spline *spline, F_point *point); F_spline * create_subspline(int *num_pts, F_spline *spline, F_point *point, F_sfactor **sfactor, F_sfactor **sub_sfactor) { F_spline *sub_spline; *sub_sfactor = NULL; *num_pts = num_points(spline->points); *sfactor = search_sfactor(spline, point); if (*num_pts > MIN_NUMPOINTS_FOR_QUICK_REDRAW) { sub_spline = extract_subspline(spline, point); if (sub_spline != NULL) *sub_sfactor = search_sfactor(sub_spline, search_spline_point(sub_spline, point->x, point->y)); } else { sub_spline = spline; *sub_sfactor = *sfactor; } return sub_spline; } void free_subspline(int num_pts, F_spline **spline) { if (num_pts > MIN_NUMPOINTS_FOR_QUICK_REDRAW) free_spline(spline); } void draw_subspline(int num_pts, F_spline *spline, int op) { if (num_pts > MIN_NUMPOINTS_FOR_QUICK_REDRAW) quick_draw_spline(spline, op); else draw_spline(spline, op); } static INLINE Boolean add_subspline_point(F_spline *spline, F_point **last_point, F_sfactor **last_sfactor, F_point *point) { Boolean point_ok, sfactor_ok; point_ok = insert_point(point->x, point->y, *last_point); sfactor_ok = append_sfactor(search_sfactor(spline, point)->s, *last_sfactor); if (!(point_ok && sfactor_ok)) return False; *last_point = (*last_point)->next; *last_sfactor = (*last_sfactor)->next; return True; } static F_spline * extract_subspline(F_spline *spline, F_point *point) { F_spline *subspline; F_point *cursor, *last_point; F_point *prev1, *prev2; F_sfactor *sfactor_cursor, *last_sfactor; int i = 0; if ((subspline = create_spline()) == NULL) return NULL; *subspline = *spline; subspline->next = NULL; subspline->points = NULL; subspline->sfactors = NULL; subspline->for_arrow = NULL; subspline->back_arrow = NULL; subspline->comments = NULL; prev1 = prev2 = spline->points; for (cursor=spline->points ; cursor!=point ; cursor = cursor->next) { prev2 = prev1; prev1 = cursor; } if ((closed_spline(spline)) && (prev2==prev1)) /* use points list as circular */ { for (cursor = point ; cursor->next->next != NULL ; cursor=cursor->next) ; if (prev1 == point) /* edition of the first point of the spline */ { prev2 = cursor; prev1 = cursor->next; } else if (prev2 == prev1) /* second point */ { prev2 = cursor->next; } cursor = point; /* reset cursor as we found it */ } sfactor_cursor = search_sfactor(spline, prev2); if (!first_spline_point(prev2->x, prev2->y, sfactor_cursor->s, subspline)) { free_spline(&subspline); return NULL; } last_point = subspline->points; last_sfactor = subspline->sfactors; if (!(add_subspline_point(spline, &last_point, &last_sfactor, prev1) && add_subspline_point(spline, &last_point, &last_sfactor, cursor))) { free_spline(&subspline); return NULL; } for (i=1; i < 3; i++) { if (cursor->next != NULL) cursor = cursor->next; else if (closed_spline(spline)) cursor = spline->points; if (!add_subspline_point(spline, &last_point, &last_sfactor, cursor)) { free_spline(&subspline); subspline = NULL; break; } } return (subspline); } xfig.3.2.5c/d_text.c0000700002656300244210000017173611641414046015026 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "f_util.h" #include "d_text.h" #include "u_create.h" #include "u_fonts.h" #include "u_list.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "w_zoom.h" #include "u_draw.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cmdpanel.h" #include "w_cursor.h" #include /* waitpid() */ #include #include #include #include #ifdef SEL_TEXT Boolean text_selection_active; #endif /* SEL_TEXT */ /* EXPORTS */ int work_font; /* LOCALS */ #define CTRL_A '\001' /* move to beginning of text */ #define CTRL_B '\002' /* move back one char */ #define CTRL_D '\004' /* delete right of cursor */ #define CTRL_E '\005' /* move to end of text */ #define CTRL_F '\006' /* move forward one char */ #define CTRL_H '\010' /* backspace */ #define CTRL_K '\013' /* kill to end of text */ #ifdef SEL_TEXT #define CTRL_W '\027' /* delete selected text */ #endif /* SEL_TEXT */ #define CTRL_HAT '\036' /* start superscript or end subscript */ #define CTRL_UNDERSCORE '\037' /* start subscript or end superscript */ #define MAX_SUPSUB 4 /* max number of nested super/subscripts */ #define CSUB_FRAC 0.75 /* fraction of current char size for super/subscript */ #define PSUB_FRAC (1.0-CSUB_FRAC) /* amount of up/down shift */ #define NL '\n' #define ESC '\033' #define CR '\r' #define CTRL_X 24 #define SP ' ' #define DEL 127 #define BUF_SIZE 400 char prefix[BUF_SIZE], /* part of string left of mouse click */ suffix[BUF_SIZE]; /* part to right of click */ int leng_prefix, leng_suffix; static int char_ht; static int base_x, base_y; static int supersub; /* < 0 = currently subscripted, > 0 = superscripted */ static int heights[MAX_SUPSUB]; /* keep prev char heights when super/subscripting */ static int orig_x, orig_y; /* to position next line */ static int orig_ht; /* to advance to next line */ static float work_float_fontsize; /* keep current font size in floating for roundoff */ static XFontStruct *canvas_zoomed_font; static Boolean is_newline; static int work_fontsize, work_flags, work_psflag, work_textjust, work_depth; static Color work_textcolor; static XFontStruct *work_fontstruct; static float work_angle; /* in RADIANS */ static double sin_t, cos_t; /* sin(work_angle) and cos(work_angle) */ static void finish_n_start(int x, int y); static void init_text_input(int x, int y), cancel_text_input(void); static F_text *new_text(void); static void new_text_line(void); static void overlay_text_input(int x, int y); static void create_textobject(void); static void draw_cursor(int x, int y); static void move_cur(int dir, unsigned char c, float div); static void move_text(int dir, unsigned char c, float div); static void reload_compoundfont(F_compound *compounds); static int prefix_length(char *string, int where_p); static void initialize_char_handler(Window w, void (*cr) (/* ??? */), int bx, int by); static void terminate_char_handler(void); static void turn_on_blinking_cursor(void (*draw_cursor) (/* ??? */), void (*erase_cursor) (/* ??? */), int x, int y, long unsigned int msec); static void turn_off_blinking_cursor(void); static void move_blinking_cursor(int x, int y); #ifdef SEL_TEXT /* for text selection */ static void track_text_select(); static Boolean text_selection_showing = False; static int startp, endp; static int prev_indx, lensel = 0; static int start_text_select = -1; static int start_sel_x, start_sel_y; static Boolean click_on_text = False; static char text_selection[500] = {'\0'}; static Boolean selection_dir = 0; #endif /* SEL_TEXT */ #ifdef I18N #include XIM xim_im = NULL; XIC xim_ic = NULL; XIMStyle xim_style = 0; Boolean xim_active = False; static int save_base_x, save_base_y; /* In EUC encoding, a character can 1 to 3 bytes long. Although fig2dev-i18n will support only G0 and G1, xfig-i18n will prepare for G2 and G3 here, too. G0: 0xxxxxxx (ASCII, for example) G1: 1xxxxxxx 1xxxxxxx (JIS X 0208, for example) G2: 10001110 1xxxxxxx (JIS X 0201, for example) G3: 10001111 1xxxxxxx 1xxxxxxx (JIS X 0212, for example) */ #define is_euc_multibyte(ch) ((unsigned char)(ch) & 0x80) #define EUC_SS3 '\217' /* single shift 3 */ static int i18n_prefix_tail(), i18n_suffix_head(); #ifdef I18N_USE_PREEDIT static pid_t preedit_pid = -1; static char preedit_filename[PATH_MAX] = ""; static open_preedit_proc(), close_preedit_proc(), paste_preedit_proc(); static Boolean is_preedit_running(); #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ /********************************************************/ /* */ /* Procedures */ /* */ /********************************************************/ void move_pref_to_suf (void); void move_suf_to_pref (void); void text_drawing_selected(void) { canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_middlebut_proc = null_proc; canvas_leftbut_proc = init_text_input; canvas_rightbut_proc = null_proc; set_mousefun("position cursor", "", "", "", "", ""); #ifdef I18N #ifdef I18N_USE_PREEDIT if (appres.international && strlen(appres.text_preedit) != 0) { if (is_preedit_running()) { canvas_middlebut_proc = paste_preedit_proc; canvas_rightbut_proc = close_preedit_proc; set_mousefun("position cursor", "paste pre-edit", "close pre-edit", "", "", ""); } else { canvas_rightbut_proc = open_preedit_proc; set_mousefun("position cursor", "", "open pre-edit", "", "", ""); } } #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ reset_action_on(); clear_mousefun_kbd(); set_cursor(text_cursor); is_newline = False; } static void finish_n_start(int x, int y) { create_textobject(); /* reset text size after any super/subscripting */ work_fontsize = cur_fontsize; work_float_fontsize = (float) work_fontsize; supersub = 0; is_newline = False; init_text_input(x, y); } void finish_text_input(int x, int y, int shift) { if (shift) { paste_primary_selection(); return; } create_textobject(); text_drawing_selected(); /* reset text size after any super/subscripting */ work_fontsize = cur_fontsize; work_float_fontsize = (float) work_fontsize; /* reset super/subscript */ supersub = 0; draw_mousefun_canvas(); } static void cancel_text_input(void) { /* reset text size after any super/subscripting */ work_fontsize = cur_fontsize; work_float_fontsize = (float) work_fontsize; /* reset super/subscript */ supersub = 0; erase_char_string(); terminate_char_handler(); reset_action_on(); if (cur_t != NULL) { /* draw it and any objects that are on top */ redisplay_text(cur_t); } text_drawing_selected(); draw_mousefun_canvas(); } static void new_text_line(void) { /* finish current text */ create_textobject(); /* restore x,y to point where user clicked first text or start of text if clicked on existing text */ cur_x = orig_x; cur_y = orig_y; /* restore orig char height */ char_ht = orig_ht; /* advance to next line */ cur_x = round(cur_x + char_ht*cur_textstep*sin_t); cur_y = round(cur_y + char_ht*cur_textstep*cos_t); is_newline = True; init_text_input(cur_x, cur_y); } static void new_text_down(void) { /* only so deep */ if (supersub <= -MAX_SUPSUB) return; create_textobject(); /* save current char height */ heights[abs(supersub)] = char_ht; if (supersub-- > 0) { /* we were previously in a superscript, go back one */ cur_x = round(cur_x + heights[supersub]*sin_t*PSUB_FRAC); cur_y = round(cur_y + heights[supersub]*cos_t*PSUB_FRAC); work_float_fontsize /= CSUB_FRAC; } else if (supersub < 0) { /* we were previously in a subscript, go deeper */ cur_x = round(cur_x + char_ht*sin_t*PSUB_FRAC); cur_y = round(cur_y + char_ht*cos_t*PSUB_FRAC); work_float_fontsize *= CSUB_FRAC; } work_fontsize = round(work_float_fontsize); is_newline = False; overlay_text_input(cur_x, cur_y); } static void new_text_up(void) { /* only so deep */ if (supersub >= MAX_SUPSUB) return; create_textobject(); /* save current char height */ heights[abs(supersub)] = char_ht; if (supersub++ < 0) { /* we were previously in a subscript, go back one */ cur_x = round(cur_x - heights[-supersub]*sin_t*PSUB_FRAC); cur_y = round(cur_y - heights[-supersub]*cos_t*PSUB_FRAC); work_float_fontsize /= CSUB_FRAC; } else if (supersub > 0) { /* we were previously in a superscript, go deeper */ cur_x = round(cur_x - char_ht*sin_t*PSUB_FRAC); cur_y = round(cur_y - char_ht*cos_t*PSUB_FRAC); work_float_fontsize *= CSUB_FRAC; } work_fontsize = round(work_float_fontsize); is_newline = False; overlay_text_input(cur_x, cur_y); } /* Version of init_text_input that allows overlaying. * Does not test for other text nearby. */ static void overlay_text_input(int x, int y) { cur_x = x; cur_y = y; set_action_on(); set_mousefun("new text", "finish text", "cancel", "", "paste text", ""); draw_mousefun_kbd(); draw_mousefun_canvas(); canvas_kbd_proc = (void (*)())char_handler; canvas_middlebut_proc = finish_text_input; canvas_leftbut_proc = finish_n_start; canvas_rightbut_proc = cancel_text_input; /* * set working font info to current settings. This allows user to change * font settings while we are in the middle of accepting text without * affecting this text i.e. we don't allow the text to change midway * through */ cur_t=NULL; leng_prefix = leng_suffix = 0; *suffix = 0; prefix[leng_prefix] = '\0'; base_x = cur_x; base_y = cur_y; #ifdef I18N save_base_x = base_x; save_base_y = base_y; #endif /* I18N */ if (is_newline) { /* working settings already set */ is_newline = False; } else { /* set working settings from ind panel */ work_textcolor = cur_pencolor; work_font = using_ps ? cur_ps_font : cur_latex_font; work_psflag = using_ps; work_flags = cur_textflags; work_textjust = cur_textjust; work_depth = cur_depth; work_angle = cur_elltextangle*M_PI/180.0; while (work_angle < 0.0) work_angle += M_2PI; sin_t = sin((double)work_angle); cos_t = cos((double)work_angle); /* load the X font and get its id for this font and size UNZOOMED */ /* this is to get widths etc for the unzoomed chars */ canvas_font = lookfont(x_fontnum(work_psflag, work_font), work_fontsize); /* get the ZOOMED font for actually drawing on the canvas */ canvas_zoomed_font = lookfont(x_fontnum(work_psflag, work_font), round(work_fontsize*display_zoomscale)); /* save the working font structure */ work_fontstruct = canvas_zoomed_font; } put_msg("Ready for text input (from keyboard)"); char_ht = ZOOM_FACTOR * max_char_height(canvas_font); initialize_char_handler(canvas_win, finish_text_input, base_x, base_y); draw_char_string(); } static void create_textobject(void) { PR_SIZE size; reset_action_on(); erase_char_string(); terminate_char_handler(); if (cur_t == NULL) { /* a brand new text */ strcat(prefix, suffix); /* re-attach any suffix */ leng_prefix=strlen(prefix); if (leng_prefix == 0) return; /* nothing afterall */ cur_t = new_text(); add_text(cur_t); } else { /* existing text modified */ strcat(prefix, suffix); leng_prefix += leng_suffix; if (leng_prefix == 0) { delete_text(cur_t); return; } if (!strcmp(cur_t->cstring, prefix)) { /* we didn't change anything */ /* draw it and any objects that are on top */ redisplay_text(cur_t); #ifdef SEL_TEXT /* if any text is selected, redraw those characters inverted */ if (lensel) draw_selection(start_sel_x, start_sel_y, text_selection); return; #endif /* SEL_TEXT */ } new_t = copy_text(cur_t); change_text(cur_t, new_t); if (strlen(new_t->cstring) >= leng_prefix) { strcpy(new_t->cstring, prefix); } else { /* free old and allocate new */ free(new_t->cstring); if ((new_t->cstring = new_string(leng_prefix)) != NULL) strcpy(new_t->cstring, prefix); } size = textsize(canvas_font, leng_prefix, prefix); new_t->ascent = size.ascent; new_t->descent = size.descent; new_t->length = size.length; cur_t = new_t; } /* draw it and any objects that are on top */ redisplay_text(cur_t); } static void init_text_input(int x, int y) { int length, posn; PR_SIZE tsize; float lensin, lencos; int prev_work_font; cur_x = x; cur_y = y; /* clear canvas loc move proc in case we were in text select mode */ canvas_locmove_proc = null_proc; set_action_on(); set_mousefun("new text", "finish text", "cancel", "", "paste text", ""); draw_mousefun_kbd(); draw_mousefun_canvas(); canvas_kbd_proc = (void (*)())char_handler; canvas_middlebut_proc = finish_text_input; canvas_leftbut_proc = finish_n_start; canvas_rightbut_proc = cancel_text_input; /* * set working font info to current settings. This allows user to change * font settings while we are in the middle of accepting text without * affecting this text i.e. we don't allow the text to change midway * through */ if ((cur_t = text_search(cur_x, cur_y, &posn)) == NULL) { /******************/ /* new text input */ /******************/ leng_prefix = leng_suffix = 0; *suffix = 0; prefix[leng_prefix] = '\0'; /* set origin where mouse was clicked */ base_x = orig_x = cur_x = x; base_y = orig_y = cur_y = y; #ifdef I18N save_base_x = base_x; save_base_y = base_y; #endif /* I18N */ /* set working settings from ind panel */ if (is_newline) { /* working settings already set from previous text */ is_newline = False; } else { /* set working settings from ind panel */ work_textcolor = cur_pencolor; work_fontsize = cur_fontsize; prev_work_font = work_font; work_font = using_ps ? cur_ps_font : cur_latex_font; /* font changed, refresh character map panel if it is up */ if (prev_work_font != work_font) refresh_character_panel(); work_psflag = using_ps; work_flags = cur_textflags; work_textjust = cur_textjust; work_depth = cur_depth; work_angle = cur_elltextangle*M_PI/180.0; while (work_angle < 0.0) work_angle += M_2PI; sin_t = sin((double)work_angle); cos_t = cos((double)work_angle); /* load the X font and get its id for this font and size UNZOOMED */ /* this is to get widths etc for the unzoomed chars */ canvas_font = lookfont(x_fontnum(work_psflag, work_font), work_fontsize); /* get the ZOOMED font for actually drawing on the canvas */ canvas_zoomed_font = lookfont(x_fontnum(work_psflag, work_font), round(work_fontsize*display_zoomscale)); /* save the working font structure */ work_fontstruct = canvas_zoomed_font; } /* (is_newline) */ } else { /*****************/ /* existing text */ /*****************/ if (hidden_text(cur_t)) { put_msg("Can't edit hidden text"); reset_action_on(); text_drawing_selected(); return; } /* update the working text parameters */ work_textcolor = cur_t->color; prev_work_font = work_font; work_font = cur_t->font; /* font changed, refresh character map panel if it is up */ if (prev_work_font != work_font) refresh_character_panel(); work_fontstruct = canvas_zoomed_font = cur_t->fontstruct; work_fontsize = cur_t->size; work_psflag = cur_t->flags & PSFONT_TEXT; work_flags = cur_t->flags; work_textjust = cur_t->type; work_depth = cur_t->depth; work_angle = cur_t->angle; while (work_angle < 0.0) work_angle += M_2PI; sin_t = sin((double)work_angle); cos_t = cos((double)work_angle); /* load the X font and get its id for this font, size and angle UNZOOMED */ /* this is to get widths etc for the unzoomed chars */ canvas_font = lookfont(x_fontnum(work_psflag, work_font), work_fontsize); toggle_textmarker(cur_t); draw_text(cur_t, ERASE); base_x = cur_t->base_x; base_y = cur_t->base_y; length = cur_t->length; lencos = length*cos_t; lensin = length*sin_t; #ifdef I18N save_base_x = base_x; save_base_y = base_y; #endif /* I18N */ /* set origin to base of this text so newline will go there */ orig_x = base_x; orig_y = base_y; switch (cur_t->type) { case T_CENTER_JUSTIFIED: base_x = round(base_x - lencos/2.0); base_y = round(base_y + lensin/2.0); break; case T_RIGHT_JUSTIFIED: base_x = round(base_x - lencos); base_y = round(base_y + lensin); break; } /* switch */ leng_suffix = strlen(cur_t->cstring); /* leng_prefix is index of char in the text before the cursor */ /* it is also used for text selection as the starting point */ leng_prefix = prefix_length(cur_t->cstring, posn); #ifdef SEL_TEXT /**********************************************/ /* user has double-clicked, select whole word */ /**********************************************/ if (pointer_click == 2) { /* if any text is selected from before, undraw the selection */ if (lensel && text_selection_showing) undraw_selection(start_sel_x, start_sel_y, text_selection); startp = leng_prefix-1; /* back up to the beginning of the word or string */ while (startp && cur_t->cstring[startp-1] != ' ') startp--; endp = leng_prefix; /* now go forward to the end of the word or string */ while (endp < leng_suffix && cur_t->cstring[endp] != ' ') endp++; lensel = endp-startp; /* copy into the selection */ strncpy(text_selection, &cur_t->cstring[startp], lensel); text_selection[lensel] = '\0'; /* save starting point of selection */ start_text_select = prev_indx = startp; /* prefix includes selected text */ leng_prefix = endp; /* save starting x,y of select */ tsize = textsize(canvas_font, leng_prefix-lensel, prefix); start_sel_x = round(base_x + tsize.length * cos_t); start_sel_y = round(base_y - tsize.length * sin_t); selection_dir = 1; /* selecting to the right */ } else { /* save starting point of text selection */ start_text_select = prev_indx = leng_prefix; } #endif /* SEL_TEXT */ leng_suffix -= leng_prefix; strncpy(prefix, cur_t->cstring, leng_prefix); prefix[leng_prefix]='\0'; strcpy(suffix, &cur_t->cstring[leng_prefix]); tsize = textsize(canvas_font, leng_prefix, prefix); /* set current to character position of mouse click (end of prefix) */ cur_x = round(base_x + tsize.length * cos_t); cur_y = round(base_y - tsize.length * sin_t); #ifdef SEL_TEXT /* set text selection flag in case user moves pointer along text with button down */ text_selection_active = True; /* set flag saying the user just clicked */ click_on_text = True; /* and set canvas move procedure to keep track of text being selected */ canvas_locmove_proc = track_text_select; #endif /* SEL_TEXT */ } /* save floating font size */ work_float_fontsize = work_fontsize; /* reset super/subscript counter */ supersub = 0; put_msg("Ready for text input (from keyboard)"); /* save original char_ht for newline */ orig_ht = char_ht = ZOOM_FACTOR * max_char_height(canvas_font); initialize_char_handler(canvas_win, finish_text_input, base_x, base_y); #ifdef SEL_TEXT /* if any text is selected from before, undraw the selection */ if (lensel && text_selection_showing) { undraw_selection(start_sel_x, start_sel_y, text_selection); text_selection_showing = False; } #endif /* SEL_TEXT */ draw_char_string(); #ifdef SEL_TEXT /* draw the selected word in inverse */ if (pointer_click == 2) { draw_selection(start_sel_x, start_sel_y, text_selection); text_selection_showing = True; } #endif /* SEL_TEXT */ } static F_text * new_text(void) { F_text *text; PR_SIZE size; if ((text = create_text()) == NULL) return (NULL); if ((text->cstring = new_string(leng_prefix)) == NULL) { free((char *) text); return (NULL); } text->type = work_textjust; text->font = work_font; /* put in current font number */ text->fontstruct = work_fontstruct; text->zoom = zoomscale; text->size = work_fontsize; text->angle = work_angle; text->flags = work_flags; text->color = cur_pencolor; text->depth = work_depth; text->pen_style = -1; size = textsize(canvas_font, leng_prefix, prefix); text->length = size.length; text->ascent = size.ascent; text->descent = size.descent; text->base_x = base_x; text->base_y = base_y; strcpy(text->cstring, prefix); text->next = NULL; return (text); } /* return the index of the character in the string before the cursor (where_p) */ static int prefix_length(char *string, int where_p) { /* c stands for character unit and p for pixel unit */ int l, len_c, len_p; int char_wid, where_c; PR_SIZE size; len_c = strlen(string); size = textsize(canvas_font, len_c, string); len_p = size.length; if (where_p >= len_p) return (len_c); /* entire string is the prefix */ #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) { where_c = 0; while (where_c < len_c) { size = textsize(canvas_font, where_c, string); if (where_p <= size.length) return where_c; if (appres.euc_encoding) { if (string[where_c] == EUC_SS3) where_c = where_c + 3; else if (is_euc_multibyte(string[where_c])) where_c = where_c + 2; } else if (appres.locale_encoding) { l=mbrlen(string+where_c, MB_LEN_MAX, NULL); if (l>0) where_c+=l; else where_c++; } else where_c++; } return len_c; } #endif /* I18N */ char_wid = ZOOM_FACTOR * char_width(canvas_font); where_c = where_p / char_wid; /* estimated char position */ size = textsize(canvas_font, where_c, string); l = size.length; /* actual length (pixels) of string of * where_c chars */ if (l < where_p) { do { /* add the width of next char to l */ l += (char_wid = ZOOM_FACTOR * char_advance(canvas_font, (unsigned char) string[where_c++])); } while (l < where_p); if (l - (char_wid >> 1) >= where_p) where_c--; } else if (l > where_p) { do { /* subtract the width of last char from l */ l -= (char_wid = ZOOM_FACTOR * char_advance(canvas_font, (unsigned char) string[--where_c])); } while (l > where_p); if (l + (char_wid >> 1) <= where_p) where_c++; } if (where_c < 0) { fprintf(stderr, "xfig file %s line %d: Error in prefix_length - adjusted\n", __FILE__, __LINE__); where_c = 0; } if ( where_c > len_c ) return (len_c); return (where_c); } /******************************************************************* char handling routines *******************************************************************/ #define BLINK_INTERVAL 700 /* milliseconds blink rate */ static Window pw; static int ch_height; static int cbase_x, cbase_y; static float rbase_x, rbase_y, rcur_x, rcur_y; static void (*cr_proc) (); static void draw_cursor(int x, int y) { pw_vector(pw, x, y, round(x-ch_height*sin_t), round(y-ch_height*cos_t), INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); } static void initialize_char_handler(Window w, void (*cr) (/* ??? */), int bx, int by) { pw = w; cr_proc = cr; rbase_x = cbase_x = bx; /* keep real base so dont have roundoff */ rbase_y = cbase_y = by; rcur_x = cur_x; rcur_y = cur_y; ch_height = ZOOM_FACTOR * canvas_font->max_bounds.ascent; turn_on_blinking_cursor(draw_cursor, draw_cursor, cur_x, cur_y, (long) BLINK_INTERVAL); #ifdef I18N if (xim_ic != NULL && (appres.latin_keyboard || is_i18n_font(canvas_font))) { put_msg("Ready for text input (from keyboard with input-method)"); XSetICFocus(xim_ic); xim_active = True; xim_set_spot(cur_x, cur_y); } #endif /* I18N */ } static void terminate_char_handler(void) { turn_off_blinking_cursor(); cr_proc = NULL; #ifdef I18N if (xim_ic != NULL) XUnsetICFocus(xim_ic); xim_active = False; #endif /* I18N */ } void do_char(unsigned char ch, int op) { char c[2]; c[0] = ch; c[1] = '\0'; pw_text(pw, cur_x, cur_y, op, MAX_DEPTH+1, canvas_zoomed_font, work_angle, c, work_textcolor, COLOR_NONE); } void draw_char(unsigned char ch) { do_char(ch, PAINT); } void erase_char(unsigned char ch) { do_char(ch, ERASE); } void do_prefix(int op) { if (leng_prefix) pw_text(pw, cbase_x, cbase_y, op, MAX_DEPTH+1, canvas_zoomed_font, work_angle, prefix, work_textcolor, COLOR_NONE); } void draw_prefix(void) { do_prefix(PAINT); } void erase_prefix(void) { do_prefix(ERASE); } void do_suffix(int op) { if (leng_suffix) pw_text(pw, cur_x, cur_y, op, MAX_DEPTH+1, canvas_zoomed_font, work_angle, suffix, work_textcolor, COLOR_NONE); } void draw_suffix(void) { do_suffix(PAINT); } void erase_suffix(void) { do_suffix(ERASE); } void erase_char_string(void) { pw_text(pw, cbase_x, cbase_y, ERASE, MAX_DEPTH+1, canvas_zoomed_font, work_angle, prefix, work_textcolor, COLOR_NONE); if (leng_suffix) pw_text(pw, cur_x, cur_y, ERASE, MAX_DEPTH+1, canvas_zoomed_font, work_angle, suffix, work_textcolor, COLOR_NONE); } void draw_char_string(void) { #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) { double cwidth; int direc, asc, des; XCharStruct overall; float mag = ZOOM_FACTOR / display_zoomscale; float prefix_width = 0, suffix_width = 0; if (0 < leng_prefix) { i18n_text_extents(canvas_zoomed_font, prefix, leng_prefix, &direc, &asc, &des, &overall); prefix_width = (float)(overall.width) * mag; } if (0 < leng_suffix) { i18n_text_extents(canvas_zoomed_font, suffix, leng_suffix, &direc, &asc, &des, &overall); suffix_width = (float)(overall.width) * mag; } cbase_x = save_base_x; cbase_y = save_base_y; switch (work_textjust) { case T_LEFT_JUSTIFIED: break; case T_RIGHT_JUSTIFIED: cbase_x = cbase_x - (prefix_width + suffix_width) * cos_t; cbase_y = cbase_y + (prefix_width + suffix_width) * sin_t; break; case T_CENTER_JUSTIFIED: cbase_x = cbase_x - (prefix_width + suffix_width) * cos_t / 2; cbase_y = cbase_y + (prefix_width + suffix_width) * sin_t / 2; break; } pw_text(pw, cbase_x, cbase_y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, prefix, work_textcolor, COLOR_NONE); cur_x = cbase_x + prefix_width * cos_t; cur_y = cbase_y - prefix_width * sin_t; if (leng_suffix) pw_text(pw, cur_x, cur_y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, suffix, work_textcolor, COLOR_NONE); move_blinking_cursor(cur_x, cur_y); return; } #endif /* I18N */ pw_text(pw, cbase_x, cbase_y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, prefix, work_textcolor, COLOR_NONE); if (leng_suffix) pw_text(pw, cur_x, cur_y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, suffix, work_textcolor, COLOR_NONE); move_blinking_cursor(cur_x, cur_y); } void char_handler(XKeyEvent *kpe, unsigned char c, KeySym keysym) { register int i; unsigned char ch; if (cr_proc == NULL) return; #ifdef SEL_TEXT /* clear text selection flag since user typed a character */ /* but only if not one of the selection editing chars */ if (c != CTRL_W) { if (text_selection_active) undraw_selection(start_sel_x, start_sel_y, text_selection); text_selection_active = False; /* and canvas loc move proc */ canvas_locmove_proc = null_proc; } #endif /* SEL_TEXT */ if (c == ESC) { create_textobject(); canvas_kbd_proc = null_proc; canvas_middlebut_proc = null_proc; canvas_leftbut_proc = null_proc; canvas_rightbut_proc = null_proc; } else if (c == CR || c == NL) { new_text_line(); } else if (c == CTRL_UNDERSCORE) { /* subscript */ new_text_down(); } else if (c == CTRL_HAT) { /* superscript */ new_text_up(); /******************************************************/ /* move cursor left - move char from prefix to suffix */ /* Control-B and the Left arrow key both do this */ /******************************************************/ } else if (keysym == XK_Left || c == CTRL_B) { #ifdef I18N if (leng_prefix > 0 && appres.international && is_i18n_font(canvas_font)) { erase_char_string(); move_pref_to_suf(); draw_char_string(); } else #endif /* I18N */ if (leng_prefix > 0) { move_pref_to_suf(); move_cur(-1, suffix[0], 1.0); } /*******************************************************/ /* move cursor right - move char from suffix to prefix */ /* Control-F and Right arrow key both do this */ /*******************************************************/ } else if (keysym == XK_Right || c == CTRL_F) { #ifdef I18N if (leng_suffix > 0 && appres.international && is_i18n_font(canvas_font)) { erase_char_string(); move_suf_to_pref(); draw_char_string(); } else #endif /* I18N */ if (leng_suffix > 0) { move_suf_to_pref(); move_cur(1, prefix[leng_prefix-1], 1.0); } /***************************************************************/ /* move cursor to beginning of text - put everything in suffix */ /* Control-A and Home key both do this */ /***************************************************************/ } else if (keysym == XK_Home || c == CTRL_A) { if (leng_prefix > 0) { #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) erase_char_string(); else #endif /* I18N */ for (i=leng_prefix-1; i>=0; i--) move_cur(-1, prefix[i], 1.0); strcat(prefix,suffix); strcpy(suffix,prefix); prefix[0]='\0'; leng_prefix=0; leng_suffix=strlen(suffix); #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) draw_char_string(); #endif /* I18N */ } /*********************************************************/ /* move cursor to end of text - put everything in prefix */ /* Control-E and End key both do this */ /*********************************************************/ } else if (keysym == XK_End || c == CTRL_E) { if (leng_suffix > 0) { #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) erase_char_string(); else #endif /* I18N */ for (i=0; i 0 && appres.international && is_i18n_font(canvas_font)) { int len; erase_char_string(); len = i18n_prefix_tail(NULL); leng_prefix-=len; erase_char(ch); prefix[leng_prefix]='\0'; draw_char_string(); } else #endif /* I18N */ if (leng_prefix > 0) { switch (work_textjust) { case T_LEFT_JUSTIFIED: erase_suffix(); move_cur(-1, ch, 1.0); erase_char(ch); break; case T_CENTER_JUSTIFIED: erase_char_string(); move_cur(-1, ch, 2.0); move_text(1, ch, 2.0); break; case T_RIGHT_JUSTIFIED: erase_prefix(); move_text(1, ch, 1.0); break; } /* remove the character from the prefix */ prefix[--leng_prefix] = '\0'; /* now redraw stuff */ switch (work_textjust) { case T_LEFT_JUSTIFIED: draw_suffix(); break; case T_CENTER_JUSTIFIED: draw_char_string(); break; case T_RIGHT_JUSTIFIED: draw_prefix(); break; } } /*****************************************/ /* delete char to right of cursor */ /* Control-D and Delete key both do this */ /*****************************************/ } else if (c == DEL || c == CTRL_D) { #ifdef I18N if (leng_suffix > 0 && appres.international && is_i18n_font(canvas_font)) { int len; erase_char_string(); len = i18n_suffix_head(NULL); for (i=0; i<=leng_suffix-len; i++) /* copies null too */ suffix[i]=suffix[i+len]; leng_suffix-=len; draw_char_string(); } else #endif /* I18N */ if (leng_suffix > 0) { switch (work_textjust) { case T_LEFT_JUSTIFIED: erase_suffix(); break; case T_CENTER_JUSTIFIED: erase_char_string(); move_cur(1, suffix[0], 2.0); move_text(1, suffix[0], 2.0); break; case T_RIGHT_JUSTIFIED: erase_prefix(); erase_char(suffix[0]); move_cur(1, suffix[0], 1.0); move_text(1, suffix[0], 1.0); break; } /* shift suffix left one char */ for (i=0; i<=leng_suffix; i++) /* copies null too */ suffix[i]=suffix[i+1]; leng_suffix--; /* now redraw stuff */ switch (work_textjust) { case T_LEFT_JUSTIFIED: draw_suffix(); break; case T_CENTER_JUSTIFIED: draw_char_string(); break; case T_RIGHT_JUSTIFIED: draw_prefix(); break; } } /*******************************/ /* delete to beginning of line */ /*******************************/ } else if (c == CTRL_X) { if (leng_prefix > 0) { #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) erase_char_string(); else #endif /* I18N */ switch (work_textjust) { case T_LEFT_JUSTIFIED: erase_char_string(); rcur_x = rbase_x; cur_x = cbase_x = round(rcur_x); rcur_y = rbase_y; cur_y = cbase_y = round(rcur_y); break; case T_CENTER_JUSTIFIED: erase_char_string(); while (leng_prefix--) { /* subtract char width/2 per char */ rcur_x -= ZOOM_FACTOR * cos_t*char_advance(canvas_font, (unsigned char) prefix[leng_prefix]) / 2.0; rcur_y += ZOOM_FACTOR * sin_t*char_advance(canvas_font, (unsigned char) prefix[leng_prefix]) / 2.0; } rbase_x = rcur_x; cur_x = cbase_x = round(rbase_x); rbase_y = rcur_y; cur_y = cbase_y = round(rbase_y); break; case T_RIGHT_JUSTIFIED: erase_prefix(); rbase_x = rcur_x; cbase_x = cur_x = round(rbase_x); rbase_y = rcur_y; cbase_y = cur_y = round(rbase_y); break; } leng_prefix = 0; *prefix = '\0'; switch (work_textjust) { case T_LEFT_JUSTIFIED: draw_char_string(); break; case T_CENTER_JUSTIFIED: draw_char_string(); break; case T_RIGHT_JUSTIFIED: break; } move_blinking_cursor(cur_x, cur_y); #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) draw_char_string(); #endif /* I18N */ } /*************************/ /* delete to end of line */ /*************************/ } else if (c == CTRL_K) { if (leng_suffix > 0) { #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) erase_char_string(); else #endif /* I18N */ switch (work_textjust) { case T_LEFT_JUSTIFIED: erase_suffix(); break; case T_CENTER_JUSTIFIED: erase_char_string(); while (leng_suffix--) { move_cur(1, suffix[leng_suffix], 2.0); move_text(1, suffix[leng_suffix], 2.0); } break; case T_RIGHT_JUSTIFIED: erase_char_string(); /* move cursor to end of (orig) string then move string over */ while (leng_suffix--) { move_cur(1, suffix[leng_suffix], 1.0); move_text(1, suffix[leng_suffix], 1.0 ); } break; } leng_suffix = 0; *suffix = '\0'; /* redraw stuff */ #ifdef I18N if (appres.international && is_i18n_font(canvas_font)) draw_char_string(); else #endif /* I18N */ switch (work_textjust) { case T_LEFT_JUSTIFIED: break; case T_CENTER_JUSTIFIED: draw_char_string(); break; case T_RIGHT_JUSTIFIED: draw_char_string(); break; } } #ifdef SEL_TEXT /************************/ /* delete selected text */ /************************/ } else if (c == CTRL_W) { /* only if active */ if (lensel) { /* simply delete lensel characters from the end of the prefix */ prefix[leng_prefix-lensel] = '\0'; leng_prefix = strlen(prefix); switch (work_textjust) { case T_LEFT_JUSTIFIED: erase_suffix(); break; case T_CENTER_JUSTIFIED: erase_prefix(); erase_suffix(); break; case T_RIGHT_JUSTIFIED: erase_prefix(); break; } /* move cursor and/or text (prefix) base */ for (i=0; icstring, posn); /* if on same character, return */ if (indx == prev_indx) return; /* if the user just clicked and has now moved the pointer */ if (click_on_text) { /* save starting point of selection for refresing if user clicks elsewhere */ start_sel_x = cur_x; start_sel_y = cur_y; /* clear the selection */ text_selection[0] = '\0'; lensel = 0; if (indx < prev_indx) selection_dir = -1; /* selecting to the left */ else selection_dir = 1; /* selecting to the right */ click_on_text = False; } if (indx > start_text_select) { /* selecting right */ if (selection_dir == -1) { /* but we were selecting left, switch */ selection_dir = 1; for (i=0; i prev_indx) { /* we selected right, and are still moving right */ for (i=0; i < (indx-prev_indx); i++) { substr[i] = cur_t->cstring[i+prev_indx]; /* move char to prefix */ move_suf_to_pref(); /* update currently selected text */ text_selection[lensel++] = substr[i]; } substr[i] = '\0'; text_selection[lensel] = '\0'; text_selection[indx-start_text_select] = '\0'; /* draw the characters inverted */ draw_selection(cur_x, cur_y, substr); /* and move the cursor to the current position */ for (i=0; icstring[i+indx]; /* put char back in suffix */ move_pref_to_suf(); /* update currently selected text */ lensel--; } substr[i] = '\0'; text_selection[lensel] = '\0'; /* move the cursor to the current position */ for (i=0; icstring[i+indx]; /* move char to suffix */ move_pref_to_suf(); } substr[i] = '\0'; /* update currently selected text */ lensel += prev_indx-indx; strncpy(text_selection, &cur_t->cstring[indx], lensel); text_selection[lensel] = '\0'; /* move the cursor to the current position */ for (i=0; icstring[i+prev_indx]; /* put char back in prefix */ move_suf_to_pref(); } substr[i] = '\0'; /* update currently selected text */ lensel -= indx-prev_indx; strncpy(text_selection, &cur_t->cstring[indx], lensel); text_selection[lensel] = '\0'; /* draw the characters normal */ undraw_selection(cur_x, cur_y, substr); /* and move the cursor to the current position */ for (i=0; i 0 && appres.international && is_i18n_font(canvas_font)) { len = i18n_prefix_tail(NULL); for (i=leng_suffix+len; i>0; i--) /* copies null too */ suffix[i]=suffix[i-len]; for (i=0; i 0) { for (i=leng_suffix+1; i>0; i--) /* copies null too */ suffix[i]=suffix[i-1]; suffix[0]=prefix[leng_prefix-1]; prefix[leng_prefix-1]='\0'; leng_prefix--; leng_suffix++; } } /* move first char of suffix to last of prefix */ void move_suf_to_pref(void) { int i; #ifdef I18N int len; if (leng_suffix > 0 && appres.international && is_i18n_font(canvas_font)) { len = i18n_suffix_head(NULL); for (i=0; i 0) { prefix[leng_prefix] = suffix[0]; prefix[leng_prefix+1]='\0'; for (i=0; i<=leng_suffix; i++) /* copies null too */ suffix[i]=suffix[i+1]; leng_suffix--; leng_prefix++; } } #ifdef SEL_TEXT /* draw string from x, y in inverse (selected) color */ draw_selection(x, y, string) int x, y; char *string; { /* turn off blinking cursor temporarily */ turn_off_blinking_cursor(); pw_text(pw, x, y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, string, CANVAS_BG, work_textcolor); /* turn on blinking cursor again */ turn_on_blinking_cursor(draw_cursor, draw_cursor, cur_x, cur_y, (long) BLINK_INTERVAL); } /* draw string from x, y in normal (unselected) color */ undraw_selection(x, y, string) int x, y; char *string; { /* turn off blinking cursor temporarily */ turn_off_blinking_cursor(); pw_text(pw, x, y, PAINT, MAX_DEPTH+1, canvas_zoomed_font, work_angle, string, work_textcolor, CANVAS_BG); /* turn on blinking cursor again */ turn_on_blinking_cursor(draw_cursor, draw_cursor, cur_x, cur_y, (long) BLINK_INTERVAL); } /* convert selection to string */ /* this the callback w_canvas.c: canvas_selected() when user pastes the selection */ Boolean ConvertSelection(w, selection, target, type, value, length, format) Widget w; Atom *selection, *target, *type; XtPointer *value; unsigned long *length; int *format; { /* if nothing, return */ if (lensel == 0) return False; if (*target == XA_STRING || *target == XA_TEXT(tool_d) || *target == XA_COMPOUND_TEXT(tool_d)) { if (*target == XA_COMPOUND_TEXT(tool_d)) *type = *target; else *type = XA_STRING; *value = text_selection; *length = lensel; *format = 8; return True; } } void LoseSelection(w, selection) Widget w; Atom *selection; { lensel = 0; text_selection[0] = '\0'; /* unhighlight text */ if (cur_t) redisplay_text(cur_t); } void TransferSelectionDone(w, selection, target) Widget w; Atom *selection, *target; { /* nothing to do */ } #endif /* SEL_TEXT */ /****************************************************************/ /* */ /* Blinking cursor handling routines */ /* */ /****************************************************************/ static int cursor_on, cursor_is_moving; static int cursor_x, cursor_y; static void (*erase) (); static void (*draw) (); static XtTimerCallbackProc blink(XtPointer client_data, XtIntervalId *id); static unsigned long blink_timer; static int stop_blinking = False; static int cur_is_blinking = False; static void turn_on_blinking_cursor(void (*draw_cursor) (/* ??? */), void (*erase_cursor) (/* ??? */), int x, int y, long unsigned int msec) { draw = draw_cursor; erase = erase_cursor; cursor_is_moving = 0; cursor_x = x; cursor_y = y; blink_timer = msec; draw(x, y); cursor_on = 1; if (!cur_is_blinking) { /* if we are already blinking, don't request * another */ (void) XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink, (XtPointer) NULL); cur_is_blinking = True; } stop_blinking = False; } static void turn_off_blinking_cursor(void) { if (cursor_on) erase(cursor_x, cursor_y); stop_blinking = True; } static XtTimerCallbackProc blink(XtPointer client_data, XtIntervalId *id) { if (!stop_blinking) { if (cursor_is_moving) return (0); if (cursor_on) { erase(cursor_x, cursor_y); cursor_on = 0; } else { draw(cursor_x, cursor_y); cursor_on = 1; } (void) XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink, (XtPointer) NULL); } else { stop_blinking = False; /* signal that we've stopped */ cur_is_blinking = False; } return (0); } static void move_blinking_cursor(int x, int y) { cursor_is_moving = 1; if (cursor_on) erase(cursor_x, cursor_y); cursor_x = x; cursor_y = y; draw(cursor_x, cursor_y); cursor_on = 1; cursor_is_moving = 0; #ifdef I18N if (xim_active) xim_set_spot(x, y); #endif /* I18N */ } /* * Reload the font structure for all texts, the saved texts and the current work_fontstruct. */ void reload_text_fstructs(void) { F_text *t; /* reload the compound objects' texts */ reload_compoundfont(objects.compounds); /* and the separate texts */ for (t=objects.texts; t != NULL; t = t->next) reload_text_fstruct(t); } /* * Reload the font structure for texts in compounds. */ static void reload_compoundfont(F_compound *compounds) { F_compound *c; F_text *t; for (c = compounds; c != NULL; c = c->next) { reload_compoundfont(c->compounds); for (t=c->texts; t != NULL; t = t->next) reload_text_fstruct(t); } } void reload_text_fstruct(F_text *t) { t->fontstruct = lookfont(x_fontnum(psfont_text(t), t->font), round(t->size*display_zoomscale)); t->zoom = zoomscale; } /****************************************************************/ /* */ /* Internationalization utility procedures */ /* */ /****************************************************************/ #ifdef I18N static void GetPreferredGeomerty(ic, name, area) XIC ic; char *name; XRectangle **area; { XVaNestedList list; list = XVaCreateNestedList(0, XNAreaNeeded, area, NULL); XGetICValues(ic, name, list, NULL); XFree(list); } static void SetGeometry(ic, name, area) XIC ic; char *name; XRectangle *area; { XVaNestedList list; list = XVaCreateNestedList(0, XNArea, area, NULL); XSetICValues(ic, name, list, NULL); XFree(list); } xim_set_ic_geometry(ic, width, height) XIC ic; int width; int height; { XRectangle preedit_area, *preedit_area_ptr; XRectangle status_area, *status_area_ptr; if (xim_ic == NULL) return; if (appres.DEBUG) fprintf(stderr, "xim_set_ic_geometry(%d, %d)\n", width, height); if (xim_style & XIMStatusArea) { GetPreferredGeomerty(ic, XNStatusAttributes, &status_area_ptr); status_area.width = status_area_ptr->width; if (width / 2 < status_area.width) status_area.width = width / 2; status_area.height = status_area_ptr->height; status_area.x = 0; status_area.y = height - status_area.height; SetGeometry(xim_ic, XNStatusAttributes, &status_area); if (appres.DEBUG) fprintf(stderr, "status geometry: %dx%d+%d+%d\n", status_area.width, status_area.height, status_area.x, status_area.y); } if (xim_style & XIMPreeditArea) { GetPreferredGeomerty(ic, XNPreeditAttributes, &preedit_area_ptr); preedit_area.width = preedit_area_ptr->width; if (preedit_area.width < width - status_area.width) preedit_area.width = width - status_area.width; if (width < preedit_area.width) preedit_area.width = width; preedit_area.height = preedit_area_ptr->height; preedit_area.x = width - preedit_area.width; preedit_area.y = height - preedit_area.height; SetGeometry(xim_ic, XNPreeditAttributes, &preedit_area); if (appres.DEBUG) fprintf(stderr, "preedit geometry: %dx%d+%d+%d\n", preedit_area.width, preedit_area.height, preedit_area.x, preedit_area.y); } } Boolean xim_initialize(w) Widget w; { const XIMStyle style_notuseful = 0; const XIMStyle style_over_the_spot = XIMPreeditPosition | XIMStatusArea; const XIMStyle style_old_over_the_spot = XIMPreeditPosition | XIMStatusNothing; const XIMStyle style_off_the_spot = XIMPreeditArea | XIMStatusArea; const XIMStyle style_root = XIMPreeditNothing | XIMStatusNothing; static long int im_event_mask = 0; XIMStyles *styles; XIMStyle preferred_style; int i; XVaNestedList preedit_att, status_att; XPoint spot; char *modifier_list; preferred_style = style_notuseful; if (strncasecmp(appres.xim_input_style, "OverTheSpot", 3) == 0) preferred_style = style_over_the_spot; else if (strncasecmp(appres.xim_input_style, "OldOverTheSpot", 6) == 0) preferred_style = style_old_over_the_spot; else if (strncasecmp(appres.xim_input_style, "OffTheSpot", 3) == 0) preferred_style = style_off_the_spot; else if (strncasecmp(appres.xim_input_style, "Root", 3) == 0) preferred_style = style_root; else if (strncasecmp(appres.xim_input_style, "None", 3) != 0) fprintf(stderr, "xfig: inputStyle should OverTheSpot, OffTheSpot, or Root\n"); if (preferred_style == style_notuseful) return; if (appres.DEBUG) fprintf(stderr, "initialize_input_method()...\n"); if ((modifier_list = XSetLocaleModifiers("")) == NULL || *modifier_list == '\0') { /* printf("Warning: XSetLocaleModifiers() failed.\n"); */ } xim_im = XOpenIM(XtDisplay(w), NULL, NULL, NULL); if (xim_im == NULL) { fprintf(stderr, "xfig: can't open input-method\n"); return False; } XGetIMValues(xim_im, XNQueryInputStyle, &styles, NULL, NULL); for (i = 0; i < styles->count_styles; i++) { if (appres.DEBUG) fprintf(stderr, "styles[%d]=%lx\n", i, styles->supported_styles[i]); if (styles->supported_styles[i] == preferred_style) { xim_style = preferred_style; } else if (styles->supported_styles[i] == style_root) { if (xim_style == 0) xim_style = style_root; } } if (xim_style != preferred_style) { fprintf(stderr, "xfig: this input-method doesn't support %s input style\n", appres.xim_input_style); if (xim_style == 0) { fprintf(stderr, "xfig: it don't support ROOT input style, too...\n"); return False; } else { fprintf(stderr, "xfig: using ROOT input style instead.\n"); } } if (appres.DEBUG) { char *s; if (xim_style == style_over_the_spot) s = "OverTheSpot"; else if (xim_style == style_off_the_spot) s = "OffTheSpot"; else if (xim_style == style_root) s = "Root"; else s = "unknown"; fprintf(stderr, "xfig: selected input style: %s\n", s); } spot.x = 20; /* dummy */ spot.y = 20; preedit_att = XVaCreateNestedList(0, XNFontSet, appres.fixed_fontset, XNSpotLocation, &spot, NULL); status_att = XVaCreateNestedList(0, XNFontSet, appres.fixed_fontset, NULL); xim_ic = XCreateIC(xim_im, XNInputStyle , xim_style, XNClientWindow, XtWindow(w), XNFocusWindow, XtWindow(w), XNPreeditAttributes, preedit_att, XNStatusAttributes, status_att, NULL, NULL); XFree(preedit_att); XFree(status_att); if (xim_ic == NULL) { fprintf(stderr, "xfig: can't create input-context\n"); return False; } if (appres.DEBUG) fprintf(stderr, "input method initialized\n"); return True; } xim_set_spot(x, y) int x, y; { static XPoint spot; XVaNestedList preedit_att; int x1, y1; if (xim_ic != NULL) { if (xim_style & XIMPreeditPosition) { if (appres.DEBUG) fprintf(stderr, "xim_set_spot(%d,%d)\n", x, y); preedit_att = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); x1 = ZOOMX(x) + 1; y1 = ZOOMY(y); if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; spot.x = x1; spot.y = y1; XSetICValues(xim_ic, XNPreeditAttributes, preedit_att, NULL); XFree(preedit_att); } } } static int i18n_prefix_tail(char *s1) { int len=1, i; if (appres.euc_encoding && is_euc_multibyte(prefix[leng_prefix-1])) { if (leng_prefix > 2 && prefix[leng_prefix-3] == EUC_SS3) len = 3; /* G3: 10001111 1xxxxxxx 1xxxxxxx (JIS X 0212, for example) */ else if (leng_prefix > 1) len = 2; /* G2: 10001110 1xxxxxxx (JIS X 0201, for example) */ /* G1: 1xxxxxxx 1xxxxxxx (JIS X 0208, for example) */ } else if (appres.locale_encoding){ for (i=0; (i0) break; } if (len<=0) len=1; } if (s1 != NULL) { for (i = 0; i < len; i++) s1[i] = prefix[leng_prefix - len + i]; s1[len] = '\0'; } return len; } static int i18n_suffix_head(char *s1) { int len=1, i; if (appres.euc_encoding && is_euc_multibyte(suffix[0])) { if (leng_suffix > 2 && suffix[0] == EUC_SS3) len = 3; /* G3 */ else if (leng_suffix > 1) len = 2; /* G1 or G2 */ } else if (appres.locale_encoding){ len=mbrlen(suffix, MB_LEN_MAX, NULL); if (len<=0) len=1; } if (s1 != NULL) { for (i = 0; i < len; i++) s1[i] = suffix[i]; s1[len] = '\0'; } return len; } i18n_char_handler(str) unsigned char *str; { int i; erase_char_string(); /* erase chars after the cursor */ for (i = 0; str[i] != '\0'; i++) prefix_append_char(str[i]); draw_char_string(); /* draw new suffix */ } prefix_append_char(ch) unsigned char ch; { if (leng_prefix + leng_suffix < BUF_SIZE) { prefix[leng_prefix++] = ch; prefix[leng_prefix] = '\0'; } else { put_msg("Text buffer is full, character is ignored"); } } #ifdef I18N_USE_PREEDIT static Boolean is_preedit_running() { pid_t pid; sprintf(preedit_filename, "%s/%s%06d", TMPDIR, "xfig-preedit", getpid()); #if defined(_POSIX_SOURCE) || defined(SVR4) pid = waitpid(-1, NULL, WNOHANG); #else pid = wait3(NULL, WNOHANG, NULL); #endif /* defined(_POSIX_SOURCE) || defined(SVR4) */ if (0 < preedit_pid && pid == preedit_pid) preedit_pid = -1; return (0 < preedit_pid && access(preedit_filename, R_OK) == 0); } kill_preedit() { if (0 < preedit_pid) { kill(preedit_pid, SIGTERM); preedit_pid = -1; } } static close_preedit_proc(x, y) int x, y; { if (is_preedit_running()) { kill_preedit(); put_msg("Pre-edit window closed"); } text_drawing_selected(); draw_mousefun_canvas(); } static open_preedit_proc(x, y) int x, y; { int i; if (!is_preedit_running()) { put_msg("Opening pre-edit window..."); draw_mousefun_canvas(); set_temp_cursor(wait_cursor); preedit_pid = fork(); if (preedit_pid == -1) { /* cannot fork */ fprintf(stderr, "Can't fork the process: %s\n", strerror(errno)); } else if (preedit_pid == 0) { /* child process; execute xfig-preedit */ execlp(appres.text_preedit, appres.text_preedit, preedit_filename, NULL); fprintf(stderr, "Can't execute %s\n", appres.text_preedit); exit(-1); } else { /* parent process; wait until xfig-preedit is up */ for (i = 0; i < 10 && !is_preedit_running(); i++) sleep(1); } if (is_preedit_running()) put_msg("Pre-edit window opened"); else put_msg("Can't open pre-edit window"); reset_cursor(); } text_drawing_selected(); draw_mousefun_canvas(); } static paste_preedit_proc(x, y) int x, y; { FILE *fp; char ch; if (!is_preedit_running()) { open_preedit_proc(x, y); } else if ((fp = fopen(preedit_filename, "r")) != NULL) { init_text_input(x, y); while ((ch = getc(fp)) != EOF) { if (ch == '\\') new_text_line(); else prefix[leng_prefix++] = ch; } prefix[leng_prefix] = '\0'; finish_text_input(0,0,0); fclose(fp); put_msg("Text pasted from pre-edit window"); } else { put_msg("Can't get text from pre-edit window"); } text_drawing_selected(); draw_mousefun_canvas(); } #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ xfig.3.2.5c/e_addpt.c0000700002656300244210000002344611641414046015131 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_addpt.h" #include "u_create.h" #include "u_draw.h" #include "u_elastic.h" #include "u_list.h" #include "u_search.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_mousefun.h" #include "w_modepanel.h" #include "u_geom.h" #include "u_markers.h" #include "u_redraw.h" #include "u_undo.h" #include "w_cursor.h" static void init_point_adding(F_line *p, int type, int x, int y, int px, int py); static void fix_linepoint_adding(int x, int y); static void fix_splinepoint_adding(int x, int y); static void init_linepointadding(int px, int py); static void init_splinepointadding(int px, int py); void point_adding_selected(void) { set_mousefun("break/add here", "", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_point_adding); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); force_nopositioning(); force_anglegeom(); constrained = MOVE_ARB; reset_action_on(); } static void init_point_adding(F_line *p, int type, int x, int y, int px, int py) { set_action_on(); set_mousefun("place new point", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); set_cursor(null_cursor); switch (type) { case O_POLYLINE: cur_l = (F_line *) p; /* the search routine will ensure that we don't have a box */ init_linepointadding(px, py); break; case O_SPLINE: cur_s = (F_spline *) p; init_splinepointadding(px, py); break; default: return; } force_positioning(); /* draw in rubber-band line */ elastic_linelink(); if (left_point == NULL || right_point == NULL) { if (latexline_mode || latexarrow_mode) { canvas_locmove_proc = latex_line; canvas_ref_proc = elastic_line; return; } if (mountain_mode || manhattan_mode) { canvas_locmove_proc = constrainedangle_line; canvas_ref_proc = elastic_line; return; } } else { force_noanglegeom(); } canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; } static void wrapup_pointadding(void) { reset_action_on(); point_adding_selected(); draw_mousefun_canvas(); } static void cancel_pointadding(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_linelink(); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_pointadding(); } static void cancel_line_pointadding(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; if (left_point != NULL && right_point != NULL) pw_vector(canvas_win, left_point->x, left_point->y, right_point->x, right_point->y, PAINT, cur_l->thickness, cur_l->style, cur_l->style_val, cur_l->pen_color); cancel_pointadding(); } /************************** spline *******************************/ static void init_splinepointadding(int px, int py) { find_endpoints(cur_s->points, px, py, &left_point, &right_point); cur_x = fix_x = px; cur_y = fix_y = py; if (left_point == NULL && closed_spline(cur_s)) { /* The added_point is between the 1st and 2nd point. */ left_point = right_point; right_point = right_point->next; } if (right_point == NULL && closed_spline(cur_s)) { /* The added_point is between the last and 1st point. */ right_point = cur_s->points; } canvas_leftbut_proc = fix_splinepoint_adding; canvas_rightbut_proc = cancel_pointadding; /* turn off all markers */ update_markers(0); } static void fix_splinepoint_adding(int x, int y) { F_point *p; /* if this point is coincident with the point being added to, return */ if (((left_point == NULL) && (cur_x == cur_s->points[0].x) && (cur_y == cur_s->points[0].y)) || ((left_point != NULL) && (left_point->x == cur_x) && (left_point->y == cur_y))) { return; } (*canvas_locmove_proc) (x, y); if ((p = create_point()) == NULL) { wrapup_pointadding(); return; } p->x = cur_x; p->y = cur_y; elastic_linelink(); wrapup_pointadding(); splinepoint_adding(cur_s, left_point, p, right_point, approx_spline(cur_s) ? S_SPLINE_APPROX : S_SPLINE_INTERP); /* turn back on all relevant markers */ update_markers(new_objmask); } /* * Added_point is always inserted between left_point and * right_point, except in two cases. (1) left_point is NULL, the added_point * will be prepended to the list of points. (2) right_point is NULL, the * added_point will be appended to the end of the list. */ void splinepoint_adding(F_spline *spline, F_point *left_point, F_point *added_point, F_point *right_point, double sfactor) { F_sfactor *c, *prev_sfactor; if ((c = create_sfactor()) == NULL) return; set_temp_cursor(wait_cursor); /* delete it and redraw underlying objects */ list_delete_spline(&objects.splines, spline); redisplay_spline(spline); if (left_point == NULL) { added_point->next = spline->points; spline->points = added_point; if (open_spline(spline)) { c->s = S_SPLINE_ANGULAR; spline->sfactors->s = sfactor; } else c->s = sfactor; c->next = spline->sfactors; spline->sfactors = c; } else { prev_sfactor = search_sfactor(spline, left_point); if (open_spline(spline) && (right_point == NULL)) { c->s = S_SPLINE_ANGULAR; prev_sfactor->s = sfactor; } else c->s = sfactor; c->next = prev_sfactor->next; prev_sfactor->next = c; added_point->next = left_point->next; /*right_point;*/ left_point->next = added_point; } /* put it back in the list and draw the new spline */ list_add_spline(&objects.splines, spline); /* redraw it and anything on top of it */ redisplay_spline(spline); clean_up(); set_modifiedflag(); set_last_prevpoint(left_point); set_last_selectedpoint(added_point); set_action_object(F_ADD_POINT, O_SPLINE); set_latestspline(spline); reset_cursor(); } /*************************** line ********************************/ static void init_linepointadding(int px, int py) { find_endpoints(cur_l->points, px, py, &left_point, &right_point); /* set cur_x etc at new point coords */ cur_x = fix_x = px; cur_y = fix_y = py; if (left_point == NULL && cur_l->type == T_POLYGON) { left_point = right_point; right_point = right_point->next; } /* erase line segment where new point is */ if (left_point != NULL && right_point != NULL) pw_vector(canvas_win, left_point->x, left_point->y, right_point->x, right_point->y, ERASE, cur_l->thickness, cur_l->style, cur_l->style_val, cur_l->pen_color); canvas_leftbut_proc = fix_linepoint_adding; canvas_rightbut_proc = cancel_line_pointadding; /* turn off all markers */ update_markers(0); } static void fix_linepoint_adding(int x, int y) { F_point *p; /* if this point is coincident with the point being added to, return */ if (((left_point == NULL) && (cur_x == cur_l->points[0].x) && (cur_y == cur_l->points[0].y)) || ((left_point != NULL) && (left_point->x == cur_x) && (left_point->y == cur_y))) { return; } (*canvas_locmove_proc) (x, y); if ((p = create_point()) == NULL) { wrapup_pointadding(); return; } p->x = cur_x; p->y = cur_y; elastic_linelink(); wrapup_pointadding(); linepoint_adding(cur_l, left_point, p); /* turn back on all relevant markers */ update_markers(new_objmask); } void linepoint_adding(F_line *line, F_point *left_point, F_point *added_point) { /* turn off all markers */ update_markers(0); /* delete it and redraw underlying objects */ list_delete_line(&objects.lines, line); redisplay_line(line); if (left_point == NULL) { added_point->next = line->points; line->points = added_point; } else { added_point->next = left_point->next; left_point->next = added_point; } /* put it back in the list and draw the new line */ list_add_line(&objects.lines, line); /* redraw it and anything on top of it */ redisplay_line(line); clean_up(); set_action_object(F_ADD_POINT, O_POLYLINE); set_latestline(line); set_last_prevpoint(left_point); set_last_selectedpoint(added_point); set_modifiedflag(); } /*******************************************************************/ /* * If (x,y) is close to a point q, fp points to q and sp points to q->next * (right). However if q is the first point, fp contains NULL and sp points * to q. */ void find_endpoints(F_point *p, int x, int y, F_point **fp, F_point **sp) { int d; F_point *a = NULL, *b = p; if (x == b->x && y == b->y) { *fp = a; *sp = b; return; } for (a = p, b = p->next; b != NULL; a = b, b = b->next) { if (x == b->x && y == b->y) { *fp = b; *sp = b->next; return; } if (close_to_vector(a->x, a->y, b->x, b->y, x, y, 1, 1.0, &d, &d)) { *fp = a; *sp = b; return; } } *fp = a; *sp = b; } xfig.3.2.5c/e_align.c0000700002656300244210000005734711641414046015136 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "paintop.h" #include "mode.h" #include "u_create.h" #include "u_draw.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_layers.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "u_bound.h" #include "u_markers.h" #include "u_translate.h" #include "w_cursor.h" static int llx, lly, urx, ury; static int xcmin, ycmin, xcmax, ycmax; static int dx, dy; static Boolean pos_arc(F_arc *a, int *min, int *size, int dir); static Boolean pos_ellipse(F_ellipse *e, int *min, int *size, int dir); static Boolean pos_line(F_line *l, int *min, int *size, int dir); static Boolean pos_spline(F_spline *s, int *min, int *size, int dir); static Boolean pos_text(F_text *t, int *min, int *size, int dir); static Boolean pos_compound(F_compound *c, int *min, int *size, int dir); static void init_align(F_line *p, int type, int x, int y, int px, int py); static void init_align_canvas(int x, int y, unsigned int shift); static void align_arc(void); static void align_ellipse(void); static void align_line(void); static void align_spline(void); static void align_text(void); static void align_compound(void); static void get_dx_dy(void); static void distribute_horizontally(void); static void distribute_vertically(void); void align_selected(void) { set_mousefun("align compound", "align canvas", "", LOC_OBJ, "", LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_align); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = init_align_canvas; canvas_rightbut_proc = null_proc; set_cursor(pick15_cursor); reset_action_on(); } /* align objects to the whole canvas */ static void init_align_canvas(int x, int y, unsigned int shift) /* Shift Key Status from XEvent */ { int ux; cur_c = &objects; toggle_all_compoundmarkers(); draw_compoundelements(cur_c, ERASE); old_c = copy_compound(&objects); xcmin=ycmin=0; /* get the current page size */ xcmax = paper_sizes[appres.papersize].width; ycmax = paper_sizes[appres.papersize].height; if (!appres.INCHES) { xcmax = (int)(xcmax*2.54*PIX_PER_CM/PIX_PER_INCH); ycmax = (int)(ycmax*2.54*PIX_PER_CM/PIX_PER_INCH); } /* swap height and width if landscape */ if (appres.landscape) { ux = xcmax; xcmax = ycmax; ycmax = ux; } align_ellipse(); align_arc(); align_line(); align_spline(); align_compound(); align_text(); /* * Display messages indicating that distribution or alignment can't be * performed with respect to the canvas. */ if ((cur_halign == ALIGN_DISTRIB_C) || (cur_halign == ALIGN_DISTRIB_E)) put_msg("Can't DISTRIBUTE horizontally with respect to the canvas"); else if (cur_halign == ALIGN_ABUT) put_msg("Can't ABUT horizontally with respect to the canvas"); if ((cur_valign == ALIGN_DISTRIB_C) || (cur_valign == ALIGN_DISTRIB_E)) put_msg("Can't DISTRIBUTE vertically with respect to the canvas"); else if (cur_valign == ALIGN_ABUT) put_msg("Can't ABUT vertically with respect to the canvas"); draw_compoundelements(cur_c, PAINT); toggle_all_compoundmarkers(); clean_up(); set_latestobjects(old_c); set_action_object(F_EDIT, O_ALL_OBJECT); set_modifiedflag(); } static void init_align(F_line *p, int type, int x, int y, int px, int py) { if (type != O_COMPOUND) return; cur_c = (F_compound *) p; toggle_compoundmarker(cur_c); draw_compoundelements(cur_c, ERASE); old_c = copy_compound(cur_c); compound_bound(cur_c, &xcmin, &ycmin, &xcmax, &ycmax); align_ellipse(); align_arc(); align_line(); align_spline(); align_compound(); align_text(); /* * Perform the distribution of the objects in the compound */ if ( (cur_halign == ALIGN_DISTRIB_C) || (cur_halign == ALIGN_DISTRIB_E) || (cur_halign == ALIGN_ABUT) ) distribute_horizontally(); if ( (cur_valign == ALIGN_DISTRIB_C) || (cur_valign == ALIGN_DISTRIB_E) || (cur_valign == ALIGN_ABUT) ) distribute_vertically(); /* * recompute the compound's bounding box */ compound_bound(cur_c, &cur_c->nwcorner.x, &cur_c->nwcorner.y, &cur_c->secorner.x, &cur_c->secorner.y); draw_compoundelements(cur_c, PAINT); toggle_compoundmarker(cur_c); clean_up(); old_c->next = cur_c; set_latestcompound(old_c); set_action_object(F_EDIT, O_COMPOUND); set_modifiedflag(); } static void align_ellipse(void) { F_ellipse *e; for (e = cur_c->ellipses; e != NULL; e = e->next) { if (!active_layer(e->depth)) continue; ellipse_bound(e, &llx, &lly, &urx, &ury); get_dx_dy(); translate_ellipse(e, dx, dy); } } static void align_arc(void) { F_arc *a; for (a = cur_c->arcs; a != NULL; a = a->next) { if (!active_layer(a->depth)) continue; arc_bound(a, &llx, &lly, &urx, &ury); get_dx_dy(); translate_arc(a, dx, dy); } } static void align_line(void) { F_line *l; for (l = cur_c->lines; l != NULL; l = l->next) { if (!active_layer(l->depth)) continue; line_bound(l, &llx, &lly, &urx, &ury); get_dx_dy(); translate_line(l, dx, dy); } } static void align_spline(void) { F_spline *s; for (s = cur_c->splines; s != NULL; s = s->next) { if (!active_layer(s->depth)) continue; spline_bound(s, &llx, &lly, &urx, &ury); get_dx_dy(); translate_spline(s, dx, dy); } } static void align_compound(void) { F_compound *c; for (c = cur_c->compounds; c != NULL; c = c->next) { if (!any_active_in_compound(c)) continue; compound_bound(c, &llx, &lly, &urx, &ury); get_dx_dy(); translate_compound(c, dx, dy); } } static void align_text(void) { F_text *t; int dum; for (t = cur_c->texts; t != NULL; t = t->next) { if (!active_layer(t->depth)) continue; text_bound(t, &llx, &lly, &urx, &ury, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); get_dx_dy(); translate_text(t, dx, dy); } } static void get_dx_dy(void) { switch (cur_valign) { case ALIGN_NONE: dy = 0; break; case ALIGN_TOP: dy = ycmin - lly; break; case ALIGN_BOTTOM: dy = ycmax - ury; break; case ALIGN_CENTER: dy = (ycmin - lly) + (abs(ycmin - lly) + abs(ycmax - ury)) / 2; break; case ALIGN_DISTRIB_C: case ALIGN_DISTRIB_E: case ALIGN_ABUT: break; } switch (cur_halign) { case ALIGN_NONE: dx = 0; break; case ALIGN_LEFT: dx = xcmin - llx; break; case ALIGN_RIGHT: dx = xcmax - urx; break; case ALIGN_CENTER: dx = (xcmin - llx) + (abs(xcmin - llx) + abs(xcmax - urx)) / 2; break; case ALIGN_DISTRIB_C: case ALIGN_DISTRIB_E: case ALIGN_ABUT: break; } } /* ====================== Object distribution routines =================== */ /* * pos_arc: If the position of the given arc is less than * passed in and the arc hasn't already been distributed, adjust the value * of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_arc (F_arc *a, int *min, int *size, int dir) { int center; arc_bound (a, &llx, &lly, &urx, &ury); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (a->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_arc */ /* * pos_ellipse: If the position of the given ellipse is less * than passed in and the ellipse hasn't already been distributed, adjust the * value of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_ellipse (F_ellipse *e, int *min, int *size, int dir) { int center; ellipse_bound (e, &llx, &lly, &urx, &ury); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (e->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_ellipse */ /* * pos_line: If the position of the given line is less than * passed in and the line hasn't already been distributed, adjust the value * of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_line (F_line *l, int *min, int *size, int dir) { int center; line_bound (l, &llx, &lly, &urx, &ury); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (l->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_line */ /* * pos_spline: If the position of the given spline is less than * passed in and the spline hasn't already been distributed, adjust the value * of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_spline (F_spline *s, int *min, int *size, int dir) { int center; spline_bound (s, &llx, &lly, &urx, &ury); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (s->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_spline */ /* * pos_text: If the position of the given text is less than * passed in and the text hasn't already been distributed, adjust the value * of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_text (F_text *t, int *min, int *size, int dir) { int center, dum; text_bound (t, &llx, &lly, &urx, &ury, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (t->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_text */ /* * pos_compound: If the position of the given compound is less * than passed in and the compound hasn't already been distributed, adjust the * value of the passed in parameter. Also set the width/height if smaller. * If dir == 0, handle horizontal, otherwise vertical. */ static Boolean pos_compound (F_compound *c, int *min, int *size, int dir) { int center; compound_bound (c, &llx, &lly, &urx, &ury); if (dir == 0) { if (cur_halign == ALIGN_DISTRIB_C) center = (urx + llx)/2; else center = min2(urx, llx); } else { if (cur_valign == ALIGN_DISTRIB_C) center = (ury + lly)/2; else center = min2(ury, lly); } if ( (center < *min) && (c->distrib == 0) ) { *min = center; if (dir == 0) *size = abs(urx - llx); else *size = abs(ury - lly); return True; } else return False; } /* pos_compound */ #define MIN_MAX_CENTRE(lower,upper,min,max) \ { \ int centre = (lower + upper)/2; \ if (centre < min) \ min = centre; \ if (centre > max) \ max = centre; \ } /* * Determine: * - the number of objects, * - the left/top most centre and the right/bottom most centre, * - mark all objects as not distributed. * * dir = 0 for horizontal, 1 for vertical. */ static int init_distrib_centres (int *min, int *max, int dir) { F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; int num_objects = 0; *min = INT_MAX; *max = INT_MIN; for (e = cur_c->ellipses; e != NULL; e = e->next) { num_objects++; e->distrib = 0; ellipse_bound (e, &llx, &lly, &urx, &ury); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } for (a = cur_c->arcs; a != NULL; a = a->next) { num_objects++; a->distrib = 0; arc_bound (a, &llx, &lly, &urx, &ury); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } for (l = cur_c->lines; l != NULL; l = l->next) { num_objects++; l->distrib = 0; line_bound (l, &llx, &lly, &urx, &ury); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } for (s = cur_c->splines; s != NULL; s = s->next) { num_objects++; s->distrib = 0; spline_bound (s, &llx, &lly, &urx, &ury); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } for (c = cur_c->compounds; c != NULL; c = c->next) { num_objects++; c->distrib = 0; compound_bound (c, &llx, &lly, &urx, &ury); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } for (t = cur_c->texts; t != NULL; t = t->next) { int dum; num_objects++; t->distrib = 0; text_bound (t, &llx, &lly, &urx, &ury, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); if (dir == 0) MIN_MAX_CENTRE(llx, urx, *min, *max) else MIN_MAX_CENTRE(lly, ury, *min, *max) } return (num_objects); } /* init_distrib_centres */ /* * Determine: * - the number of objects, * - the sum of the widths/heights of all objects, * - the left/top most left/top object edge, * - the right/bottom most right/bottom object edge, * - mark all objects as not distributed. * * dir = 0 for horizontal, 1 for vertical. */ static int init_distrib_edges (int *min, int *max, int *sum, int dir) { F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; int num_objects = 0; *min = INT_MAX; *max = INT_MIN; *sum = 0; for (e = cur_c->ellipses; e != NULL; e = e->next) { num_objects++; e->distrib = 0; ellipse_bound (e, &llx, &lly, &urx, &ury); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } for (a = cur_c->arcs; a != NULL; a = a->next) { num_objects++; a->distrib = 0; arc_bound (a, &llx, &lly, &urx, &ury); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } for (l = cur_c->lines; l != NULL; l = l->next) { num_objects++; l->distrib = 0; line_bound (l, &llx, &lly, &urx, &ury); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } for (s = cur_c->splines; s != NULL; s = s->next) { num_objects++; s->distrib = 0; spline_bound (s, &llx, &lly, &urx, &ury); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } for (c = cur_c->compounds; c != NULL; c = c->next) { num_objects++; c->distrib = 0; compound_bound (c, &llx, &lly, &urx, &ury); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } for (t = cur_c->texts; t != NULL; t = t->next) { int dum; num_objects++; t->distrib = 0; text_bound (t, &llx, &lly, &urx, &ury, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); if (dir == 0) { *sum += abs(urx - llx); if (llx < *min) *min = llx; if (urx > *max) *max = urx; } else { *sum += abs(ury - lly); if (lly < *min) *min = lly; if (ury > *max) *max = ury; } } return (num_objects); } /* init_distrib_edges */ static void adjust_object_pos (F_line *obj_ptr, int obj_type, int delta_x, int delta_y) { F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; switch (obj_type) { case O_ELLIPSE: e = (F_ellipse *) obj_ptr; translate_ellipse(e, delta_x, delta_y); e->distrib = 1; break; case O_POLYLINE: l = (F_line *) obj_ptr; translate_line(l, delta_x, delta_y); l->distrib = 1; break; case O_SPLINE: s = (F_spline *) obj_ptr; translate_spline(s, delta_x, delta_y); s->distrib = 1; break; case O_TXT: t = (F_text *) obj_ptr; translate_text(t, delta_x, delta_y); t->distrib = 1; break; case O_ARC: a = (F_arc *) obj_ptr; translate_arc(a, delta_x, delta_y); a->distrib = 1; break; case O_COMPOUND: c = (F_compound *) obj_ptr; translate_compound(c, delta_x, delta_y); c->distrib = 1; break; default: break; } } /* adjust_object_pos */ static void distribute_horizontally(void) { int num_objects = 0; F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; float inter_obj_space; int min_x, max_x; int obj1, obj2; int obj_type; F_line *obj_ptr; int min_left, min_width; int req_pos; int sum_obj_width; if (cur_halign == ALIGN_DISTRIB_C) num_objects = init_distrib_centres (&min_x, &max_x, 0); else { num_objects = init_distrib_edges (&min_x, &max_x, &sum_obj_width, 0); req_pos = min_x; } if (num_objects <= 1) return; /* Determine the amount of space between objects (centres or edges) */ if (cur_halign == ALIGN_DISTRIB_C) inter_obj_space = (float) (max_x - min_x) / (float)(num_objects - 1); else if (cur_halign == ALIGN_DISTRIB_E) inter_obj_space = (float) (max_x - min_x - sum_obj_width) / (float)(num_objects - 1); else inter_obj_space = 0.0; /* * Go through all of the objects, finding the left most, then the second * left-most, ... */ for (obj1=0; obj1ellipses; e != NULL; e = e->next) if (pos_ellipse(e, &min_left, &min_width, 0)) { obj_ptr = (F_line *) e; obj_type = O_ELLIPSE; } for (a = cur_c->arcs; a != NULL; a = a->next) if (pos_arc(a, &min_left, &min_width, 0)) { obj_ptr = (F_line *) a; obj_type = O_ARC; } for (l = cur_c->lines; l != NULL; l = l->next) if (pos_line(l, &min_left, &min_width, 0)) { obj_ptr = l; obj_type = O_POLYLINE; } for (s = cur_c->splines; s != NULL; s = s->next) if (pos_spline(s, &min_left, &min_width, 0)) { obj_ptr = (F_line *) s; obj_type = O_SPLINE; } for (c = cur_c->compounds; c != NULL; c = c->next) if (pos_compound(c, &min_left, &min_width, 0)) { obj_ptr = (F_line *) c; obj_type = O_COMPOUND; } for (t = cur_c->texts; t != NULL; t = t->next) if (pos_text(t, &min_left, &min_width, 0)) { obj_ptr = (F_line *) t; obj_type = O_TXT; } } /* Determine the new horizontal position of the object */ if (cur_halign == ALIGN_DISTRIB_C) req_pos = min_x + (int)((float)obj1 * inter_obj_space); /* Adjust position of left-most undistributed object */ adjust_object_pos (obj_ptr, obj_type, req_pos - min_left, 0); /* Determine the horizontal position of the next object */ if ( (cur_halign == ALIGN_DISTRIB_E) || (cur_halign == ALIGN_ABUT) ) req_pos += min_width + (int)inter_obj_space; } /* next object */ } /* distribute_horizontally */ static void distribute_vertically(void) { int num_objects = 0; F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; float inter_obj_space; int min_y, max_y; int obj1, obj2; int obj_type; F_line *obj_ptr; int min_top, min_height; int req_pos; int sum_obj_height; if (cur_valign == ALIGN_DISTRIB_C) num_objects = init_distrib_centres (&min_y, &max_y, 1); else { num_objects = init_distrib_edges (&min_y, &max_y, &sum_obj_height, 1); req_pos = min_y; } if (num_objects <= 1) return; /* Determine the amount of space between objects (centres or edges) */ if (cur_valign == ALIGN_DISTRIB_C) inter_obj_space = (float) (max_y - min_y) / (float)(num_objects - 1); else if (cur_valign == ALIGN_DISTRIB_E) inter_obj_space = (float) (max_y - min_y - sum_obj_height) / (float)(num_objects - 1); else inter_obj_space = 0.0; /* * Go through all of the objects, finding the top-most, then the second * top-most, ... */ for (obj1=0; obj1ellipses; e != NULL; e = e->next) if (pos_ellipse(e, &min_top, &min_height, 1)) { obj_ptr = (F_line *) e; obj_type = O_ELLIPSE; } for (a = cur_c->arcs; a != NULL; a = a->next) if (pos_arc(a, &min_top, &min_height, 1)) { obj_ptr = (F_line *) a; obj_type = O_ARC; } for (l = cur_c->lines; l != NULL; l = l->next) if (pos_line(l, &min_top, &min_height, 1)) { obj_ptr = (F_line *) l; obj_type = O_POLYLINE; } for (s = cur_c->splines; s != NULL; s = s->next) if (pos_spline(s, &min_top, &min_height, 1)) { obj_ptr = (F_line *) s; obj_type = O_SPLINE; } for (c = cur_c->compounds; c != NULL; c = c->next) if (pos_compound(c, &min_top, &min_height, 1)) { obj_ptr = (F_line *) c; obj_type = O_COMPOUND; } for (t = cur_c->texts; t != NULL; t = t->next) if (pos_text(t, &min_top, &min_height, 1)) { obj_ptr = (F_line *) t; obj_type = O_TXT; } } /* Determine the new vertical position of the object */ if (cur_valign == ALIGN_DISTRIB_C) req_pos = min_y + (int)((float)obj1 * inter_obj_space); /* Adjust position of left-most undistributed object */ adjust_object_pos (obj_ptr, obj_type, 0, req_pos - min_top); /* Determine the virtical position of the next object */ if ((cur_valign == ALIGN_DISTRIB_E) || (cur_valign == ALIGN_ABUT) ) req_pos += min_height + (int)inter_obj_space; } } /* distribute_vertically */ xfig.3.2.5c/e_arrow.c0000700002656300244210000001717411641414046015170 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_arrow.h" #include "u_create.h" #include "u_draw.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_mousefun.h" #include "u_redraw.h" #include "w_cursor.h" static void add_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void delete_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void add_linearrow(F_line *line, F_point *prev_point, F_point *selected_point); static void add_arcarrow(F_arc *arc, int point_num); static void add_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point); void arrow_head_selected(void) { set_mousefun("add arrow", "delete arrow", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(add_arrow_head); init_searchproc_middle(delete_arrow_head); canvas_leftbut_proc = point_search_left; canvas_middlebut_proc = point_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); reset_action_on(); } static void add_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; add_linearrow(cur_l, p, q); break; case O_SPLINE: cur_s = (F_spline *) obj; add_splinearrow(cur_s, p, q); break; case O_ARC: cur_a = (F_arc *) obj; /* dirty trick - arc point number is stored in p */ add_arcarrow(cur_a, (int) p); break; } } static void delete_arrow_head(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; delete_linearrow(cur_l, p, q); break; case O_SPLINE: cur_s = (F_spline *) obj; delete_splinearrow(cur_s, p, q); break; case O_ARC: cur_a = (F_arc *) obj; /* dirty trick - arc point number is stored in p */ delete_arcarrow(cur_a, (int) p); break; } } static void add_linearrow(F_line *line, F_point *prev_point, F_point *selected_point) { if (line->points->next == NULL) return; /* A single point line */ if (prev_point == NULL) { /* selected_point is the first point */ if (line->back_arrow) return; line->back_arrow = backward_arrow(); redisplay_line(line); } else if (selected_point->next == NULL) { /* forward arrow */ if (line->for_arrow) return; line->for_arrow = forward_arrow(); redisplay_line(line); } else return; clean_up(); set_last_prevpoint(prev_point); set_last_selectedpoint(selected_point); set_latestline(line); set_action_object(F_ADD_ARROW_HEAD, O_POLYLINE); set_modifiedflag(); } static void add_arcarrow(F_arc *arc, int point_num) { /* only allow arrowheads on open arc */ if (arc->type == T_PIE_WEDGE_ARC) return; if (point_num == 0) { /* backward arrow */ if (arc->back_arrow) return; arc->back_arrow = backward_arrow(); redisplay_arc(arc); } else if (point_num == 2) {/* for_arrow */ if (arc->for_arrow) return; arc->for_arrow = forward_arrow(); redisplay_arc(arc); } else return; clean_up(); set_last_arcpointnum(point_num); set_latestarc(arc); set_action_object(F_ADD_ARROW_HEAD, O_ARC); set_modifiedflag(); } static void add_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point) { if (prev_point == NULL) { /* add backward arrow */ if (spline->back_arrow) return; spline->back_arrow = backward_arrow(); redisplay_spline(spline); } else if (selected_point->next == NULL) { /* add forward arrow */ if (spline->for_arrow) return; spline->for_arrow = forward_arrow(); redisplay_spline(spline); } clean_up(); set_last_prevpoint(prev_point); set_last_selectedpoint(selected_point); set_latestspline(spline); set_action_object(F_ADD_ARROW_HEAD, O_SPLINE); set_modifiedflag(); } void delete_linearrow(F_line *line, F_point *prev_point, F_point *selected_point) { if (line->points->next == NULL) return; /* A single point line */ if (prev_point == NULL) { /* selected_point is the first point */ if (!line->back_arrow) return; draw_line(line, ERASE); saved_back_arrow=line->back_arrow; if (saved_for_arrow && saved_for_arrow != line->for_arrow) free((char *) saved_for_arrow); saved_for_arrow = NULL; line->back_arrow = NULL; redisplay_line(line); } else if (selected_point->next == NULL) { /* forward arrow */ if (!line->for_arrow) return; draw_line(line, ERASE); saved_for_arrow=line->for_arrow; if (saved_back_arrow && saved_back_arrow != line->back_arrow) free((char *) saved_back_arrow); saved_back_arrow = NULL; line->for_arrow = NULL; redisplay_line(line); } else return; clean_up(); set_last_prevpoint(prev_point); set_last_selectedpoint(selected_point); set_latestline(line); set_action_object(F_DELETE_ARROW_HEAD, O_POLYLINE); set_modifiedflag(); } void delete_arcarrow(F_arc *arc, int point_num) { if (arc->type == T_PIE_WEDGE_ARC) return;; if (point_num == 0) { /* backward arrow */ if (!arc->back_arrow) return; draw_arc(arc, ERASE); saved_back_arrow=arc->back_arrow; if (saved_for_arrow && saved_for_arrow != arc->for_arrow) free((char *) saved_for_arrow); saved_for_arrow = NULL; arc->back_arrow = NULL; redisplay_arc(arc); } else if (point_num == 2) {/* for_arrow */ if (!arc->for_arrow) return; draw_arc(arc, ERASE); saved_for_arrow=arc->for_arrow; if (saved_back_arrow && saved_back_arrow != arc->back_arrow) free((char *) saved_back_arrow); saved_back_arrow = NULL; arc->for_arrow = NULL; redisplay_arc(arc); } else return; clean_up(); set_last_arcpointnum(point_num); set_latestarc(arc); set_action_object(F_DELETE_ARROW_HEAD, O_ARC); set_modifiedflag(); } void delete_splinearrow(F_spline *spline, F_point *prev_point, F_point *selected_point) { if (closed_spline(spline)) return; if (prev_point == NULL) { /* selected_point is the first point */ if (!spline->back_arrow) return; draw_spline(spline, ERASE); saved_back_arrow=spline->back_arrow; if (saved_for_arrow && saved_for_arrow != spline->for_arrow) free((char *) saved_for_arrow); saved_for_arrow = NULL; spline->back_arrow = NULL; redisplay_spline(spline); } else if (selected_point->next == NULL) { /* forward arrow */ if (!spline->for_arrow) return; draw_spline(spline, ERASE); saved_for_arrow=spline->for_arrow; if (saved_back_arrow && saved_back_arrow != spline->back_arrow) free((char *) saved_back_arrow); saved_back_arrow = NULL; spline->for_arrow = NULL; redisplay_spline(spline); } else return; clean_up(); set_last_prevpoint(prev_point); set_last_selectedpoint(selected_point); set_latestspline(spline); set_action_object(F_DELETE_ARROW_HEAD, O_SPLINE); set_modifiedflag(); } xfig.3.2.5c/e_break.c0000700002656300244210000000474511641414046015122 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_search.h" #include "u_list.h" #include "u_undo.h" #include "w_canvas.h" #include "w_mousefun.h" #include "u_markers.h" #include "w_cursor.h" static void init_break(F_line *p, int type, int x, int y, int px, int py, int loc_tag); static void init_break_only(F_line *p, int type, int x, int y, int px, int py); static void init_break_tag(F_line *p, int type, int x, int y, int px, int py); void break_selected(void) { set_mousefun("break compound", "break and tag", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_break_only); init_searchproc_middle(init_break_tag); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick15_cursor); reset_action_on(); } static void init_break_only(F_line *p, int type, int x, int y, int px, int py) { init_break(p, type, x, y, px, py, 0); } static void init_break_tag(F_line *p, int type, int x, int y, int px, int py) { init_break(p, type, x, y, px, py, 1); } static void init_break(F_line *p, int type, int x, int y, int px, int py, int loc_tag) { if (type != O_COMPOUND) return; cur_c = (F_compound *) p; mask_toggle_compoundmarker(cur_c); clean_up(); list_delete_compound(&objects.compounds, cur_c); tail(&objects, &object_tails); append_objects(&objects, cur_c, &object_tails); toggle_markers_in_compound(cur_c); set_tags(cur_c, loc_tag); set_action(F_BREAK); set_latestcompound(cur_c); set_modifiedflag(); } xfig.3.2.5c/e_chop.c0000700002656300244210000006067412010766644014777 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* >>>>>>>>>>>>>>>>>>> fixme -- don't forget undo ! <<<<<<<<<<<<<<<< */ #include #ifndef __FreeBSD__ #include #endif #include #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "u_create.h" #include "u_draw.h" #include "u_list.h" #include "u_search.h" #include "u_undo.h" #include "u_markers.h" #include "u_geom.h" #include "u_redraw.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_modepanel.h" #include "w_zoom.h" #include "w_snap.h" #include "w_intersect.h" #include "w_cursor.h" #include "f_util.h" static void select_axe_object(); static void select_log_object(); static void clear_axe_objects(); typedef struct { void * object; int type; } axe_objects_s; static axe_objects_s * axe_objects = NULL; static int axe_objects_next = 0; static int axe_objects_max = 0; #define AXE_OBJECTS_INCR 8 typedef enum { PTYPE_NONE, PTYPE_START_PLINE, PTYPE_START_VERTEX, PTYPE_END_VERTEX, PTYPE_END_PLINE, PTYPE_CUT } ptype_e; typedef struct { int x; int y; ptype_e ptype; double dist; } s_point_s; typedef struct { s_point_s * points; int points_next; int points_max; } l_point_s; #define POINTS_INCR 8 void chop_selected(void) { set_mousefun("Select axe object", "Select log object", "Clear axe list", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(select_axe_object); init_searchproc_middle(select_log_object); /* init_searchproc_right(init_chop_right); */ /* fixme don't need this now */ canvas_leftbut_proc = object_search_left; /* point search for axe */ canvas_middlebut_proc = object_search_middle; /* object search for log */ canvas_rightbut_proc = clear_axe_objects; set_cursor(pick9_cursor); /* set the markers to show we only allow POLYLINES, ARCS and ELLIPSES */ /* (the markers are originally set this way from the mode panel, but we need to set them again after the previous chop */ /* fixme -- neede for chop ? */ update_markers(M_POLYLINE | M_ARC | M_ELLIPSE); reset_action_on(); axe_objects_next = 0; } static void select_axe_object(obj, type, x, y, p, q) /* select axe objects */ void * obj; int type; int x, y; F_point * p; F_point * q; { int i; for (i = 0; i < axe_objects_next; i++) { if ((axe_objects[i].type == type) && (axe_objects[i].object == obj)) { put_msg("Duplicate axe object selected."); beep(); return; } } if (axe_objects_max <= axe_objects_next) { axe_objects_max += AXE_OBJECTS_INCR; axe_objects = realloc(axe_objects, axe_objects_max * sizeof(axe_objects_s)); } axe_objects[axe_objects_next].type = type; axe_objects[axe_objects_next++].object = obj; put_msg("Axe object %d selected", axe_objects_next); } static void clear_axe_objects(obj, type, x, y, p, q) /* clear axe objects */ void * obj; int type; int x, y; F_point * p; F_point * q; { put_msg("Axe object list cleared."); axe_objects_next = 0; } static int point_sort_fcn(a, b) s_point_s * a; s_point_s * b; { return (a->dist == b->dist) ? 0 : ((a->dist < b->dist) ? -1 : 1); } static int point_sort_reverse_fcn(a, b) s_point_s * a; s_point_s * b; { return (a->dist == b->dist) ? 0 : ((a->dist > b->dist) ? -1 : 1); } static void create_new_line( int x, int y, F_point ** this_point, F_line ** this_line, F_line * l) { *this_line = create_line(); (*this_line)->type = l->type; (*this_line)->style = l->style; (*this_line)->thickness = l->thickness; (*this_line)->pen_color = l->pen_color; (*this_line)->fill_color = l->fill_color; (*this_line)->depth = l->depth; (*this_line)->pen_style = l->pen_style; (*this_line)->join_style = l->join_style; (*this_line)->cap_style = l->cap_style; (*this_line)->fill_style = l->fill_style; (*this_line)->style_val = l->style_val; if (l->for_arrow) { (*this_line)->for_arrow = create_arrow(); memcpy((*this_line)->for_arrow, l->for_arrow, sizeof(F_arrow)); } if (l->back_arrow) { (*this_line)->back_arrow = create_arrow(); memcpy((*this_line)->back_arrow, l->back_arrow, sizeof(F_arrow)); } (*this_point) = create_point(); (*this_point)->x = x; (*this_point)->y = y; (*this_line)->points = (*this_point); } static Boolean check_poly(F_line * this_line, struct f_point ** i_point_p, int type) { int nr_pts; struct f_point * next_point; struct f_point * this_point; struct f_point * prev_prev_point; struct f_point * prev_point = NULL; if (!this_line || !(this_line->points)) return False; nr_pts = 0; for (this_point = this_line->points; this_point; this_point = next_point) { Boolean update_pp; update_pp = True; next_point = this_point->next; nr_pts++; if (prev_point) { if ((prev_point->x == this_point->x) && (prev_point->y == this_point->y)) { prev_point->next = next_point; free(this_point); nr_pts--; update_pp = False; } } if (True == update_pp) { prev_prev_point = prev_point; prev_point = this_point; } } if (i_point_p) *i_point_p = prev_prev_point; return (nr_pts < ((T_POLYGON == type) ? 3 : 2)) ? False : True; } static int dice_polygons(int nr_segs, l_point_s * top_l_points, F_line * l) { int i, j, k; int rc; int start_x; int start_y; int last_x = -1; int last_y = -1; ptype_e last_ptype = PTYPE_NONE; int start_point = -1; int this_x; int this_y; int this_ptype; F_line * this_line; F_point * this_point; s_point_s * points; int nr_points = 0; for (i = 0; i < nr_segs; i++) { /* analyse points */ for (j = 0; j < top_l_points[i].points_next; j++) { if ((-1 == start_point) && (PTYPE_CUT == top_l_points[i].points[j].ptype)) /* find first cut */ start_point = nr_points; nr_points++; } } if (-1 == start_point) return 0; /* no cuts, shouldn't be possible ... */ if (T_PIE_WEDGE_ARC == cur_arctype) snap_polyline_focus_handler(l, 0, 0); points = alloca(nr_points * sizeof(s_point_s)); for (k = 0, i = 0; i < nr_segs; i++) { /* serialise the points */ for (j = 0; j < top_l_points[i].points_next; j++, k++) { points[k] = top_l_points[i].points[j]; } } rc = 0; this_line = NULL; for (i = 0; i <= nr_points; i++) { /* yes, i do mean "<=" */ j = (start_point + i) % nr_points; this_x = points[j].x; this_y = points[j].y; this_ptype = points[j].ptype; switch(this_ptype) { case PTYPE_END_PLINE: case PTYPE_END_VERTEX: /* do nothing -- same as next start vertex */ break; case PTYPE_CUT: if (this_line) { /* will be null on first cut point */ float area; F_point * i_point; append_point(this_x, this_y, &this_point); /* current point */ if (T_PIE_WEDGE_ARC == cur_arctype) append_point(snap_gx, snap_gy, &this_point); /* centerpoint */ append_point(start_x, start_y, &this_point); /* close pgon */ add_line(this_line); area = 0.0; if (True == check_poly(this_line, &i_point, T_POLYGON)) /* chk for dup adjacent pts */ compute_poly_area(this_line, &area); /* make sure the pgon is real; */ if (0.0 >= area) delete_line(this_line); else { #if 0 /* this creates bizarre but interesting results... */ if (T_PIE_WEDGE_ARC == cur_arctype) insert_point(snap_gx, snap_gy, i_point); #endif rc++; } this_line = NULL; } if (i < (nr_points -1)) { create_new_line(this_x, this_y, &this_point, &this_line, l); start_x = last_x = this_x; start_y = last_y = this_y; last_ptype = this_ptype; } break; case PTYPE_START_VERTEX: case PTYPE_START_PLINE: append_point(this_x, this_y, &this_point); last_x = this_x; last_y = this_y; last_ptype = this_ptype; break; } /* end of switch point type */ } /* end of points loop */ return rc; } static int dice_polylines(int nr_segs, l_point_s * top_l_points, F_line * l) { int i, j; int rc; Boolean completed = False; int last_x = -1; int last_y = -1; ptype_e last_ptype = PTYPE_NONE; rc = 0; for (i = 0; (False == completed) && (i < nr_segs); i++) { /* analyse points */ for (j = 0; (False == completed) && (j < top_l_points[i].points_next); j++) { F_line * this_line; F_point * this_point; int this_x = top_l_points[i].points[j].x; int this_y = top_l_points[i].points[j].y; int this_ptype = top_l_points[i].points[j].ptype; switch(this_ptype) { case PTYPE_END_VERTEX: /* do nothing -- same as next start vertex */ break; case PTYPE_CUT: append_point(this_x, this_y, &this_point); add_line(this_line); if (True == check_poly(this_line, NULL, T_POLYLINE)) rc++; /* chk for dup adjacent pts */ else delete_line(this_line); create_new_line(this_x, this_y, &this_point, &this_line, l); last_x = this_x; last_y = this_y; last_ptype = this_ptype; break; case PTYPE_END_PLINE: append_point(this_x, this_y, &this_point); add_line(this_line); if (True == check_poly(this_line, NULL, T_POLYLINE)) rc++; /* chk for dup adjacent pts */ else delete_line(this_line); completed = True; /* catches anomalous case of cut following end of pline */ break; case PTYPE_START_VERTEX: append_point(this_x, this_y, &this_point); last_x = this_x; last_y = this_y; last_ptype = this_ptype; break; case PTYPE_START_PLINE: create_new_line(this_x, this_y, &this_point, &this_line, l); last_x = this_x; last_y = this_y; last_ptype = this_ptype; break; } /* end of switch point type */ } /* end of points loop with seg */ } /* end of segs loop */ return rc; } static int chop_polyline(F_line * l, int x, int y) { int i, j; isect_cb_s isect_cb; struct f_point * p; int nr_verts; int nr_segs; Boolean runnable; int rc; l_point_s * top_l_points; typedef enum { STATE_PLINE_IDLE, STATE_PLINE_RUNNING } state_pline_e; if ((T_POLYLINE != l->type) && (T_POLYGON != l->type)) { put_msg("Only unconstrained polylines and polygons may be chopped."); beep(); return -1; } rc = 0; isect_cb.nr_isects = 0; isect_cb.max_isects = 0; isect_cb.isects = NULL; /* chopping polyline l by various things */ runnable = True; for (i = 0; i < axe_objects_next; i++) { switch (axe_objects[i].type) { case O_POLYLINE: /* check for congruent axe/log */ if (l == axe_objects[i].object) { put_msg("An axe cannot chop itself."); beep(); runnable = False; break; } else intersect_polyline_polyline_handler((F_line *)(axe_objects[i].object), l, x, y, &isect_cb); break; case O_ARC: intersect_polyline_arc_handler(l, (F_arc *)(axe_objects[i].object), x, y, &isect_cb); break; case O_ELLIPSE: intersect_ellipse_polyline_handler((F_ellipse *)(axe_objects[i].object), l, x, y, &isect_cb); break; } } if ((True == runnable) && (0 < isect_cb.nr_isects)) { if ((T_POLYGON == l->type) && (2 > isect_cb.nr_isects)) { put_msg("Closed figures require two or more intersects."); beep(); return -1; } for (p = l->points, nr_verts = 0; p != NULL; p = p->next, nr_verts++); /* just counting */ nr_segs = nr_verts - 1; top_l_points = alloca(nr_segs * sizeof(l_point_s)); { struct f_point * pp; int p_idx; for (p_idx = -1, pp = NULL, p = l->points; p != NULL; p = p->next, p_idx++) { if (pp) { top_l_points[p_idx].points_next = 2; top_l_points[p_idx].points_max = POINTS_INCR; top_l_points[p_idx].points = malloc(POINTS_INCR * sizeof(s_point_s)); top_l_points[p_idx].points[0].x = pp->x; top_l_points[p_idx].points[0].y = pp->y; top_l_points[p_idx].points[0].dist = 0.0; top_l_points[p_idx].points[0].ptype = (p_idx == 0) ? PTYPE_START_PLINE : PTYPE_START_VERTEX; top_l_points[p_idx].points[1].x = p->x; top_l_points[p_idx].points[1].y = p->y; top_l_points[p_idx].points[1].dist = hypot((double)(p->y - pp->y), (double)(p->x - pp->x)); top_l_points[p_idx].points[1].ptype = (NULL == p->next) ? PTYPE_END_PLINE : PTYPE_END_VERTEX; } pp = p; } } for (j = 0; j < isect_cb.nr_isects; j++) { /* insert isect points */ int next_p; int t_idx = isect_cb.isects[j].seg_idx; next_p = top_l_points[t_idx].points_next; if (next_p >= top_l_points[t_idx].points_max) { top_l_points[t_idx].points_max += POINTS_INCR; top_l_points[t_idx].points = realloc(top_l_points[t_idx].points, top_l_points[t_idx].points_max * sizeof(s_point_s)); } top_l_points[t_idx].points[next_p].x = isect_cb.isects[j].x; top_l_points[t_idx].points[next_p].y = isect_cb.isects[j].y; top_l_points[t_idx].points[next_p].dist = hypot((double)(isect_cb.isects[j].y - top_l_points[t_idx].points[0].y), (double)(isect_cb.isects[j].x - top_l_points[t_idx].points[0].x)); top_l_points[t_idx].points[next_p].ptype = PTYPE_CUT; top_l_points[t_idx].points_next += 1; } for (i = 0; i < nr_segs; i++) /* sort points by dist along seg */ qsort(top_l_points[i].points, top_l_points[i].points_next, sizeof(s_point_s), point_sort_fcn); rc = (T_POLYLINE == l->type) ? dice_polylines(nr_segs, top_l_points, l) : dice_polygons(nr_segs, top_l_points, l); if (0 < rc) { delete_line(l); redisplay_canvas(); } if (isect_cb.isects) free(isect_cb.isects); for (i = 0; i < nr_segs; i++) { if (top_l_points[i].points) free(top_l_points[i].points); } } /* end of check for 0 isects */ return rc; } static int chop_arc(F_arc * a, int x, int y) { int i; isect_cb_s isect_cb; Boolean runnable; int rc; s_point_s * s_points = NULL; F_arc * this_arc = copy_arc(a); rc = 0; isect_cb.nr_isects = 0; isect_cb.max_isects = 0; isect_cb.isects = NULL;; /* seg_idx irrelevant */ insert_isect(&isect_cb, (double)(a->point[0].x), (double)(a->point[0].y), -1); insert_isect(&isect_cb, (double)(a->point[2].x), (double)(a->point[2].y), -1); /* chopping arc a by various things */ runnable = True; for (i = 0; i < axe_objects_next; i++) { switch (axe_objects[i].type) { case O_POLYLINE: intersect_polyline_arc_handler((F_line *)(axe_objects[i].object), a, x, y, &isect_cb); break; case O_ARC: /* check for congruent axe/log */ if (a == axe_objects[i].object) { put_msg("An axe cannot chop itself."); beep(); runnable = False; break; } else intersect_arc_arc_handler(a, (F_arc *)(axe_objects[i].object), x, y, &isect_cb); break; case O_ELLIPSE: intersect_ellipse_arc_handler((F_ellipse *)(axe_objects[i].object), a, x, y, &isect_cb); break; } } if ((True == runnable) && (2 < isect_cb.nr_isects)) { /* first two set are eps of original */ double vsumx, vsumy; int sp = (1 == a->direction) ? 2 : 0; double dsx = (double)(a->point[sp].x) - (double)(a->center.x); double dsy = (double)(a->point[sp].y) - (double)(a->center.y); double rx = hypot((double)(a->point[1].y) - (double)(a->center.y), (double)(a->point[1].x) - (double)(a->center.x)); /* * dist = ((x2 - x0)(y0 - y) - (y2 - y0)(x0 - x))/mag((x2 - x0), (y2 - y0)) * * x0, y0 = center point * x2, y2 = start point * dsx, dsy = start vector = (x2- x0),(y2 - y0) * dx, dy = t-vector * * dist = dsx * dy - dsy * dx (magnitude irrelevant) * */ #define lp_distance(dx, dy) ((dsx * (dy)) - (dsy * (dx))) s_points = malloc(isect_cb.nr_isects * sizeof(s_point_s)); for (i = 0; i < isect_cb.nr_isects; i++) { double dist, C; double dx = (double)(isect_cb.isects[i].x) - (double)(a->center.x); double dy = (double)(isect_cb.isects[i].y) - (double)(a->center.y); double c = hypot((double)(isect_cb.isects[i].y - a->point[sp].y), (double)(isect_cb.isects[i].x - a->point[sp].x)); if (0.0 > c) c = 0.0; else if (c > (2.0 * rx)) c = 2.0 * rx; /* * cos C = (a^2 + b^2 - c^2)/2ab * * a = b = r * * cos C = (2 r^2 - c^2)/2 r^2 * * cos C = 1 - c^2 / (2 r^2) * */ C = acos(1 - (pow(c, 2.0) / (2.0 * pow(rx, 2.0)))); dist = lp_distance(dx, dy); if (dist < 0.0) C = (2.0 * M_PI) - C; s_points[i].x = isect_cb.isects[i].x; s_points[i].y = isect_cb.isects[i].y; s_points[i].dist = C; } qsort(s_points, isect_cb.nr_isects, sizeof(s_point_s), (1 == a->direction) ? point_sort_reverse_fcn : point_sort_fcn); for (i = 1; i < isect_cb.nr_isects; i++) { if ((rx * fabs(sin(s_points[i - 1].dist - s_points[i].dist))) > 5.0) { double vmag, vpha; vsumx = ((double)(s_points[i - 1].x + s_points[i].x)) - (2.0 * (double)(a->center.x)); vsumy = ((double)(s_points[i - 1].y + s_points[i].y)) - (2.0 * (double)(a->center.y)); vmag = hypot(vsumy, vsumx); vpha = atan2(vsumy, vsumx); vsumx *= rx/vmag; vsumy *= rx/vmag; if (fabs(s_points[i - 1].dist - s_points[i].dist) > M_PI) { vsumx *= -1.0; vsumy *= -1.0; } #if 0 /* probably don't need this */ else if (fabs(s_points[i - 1].dist - s_points[i].dist) < 0.01) { snap_rotate_vector(&vsumx, &vsumy, vsumx, vsumy, M_PI - .001); } #endif this_arc->point[0].x = s_points[i - 1].x; this_arc->point[0].y = s_points[i - 1].y; this_arc->point[1].x = (int)rint((double)(a->center.x) + vsumx); this_arc->point[1].y = (int)rint((double)(a->center.y) + vsumy); this_arc->point[2].x = s_points[i].x; this_arc->point[2].y = s_points[i].y; add_arc(this_arc); rc++; } } delete_arc(a); redisplay_canvas(); } /* end of runnable */ if (s_points) free(s_points); if (isect_cb.isects) free(isect_cb.isects); return rc; } static int chop_ellipse(F_ellipse * e, int x, int y) { int i; isect_cb_s isect_cb; Boolean runnable; int rc; s_point_s * s_points = NULL; rc = 0; isect_cb.nr_isects = 0; isect_cb.max_isects = 0; isect_cb.isects = NULL;; /* chopping ellipse e by various things */ runnable = True; for (i = 0; i < axe_objects_next; i++) { switch (axe_objects[i].type) { case O_POLYLINE: intersect_ellipse_polyline_handler(e, (F_line *)(axe_objects[i].object), x, y, &isect_cb); break; case O_ARC: intersect_ellipse_arc_handler(e, (F_arc *)(axe_objects[i].object), x, y, &isect_cb); break; case O_ELLIPSE: /* check for congruent axe/log */ if (e == axe_objects[i].object) { put_msg("An axe cannot chop itself."); beep(); runnable = False; break; } else intersect_ellipse_ellipse_handler((F_ellipse *)(axe_objects[i].object), e, x, y, &isect_cb); break; } } if (True == runnable) { if (2 > isect_cb.nr_isects) { put_msg("Closed figures require two or more intersects."); beep(); return -1; } s_points = malloc((isect_cb.nr_isects + 1) * sizeof(s_point_s)); for (i = 0; i < isect_cb.nr_isects; i++) { s_points[i].x = isect_cb.isects[i].x; s_points[i].y = isect_cb.isects[i].y; s_points[i].dist = atan2((double)( isect_cb.isects[i].y) - (double)(e->center.y), (double)( isect_cb.isects[i].x) - (double)(e->center.x)); } qsort(s_points, isect_cb.nr_isects, sizeof(s_point_s), point_sort_fcn); s_points[isect_cb.nr_isects].x = s_points[0].x; s_points[isect_cb.nr_isects].y = s_points[0].y; s_points[isect_cb.nr_isects].dist = (2.0 * M_PI) + s_points[0].dist; switch(e->type) { case T_ELLIPSE_BY_RAD: case T_ELLIPSE_BY_DIA: put_msg("Elliptical arcs not (yet) supported."); rc = -1; beep(); break; case T_CIRCLE_BY_RAD: case T_CIRCLE_BY_DIA: for (i = 0; i < isect_cb.nr_isects; i++) { double vmag, vpha; double vsumx, vsumy; double rx = (double)(e->radiuses.x); int sp = i; int ep = i + 1; F_arc * arc = create_arc(); arc->type = T_PIE_WEDGE_ARC; arc->depth = e->depth; arc->thickness = e->thickness; arc->pen_color = e->pen_color; arc->fill_color = e->fill_color; arc->fill_style = e->fill_style; arc->pen_style = e->pen_style; arc->style = e->style; arc->style_val = e->style_val; arc->direction = 0; arc->center.x = e->center.x; arc->center.y = e->center.y; vsumx = ((double)(s_points[sp].x + s_points[ep].x)) - (2.0 * (double)(arc->center.x)); vsumy = ((double)(s_points[sp].y + s_points[ep].y)) - (2.0 * (double)(arc->center.y)); vmag = hypot(vsumy, vsumx); vpha = atan2(vsumy, vsumx); vsumx *= rx/vmag; vsumy *= rx/vmag; if (fabs(s_points[sp].dist - s_points[ep].dist) > M_PI) { vsumx *= -1.0; vsumy *= -1.0; } else if (fabs(s_points[sp].dist - s_points[ep].dist) < 0.01) { snap_rotate_vector(&vsumx, &vsumy, vsumx, vsumy, M_PI - .001); } arc->point[0].x = s_points[sp].x; arc->point[0].y = s_points[sp].y; arc->point[1].x = (int)rint((double)(arc->center.x) + vsumx); arc->point[1].y = (int)rint((double)(arc->center.y) + vsumy); arc->point[2].x = s_points[ep].x; arc->point[2].y = s_points[ep].y; add_arc(arc); rc++; } delete_ellipse(e); redisplay_canvas(); break; } /* switch type */ } /* if runnable */ if (s_points) free(s_points); if (isect_cb.isects) free(isect_cb.isects); return rc; } static void select_log_object(obj, type, x, y, p, q) /* select log objects */ void * obj; int type; int x, y; F_point * p; F_point * q; { Boolean rc; switch(type) { case O_POLYLINE: rc = chop_polyline(obj, x, y); switch(rc) { case -1: /* do nothing -- especially don't overwrite the previous msg */ break; case 0: put_msg("Polyline does not intersect with any selected axe elements."); break; default: put_msg("Polyline chopped into %d pieces.", rc); break; } break; case O_ARC: rc = chop_arc(obj, x, y); switch(rc) { case -1: /* do nothing -- especially don't overwrite the previous msg */ break; case 0: put_msg("Arc does not intersect with any selected axe elements."); break; default: put_msg("Arc chopped into %d pieces.", rc); break; } break; case O_ELLIPSE: rc = chop_ellipse(obj, x, y); switch(rc) { case -1: /* do nothing -- especially don't overwrite the previous msg */ break; case 0: put_msg("Ellipse does not intersect with any selected axe elements."); break; default: put_msg("Ellipse chopped into %d pieces.", rc); break; } break; } } #if 0 static void init_chop_right(obj, type, x, y, px, py) F_line *obj; int type; int x, y; int px, py; { } #endif #if 0 /* fixme -- may find a use for this stuff */ draw_join_marker(point) F_point *point; { int x=ZOOMX(point->x), y=ZOOMY(point->y); pw_vector(canvas_win, x-10, y-10, x-10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x-10, y+10, x+10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y+10, x+10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y-10, x-10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); } erase_join_marker(point) F_point *point; { int x=ZOOMX(point->x), y=ZOOMY(point->y); if (point) { pw_vector(canvas_win, x-10, y-10, x-10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x-10, y+10, x+10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y+10, x+10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y-10, x-10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); } point = NULL; } #endif xfig.3.2.5c/e_compound.c0000700002656300244210000001741511641414046015660 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1994 by Bill Taylor * "Enter Compound" written by Bill Taylor (bill@mainstream.com) 1994 * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* * open_compound lets the user select a compound with the left button, * then replaces the current drawing with that compound alone so that the * user can edit the insides of that compound without taking it apart. * * close_compound pops out one compound; close_all_compounds pops all the way out. * */ #include "fig.h" #include "figx.h" #include "resources.h" #include "mode.h" #include "object.h" #include "u_search.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_icons.h" #include "w_indpanel.h" #include "w_setup.h" #include "w_util.h" #include "e_scale.h" #include "u_bound.h" #include "u_list.h" #include "u_markers.h" #include "u_redraw.h" #include "w_color.h" #include "w_cursor.h" #include "w_modepanel.h" #include "w_mousefun.h" Widget close_compound_popup; Boolean close_popup_isup = False; void open_this_compound(F_compound *c, Boolean vis); int save_mask; void popup_close_compound (void); static void init_open_compound(F_compound *c, int type, int x, int y, int px, int py) { if (type != O_COMPOUND) return; open_this_compound(c, False); } static void init_open_compound_vis(F_compound *c, int type, int x, int y, int px, int py, int loc_tag) { if (type != O_COMPOUND) return; open_this_compound(c, True); } void open_this_compound(F_compound *c, Boolean vis) { F_compound *d; mask_toggle_compoundmarker(c); /* save current indicator panel button mask */ save_mask = cur_indmask; /* show the point positioning button if user wants to control the compound when he closes it */ update_indpanel(cur_indmask | I_POINTPOSN); c->parent = d = (F_compound *) malloc(sizeof(F_compound)); *d = objects; /* Preserve the parent, it points to c */ objects = *c; objects.GABPtr = c; /* Where original compound came from */ objects.draw_parent = vis; if (!close_popup_isup) popup_close_compound(); redisplay_canvas(); } void open_compound_selected(void) { /* prepatory functions done for mode operations by sel_mode_but */ update_markers((int)M_COMPOUND); set_mousefun("open compound", "open, keep visible", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_open_compound); init_searchproc_middle(init_open_compound_vis); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick15_cursor); reset_action_on(); } void close_compound(void) { F_compound *c; F_compound *d; /* Destination */ /* if trying to close compound while drawing an object, don't allow it */ if (check_action_on()) return; if (c = (F_compound *)objects.parent) { objects.parent = NULL; d = (F_compound *)objects.GABPtr; /* Where this compound was */ objects.GABPtr = NULL; /* go see if this is a dimension line and calculate angles, box size etc */ rescale_dimension_line(&objects, 1.0, 1.0, 0, 0); /* compute new bounding box if changed */ compound_bound(&objects, &objects.nwcorner.x, &objects.nwcorner.y, &objects.secorner.x, &objects.secorner.y); *d = objects; /* Put in any changes */ objects = *c; /* Restore compound above */ /* user may have deleted all objects inside the compound */ if (object_count(d)==0) { list_delete_compound(&objects.compounds, d); } free(c); /* popdown close panel if this is the last one */ if ((F_compound *)objects.parent == NULL) { XtPopdown(close_compound_popup); XtDestroyWidget(close_compound_popup); close_popup_isup = False; } redisplay_canvas(); /* re-select open compound mode */ change_mode(&open_comp_ic); /* restore indicator panel mask */ cur_indmask = save_mask; update_indpanel(cur_indmask); } } void close_all_compounds(void) { F_compound *c; F_compound *d; /* Destination */ /* if trying to close compound while drawing an object, don't allow it */ if (check_action_on()) return; if (objects.parent) { while (c = (F_compound *)objects.parent) { objects.parent = NULL; d = (F_compound *)objects.GABPtr; /* Where this compound was */ objects.GABPtr = NULL; /* compute new bounding box if changed */ compound_bound(&objects, &objects.nwcorner.x, &objects.nwcorner.y, &objects.secorner.x, &objects.secorner.y); *d = objects; /* Put in any changes */ objects = *c; /* user may have deleted all objects inside the compound */ if (object_count(d)==0) { list_delete_compound(&objects.compounds, d); } free(c); } /* popdown close panel */ XtPopdown(close_compound_popup); XtDestroyWidget(close_compound_popup); close_popup_isup = False; redisplay_canvas(); /* re-select open compound mode */ change_mode(&open_comp_ic); } } void popup_close_compound(void) { Widget close_compound_form; Widget close_compoundw, close_compound_allw; Position xposn, yposn; int llx, lly, urx, ury; DeclareArgs(10); /* position the popup above the compound we're opening */ compound_bound(&objects, &llx, &lly, &urx, &ury); /* translate object coords to screen coords relative to the canvas */ llx = ZOOMX(llx); lly = ZOOMY(lly); /* translate those to absolute screen coords */ XtTranslateCoords(canvas_sw, llx, lly, &xposn, &yposn); /* but not off the screen */ if (xposn < 100) xposn = 100; if (yposn < 100) yposn = 100; FirstArg(XtNallowShellResize, True); NextArg(XtNx, xposn-40); NextArg(XtNy, yposn-65); NextArg(XtNtitle, "Xfig: Close Compound"); NextArg(XtNcolormap, tool_cm); close_compound_popup = XtCreatePopupShell("close_compound_popup", transientShellWidgetClass, tool, Args, ArgCount); close_compound_form = XtCreateManagedWidget("close_compound_form", formWidgetClass, close_compound_popup, (XtPointer) NULL, 0); FirstArg(XtNlabel, "Close This Compound") close_compoundw = XtCreateManagedWidget("close_compound", commandWidgetClass, close_compound_form, Args, ArgCount); XtAddEventHandler(close_compoundw, ButtonReleaseMask, False, (XtEventHandler)close_compound, (XtPointer) NULL); FirstArg(XtNlabel, "Close All Compounds"); NextArg(XtNfromHoriz, close_compoundw); close_compound_allw = XtCreateManagedWidget("close_all_compounds", commandWidgetClass, close_compound_form, Args, ArgCount); XtAddEventHandler(close_compound_allw, ButtonReleaseMask, False, (XtEventHandler)close_all_compounds, (XtPointer) NULL); /* now pop it up */ XtPopup(close_compound_popup, XtGrabNone); /* insure that the most recent colormap is installed */ set_cmap(XtWindow(close_compound_popup)); (void) XSetWMProtocols(tool_d, XtWindow(close_compound_popup), &wm_delete_window, 1); XDefineCursor(tool_d, XtWindow(close_compound_popup), arrow_cursor); close_popup_isup = True; } xfig.3.2.5c/e_convert.c0000700002656300244210000002530411641414046015510 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_convert.h" #include "u_create.h" #include "u_draw.h" #include "u_list.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "d_spline.h" #include "f_util.h" #include "u_free.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" static void init_convert_line_spline(F_line *p, int type, int x, int y, int px, int py); static void init_convert_open_closed(F_line *obj, int type, int x, int y, F_point *p, F_point *q); void convert_selected(void) { set_mousefun("spline<->line", "", "open<->closed", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_convert_line_spline); init_searchproc_right(init_convert_open_closed); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = point_search_right; set_cursor(pick15_cursor); reset_action_on(); } static void init_convert_open_closed(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; toggle_polyline_polygon(cur_l, p, q); break; case O_SPLINE: cur_s = (F_spline *) obj; toggle_open_closed_spline(cur_s, p, q); break; default: return; } } static void init_convert_line_spline(F_line *p, int type, int x, int y, int px, int py) { static int flag = 0; switch (type) { case O_POLYLINE: cur_l = (F_line *) p; /* the search routine will ensure that we don't have a box */ if (cur_l->type == T_POLYLINE || cur_l->type == T_POLYGON) { line_spline(cur_l, cur_l->type == T_POLYGON ? flag ? T_CLOSED_APPROX : T_CLOSED_INTERP : flag ? T_OPEN_APPROX : T_OPEN_INTERP); } else if (cur_l->type == T_ARCBOX || cur_l->type == T_BOX) { box_2_box(cur_l); } break; case O_SPLINE: cur_s = (F_spline *) p; flag = (cur_s->type==T_OPEN_INTERP) || (cur_s->type==T_CLOSED_INTERP); spline_line(cur_s); break; default: return; } } /* handle conversion of box to arc_box and arc_box to box */ void box_2_box(F_line *old_l) { F_line *new_l; new_l = copy_line(old_l); switch (old_l->type) { case T_BOX: new_l->type = T_ARCBOX; if (new_l->radius == DEFAULT || new_l->radius == 0) new_l->radius = cur_boxradius; break; case T_ARCBOX: new_l->type = T_BOX; break; } list_delete_line(&objects.lines, old_l); list_add_line(&objects.lines, new_l); clean_up(); old_l->next = new_l; set_latestline(old_l); set_action_object(F_CONVERT, O_POLYLINE); set_modifiedflag(); /* save pointer to this line for undo */ latest_line = new_l; redisplay_line(new_l); return; } void line_spline(F_line *l, int type_value) { F_spline *s; if (num_points(l->points) < CLOSED_SPLINE_MIN_NUM_POINTS) { put_msg("Not enough points for a spline"); beep(); return; } if ((s = create_spline()) == NULL) return; s->type = type_value; if (l->type == T_POLYGON) s->points = copy_points(l->points->next); else s->points = copy_points(l->points); s->style = l->style; s->thickness = l->thickness; s->pen_color = l->pen_color; s->fill_color = l->fill_color; s->depth = l->depth; s->style_val = l->style_val; s->cap_style = l->cap_style; s->pen_style = l->pen_style; s->fill_style = l->fill_style; s->sfactors = NULL; s->next = NULL; if (l->for_arrow) { s->for_arrow = create_arrow(); s->for_arrow->type = l->for_arrow->type; s->for_arrow->style = l->for_arrow->style; s->for_arrow->thickness = l->for_arrow->thickness; s->for_arrow->wd = l->for_arrow->wd; s->for_arrow->ht = l->for_arrow->ht; } else { s->for_arrow = NULL; } if (l->back_arrow) { s->back_arrow = create_arrow(); s->back_arrow->type = l->back_arrow->type; s->back_arrow->style = l->back_arrow->style; s->back_arrow->thickness = l->back_arrow->thickness; s->back_arrow->wd = l->back_arrow->wd; s->back_arrow->ht = l->back_arrow->ht; } else { s->back_arrow = NULL; } /* A spline must have an s parameter for each point */ if (!make_sfactors(s)) { free_spline(&s); return; } /* Get rid of the line and draw the new spline */ delete_line(l); /* now put back the new spline */ mask_toggle_splinemarker(s); list_add_spline(&objects.splines, s); redisplay_spline(s); set_action_object(F_CONVERT, O_POLYLINE); set_latestspline(s); set_modifiedflag(); } void spline_line(F_spline *s) { F_line *l; F_point *tmppoint; /* Now we turn s into a line */ if ((l = create_line()) == NULL) return; if (open_spline(s)) { l->type = T_POLYLINE; l->points = s->points; } else { l->type = T_POLYGON; if ((l->points = create_point())==NULL) return; tmppoint = last_point(s->points); l->points->x = tmppoint->x; l->points->y = tmppoint->y; l->points->next = copy_points(s->points); } l->style = s->style; l->thickness = s->thickness; l->pen_color = s->pen_color; l->fill_color = s->fill_color; l->depth = s->depth; l->style_val = s->style_val; l->cap_style = s->cap_style; l->join_style = cur_joinstyle; l->pen_style = s->pen_style; l->radius = DEFAULT; l->fill_style = s->fill_style; if (s->for_arrow) { l->for_arrow = create_arrow(); l->for_arrow->type = s->for_arrow->type; l->for_arrow->style = s->for_arrow->style; l->for_arrow->thickness = s->for_arrow->thickness; l->for_arrow->wd = s->for_arrow->wd; l->for_arrow->ht = s->for_arrow->ht; } else { l->for_arrow = NULL; } if (s->back_arrow) { l->back_arrow = create_arrow(); l->back_arrow->type = s->back_arrow->type; l->back_arrow->style = s->back_arrow->style; l->back_arrow->thickness = s->back_arrow->thickness; l->back_arrow->wd = s->back_arrow->wd; l->back_arrow->ht = s->back_arrow->ht; } else { l->back_arrow = NULL; } /* now we have finished creating the line, we can get rid of the spline */ delete_spline(s); /* and put in the new line */ mask_toggle_linemarker(l); list_add_line(&objects.lines, l); redisplay_line(l); set_action_object(F_CONVERT, O_SPLINE); set_latestline(l); set_modifiedflag(); return; } void toggle_polyline_polygon(F_line *line, F_point *previous_point, F_point *selected_point) { F_point *point, *last_pt; last_pt = last_point(line->points); if (line->type == T_POLYLINE) { if (line->points->next == NULL || line->points->next->next == NULL) { put_msg("Not enough points for a polygon"); beep(); return; /* less than 3 points - don't close the polyline */ } if ((point = create_point()) == NULL) return; point->x = last_pt->x; point->y = last_pt->y; point->next = line->points; line->points = point; line->type = T_POLYGON; clean_up(); set_last_arrows(line->for_arrow, line->back_arrow); line->back_arrow = line->for_arrow = NULL; } else if (line->type == T_POLYGON) { point = line->points; line->points = point->next; /* unchain the first point */ free((char *) point); if ((line->points != selected_point) && (previous_point != NULL)) { last_pt->next = line->points; /* let selected point become */ previous_point->next = NULL; /* first point */ line->points = selected_point; } line->type = T_POLYLINE; clean_up(); } redisplay_line(line); set_action_object(F_OPEN_CLOSE, O_POLYLINE); set_last_selectedpoint(line->points); set_last_prevpoint(NULL); set_latestline(line); set_modifiedflag(); } void toggle_open_closed_spline(F_spline *spline, F_point *previous_point, F_point *selected_point) { F_point *last_pt; F_sfactor *last_sfactor, *previous_sfactor, *selected_sfactor; if (spline->points->next == NULL || spline->points->next->next == NULL) { put_msg("Not enough points for a spline"); beep(); return; /* less than 3 points - don't close the spline */ } last_pt = last_point(spline->points); last_sfactor = search_sfactor(spline, last_pt); if (previous_point == NULL) { previous_sfactor = NULL; selected_sfactor = spline->sfactors; } else { previous_sfactor = search_sfactor(spline, previous_point); selected_sfactor = previous_sfactor->next; set_last_tension(selected_sfactor->s, previous_sfactor->s); } draw_spline(spline, ERASE); if (closed_spline(spline)) { if (spline->points != selected_point) { last_pt->next = spline->points; last_sfactor->next = spline->sfactors; previous_point->next = NULL; previous_sfactor->next = NULL; previous_sfactor->s = S_SPLINE_ANGULAR; spline->points = selected_point; spline->sfactors = selected_sfactor; } else { last_sfactor->s = S_SPLINE_ANGULAR; } spline->sfactors->s = S_SPLINE_ANGULAR; spline->type = (x_spline(spline)) ? T_OPEN_XSPLINE : (int_spline(spline)) ? T_OPEN_INTERP : T_OPEN_APPROX; clean_up(); } else { int type_tmp; double s_tmp; if(int_spline(spline)) { s_tmp = S_SPLINE_INTERP; type_tmp = T_CLOSED_INTERP; } else if (x_spline(spline)) { s_tmp = S_SPLINE_INTERP; type_tmp = T_CLOSED_XSPLINE; } else { s_tmp = S_SPLINE_APPROX; type_tmp = T_CLOSED_APPROX; } spline->sfactors->s = last_sfactor->s = s_tmp; spline->type = type_tmp; clean_up(); set_last_arrows(spline->for_arrow, spline->back_arrow); spline->back_arrow = spline->for_arrow = NULL; } draw_spline(spline, PAINT); set_action_object(F_OPEN_CLOSE, O_SPLINE); set_last_selectedpoint(spline->points); set_last_prevpoint(NULL); set_latestspline(spline); set_modifiedflag(); } xfig.3.2.5c/e_copy.c0000700002656300244210000001124711641414046015003 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_drag.h" #include "u_elastic.h" #include "u_search.h" #include "u_create.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "f_save.h" #include "u_markers.h" #include "w_cursor.h" /* local routine declarations */ static void init_copy(F_line *p, int type, int x, int y, int px, int py), init_arb_copy(F_line *p, int type, int x, int y, int px, int py), init_constrained_copy(F_line *p, int type, int x, int y, int px, int py); static void init_copy_to_scrap(F_line *p, int type, int x, int y, int px, int py); void copy_selected(void) { canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_arb_copy); init_searchproc_middle(init_constrained_copy); init_searchproc_right(init_copy_to_scrap); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = object_search_right; return_proc = copy_selected; set_cursor(pick15_cursor); set_mousefun("copy object", "horiz/vert copy", "copy to cut buf", LOC_OBJ, LOC_OBJ, LOC_OBJ); reset_action_on(); } static void init_arb_copy(F_line *p, int type, int x, int y, int px, int py) { constrained = MOVE_ARB; init_copy(p, type, x, y, px, py); set_mousefun("place object", "array placement", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); } static void init_constrained_copy(F_line *p, int type, int x, int y, int px, int py) { constrained = MOVE_HORIZ_VERT; init_copy(p, type, x, y, px, py); set_mousefun("place object", "array placement", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); } static void init_copy(F_line *p, int type, int x, int y, int px, int py) { /* turn off all markers */ update_markers(0); switch (type) { case O_COMPOUND: set_cursor(null_cursor); cur_c = (F_compound *) p; new_c = copy_compound(cur_c); init_compounddragging(new_c, px, py); break; case O_POLYLINE: set_cursor(null_cursor); cur_l = (F_line *) p; new_l = copy_line(cur_l); init_linedragging(new_l, px, py); break; case O_TXT: set_cursor(null_cursor); cur_t = (F_text *) p; new_t = copy_text(cur_t); init_textdragging(new_t, x, y); break; case O_ELLIPSE: set_cursor(null_cursor); cur_e = (F_ellipse *) p; new_e = copy_ellipse(cur_e); init_ellipsedragging(new_e, px, py); break; case O_ARC: set_cursor(null_cursor); cur_a = (F_arc *) p; new_a = copy_arc(cur_a); init_arcdragging(new_a, px, py); break; case O_SPLINE: set_cursor(null_cursor); cur_s = (F_spline *) p; new_s = copy_spline(cur_s); init_splinedragging(new_s, px, py); break; default: return; } } static void init_copy_to_scrap(F_line *p, int type, int x, int y, int px, int py) { FILE *fp; FILE *open_cut_file(void); if ((fp=open_cut_file())==NULL) return; #ifdef I18N /* set the numeric locale to C so we get decimal points for numbers */ setlocale(LC_NUMERIC, "C"); #endif /* I18N */ write_fig_header(fp); switch (type) { case O_COMPOUND: cur_c = (F_compound *) p; write_compound(fp, cur_c); break; case O_ARC: cur_a = (F_arc *) p; write_arc(fp, cur_a); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; write_ellipse(fp, cur_e); break; case O_POLYLINE: cur_l = (F_line *) p; write_line(fp, cur_l); break; case O_TXT: cur_t = (F_text *) p; write_text(fp, cur_t); break; case O_SPLINE: cur_s = (F_spline *) p; write_spline(fp, cur_s); break; default: fclose(fp); #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ return; } #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ put_msg("Object copied to scrapfile %s",cut_buf_name); fclose(fp); } xfig.3.2.5c/e_delete.c0000700002656300244210000001634211641414046015274 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_line.h" #include "u_create.h" #include "u_draw.h" #include "u_elastic.h" #include "u_redraw.h" #include "u_search.h" #include "u_list.h" #include "u_undo.h" #include "w_canvas.h" #include "w_layers.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "d_box.h" #include "e_compound.h" #include "e_glue.h" #include "f_save.h" #include "u_markers.h" #include "w_cursor.h" static void init_delete(F_line *p, int type, int x, int y, int px, int py); static void init_delete_region(int x, int y), delete_region(int x, int y), cancel_delete_region(void); static void init_delete_to_scrap(F_line *p, int type, int x, int y, int px, int py); void delete_selected(void) { set_mousefun("delete object", "delete region", "del to cut buf", LOC_OBJ, "", LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_delete); init_searchproc_right(init_delete_to_scrap); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = init_delete_region; canvas_rightbut_proc = object_search_right; set_cursor(buster_cursor); reset_action_on(); } static void init_delete(F_line *p, int type, int x, int y, int px, int py) { switch (type) { case O_COMPOUND: cur_c = (F_compound *) p; delete_compound(cur_c); redisplay_compound(cur_c); break; case O_POLYLINE: cur_l = (F_line *) p; delete_line(cur_l); redisplay_line(cur_l); break; case O_TXT: cur_t = (F_text *) p; delete_text(cur_t); redisplay_text(cur_t); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; delete_ellipse(cur_e); redisplay_ellipse(cur_e); break; case O_ARC: cur_a = (F_arc *) p; delete_arc(cur_a); redisplay_arc(cur_a); break; case O_SPLINE: cur_s = (F_spline *) p; delete_spline(cur_s); redisplay_spline(cur_s); break; default: return; } } static void init_delete_region(int x, int y) { init_box_drawing(x, y); set_mousefun("", "final corner", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_leftbut_proc = null_proc; canvas_middlebut_proc = delete_region; canvas_rightbut_proc = cancel_delete_region; } static void cancel_delete_region(void) { elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); delete_selected(); draw_mousefun_canvas(); } static void delete_region(int x, int y) { F_compound *c; if ((c = create_compound()) == NULL) return; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); c->nwcorner.x = min2(fix_x, x); c->nwcorner.y = min2(fix_y, y); c->secorner.x = max2(fix_x, x); c->secorner.y = max2(fix_y, y); tag_obj_in_region(c->nwcorner.x,c->nwcorner.y,c->secorner.x,c->secorner.y); if (compose_compound(c) == 0) { free((char *) c); delete_selected(); draw_mousefun_canvas(); put_msg("Empty region, figure unchanged"); return; } clean_up(); toggle_markers_in_compound(c); set_tags(c,0); set_latestobjects(c); tail(&objects, &object_tails); append_objects(&objects, &saved_objects, &object_tails); cut_objects(&objects, &object_tails); set_action_object(F_DELETE, O_ALL_OBJECT); set_modifiedflag(); redisplay_compound(c); delete_selected(); draw_mousefun_canvas(); } static void init_delete_to_scrap(F_line *p, int type, int x, int y, int px, int py) { FILE *fp; FILE *open_cut_file(void); if ((fp=open_cut_file())==NULL) return; #ifdef I18N /* set the numeric locale to C so we get decimal points for numbers */ setlocale(LC_NUMERIC, "C"); #endif /* I18N */ write_fig_header(fp); switch (type) { case O_COMPOUND: cur_c = (F_compound *) p; write_compound(fp, cur_c); delete_compound(cur_c); redisplay_compound(cur_c); break; case O_POLYLINE: cur_l = (F_line *) p; write_line(fp, cur_l); delete_line(cur_l); redisplay_line(cur_l); break; case O_TXT: cur_t = (F_text *) p; write_text(fp, cur_t); delete_text(cur_t); redisplay_text(cur_t); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; write_ellipse(fp, cur_e); delete_ellipse(cur_e); redisplay_ellipse(cur_e); break; case O_ARC: cur_a = (F_arc *) p; write_arc(fp, cur_a); delete_arc(cur_a); redisplay_arc(cur_a); break; case O_SPLINE: cur_s = (F_spline *) p; write_spline(fp, cur_s); delete_spline(cur_s); redisplay_spline(cur_s); break; default: fclose(fp); #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ return; } #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ put_msg("Object deleted to scrapfile %s",cut_buf_name); fclose(fp); } FILE * open_cut_file(void) { FILE *fp; struct stat file_status; if (stat(cut_buf_name, &file_status) == 0) { /* file exists */ if (file_status.st_mode & S_IFDIR) { put_msg("Error: \"%s\" is a directory", cut_buf_name); return NULL; } if (file_status.st_mode & S_IWRITE) { /* writing is permitted */ if (file_status.st_uid != geteuid()) { put_msg("Error: access denied to cut file"); return NULL; } } else { put_msg("Error: cut file is read only"); return NULL; } } else if (errno != ENOENT) { put_msg("Error: cut file didn't pass stat check"); return NULL; /* file does exist but stat fails */ } if ((fp = fopen(cut_buf_name, "wb")) == NULL) { put_msg("Error: couldn't open cut file %s", strerror(errno)); return NULL; } return fp; } void delete_all(void) { clean_up(); set_action_object(F_DELETE, O_ALL_OBJECT); /* initialize layer/depth info */ reset_layers(); save_depths(); /* reset min,max depth */ min_depth = max_depth = -1; save_counts_and_clear(); reset_depths(); /* refresh depth manager */ update_layers(); /* in case the user is inside any compounds */ close_all_compounds(); set_latestobjects(&objects); objects.arcs = NULL; objects.compounds = NULL; objects.ellipses = NULL; objects.lines = NULL; objects.splines = NULL; objects.texts = NULL; objects.comments = NULL; object_tails.arcs = NULL; object_tails.compounds = NULL; object_tails.ellipses = NULL; object_tails.lines = NULL; object_tails.splines = NULL; object_tails.texts = NULL; } xfig.3.2.5c/e_deletept.c0000700002656300244210000001432111641414046015633 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_deletept.h" #include "u_list.h" #include "u_search.h" #include "u_draw.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "d_spline.h" #include "f_util.h" #include "u_redraw.h" #include "u_undo.h" #include "w_cursor.h" static void init_delete_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q); void delete_point_selected(void) { set_mousefun("delete point", "", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_delete_point); canvas_leftbut_proc = point_search_left; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); reset_action_on(); } static void init_delete_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { int n; switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; /* the search routine will ensure we don't have a box */ n = num_points(cur_l->points); if (cur_l->type == T_POLYGON) { if (n <= 4) { /* count first pt twice for closed object */ put_msg("A polygon cannot have less than 3 points"); beep(); return; } } else if (n <= 1) { /* alternative would be to remove the dot altogether */ put_msg("A dot must have at least 1 point"); beep(); return; } linepoint_deleting(cur_l, p, q); break; case O_SPLINE: cur_s = (F_spline *) obj; n = num_points(cur_s->points); if (closed_spline(cur_s)) { if (n <= CLOSED_SPLINE_MIN_NUM_POINTS) { put_msg("A closed spline cannot have less than %d points", CLOSED_SPLINE_MIN_NUM_POINTS); beep(); return; } } else if (n <= OPEN_SPLINE_MIN_NUM_POINTS) { put_msg("A spline cannot have less than %d points", OPEN_SPLINE_MIN_NUM_POINTS); beep(); return; } splinepoint_deleting(cur_s, p, q); break; default: return; } } /************************** spline *******************************/ void splinepoint_deleting(F_spline *spline, F_point *previous_point, F_point *selected_point) { F_point *next_point; F_sfactor *s_prev_point, *selected_sfactor; next_point = selected_point->next; set_temp_cursor(wait_cursor); clean_up(); set_last_prevpoint(previous_point); /* delete it and redraw underlying objects */ list_delete_spline(&objects.splines, spline); draw_spline(spline, ERASE); redisplay_spline(spline); if (previous_point == NULL) { spline->points = next_point; if (open_spline(spline)) { selected_sfactor = spline->sfactors->next; spline->sfactors->next = selected_sfactor->next; } else { selected_sfactor = spline->sfactors; spline->sfactors = spline->sfactors->next; } } else { previous_point->next = next_point; if ((next_point == NULL) && (open_spline(spline))) previous_point = prev_point(spline->points, previous_point); s_prev_point = search_sfactor(spline,previous_point); selected_sfactor = s_prev_point->next; s_prev_point->next = s_prev_point->next->next; } /* put it back in the list and draw the new spline */ list_add_spline(&objects.splines, spline); /* redraw it and anything on top of it */ redisplay_spline(spline); set_action_object(F_DELETE_POINT, O_SPLINE); set_latestspline(spline); set_last_selectedpoint(selected_point); set_last_selectedsfactor(selected_sfactor); set_last_nextpoint(next_point); set_modifiedflag(); reset_cursor(); } /*************************** line ********************************/ /* * In deleting a point selected_point, linepoint_deleting uses prev_point and * next_point of the point. The relationship between the three points is: * prev_point->selected_point->next_point except when selected_point is the * first point in the list, in which case prev_point will be NULL. */ void linepoint_deleting(F_line *line, F_point *prev_point, F_point *selected_point) { F_point *p, *next_point; next_point = selected_point->next; /* delete it and redraw underlying objects */ list_delete_line(&objects.lines, line); redisplay_line(line); if (line->type == T_POLYGON) { if (prev_point == NULL) { /* The deleted point is the first point */ line->points = next_point; for (prev_point = next_point, p = prev_point->next; p->next != NULL; prev_point = p, p = p->next); /* * prev_point now points at next to last point (the last point is * a copy of the first). */ p->x = next_point->x; p->y = next_point->y; next_point = p; /* * next_point becomes the last point. If this operation (point * deletion) is reversed (undo), the selected_point will not be * inserted into it original place, but will be between * prev_point and next_point. */ } else prev_point->next = next_point; } else { /* polyline */ if (prev_point == NULL) line->points = next_point; else prev_point->next = next_point; } /* put it back in the list and draw the new line */ list_add_line(&objects.lines, line); /* redraw it and anything on top of it */ redisplay_line(line); clean_up(); set_modifiedflag(); set_action_object(F_DELETE_POINT, O_POLYLINE); set_latestline(line); set_last_prevpoint(prev_point); set_last_selectedpoint(selected_point); set_last_nextpoint(next_point); } xfig.3.2.5c/e_edit.c0000644002656300244210000052216112010770177014770 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Change function implemented by Frank Schmuck (schmuck@svax.cs.cornell.edu) * X version by Jon Tombs * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * Parts Copyright (c) 1995 by C. Blanc and C. Schlick * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "figx.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_edit.h" #include "d_subspline.h" #include "d_text.h" #include "f_read.h" #include "f_util.h" #include "u_create.h" #include "u_fonts.h" #include "u_search.h" #include "u_list.h" #include "u_create.h" #include "u_draw.h" #include "u_markers.h" #include "u_undo.h" #include "w_browse.h" #include "w_canvas.h" #include "w_capture.h" #include "w_drawprim.h" #include "w_fontbits.h" #include "w_icons.h" #include "w_indpanel.h" #include "w_msgpanel.h" #include "w_mousefun.h" #include "w_setup.h" #include "w_util.h" #include "w_zoom.h" #include "d_line.h" #include "e_placelib.h" #include "e_scale.h" #include "f_picobj.h" #include "u_bound.h" #include "u_free.h" #include "u_geom.h" #include "u_redraw.h" #include "u_translate.h" #include "w_color.h" #include "w_cursor.h" #include "w_dir.h" #include /* waitpid() */ /* EXPORTS */ Widget pic_name_panel; /* global to be visible in w_browse */ /* LOCAL */ #define NUM_IMAGES 16 #define MAXDISPTS 100 /* maximum number of points to display for line, spline, etc */ static int what_rotation(int dx, int dy); #define XY_WIDTH 56 /* width of text widgets for x/y points */ /* define some true/false constants to make proc calls easier to read */ #define GENERICS True #define NO_GENERICS False #define ARROWS True #define NO_ARROWS False static Position rootx, rooty; static void new_generic_values(void); static void new_arrow_values(void); static void get_new_line_values(void); static void generic_window(char *object_type, char *sub_type, icon_struct *icon, void (*d_proc) (/* ??? */), Boolean generics, Boolean arrows, char *comments); static void spline_point_window(int x, int y); static void font_image_panel(Pixmap pixmap, char *label, Widget *pi_x); static Widget pen_color_selection_panel(void); static Widget fill_color_selection_panel(void); static void float_label(float x, char *label, Widget *pi_x); static void int_label(int x, char *label, Widget *pi_x); static void str_panel(char *string, char *name, Widget *pi_x, int width, Boolean size_to_width, Boolean international); static void xy_panel(int x, int y, char *label, Widget *pi_x, Widget *pi_y, Boolean make_unit_menu); static void f_pair_panel(F_pos *fp, char *label, Widget *pi_x, char *xlabel, Widget *pi_y, char *ylabel, Boolean make_unit_menu); static void get_f_pos(F_pos *fp, Widget pi_x, Widget pi_y); static void points_panel(struct f_point *p); static void get_points(struct f_point *p); static void arc_type_select(Widget w, XtPointer new_style, XtPointer call_data); static void cap_style_select(Widget w, XtPointer new_type, XtPointer call_data); static void join_style_select(Widget w, XtPointer new_type, XtPointer call_data); static void line_style_select(Widget w, XtPointer new_style, XtPointer call_data); static void for_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data); static void back_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data); static void textjust_select(Widget w, XtPointer new_textjust, XtPointer call_data); static void fill_style_select(Widget w, XtPointer new_fillflag, XtPointer call_data); static void flip_pic_select(Widget w, XtPointer new_flipflag, XtPointer call_data); static void rotation_select(Widget w, XtPointer new_rotation, XtPointer call_data); static void hidden_text_select(Widget w, XtPointer new_hidden_text, XtPointer call_data); static void rigid_text_select(Widget w, XtPointer new_rigid_text, XtPointer call_data); static void special_text_select(Widget w, XtPointer new_special_text, XtPointer call_data); static void pen_color_select(Widget w, XtPointer new_color, XtPointer call_data); static void fill_color_select(Widget w, XtPointer new_color, XtPointer call_data); static int panel_get_dim_value(Widget widg); static void panel_clear_value(Widget widg); static void get_new_compound_values(void); static void panel_set_scaled_int(Widget widg, int intval); static void unit_select(Widget w, XtPointer new_unit, XtPointer call_data); static void init_convert_array(void); static void add_to_convert(Widget widget); static double cvt_to_units(int fig_unit); static void cvt_to_units_str(int x, char *buf); static int cvt_to_fig(double real_unit); static void reposition_picture(Widget w); static void resize_picture(Widget w); static void modify_compound(Widget w); static void reposition_top(void); static void reposition_bottom(void); static void rescale_compound(void); static void collapse_depth(Widget panel_local, XtPointer closure, XtPointer call_data); static void done_line(void); static void done_text(void); static void done_arc(void); static void done_ellipse(void); static void done_spline(void); static void done_spline_point(void); static void done_compound(void); static void done_figure_comments(void); static void done_button(Widget panel_local, XtPointer closure, XtPointer call_data), apply_button(Widget panel_local, XtPointer closure, XtPointer call_data), cancel_button(Widget panel_local, XtPointer closure, XtPointer call_data); static void toggle_sfactor_type(Widget panel_local, XtPointer _sfactor_index, XtPointer call_data); static void change_sfactor_value(Widget panel_local, XtPointer closure, XtPointer _top); static void scroll_sfactor_value(Widget panel_local, XtPointer closure, XtPointer _num_pixels); static void grab_button(Widget panel_local, XtPointer closure, XtPointer call_data), browse_button(Widget panel_local, XtPointer closure, XtPointer call_data), image_edit_button(Widget panel_local, XtPointer closure, XtPointer call_data); static void update_fill_image(Widget w, XtPointer dummy, XtPointer dummy2); static Widget popup, form; static Widget below, beside; static Widget above_arrows; static Widget comment_popup; static Widget arc_points_form; static Widget float_panel(float x, Widget parent, char *label, Widget pbeside, Widget *pi_x, float min, float max, float inc, int prec); static Widget int_panel(int x, Widget parent, char *label, Widget beside, Widget *pi_x, int min, int max, int inc); static Widget int_panel_callb(int x, Widget parent, char *label, Widget pbeside, Widget *pi_x, int min, int max, int inc, XtCallbackProc callback); static Widget reread, shrink, expand, origsize; static Widget percent_button, percent, percent_entry; static Widget label; static Widget thickness_panel; static Widget depth_panel; static Widget angle_panel; static Widget textjust_panel; static Widget hidden_text_panel; static Widget rigid_text_panel; static Widget special_text_panel; static Widget fill_intens, fill_intens_panel, fill_intens_label, fill_image; static Widget fill_pat, fill_pat_panel, fill_pat_label; static Widget flip_pic_panel; static Widget rotation_panel; static Widget arc_type_panel; static Widget cap_style_panel; static Widget join_style_panel; static Widget line_style_panel; static Widget for_arrow_type_panel; static Widget back_arrow_type_panel; static Widget style_val, style_val_panel, style_val_label; static Widget for_arrow_height,for_arrow_width,for_arrow_thick; static Widget back_arrow_height,back_arrow_width,back_arrow_thick; static Widget for_thick_label,for_height_label,for_width_label; static Widget back_thick_label,back_height_label,back_width_label; static Widget for_thick,for_height,for_width; static Widget back_thick,back_height,back_width; static Boolean for_arrow, back_arrow; static Widget text_panel; static Widget x1_panel, y1_panel; static Widget x2_panel, y2_panel; static Widget x3_panel, y3_panel; static Widget width_panel, height_panel; static Widget hw_ratio_panel; static Widget orig_hw_panel; static Widget font_panel; static Widget cur_fontsize_panel; static Widget fill_style_button; static Widget radius, num_objects; static Widget comments_panel; static Widget for_aform,back_aform; static Widget but1; static Widget unit_menu_button; static Widget unit_pulldown_menu(Widget below, Widget beside); static Widget min_depth_w, max_depth_w; /* for PIC object type */ static Widget pic_size, pic_type_box[NUM_PIC_TYPES], pic_colors, transp_color; static Widget pen_col_button, pen_color_popup=0; static Widget fill_col_button, fill_color_popup=0; DeclareStaticArgs(20); static char buf[64]; static Widget px_panel[MAXDISPTS]; static Widget py_panel[MAXDISPTS]; /* for our own fill % and fill pattern pixmap in the popup */ #define FILL_SIZE 40 /* size of indicators */ static Pixmap fill_image_pm,fill_image_bm[NUMFILLPATS]; static Boolean fill_image_bm_exist = False; static GC fill_image_gc = 0; static Boolean fill_style_exists = False; static Pixel form_bg = -1; /* pulldown menu for units of point coords */ static char *unit_items[] = {NULL, /* this is modified in unit_select() */ "Fig units"}; static intptr_t points_units=0; /* 0=Ruler scale, 1=Fig*/ static int conv_array_idx = 0; /* to keep track of widgets that need unit conversions */ static Widget convert_array[MAXDISPTS*2]; /* array for those widgets */ /* For edit all texts inside compound function */ #define MAX_COMPOUND_TEXT_PANELS 2000 /* max number of texts that can be edited in compound */ static Widget compound_text_panels[MAX_COMPOUND_TEXT_PANELS]; Boolean edit_remember_lib_mode = False; /* Remember that we were in library mode */ Boolean edit_remember_dimline_mode = False; /* Remember that we were in dimension line mode */ Boolean lib_cursor = False; /* to reset cursor back to lib mode */ Boolean dim_cursor = False; /* to reset cursor back to line mode */ /*********************************************************************/ /* NOTE: If you change this you must change pictypes in object.h too */ /*********************************************************************/ static char *pic_names[] = { "--", "EPS/PS", "GIF", #ifdef USE_JPEG "JPEG", #endif /* USE_JPEG */ "PCX", "PNG", "PPM", "TIFF", "XBM", #ifdef USE_XPM "XPM", #endif /* USE_XPM */ }; static int ellipse_flag; static intptr_t fill_flag; static intptr_t flip_pic_flag; static void (*done_proc) (); static int button_result; static intptr_t textjust; static Color pen_color, fill_color; static intptr_t hidden_text_flag; static intptr_t special_text_flag; static intptr_t rigid_text_flag; static int new_ps_font, new_latex_font; static int new_psflag; static int min_compound_depth; static Boolean changed, reread_file; static Boolean file_changed=False; static Boolean actions_added=False; static void edit_cancel(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params); static void edit_done(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params), edit_apply(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params); static void popdown_comments(void); /* * the following pix_table and xxxx_pixmaps entries are guaranteed to be * initialized to 0 by the compiler */ static struct { icon_struct *image; Pixmap image_pm; } pix_table[NUM_IMAGES]; static Pixmap capstyle_pixmaps[NUM_JOINSTYLE_TYPES] = {0}; static Pixmap joinstyle_pixmaps[NUM_CAPSTYLE_TYPES] = {0}; /* picture flip menu options */ static char *flip_pic_items[] = {"Normal ", "Flipped about diag"}; /* picture rotation menu options */ static char *rotation_items[] = {" 0", " 90", "180", "270"}; /**********************************************/ /* Translations and actions for edit cancel */ /* Make Escape cancel the edit in addition to */ /* destroy window */ /**********************************************/ static String edit_popup_translations = "Escape: CancelEdit()\n\ WM_PROTOCOLS: CancelEdit()\n"; static XtActionsRec edit_actions[] = { {"CancelEdit", (XtActionProc) edit_cancel}, }; /*************************************************/ /* Translations and actions for showing comments */ /*************************************************/ static String showcomment_popup_translations = ": PopdownComments()\n\ WM_PROTOCOLS: PopdownComments()"; static XtActionsRec showcomment_actions[] = { {"PopdownComments", (XtActionProc) popdown_comments}, }; /*********************************************/ /* Translations and actions for text widgets */ /*********************************************/ /* don't allow newlines in text until we handle multiple line texts */ /** Add Ctrl-Return to do a quick apply and DONE */ /** Bound ^U to erase line instead of multiply(4) */ static String edit_text_translations = "CtrlReturn: DoneEdit()\n\ Return: ApplyEdit()\n\ Escape: CancelEdit()\n\ CtrlJ: no-op(RingBell)\n\ CtrlM: no-op(RingBell)\n\ CtrlX: EmptyTextKey()\n\ CtrlU: EmptyTextKey()\n\ F18: PastePanelKey()\n"; /* scroll in comments */ static String edit_comment_translations = ": scroll-one-line-up()\n\ : scroll-one-line-down()\n"; static XtActionsRec text_actions[] = { {"DoneEdit", (XtActionProc) edit_done}, {"ApplyEdit", (XtActionProc) edit_apply}, }; static String edit_picture_pos_translations = "Return: RepositionPicture()\n"; static XtActionsRec picture_pos_actions[] = { {"RepositionPicture", (XtActionProc) reposition_picture}, }; static String edit_picture_size_translations = "Return: ResizePicture()\n"; static XtActionsRec picture_size_actions[] = { {"ResizePicture", (XtActionProc) resize_picture}, }; static String edit_compound_translations = "Return: ModifyCompound()\n"; static XtActionsRec compound_actions[] = { {"ModifyCompound", (XtActionProc) modify_compound}, }; #define CANCEL 0 #define DONE 1 #define APPLY 2 /******************************/ /* specific stuff for splines */ /******************************/ #define THUMB_H 0.05 #define STEP_VALUE 0.02 #define SFACTOR_BAR_HEIGHT 200 #define SFACTOR_BAR_WIDTH (SFACTOR_BAR_HEIGHT/10) #define SFACTOR_SIGN(x) ( (x) < 0 ? 1.0 : -1.0) #define SFACTOR_TO_PERCENTAGE(x) ((-(x) + 1.0) / 2.0) #define PERCENTAGE_TO_CONTROL(x) (-(SFACTOR_BAR_HEIGHT/100) * (x) + 1.0) static void update_sfactor_value(double new_value); static struct sfactor_def { char label[13]; double value; } sfactor_type[3] = { { "Approximated", S_SPLINE_APPROX }, { "Angular", S_SPLINE_ANGULAR }, { "Interpolated", S_SPLINE_INTERP } }; static void make_window_spline_point(F_spline *s, int x, int y); static Widget sfactor_bar; static F_sfactor *edited_sfactor, *sub_sfactor; static F_point *edited_point; static F_spline *sub_new_s; static int num_spline_points; /*************************************/ /* end of specific stuff for splines */ /*************************************/ static struct { int thickness; Color pen_color; Color fill_color; int depth; intptr_t arc_type; int cap_style; int join_style; int style; float style_val; int pen_style; int fill_style; char *comments; F_arrow for_arrow; F_arrow back_arrow; } generic_vals; #define put_generic_vals(x) \ generic_vals.thickness = x->thickness; \ generic_vals.pen_color = x->pen_color; \ generic_vals.fill_color = x->fill_color; \ generic_vals.depth = x->depth; \ generic_vals.style = x->style; \ generic_vals.style_val = x->style_val; \ generic_vals.pen_style = x->pen_style; \ generic_vals.fill_style = x->fill_style #define get_generic_vals(x) \ new_generic_values(); \ x->thickness = generic_vals.thickness; \ x->pen_color = generic_vals.pen_color; \ x->fill_color = generic_vals.fill_color; \ x->depth = generic_vals.depth; \ x->style = generic_vals.style; \ x->style_val = generic_vals.style_val; \ x->pen_style = generic_vals.pen_style; \ x->fill_style = generic_vals.fill_style; \ x->comments = generic_vals.comments #define put_join_style(x) \ generic_vals.join_style = x->join_style; #define get_join_style(x) \ x->join_style = generic_vals.join_style; #define put_cap_style(x) \ generic_vals.cap_style = x->cap_style; #define get_cap_style(x) \ x->cap_style = generic_vals.cap_style; #define put_arc_type(x) \ generic_vals.arc_type = x->type; void make_window_line (F_line *l); void make_window_text (F_text *t); void make_window_ellipse (F_ellipse *e); void make_window_arc (F_arc *a); void make_window_spline (F_spline *s); void make_window_compound (F_compound *c); void make_window_figure (void); void check_depth (void); void text_transl (Widget w); void check_thick (void); void reset_edit_cursor (void); void arc_type_menu (void); void fill_style_menu (int fill, int fill_flag); void cap_style_panel_menu (void); void join_style_panel_menu (void); void set_image_pm (int val); void fill_style_sens (Boolean state); void fill_pat_sens (Boolean state); void collapse_depths (F_compound *compound); void get_arc_type(F_arc *arc) { arc->type = generic_vals.arc_type; /* remove any arrowheads from pie-wedge style arc */ if (arc->type == T_PIE_WEDGE_ARC) { if (arc->for_arrow) { free((char *) arc->for_arrow); arc->for_arrow = NULL; } if (arc->back_arrow) { free((char *) arc->back_arrow); arc->back_arrow = NULL; } } } /* NOTE: This procedure requires that the structure components for f_arc, f_line and f_spline are in the same order up to and including the arrows */ void put_generic_arrows(F_line *x) { for_arrow = (x->for_arrow != NULL); back_arrow = (x->back_arrow != NULL); if (for_arrow) { generic_vals.for_arrow.type = x->for_arrow->type; generic_vals.for_arrow.style = x->for_arrow->style; generic_vals.for_arrow.thickness = x->for_arrow->thickness; generic_vals.for_arrow.wd = x->for_arrow->wd; generic_vals.for_arrow.ht = x->for_arrow->ht; } else { generic_vals.for_arrow.type = -1; generic_vals.for_arrow.style = -1; /* no existing arrow, set dialog to current ind panel settings */ if (use_abs_arrowvals) { generic_vals.for_arrow.thickness = cur_arrowthick; generic_vals.for_arrow.wd = cur_arrowwidth; generic_vals.for_arrow.ht = cur_arrowheight; } else { /* use multiple of current line thickness */ generic_vals.for_arrow.thickness = cur_arrow_multthick * x->thickness; generic_vals.for_arrow.wd = cur_arrow_multwidth * x->thickness; generic_vals.for_arrow.ht = cur_arrow_multheight * x->thickness; } } if (back_arrow) { generic_vals.back_arrow.type = x->back_arrow->type; generic_vals.back_arrow.style = x->back_arrow->style; generic_vals.back_arrow.thickness = x->back_arrow->thickness; generic_vals.back_arrow.wd = x->back_arrow->wd; generic_vals.back_arrow.ht = x->back_arrow->ht; } else { generic_vals.back_arrow.type = -1; generic_vals.back_arrow.style = -1; /* no existing arrow, set dialog to current ind panel settings */ if (use_abs_arrowvals) { generic_vals.back_arrow.thickness = cur_arrowthick; generic_vals.back_arrow.wd = cur_arrowwidth; generic_vals.back_arrow.ht = cur_arrowheight; } else { /* use multiple of current line thickness */ generic_vals.back_arrow.thickness = cur_arrow_multthick * x->thickness; generic_vals.back_arrow.wd = cur_arrow_multwidth * x->thickness; generic_vals.back_arrow.ht = cur_arrow_multheight * x->thickness; } } } /* NOTE: This procedure requires that the structure components for f_arc, f_line and f_spline are in the same order up to and including the arrows */ void get_generic_arrows(F_line *x) { new_arrow_values(); if (for_arrow) { if (!x->for_arrow) x->for_arrow = create_arrow(); x->for_arrow->type = generic_vals.for_arrow.type; x->for_arrow->style = generic_vals.for_arrow.style; x->for_arrow->thickness = (float) fabs((double) generic_vals.for_arrow.thickness); x->for_arrow->wd = (float) fabs((double) generic_vals.for_arrow.wd); x->for_arrow->ht = (float) fabs((double) generic_vals.for_arrow.ht); } else { if (x->for_arrow) free((char *) x->for_arrow); x->for_arrow = (F_arrow *) NULL; } if (back_arrow) { if (!x->back_arrow) x->back_arrow = create_arrow(); x->back_arrow->type = generic_vals.back_arrow.type; x->back_arrow->style = generic_vals.back_arrow.style; x->back_arrow->thickness = (float) fabs((double) generic_vals.back_arrow.thickness); x->back_arrow->wd = (float) fabs((double) generic_vals.back_arrow.wd); x->back_arrow->ht = (float) fabs((double) generic_vals.back_arrow.ht); } else { if (x->back_arrow) free((char *) x->back_arrow); x->back_arrow = (F_arrow *) NULL; } } void edit_item(void *p, int type, int x, int y); void edit_spline_point(F_spline *spline, int type, int x, int y, F_point *previous_point, F_point *the_point); void edit_figure_comments(int x, int y, unsigned int shift); void edit_item_selected(void) { set_mousefun("edit object", "edit Main comment", "edit point", LOC_OBJ, "show comments", LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(edit_item); init_searchproc_right(edit_spline_point); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = edit_figure_comments; canvas_rightbut_proc = point_search_right; set_cursor(pick9_cursor); reset_action_on(); } /* this handles both viewing of any object's comments (shift=1) and editing of the whole figure comments (shift=0) */ void popup_show_comments(F_line *p, int type, int x, int y); void edit_figure_comments(int x, int y, unsigned int shift) /* Shift Key Status from XEvent */ { if (shift) { /* locate the object and popup the comments panel */ init_searchproc_left(popup_show_comments); object_search_left(x, y, False); /* reset search proc function */ init_searchproc_left(edit_item); } else { /* popup an edit window for the whole figure */ edit_item(&objects, O_FIGURE, 0, 0); } } void popup_show_comments(F_line *p, int type, int x, int y) { Widget form; static Boolean actions_added = False; char *comments; F_arc *a; F_compound *c; F_ellipse *e; F_line *l; F_spline *s; F_text *t; switch (type) { case O_ARC: a = (F_arc *) p; comments = a->comments; break; case O_COMPOUND: c = (F_compound *) p; comments = c->comments; break; case O_ELLIPSE: e = (F_ellipse *) p; comments = e->comments; break; case O_POLYLINE: l = (F_line *) p; comments = l->comments; break; case O_SPLINE: s = (F_spline *) p; comments = s->comments; break; case O_TXT: t = (F_text *) p; comments = t->comments; break; } /* switch */ /* locate the mouse in screen coords */ XtTranslateCoords(canvas_sw, ZOOMX(x), ZOOMY(y), &rootx, &rooty); /* popup a panel showing the object comments */ FirstArg(XtNtitle, "Xfig: Object comments"); NextArg(XtNcolormap, tool_cm); NextArg(XtNx, rootx-10); /* pop it up just under the mouse */ NextArg(XtNy, rooty-10); comment_popup = XtCreatePopupShell("show_comments", overrideShellWidgetClass, tool, Args, ArgCount); FirstArg(XtNborderWidth, 1); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); form = XtCreateManagedWidget("comment_form", formWidgetClass, comment_popup, Args, ArgCount); FirstArg(XtNlabel, "Comments:"); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget("comment_label", labelWidgetClass, form, Args, ArgCount); /* make label widgets for comment lines */ if (comments == NULL) comments = "(None)"; FirstArg(XtNlabel, comments); NextArg(XtNfromVert, below); NextArg(XtNvertDistance, 2); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); below = XtCreateManagedWidget("comments", labelWidgetClass, form, Args, ArgCount); XtAugmentTranslations(comment_popup, XtParseTranslationTable(showcomment_popup_translations)); if (!actions_added) { XtAppAddActions(tool_app, showcomment_actions, XtNumber(showcomment_actions)); actions_added = True; } XtPopupSpringLoaded(comment_popup); } static void popdown_comments(void) { XtDestroyWidget(comment_popup); } void edit_item(void *p, int type, int x, int y) { XtWidgetGeometry xtgeom,comp; int llx, lly, urx, ury, dum; Dimension w, h; Position rootlx, rootly, rootux, rootuy; /* make some pixmaps if we haven't already */ if (joinstyle_pixmaps[0] == 0) { joinstyle_pixmaps[0] = XCreateBitmapFromData(tool_d,canvas_win, (char*) joinmiter_ic.bits, joinmiter_ic.width, joinmiter_ic.height); joinstyle_pixmaps[1] = XCreateBitmapFromData(tool_d,canvas_win, (char*) joinround_ic.bits, joinround_ic.width, joinround_ic.height); joinstyle_pixmaps[2] = XCreateBitmapFromData(tool_d,canvas_win, (char*) joinbevel_ic.bits, joinbevel_ic.width, joinbevel_ic.height); } if (capstyle_pixmaps[0] == 0) { capstyle_pixmaps[0] = XCreateBitmapFromData(tool_d,canvas_win, (char*) capbutt_ic.bits, capbutt_ic.width, capbutt_ic.height); capstyle_pixmaps[1] = XCreateBitmapFromData(tool_d,canvas_win, (char*) capround_ic.bits, capround_ic.width, capround_ic.height); capstyle_pixmaps[2] = XCreateBitmapFromData(tool_d,canvas_win, (char*) capproject_ic.bits, capproject_ic.width, capproject_ic.height); } changed = False; reread_file = False; /* make a window based on the object being edited */ /* also get the bounds of the object to position the popup away from it */ switch (type) { case O_POLYLINE: line_bound((F_line *) p, &llx, &lly, &urx, &ury); make_window_line((F_line *) p); break; case O_TXT: text_bound((F_text *) p, &llx, &lly, &urx, &ury, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); make_window_text((F_text *) p); break; case O_ELLIPSE: ellipse_bound((F_ellipse *) p, &llx, &lly, &urx, &ury); make_window_ellipse((F_ellipse *) p); break; case O_ARC: arc_bound((F_arc *) p, &llx, &lly, &urx, &ury); make_window_arc((F_arc *) p); break; case O_SPLINE: spline_bound((F_spline *) p, &llx, &lly, &urx, &ury); make_window_spline((F_spline *) p); break; case O_COMPOUND: compound_bound((F_compound *) p, &llx, &lly, &urx, &ury); /* turn on the point positioning indicator since it is used for editing compound */ update_indpanel(I_MIN2); make_window_compound((F_compound *) p); break; case O_FIGURE: compound_bound((F_compound *) p, &llx, &lly, &urx, &ury); make_window_figure(); break; } /* try to position the window so it doesn't obscure the object being edited */ /* first realize the popup widget so we can get its width */ XtRealizeWidget(popup); /* translate object coords to screen coords relative to the canvas */ llx = ZOOMX(llx); urx = ZOOMX(urx); lly = ZOOMY(lly); ury = ZOOMY(ury); /* translate those to absolute screen coords */ XtTranslateCoords(canvas_sw, llx, lly, &rootlx, &rootly); XtTranslateCoords(canvas_sw, urx, ury, &rootux, &rootuy); /* size of popup window */ FirstArg(XtNwidth, &w); NextArg(XtNheight, &h); GetValues(popup); /* try putting it just to the right of the object */ if (rootux + 10 + w < screen_wd) { x = rootux+10; } else { /* else put it to the left of the object */ x = rootlx - 10 - w; /* but always on the screen */ if (x < 0) x = 0; } y = 40; /* only change X position of widget */ xtgeom.request_mode = CWX|CWY; xtgeom.x = x; xtgeom.y = y; (void) XtMakeGeometryRequest(popup, &xtgeom, &comp); /* now pop it up */ XtPopup(popup, XtGrabNonexclusive); popup_up = True; /* if the file message window is up add it to the grab */ file_msg_add_grab(); /* insure that the most recent colormap is installed */ set_cmap(XtWindow(popup)); (void) XSetWMProtocols(tool_d, XtWindow(popup), &wm_delete_window, 1); } static void reread_picfile(Widget panel_local, XtPointer closure, XtPointer call_data) { Boolean dum; if (new_l->pic->pic_cache == 0) return; /* hmm, shouldn't get here if no picture */ changed = True; reread_file = True; /* force remapping colors */ list_delete_line(&objects.lines, new_l); redisplay_line(new_l); /* reread the file */ read_picobj(new_l->pic, new_l->pic->pic_cache->file, new_l->pen_color, True, &dum); /* calculate h/w ratio */ new_l->pic->hw_ratio = (float) new_l->pic->pic_cache->bit_size.y/new_l->pic->pic_cache->bit_size.x; get_new_line_values(); list_add_line(&objects.lines, new_l); redisplay_line(new_l); } void edit_spline_point(F_spline *spline, int type, int x, int y, F_point *previous_point, F_point *the_point) { if (type!=O_SPLINE) { put_msg("Only spline points can be edited"); return; } if (open_spline(spline) && (previous_point==NULL || the_point->next==NULL)) { put_msg("Cannot edit end-points"); return; } changed = False; make_window_spline_point(spline, the_point->x, the_point->y); XtPopup(popup, XtGrabNonexclusive); /* if the file message window is up add it to the grab */ file_msg_add_grab(); /* insure that the most recent colormap is installed */ set_cmap(XtWindow(popup)); (void) XSetWMProtocols(tool_d, XtWindow(popup), &wm_delete_window, 1); } static void expand_pic(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { struct f_point p1, p2; int dx, dy, rotation; float ratio; register float orig_ratio = new_l->pic->hw_ratio; p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; rotation = what_rotation(dx,dy); if (dx == 0 || dy == 0 || orig_ratio == 0.0) return; if (((rotation == 0 || rotation == 180) && !flip_pic_flag) || (rotation != 0 && rotation != 180 && flip_pic_flag)) { ratio = (float) fabs((double) dy / (double) dx); if (ratio < orig_ratio) p2.y = p1.y + signof(dy) * (int) (fabs((double) dx) * orig_ratio); else p2.x = p1.x + signof(dx) * (int) (fabs((double) dy) / orig_ratio); } else { ratio = (float) fabs((double) dx / (double) dy); if (ratio < orig_ratio) p2.x = p1.x + signof(dx) * (int) (fabs((double) dy) * orig_ratio); else p2.y = p1.y + signof(dy) * (int) (fabs((double) dx) / orig_ratio); } panel_set_scaled_int(x2_panel, p2.x); panel_set_scaled_int(y2_panel, p2.y); sprintf(buf, "%1.1f", orig_ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); } static void shrink_pic(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { struct f_point p1, p2; int dx, dy, rotation; float ratio; register float orig_ratio = new_l->pic->hw_ratio; p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; rotation = what_rotation(dx,dy); if (dx == 0 || dy == 0 || orig_ratio == 0.0) return; if (((rotation == 0 || rotation == 180) && !flip_pic_flag) || (rotation != 0 && rotation != 180 && flip_pic_flag)) { ratio = (float) fabs((double) dy / (double) dx); /* upper coord is lower+size */ if (ratio > orig_ratio) p2.y = p1.y + signof(dy) * (int) (fabs((double) dx) * orig_ratio); else p2.x = p1.x + signof(dx) * (int) (fabs((double) dy) / orig_ratio); } else { ratio = (float) fabs((double) dx / (double) dy); if (ratio > orig_ratio) p2.x = p1.x + signof(dx) * (int) (fabs((double) dy) * orig_ratio); else p2.y = p1.y + signof(dy) * (int) (fabs((double) dx) / orig_ratio); } panel_set_scaled_int(x2_panel, p2.x); panel_set_scaled_int(y2_panel, p2.y); sprintf(buf, "%1.1f", orig_ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); } static void origsize_pic(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { struct f_point p1, p2; int dx, dy; register float orig_ratio = new_l->pic->hw_ratio; p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; if (dx == 0 || dy == 0 || orig_ratio == 0.0) return; /* upper coord is lower+size */ p2.x = p1.x + signof(dx) * new_l->pic->pic_cache->size_x; p2.y = p1.y + signof(dy) * new_l->pic->pic_cache->size_y; panel_set_scaled_int(x2_panel, p2.x); panel_set_scaled_int(y2_panel, p2.y); sprintf(buf, "%1.1f", orig_ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); } static void scale_percent_pic(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { struct f_point p1, p2; int dx, dy; float orig_ratio = new_l->pic->hw_ratio; float pct; if (orig_ratio == 0.0) return; p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* get the percent scale */ pct = atof(panel_get_value(percent_entry)); if (pct <= 0.0) { panel_set_value(percent_entry,"0.001"); pct = 0.001; } /* find direction of corners - size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; /* upper coord is lower+size */ p2.x = p1.x + (signof(dx) * new_l->pic->pic_cache->size_x * pct/100.0); p2.y = p1.y + (signof(dy) * new_l->pic->pic_cache->size_y * pct/100.0); panel_set_scaled_int(x2_panel, p2.x); panel_set_scaled_int(y2_panel, p2.y); sprintf(buf, "%1.1f", orig_ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); } /* make a panel for the user to change the comments for the whole figure */ void make_window_figure(void) { generic_window("Whole Figure", "", &figure_ic, done_figure_comments, NO_GENERICS, NO_ARROWS, objects.comments); } static void done_figure_comments(void) { char *s; switch (button_result) { case DONE: /* save old comments */ saved_objects.comments = objects.comments; /* get new comments */ s = panel_get_value(comments_panel); /* allocate space and copy */ copy_comments(&s, &objects.comments); clean_up(); set_action_object(F_EDIT, O_FIGURE); set_modifiedflag(); break; case CANCEL: break; } } void make_window_compound(F_compound *c) { F_text *t; int i; Widget save_form, viewp; F_pos dimen; /* need temp storage for width, height panel */ set_cursor(panel_cursor); mask_toggle_compoundmarker(c); old_c = copy_compound(c); new_c = c; generic_window("COMPOUND", "", &glue_ic, done_compound, NO_GENERICS, NO_ARROWS, c->comments); /* tell the pulldown unit menu which panels to convert */ init_convert_array(); f_pair_panel(&c->nwcorner, "Top left corner", &x1_panel, "X =", &y1_panel, "Y =", True); /* override translations for Return to reposition top-left of compound */ XtOverrideTranslations(x1_panel, XtParseTranslationTable(edit_compound_translations)); XtOverrideTranslations(y1_panel, XtParseTranslationTable(edit_compound_translations)); f_pair_panel(&c->secorner, "Bottom right corner", &x2_panel, "X =", &y2_panel, "Y =", False); /* override translations for Return to reposition bottom-right of compound */ XtOverrideTranslations(x2_panel, XtParseTranslationTable(edit_compound_translations)); XtOverrideTranslations(y2_panel, XtParseTranslationTable(edit_compound_translations)); dimen.x = c->secorner.x - c->nwcorner.x; dimen.y = c->secorner.y - c->nwcorner.y; f_pair_panel(&dimen, "Dimensions", &width_panel, "Width =", &height_panel, "Height =", False); /* override translations for Return to scale compound */ XtOverrideTranslations(width_panel, XtParseTranslationTable(edit_compound_translations)); XtOverrideTranslations(height_panel, XtParseTranslationTable(edit_compound_translations)); FirstArg(XtNlabel, "Depths"); NextArg(XtNborderWidth, 0); NextArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget("min_depth", labelWidgetClass, form, Args, ArgCount); /* show min/max depths in compound */ min_compound_depth = find_smallest_depth(c); sprintf(buf,"Minimum: %d", min_compound_depth); FirstArg(XtNlabel, buf); NextArg(XtNborderWidth, 0); NextArg(XtNhorizDistance, 10); NextArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); min_depth_w = beside = XtCreateManagedWidget("min_depth", labelWidgetClass, form, Args, ArgCount); sprintf(buf,"Maximum: %d", find_largest_depth(c)); FirstArg(XtNlabel, buf); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, beside); NextArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); max_depth_w = below = XtCreateManagedWidget("max_depth", labelWidgetClass, form, Args, ArgCount); /* button to collapse depths */ FirstArg(XtNlabel, "Collapse Depths"); NextArg(XtNfromVert, below); NextArg(XtNhorizDistance, 10); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget("collapse_depths", commandWidgetClass, form, Args, ArgCount); XtAddCallback(below, XtNcallback, (XtCallbackProc) collapse_depth, (XtPointer) NULL); int_label(object_count(c), "Number of objects", &num_objects); /* make a form to contain the text objects in the compound */ if (c->texts) { /* save toplevel form so that the following widgets will go in this sub-form */ save_form = form; /* form to frame the text heading with the texts */ FirstArg(XtNborderWidth, 1); NextArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); form = XtCreateManagedWidget("form", formWidgetClass, save_form, Args, ArgCount); FirstArg(XtNlabel, "Text objects in this compound"); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget("label", labelWidgetClass, form, Args, ArgCount); /* first make a viewport in case we need a scrollbar */ FirstArg(XtNallowVert, True); NextArg(XtNborderWidth, 0); NextArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); viewp = XtCreateManagedWidget("textview", viewportWidgetClass, form, Args, ArgCount); /* form in the viewport */ FirstArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); form = XtCreateManagedWidget("form", formWidgetClass, viewp, Args, ArgCount); below = NULL; for (t=c->texts, i=0; t && inext, i++) { str_panel(t->cstring, "Text", &compound_text_panels[i], 220, True, False); /* make the margins small */ FirstArg(XtNhorizDistance, 1); SetValues(below); if (i>0) { /* scrunch the texts together vertically */ FirstArg(XtNvertDistance, 1); SetValues(below); } } /* if many texts, set height of viewport */ if (i > 8) { FirstArg(XtNheight, 320); SetValues(viewp); } /* restore original form */ form = save_form; } } /* come here when user presses return in any compound corner/size entry */ static void modify_compound(Widget w) { if (w == x1_panel || w == y1_panel) reposition_top(); else if (w == x2_panel || w == y2_panel) reposition_bottom(); else if (w == width_panel || w == height_panel) rescale_compound(); } /* come here when user presses return in picture X/Y position */ static void reposition_picture(Widget w) { int x1, y1, x2, y2; int width, height, rotation; x1 = panel_get_dim_value(x1_panel); y1 = panel_get_dim_value(y1_panel); x2 = panel_get_dim_value(x2_panel); y2 = panel_get_dim_value(y2_panel); /* calculate new width, height - keep sign for now to determine rotation */ width = x2-x1; height = y2-y1; rotation = 0; if (width < 0 && height < 0) rotation = 2; /* 180 degrees */ else if (width < 0 && height >= 0) rotation = 3; /* 270 degrees */ else if (height < 0 && width >= 0) rotation = 1; /* 90 degrees */ FirstArg(XtNlabel, rotation_items[rotation]); SetValues(rotation_panel); /* absolute value */ width = abs(width); height = abs(height); if (width > 50*PIX_PER_INCH) { file_msg("Picture too wide (> 50 inches)"); return; } if (height > 50*PIX_PER_INCH) { file_msg("Picture too tall (> 50 inches)"); return; } /* put back */ panel_set_scaled_int(width_panel, width); panel_set_scaled_int(height_panel, height); /* resize the picture */ edit_apply(w, (XButtonEvent *) 0, (String*) 0, (Cardinal*) 0); } /* come here when user presses return in picture width or height */ static void resize_picture(Widget w) { int x1, y1, x2, y2; int width, height; x1 = panel_get_dim_value(x1_panel); y1 = panel_get_dim_value(y1_panel); x2 = panel_get_dim_value(x2_panel); y2 = panel_get_dim_value(y2_panel); width = panel_get_dim_value(width_panel); height = panel_get_dim_value(height_panel); if (width > 50*PIX_PER_INCH) { file_msg("Picture too wide (> 50 inches)"); return; } if (height > 50*PIX_PER_INCH) { file_msg("Picture too tall (> 50 inches)"); return; } if (w == width_panel) { /* adjust x to reflect new width */ if (x1 < x2) { x2 = x1 + width; panel_set_scaled_int(x2_panel, x2); } else { x1 = x2 + width; panel_set_scaled_int(x1_panel, x1); } } else { /* adjust y to reflect new height */ if (y1 < y2) { y2 = y1 + height; panel_set_scaled_int(y2_panel, y2); } else { y1 = y2 + height; panel_set_scaled_int(y1_panel, y1); } } /* resize the picture */ edit_apply(w, (XButtonEvent *) 0, (String*) 0, (Cardinal*) 0); } /* reposition the compound using the user's new upper-left values */ static void reposition_top(void) { int nw_x, nw_y, se_x, se_y, dx, dy; /* get user's new top-left corner values */ nw_x = panel_get_dim_value(x1_panel); nw_y = panel_get_dim_value(y1_panel); /* get shift */ dx = nw_x - new_c->nwcorner.x; dy = nw_y - new_c->nwcorner.y; /* adjust lower-right corner */ se_x = new_c->secorner.x + dx; se_y = new_c->secorner.y + dy; /* and update those values in panel */ panel_set_scaled_int(x2_panel, se_x); panel_set_scaled_int(y2_panel, se_y); /* update the compound on the screen */ button_result = APPLY; done_compound(); } /* reposition the compound using the user's new lower-right values */ static void reposition_bottom(void) { int nw_x, nw_y, se_x, se_y, dx, dy; /* get user's new lower-right corner values */ se_x = panel_get_dim_value(x2_panel); se_y = panel_get_dim_value(y2_panel); /* get shift */ dx = se_x - new_c->secorner.x; dy = se_y - new_c->secorner.y; /* adjust upper-left corner */ nw_x = new_c->nwcorner.x + dx; nw_y = new_c->nwcorner.y + dy; /* and update those values in panel */ panel_set_scaled_int(x1_panel, nw_x); panel_set_scaled_int(y1_panel, nw_y); /* update the compound on the screen */ button_result = APPLY; done_compound(); } /* rescale the compound using the user's new width/height values */ /* it is rescaled relative to the upper-left corner */ static void rescale_compound(void) { int width, height, se_x, se_y; /* get user's new width/height values */ width = panel_get_dim_value(width_panel); height = panel_get_dim_value(height_panel); /* adjust lower-right corner with new size */ se_x = new_c->nwcorner.x + width; se_y = new_c->nwcorner.y + height; /* update the lower-right corner values in panel */ panel_set_scaled_int(x2_panel, se_x); panel_set_scaled_int(y2_panel, se_y); /* update the compound on the screen */ button_result = APPLY; done_compound(); } static void get_new_compound_values(void) { int dx, dy, nw_x, nw_y, se_x, se_y; float scalex, scaley; F_text *t; int i; PR_SIZE size; nw_x = panel_get_dim_value(x1_panel); nw_y = panel_get_dim_value(y1_panel); se_x = panel_get_dim_value(x2_panel); se_y = panel_get_dim_value(y2_panel); dx = nw_x - new_c->nwcorner.x; dy = nw_y - new_c->nwcorner.y; if (new_c->nwcorner.x - new_c->secorner.x == 0) scalex = 0.0; else scalex = (float) (nw_x - se_x) / (float) (new_c->nwcorner.x - new_c->secorner.x); if (new_c->nwcorner.y - new_c->secorner.y == 0) scaley = 0.0; else scaley = (float) (nw_y - se_y) / (float) (new_c->nwcorner.y - new_c->secorner.y); /* get any comments */ new_c->comments = my_strdup(panel_get_value(comments_panel)); /* get any new text object values */ for (t=new_c->texts,i=0; t ;t=t->next,i++) { if (t->cstring) free(t->cstring); t->cstring = my_strdup(panel_get_value(compound_text_panels[i])); /* calculate new size */ /* get the fontstruct for zoom = 1 to get the size of the string */ canvas_font = lookfont(x_fontnum(psfont_text(t), t->font), t->size); size = textsize(canvas_font, strlen(t->cstring), t->cstring); t->length = size.length; t->ascent = size.ascent; t->descent = size.descent; } translate_compound(new_c, dx, dy); scale_compound(new_c, scalex, scaley, nw_x, nw_y); } static void done_compound(void) { switch (button_result) { case APPLY: changed = True; list_delete_compound(&objects.compounds, new_c); redisplay_compound(new_c); get_new_compound_values(); compound_bound(new_c, &new_c->nwcorner.x, &new_c->nwcorner.y, &new_c->secorner.x, &new_c->secorner.y); /* update top-left and bottom-right values in panel from new bounding box */ panel_set_scaled_int(x1_panel, new_c->nwcorner.x); panel_set_scaled_int(y1_panel, new_c->nwcorner.y); panel_set_scaled_int(x2_panel, new_c->secorner.x); panel_set_scaled_int(y2_panel, new_c->secorner.y); list_add_compound(&objects.compounds, new_c); redisplay_compound(new_c); toggle_compoundmarker(new_c); break; case DONE: get_new_compound_values(); compound_bound(new_c, &new_c->nwcorner.x, &new_c->nwcorner.y, &new_c->secorner.x, &new_c->secorner.y); /* update top-left and bottom-right values in panel from new bounding box */ panel_set_scaled_int(x1_panel, new_c->nwcorner.x); panel_set_scaled_int(y1_panel, new_c->nwcorner.y); panel_set_scaled_int(x2_panel, new_c->secorner.x); panel_set_scaled_int(y2_panel, new_c->secorner.y); redisplay_compounds(new_c, old_c); clean_up(); old_c->next = new_c; set_latestcompound(old_c); set_action_object(F_EDIT, O_COMPOUND); set_modifiedflag(); remove_compound_depth(old_c); add_compound_depth(new_c); /* if this was a place-and-edit, continue with library place */ if (edit_remember_lib_mode) { edit_remember_lib_mode = False; put_selected(); /* and set flag to reset cursor back to place lib */ lib_cursor = True; } /* if this was a dimension line edit, continue with line mode */ if (edit_remember_dimline_mode) { edit_remember_dimline_mode = False; line_drawing_selected(); /* and set flag to reset cursor back to place lib */ dim_cursor = True; } break; case CANCEL: list_delete_compound(&objects.compounds, new_c); list_add_compound(&objects.compounds, old_c); if (saved_objects.compounds && saved_objects.compounds->next && saved_objects.compounds->next == new_c) saved_objects.compounds->next = old_c; else if (saved_objects.compounds == new_c) saved_objects.compounds = old_c; if (changed) redisplay_compounds(old_c, new_c); else toggle_compoundmarker(old_c); free_compound(&new_c); /* if this was a place-and-edit, continue with library place */ if (edit_remember_lib_mode) { edit_remember_lib_mode = False; put_selected(); /* and set flag to reset cursor back to place lib */ lib_cursor = True; } /* if this was a dimension line edit, continue with line mode */ if (edit_remember_dimline_mode) { edit_remember_dimline_mode = False; line_drawing_selected(); /* and set flag to reset cursor back to place lib */ dim_cursor = True; } break; } } void make_window_line(F_line *l) { struct f_point p1, p2; int dx, dy, rotation; float ratio; int i, vdist; F_pos dimen; /* need temp storage for width, height panel */ Widget type; set_cursor(panel_cursor); mask_toggle_linemarker(l); old_l = copy_line(l); new_l = l; put_generic_vals(new_l); put_cap_style(new_l); put_join_style(new_l); pen_color = new_l->pen_color; fill_color = new_l->fill_color; /* tell the pulldown unit menu which panels to convert */ init_convert_array(); /* single-point lines don't get arrows - delete any that might already exist */ if (new_l->points->next == NULL) { if (new_l->for_arrow) free((char *) new_l->for_arrow); if (new_l->back_arrow) free((char *) new_l->back_arrow); new_l->for_arrow = new_l->back_arrow = (F_arrow *) NULL; } switch (new_l->type) { case T_POLYLINE: put_generic_arrows(new_l); /* don't make arrow panels if single-point line */ generic_window("POLYLINE", "Polyline", &line_ic, done_line, GENERICS, (new_l->points->next? ARROWS: NO_ARROWS), l->comments); points_panel(new_l->points); break; case T_POLYGON: generic_window("POLYLINE", "Polygon", &polygon_ic, done_line, GENERICS, NO_ARROWS, l->comments); points_panel(new_l->points); break; case T_BOX: generic_window("POLYLINE", "Box", &box_ic, done_line, GENERICS, NO_ARROWS, l->comments); p1 = *new_l->points; p2 = *new_l->points->next->next; xy_panel(p1.x, p1.y, "First corner", &x1_panel, &y1_panel, True); xy_panel(p2.x, p2.y, "Opposite corner", &x2_panel, &y2_panel, False); break; case T_ARCBOX: generic_window("POLYLINE", "ArcBox", &arc_box_ic, done_line, GENERICS, NO_ARROWS, l->comments); p1 = *new_l->points; p2 = *new_l->points->next->next; (void) int_panel(new_l->radius, form, "Corner radius", (Widget) 0, &radius, MIN_BOX_RADIUS, MAX_BOX_RADIUS, 1); xy_panel(p1.x, p1.y, "First corner", &x1_panel, &y1_panel, True); xy_panel(p2.x, p2.y, "Opposite corner", &x2_panel, &y2_panel, False); break; case T_PICTURE: old_l->type = T_BOX; /* so colors of old won't be included in new */ generic_window("POLYLINE", "Picture Object", &picobj_ic, done_line, NO_GENERICS, NO_ARROWS, l->comments); below = pen_color_selection_panel(); /* only the XBM (bitmap) type has a pen color */ if (new_l->pic != 0 && new_l->pic->pic_cache && new_l->pic->pic_cache->subtype != T_PIC_XBM) XtSetSensitive(pen_col_button, False); (void) int_panel(new_l->depth, form, " Depth", (Widget) 0, &depth_panel, MIN_DEPTH, MAX_DEPTH, 1); str_panel(new_l->pic->pic_cache? new_l->pic->pic_cache->file: "", "Picture filename", &pic_name_panel, 290, False, False); /* make a button to reread the picture file */ FirstArg(XtNfromVert, beside); NextArg(XtNhorizDistance, 10); NextArg(XtNlabel, "Reread"); NextArg(XtNsensitive, (new_l->pic->pic_cache && new_l->pic->pic_cache->file[0])); /* only sensitive if there is a filename */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); reread = below = XtCreateManagedWidget("reread", commandWidgetClass, form, Args, ArgCount); XtAddCallback(below, XtNcallback, (XtCallbackProc) reread_picfile, (XtPointer) NULL); /* add browse button for image files */ FirstArg(XtNlabel, "Browse"); NextArg(XtNfromHoriz, below); NextArg(XtNfromVert, beside); NextArg(XtNhorizDistance, 10); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("browse", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) browse_button, (XtPointer) NULL); FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNlabel, "Type:"); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); type = beside = XtCreateManagedWidget("pic_type_label", labelWidgetClass, form, Args, ArgCount); vdist = 4; for (i=0; ipic != 0 && new_l->pic->pic_cache && new_l->pic->pic_cache->subtype == i+1) { NextArg(XtNbackground, colors[RED]); NextArg(XtNsensitive, True); } else { NextArg(XtNbackground, colors[WHITE]); NextArg(XtNsensitive, False); } NextArg(XtNlabel, " "); pic_type_box[i] = XtCreateManagedWidget("pic_type_box", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromHoriz, pic_type_box[i]); NextArg(XtNfromVert, below); NextArg(XtNhorizDistance, 0); NextArg(XtNvertDistance, vdist); NextArg(XtNborderWidth, 0); NextArg(XtNlabel, pic_names[i+1]); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("pic_type_name", labelWidgetClass, form, Args, ArgCount); } below = beside; FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNlabel, "Size:"); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("pic_size_label", labelWidgetClass, form, Args, ArgCount); if (new_l->pic != 0 && new_l->pic->pic_cache && new_l->pic->pic_cache->subtype != T_PIC_NONE) sprintf(buf,"%4d x %4d", new_l->pic->pic_cache->bit_size.x,new_l->pic->pic_cache->bit_size.y); else strcpy(buf," -- "); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNresizable, False); NextArg(XtNborderWidth, 0); NextArg(XtNlabel, buf); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); pic_size = XtCreateManagedWidget("pic_size", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, pic_size); NextArg(XtNhorizDistance, 10); NextArg(XtNlabel, "Colors:"); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("pic_colors_label", labelWidgetClass, form, Args, ArgCount); /* although the EPS may have colors, the actual number is not known */ if (new_l->pic != 0 && new_l->pic->pic_cache && ( new_l->pic->pic_cache->subtype == T_PIC_PNG || #ifdef USE_XPM new_l->pic->pic_cache->subtype == T_PIC_XPM || #endif /* USE_XPM */ new_l->pic->pic_cache->subtype == T_PIC_PCX || new_l->pic->pic_cache->subtype == T_PIC_PPM || new_l->pic->pic_cache->subtype == T_PIC_TIF || #ifdef USE_JPEG new_l->pic->pic_cache->subtype == T_PIC_JPEG || #endif /* USE_JPEG */ new_l->pic->pic_cache->subtype == T_PIC_GIF)) sprintf(buf,"%3d",new_l->pic->pic_cache->numcols); else strcpy(buf,"N/A"); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNresizable, False); NextArg(XtNborderWidth, 0); NextArg(XtNlabel, buf); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); pic_colors = XtCreateManagedWidget("pic_colors", labelWidgetClass, form, Args, ArgCount); /* transparent color entry for GIF files */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, pic_colors); NextArg(XtNhorizDistance, 10); NextArg(XtNlabel, "Transp color:"); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("transp_label", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, beside); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); if (new_l->pic->pic_cache && new_l->pic->pic_cache->subtype == T_PIC_GIF) { if (new_l->pic->pic_cache->transp == TRANSP_NONE) sprintf(buf,"None"); else sprintf(buf,"%4d",(unsigned int) new_l->pic->pic_cache->transp); } else sprintf(buf," N/A"); NextArg(XtNlabel, buf); transp_color = XtCreateManagedWidget("transp_color", labelWidgetClass, form, Args, ArgCount); below = pic_colors; p1 = *new_l->points; p2 = *new_l->points->next->next; xy_panel(p1.x, p1.y, "First corner", &x1_panel, &y1_panel, True); xy_panel(p2.x, p2.y, "Opposite corner", &x2_panel, &y2_panel, False); /* call the resize_picture proc when the user changes x or y */ XtOverrideTranslations(x1_panel, XtParseTranslationTable(edit_picture_pos_translations)); XtOverrideTranslations(y1_panel, XtParseTranslationTable(edit_picture_pos_translations)); XtOverrideTranslations(x2_panel, XtParseTranslationTable(edit_picture_pos_translations)); XtOverrideTranslations(y2_panel, XtParseTranslationTable(edit_picture_pos_translations)); /* width and height */ dimen.x = abs(p1.x - p2.x); dimen.y = abs(p1.y - p2.y); f_pair_panel(&dimen, "Dimensions", &width_panel, "Width =", &height_panel, "Length =", False); /* override translations for Return to resize picture */ XtOverrideTranslations(width_panel, XtParseTranslationTable(edit_picture_size_translations)); XtOverrideTranslations(height_panel, XtParseTranslationTable(edit_picture_size_translations)); /* make pulldown flipped menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Orientation", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); flip_pic_flag = new_l->pic->flipped; flip_pic_panel = XtCreateManagedWidget( flip_pic_items[flip_pic_flag ? 1 : 0], menuButtonWidgetClass, form, Args, ArgCount); below = flip_pic_panel; make_pulldown_menu(flip_pic_items, XtNumber(flip_pic_items), -1, "", flip_pic_panel, flip_pic_select); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; rotation = 0; if (dx < 0 && dy < 0) rotation = 2; /* 180 */ else if (dx < 0 && dy >= 0) rotation = 3; /* 270 */ else if (dx >= 0 && dy < 0) rotation = 1; /* 90 */ if (dx == 0 || dy == 0) ratio = 0.0; else if (((rotation == 0 || rotation == 2) && !flip_pic_flag) || (rotation != 0 && rotation != 2 && flip_pic_flag)) ratio = (float) fabs((double) dy / (double) dx); else ratio = (float) fabs((double) dx / (double) dy); /* make pulldown rotation menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Rotation", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); rotation_panel = XtCreateManagedWidget( rotation_items[rotation], menuButtonWidgetClass, form, Args, ArgCount); below = rotation_panel; make_pulldown_menu(rotation_items, XtNumber(rotation_items), -1, "", rotation_panel, rotation_select); float_label(ratio, " Curr h/w Ratio", &hw_ratio_panel); float_label(new_l->pic->hw_ratio, " Orig h/w Ratio", &orig_hw_panel); below = orig_hw_panel; FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Change h/w ratio", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNsensitive, new_l->pic->hw_ratio ? True : False); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); NextArg(XtNfromHoriz, beside); shrink = XtCreateManagedWidget("Shrink to orig", commandWidgetClass, form, Args, ArgCount); XtAddEventHandler(shrink, ButtonReleaseMask, False, (XtEventHandler) shrink_pic, (XtPointer) NULL); beside = shrink; /* TRICK - make sure XtNfromHoriz is last resource above */ ArgCount--; /*********************************************************/ NextArg(XtNfromHoriz, beside); expand = XtCreateManagedWidget("Expand to orig", commandWidgetClass, form, Args, ArgCount); XtAddEventHandler(expand, ButtonReleaseMask, False, (XtEventHandler) expand_pic, (XtPointer) NULL); below = expand; FirstArg(XtNfromVert, below); NextArg(XtNsensitive, new_l->pic->hw_ratio ? True : False); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); origsize = XtCreateManagedWidget("Use original size", commandWidgetClass, form, Args, ArgCount); XtAddEventHandler(origsize, ButtonReleaseMask, False, (XtEventHandler) origsize_pic, (XtPointer) NULL); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, origsize); NextArg(XtNhorizDistance, 15); NextArg(XtNsensitive, new_l->pic->hw_ratio ? True : False); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); percent_button = XtCreateManagedWidget("Scale by %", commandWidgetClass, form, Args, ArgCount); XtAddEventHandler(percent_button, ButtonReleaseMask, False, (XtEventHandler) scale_percent_pic, (XtPointer) NULL); percent = MakeFloatSpinnerEntry(form, &percent_entry, "scale_percent", below, percent_button, (XtCallbackProc) 0, "100.0", 0.00001, 1000.0, 1.0, 45); XtSetSensitive(percent, new_l->pic->hw_ratio ? True : False); break; } } static void get_new_line_values(void) { struct f_point p1, p2, *p; char *string; char longname[PATH_MAX]; int dx, dy, rotation; float ratio; int i; Boolean existing; switch (new_l->type) { case T_POLYLINE: get_generic_vals(new_l); get_cap_style(new_l); get_join_style(new_l); get_generic_arrows(new_l); get_points(new_l->points); return; case T_POLYGON: get_generic_vals(new_l); get_join_style(new_l); get_points(new_l->points); return; case T_ARCBOX: new_l->radius = atoi(panel_get_value(radius)); case T_BOX: get_generic_vals(new_l); get_join_style(new_l); p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); break; case T_PICTURE: check_depth(); new_l->pen_color = pen_color; new_l->fill_color = fill_color; new_l->depth = atoi(panel_get_value(depth_panel)); /* get any comments (this is done in get_generic_vals for other line types) */ new_l->comments = my_strdup(panel_get_value(comments_panel)); p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; rotation = what_rotation(dx,dy); if (dx == 0 || dy == 0) ratio = 0.0; else if (((rotation == 0 || rotation == 180) && !flip_pic_flag) || (rotation != 0 && rotation != 180 && flip_pic_flag)) ratio = (float) fabs((double) dy / (double) dx); else ratio = (float) fabs((double) dx / (double) dy); new_l->pic->flipped = flip_pic_flag; sprintf(buf, "%1.1f", ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); string = panel_get_value(pic_name_panel); if (string[0] == '\0') string = EMPTY_PIC; else if (string[0] == '~') { /* if user typed tilde, parse user path and put in string panel */ parseuserpath(string,longname); panel_set_value(pic_name_panel, longname); string = longname; } else if (string[0] != '/') { /* make absolute */ sprintf(longname, "%s/%s", cur_file_dir, string); panel_set_value(pic_name_panel, longname); string = longname; } file_changed = False; /* if the filename changed, or this is a new picture */ if (!new_l->pic->pic_cache || strcmp(string, new_l->pic->pic_cache->file)) { reread_file = False; file_changed = True; if (new_l->pic->pic_cache) { /* decrease ref count in picture repository for this name and free if 0 */ free_picture_entry(new_l->pic->pic_cache); } new_l->pic->hw_ratio = 0.0; /* read the new picture file */ if (strcmp(string, EMPTY_PIC)) { read_picobj(new_l->pic, string, new_l->pen_color, reread_file, &existing); /* calculate h/w ratio */ new_l->pic->hw_ratio = (float) new_l->pic->pic_cache->bit_size.y/new_l->pic->pic_cache->bit_size.x; } /* enable reread button now */ XtSetSensitive(reread, True); } /* update bitmap size */ if (new_l->pic->pic_cache && new_l->pic->pic_cache->subtype != T_PIC_NONE) { sprintf(buf,"%d x %d", new_l->pic->pic_cache->bit_size.x,new_l->pic->pic_cache->bit_size.y); /* only the XBM (bitmap) type has a pen color */ if (new_l->pic->pic_cache->subtype == T_PIC_XBM) XtSetSensitive(pen_col_button, True); else XtSetSensitive(pen_col_button, False); } else { strcpy(buf,"--"); } FirstArg(XtNlabel, buf); SetValues(pic_size); /* stop here if no picture file specified yet */ if (strcmp(string, EMPTY_PIC) == 0) break; /* make box red indicating this type of picture file */ for (i=0; ipic->pic_cache->subtype == i+1) { FirstArg(XtNbackground, colors[RED]); NextArg(XtNsensitive, True); } else { FirstArg(XtNbackground, colors[WHITE]); NextArg(XtNsensitive, False); } SetValues(pic_type_box[i]); } /* number of colors */ /* although the FIG and EPS may have colors, the actual number is not known */ FirstArg(XtNlabel, buf); if ( new_l->pic->pic_cache->subtype == T_PIC_PCX || new_l->pic->pic_cache->subtype == T_PIC_PPM || new_l->pic->pic_cache->subtype == T_PIC_TIF || new_l->pic->pic_cache->subtype == T_PIC_PNG || #ifdef USE_XPM new_l->pic->pic_cache->subtype == T_PIC_XPM || #endif /* USE_XPM */ #ifdef USE_JPEG new_l->pic->pic_cache->subtype == T_PIC_JPEG || #endif /* USE_JPEG */ new_l->pic->pic_cache->subtype == T_PIC_GIF) sprintf(buf,"%3d",new_l->pic->pic_cache->numcols); else strcpy(buf,"N/A"); SetValues(pic_colors); /* now transparent color if GIF file */ if (new_l->pic->pic_cache->subtype == T_PIC_GIF) { if (new_l->pic->pic_cache->transp == TRANSP_NONE) sprintf(buf,"None"); else sprintf(buf,"%4d",(unsigned int) new_l->pic->pic_cache->transp); } else sprintf(buf," N/A"); SetValues(transp_color); /* h/w ratio */ sprintf(buf, "%1.1f", new_l->pic->hw_ratio); FirstArg(XtNlabel, buf); SetValues(orig_hw_panel); app_flush(); if (new_l->pic->pic_cache->subtype == T_PIC_XBM) put_msg("Read XBM image of %dx%d pixels OK", new_l->pic->pic_cache->bit_size.x, new_l->pic->pic_cache->bit_size.y); /* recolor and redraw all pictures if this is a NEW picture */ if (reread_file || !existing && file_changed && !appres.monochrome && (new_l->pic->pic_cache->numcols > 0) && (new_l->pic->pic_cache->bitmap != 0)) { reread_file = False; /* remap all picture colors */ remap_imagecolors(); /* make sure current colormap is installed */ set_cmap(XtWindow(popup)); /* and redraw all of the pictures already on the canvas */ redraw_images(&objects); put_msg("Read %s image of %dx%d pixels and %d colors OK", new_l->pic->pic_cache->subtype == T_PIC_EPS? "EPS": new_l->pic->pic_cache->subtype == T_PIC_GIF? "GIF": #ifdef USE_JPEG new_l->pic->pic_cache->subtype == T_PIC_JPEG? "JPEG": #endif /* USE_JPEG */ new_l->pic->pic_cache->subtype == T_PIC_PCX? "PCX": new_l->pic->pic_cache->subtype == T_PIC_PPM? "PPM": new_l->pic->pic_cache->subtype == T_PIC_TIF? "TIFF": new_l->pic->pic_cache->subtype == T_PIC_PNG? "PNG": #ifdef USE_XPM new_l->pic->pic_cache->subtype == T_PIC_XPM? "XPM": #endif /* USE_XPM */ "Unknown", new_l->pic->pic_cache->bit_size.x, new_l->pic->pic_cache->bit_size.y, new_l->pic->pic_cache->numcols); app_flush(); } FirstArg(XtNsensitive, new_l->pic->hw_ratio ? True : False); SetValues(shrink); SetValues(expand); SetValues(origsize); SetValues(percent_button); /* must explicitely set a spinner with XtSetSensitive() */ XtSetSensitive(percent, new_l->pic->hw_ratio ? True : False); break; } /* switch */ p = new_l->points; p->x = p1.x; p->y = p1.y; p = p->next; p->x = p2.x; p->y = p1.y; p = p->next; p->x = p2.x; p->y = p2.y; p = p->next; p->x = p1.x; p->y = p2.y; p = p->next; p->x = p1.x; p->y = p1.y; } static void done_line(void) { int prev_depth; switch (button_result) { case APPLY: changed = True; list_delete_line(&objects.lines, new_l); redisplay_line(new_l); get_new_line_values(); list_add_line(&objects.lines, new_l); redisplay_line(new_l); toggle_linemarker(new_l); break; case DONE: /* save in case user changed depth */ prev_depth = new_l->depth; get_new_line_values(); if (new_l->pic) new_l->pic->new = False; /* user has modified it */ if (prev_depth != new_l->depth) { remove_depth(O_POLYLINE, prev_depth); add_depth(O_POLYLINE, new_l->depth); } redisplay_lines(new_l, old_l); if (new_l->type == T_PICTURE) old_l->type = T_PICTURE; /* restore type */ clean_up(); old_l->next = new_l; set_latestline(old_l); set_action_object(F_EDIT, O_POLYLINE); set_modifiedflag(); break; case CANCEL: list_delete_line(&objects.lines, new_l); /* if user created it but cancelled, delete it */ if (new_l->pic && new_l->pic->new) { redisplay_line(old_l); free_line(&new_l); return; } list_add_line(&objects.lines, old_l); if (saved_objects.lines && saved_objects.lines->next && saved_objects.lines->next == new_l) saved_objects.lines->next = old_l; else if (saved_objects.lines == new_l) saved_objects.lines = old_l; if (new_l->type == T_PICTURE) { old_l->type = T_PICTURE; /* restore type */ if (file_changed) { remap_imagecolors(); /* and restore colors */ redraw_images(&objects); /* and refresh them */ } } if (changed) redisplay_lines(new_l, old_l); else toggle_linemarker(old_l); free_line(&new_l); break; } } void make_window_text(F_text *t) { static char *textjust_items[] = { "Left justified ", "Centered ", "Right justified"}; static char *hidden_text_items[] = { "Normal ", "Hidden "}; static char *rigid_text_items[] = { "Normal ", "Rigid "}; static char *special_text_items[] = { "Normal ", "Special"}; set_cursor(panel_cursor); toggle_textmarker(t); old_t = copy_text(t); new_t = t; textjust = new_t->type; /* get current justification */ hidden_text_flag = hidden_text(new_t) ? 1 : 0; new_psflag = psfont_text(new_t) ? 1 : 0; rigid_text_flag = (intptr_t) (rigid_text(new_t) ? 1 : 0); special_text_flag = special_text(new_t) ? 1 : 0; new_ps_font = cur_ps_font; new_latex_font = cur_latex_font; generic_vals.pen_color = new_t->color; pen_color = new_t->color; if (new_psflag) new_ps_font = new_t->font; /* get current font */ else new_latex_font = new_t->font; /* get current font */ generic_window("TEXT", "", &text_ic, done_text, NO_GENERICS, NO_ARROWS, t->comments); (void) int_panel(new_t->size, form, " Size", (Widget) 0, &cur_fontsize_panel, MIN_FONT_SIZE, MAX_FONT_SIZE, 1); below = pen_color_selection_panel(); (void) int_panel(new_t->depth, form, " Depth", (Widget) 0, &depth_panel, MIN_DEPTH, MAX_DEPTH, 1); (void) float_panel(180.0 / M_PI * new_t->angle, form, "Angle (degrees)", (Widget) 0, &angle_panel, -360.0, 360.0, 1.0, 2); /* make text justification menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Justification", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNlabel, textjust_items[textjust]); NextArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); textjust_panel = XtCreateManagedWidget( "justify", menuButtonWidgetClass, form, Args, ArgCount); below = textjust_panel; make_pulldown_menu(textjust_items, XtNumber(textjust_items), -1, "", textjust_panel, textjust_select); /* make hidden text menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Hidden Flag", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); hidden_text_panel = XtCreateManagedWidget( hidden_text_items[hidden_text_flag], menuButtonWidgetClass, form, Args, ArgCount); below = hidden_text_panel; make_pulldown_menu(hidden_text_items, XtNumber(hidden_text_items), -1, "", hidden_text_panel, hidden_text_select); /* make rigid text menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Rigid Flag", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); rigid_text_panel = XtCreateManagedWidget( rigid_text_items[rigid_text_flag], menuButtonWidgetClass, form, Args, ArgCount); below = rigid_text_panel; make_pulldown_menu(rigid_text_items, XtNumber(rigid_text_items), -1, "", rigid_text_panel, rigid_text_select); /* make special text menu */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Special Flag", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); special_text_panel = XtCreateManagedWidget( special_text_items[special_text_flag], menuButtonWidgetClass, form, Args, ArgCount); below = special_text_panel; make_pulldown_menu(special_text_items, XtNumber(special_text_items), -1, "", special_text_panel, special_text_select); /* tell the pulldown unit menu which panels to convert (xy_panel adds them automatically) */ init_convert_array(); xy_panel(new_t->base_x, new_t->base_y, "Origin", &x1_panel, &y1_panel, True); /* make the popup font menu */ font_image_panel(new_psflag ? psfont_menu_bitmaps[new_t->font + 1] : latexfont_menu_bitmaps[new_t->font], "Font", &font_panel); #ifdef I18N str_panel(new_t->cstring, "Text", &text_panel, 220, True, appres.latin_keyboard || is_i18n_font(new_t->fontstruct)); #else str_panel(new_t->cstring, "Text", &text_panel, 220, True, False); #endif /* I18N */ } static void get_new_text_values(void) { PR_SIZE size; check_depth(); new_t->type = textjust; new_t->flags = (rigid_text_flag ? RIGID_TEXT : 0) | (special_text_flag ? SPECIAL_TEXT : 0) | (hidden_text_flag ? HIDDEN_TEXT : 0) | (new_psflag ? PSFONT_TEXT : 0); if (psfont_text(new_t)) new_t->font = new_ps_font; else new_t->font = new_latex_font; new_t->size = atoi(panel_get_value(cur_fontsize_panel)); if (new_t->size < 1) { new_t->size = 1; panel_set_int(cur_fontsize_panel, 1); } new_t->color = pen_color; new_t->depth = atoi(panel_get_value(depth_panel)); new_t->angle = M_PI / 180.0 * atof(panel_get_value(angle_panel)); fix_angle(&new_t->angle); /* keep between 0 and 2PI */ new_t->base_x = panel_get_dim_value(x1_panel); new_t->base_y = panel_get_dim_value(y1_panel); if (new_t->cstring) free(new_t->cstring); /* get the text string itself */ new_t->cstring = my_strdup(panel_get_value(text_panel)); /* get any comments */ new_t->comments = my_strdup(panel_get_value(comments_panel)); /* get the fontstruct for zoom = 1 to get the size of the string */ canvas_font = lookfont(x_fontnum(psfont_text(new_t), new_t->font), new_t->size); size = textsize(canvas_font, strlen(new_t->cstring), new_t->cstring); new_t->ascent = size.ascent; new_t->descent = size.descent; new_t->length = size.length; /* now set the fontstruct for this zoom scale */ reload_text_fstruct(new_t); } static void done_text(void) { int prev_depth; switch (button_result) { case APPLY: changed = True; list_delete_text(&objects.texts, new_t); redisplay_text(new_t); get_new_text_values(); list_add_text(&objects.texts, new_t); redisplay_text(new_t); toggle_textmarker(new_t); break; case DONE: /* save in case user changed depth */ prev_depth = new_t->depth; get_new_text_values(); if (prev_depth != new_t->depth) { remove_depth(O_TXT, prev_depth); add_depth(O_TXT, new_t->depth); } redisplay_texts(new_t, old_t); clean_up(); old_t->next = new_t; set_latesttext(old_t); set_action_object(F_EDIT, O_TXT); set_modifiedflag(); break; case CANCEL: list_delete_text(&objects.texts, new_t); list_add_text(&objects.texts, old_t); if (saved_objects.texts && saved_objects.texts->next && saved_objects.texts->next == new_t) saved_objects.texts->next = old_t; else if (saved_objects.texts == new_t) saved_objects.texts = old_t; if (changed) redisplay_texts(new_t, old_t); else toggle_textmarker(old_t); free_text(&new_t); break; } } void make_window_ellipse(F_ellipse *e) { char *s1, *s2; icon_struct *image; set_cursor(panel_cursor); toggle_ellipsemarker(e); old_e = copy_ellipse(e); new_e = e; pen_color = new_e->pen_color; fill_color = new_e->fill_color; switch (new_e->type) { case T_ELLIPSE_BY_RAD: s1 = "ELLIPSE"; s2 = "specified by radiii"; ellipse_flag = 1; image = &ellrad_ic; break; case T_ELLIPSE_BY_DIA: s1 = "ELLIPSE"; s2 = "specified by diameters"; ellipse_flag = 1; image = &elldia_ic; break; case T_CIRCLE_BY_RAD: s1 = "CIRCLE"; s2 = "specified by radius"; ellipse_flag = 0; image = &ellrad_ic; break; case T_CIRCLE_BY_DIA: s1 = "CIRCLE"; s2 = "specified by diameter"; ellipse_flag = 0; image = &elldia_ic; break; } put_generic_vals(new_e); generic_window(s1, s2, image, done_ellipse, GENERICS, NO_ARROWS, e->comments); if (new_e->type == T_ELLIPSE_BY_RAD || new_e->type == T_ELLIPSE_BY_DIA) { (void) int_panel(round(180 / M_PI * new_e->angle), form, "Angle (degrees)", (Widget) 0, &angle_panel, -360, 360, 1); } /* tell the pulldown unit menu which panels to convert */ init_convert_array(); if (ellipse_flag) { f_pair_panel(&new_e->center, "Center", &x1_panel, "X =", &y1_panel, "Y =", True); f_pair_panel(&new_e->radiuses, "Radii", &x2_panel, "X =", &y2_panel, "Y =", False); } else { f_pair_panel(&new_e->center, "Center", &x1_panel, "X =", &y1_panel, "Y =", True); FirstArg(XtNlabel, "Radius"); NextArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("radius_label", labelWidgetClass, form, Args, ArgCount); cvt_to_units_str(new_e->radiuses.x, buf); FirstArg(XtNstring, buf); NextArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); x2_panel = XtCreateManagedWidget("radius", asciiTextWidgetClass, form, Args, ArgCount); text_transl(x2_panel); add_to_convert(x2_panel); } } static void get_new_ellipse_values(void) { get_generic_vals(new_e); if (new_e->type == T_ELLIPSE_BY_RAD || new_e->type == T_ELLIPSE_BY_DIA) { new_e->angle = M_PI / 180 * atoi(panel_get_value(angle_panel)); fix_angle(&new_e->angle); /* keep between 0 and 2PI */ } get_f_pos(&new_e->center, x1_panel, y1_panel); if (ellipse_flag) get_f_pos(&new_e->radiuses, x2_panel, y2_panel); else new_e->radiuses.x = new_e->radiuses.y = panel_get_dim_value(x2_panel); if (new_e->type == T_ELLIPSE_BY_RAD || new_e->type == T_CIRCLE_BY_RAD) { new_e->start = new_e->center; } else { new_e->start.x = new_e->center.x - new_e->radiuses.x; new_e->start.y = new_e->center.y; } new_e->end.x = new_e->center.x + new_e->radiuses.x; new_e->end.y = new_e->center.y; } static void done_ellipse(void) { int prev_depth; switch (button_result) { case APPLY: changed = True; list_delete_ellipse(&objects.ellipses, new_e); redisplay_ellipse(new_e); get_new_ellipse_values(); list_add_ellipse(&objects.ellipses, new_e); redisplay_ellipse(new_e); toggle_ellipsemarker(new_e); break; case DONE: /* save in case user changed depth */ prev_depth = new_e->depth; get_new_ellipse_values(); if (prev_depth != new_e->depth) { remove_depth(O_ELLIPSE, prev_depth); add_depth(O_ELLIPSE, new_e->depth); } redisplay_ellipses(new_e, old_e); clean_up(); old_e->next = new_e; set_latestellipse(old_e); set_action_object(F_EDIT, O_ELLIPSE); set_modifiedflag(); break; case CANCEL: list_delete_ellipse(&objects.ellipses, new_e); list_add_ellipse(&objects.ellipses, old_e); if (saved_objects.ellipses && saved_objects.ellipses->next && saved_objects.ellipses->next == new_e) saved_objects.ellipses->next = old_e; else if (saved_objects.ellipses == new_e) saved_objects.ellipses = old_e; if (changed) redisplay_ellipses(new_e, old_e); else toggle_ellipsemarker(old_e); free_ellipse(&new_e); break; } } Pixel arrow_panel_bg; void make_window_arc(F_arc *a) { Widget save_form, save_below; set_cursor(panel_cursor); toggle_arcmarker(a); old_a = copy_arc(a); new_a = a; pen_color = new_a->pen_color; fill_color = new_a->fill_color; put_generic_vals(new_a); put_generic_arrows((F_line *) new_a); put_arc_type(new_a); put_cap_style(new_a); /* tell the pulldown unit menu which panels to convert */ init_convert_array(); /* create main window */ generic_window("ARC", "Specified by 3 points", &arc_ic, done_arc, GENERICS, ARROWS, a->comments); save_form = form; /* put the points panel in a sub-form */ FirstArg(XtNborderWidth, 0); if (new_a->type == T_PIE_WEDGE_ARC) { NextArg(XtNfromVert, above_arrows); /* put it just below the stuff before arrows */ } else { NextArg(XtNfromVert, below); /* after the arrow forms */ } NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); form = arc_points_form = XtCreateManagedWidget("form", formWidgetClass, save_form, Args, ArgCount); save_below = below; below = (Widget) NULL; f_pair_panel(&new_a->point[0], "First point", &x1_panel, "X =", &y1_panel, "Y =", True); f_pair_panel(&new_a->point[1], "Second point", &x2_panel, "X =", &y2_panel, "Y =", False); f_pair_panel(&new_a->point[2], "Third point", &x3_panel, "X =", &y3_panel, "Y =", False); form = save_form; below = save_below; /* if this is a pie-wedge arc, unmanage the arrow stuff until user changes it to an open type */ if (new_a->type == T_PIE_WEDGE_ARC) { XtRealizeWidget(popup); XtUnmanageChild(form); XtUnmanageChild(for_aform); XtUnmanageChild(back_aform); XtManageChild(form); } } static void get_new_arc_values(void) { F_pos p0, p1, p2; float cx, cy; get_generic_vals(new_a); get_generic_arrows((F_line *) new_a); get_cap_style(new_a); get_arc_type(new_a); get_f_pos(&p0, x1_panel, y1_panel); get_f_pos(&p1, x2_panel, y2_panel); get_f_pos(&p2, x3_panel, y3_panel); if (compute_arccenter(p0, p1, p2, &cx, &cy)) { new_a->point[0] = p0; new_a->point[1] = p1; new_a->point[2] = p2; new_a->center.x = cx; new_a->center.y = cy; new_a->direction = compute_direction(p0, p1, p2); } else put_msg("Invalid ARC points!"); } static void done_arc(void) { int prev_depth; switch (button_result) { case APPLY: changed = True; list_delete_arc(&objects.arcs, new_a); redisplay_arc(new_a); get_new_arc_values(); list_add_arc(&objects.arcs, new_a); redisplay_arc(new_a); toggle_arcmarker(new_a); break; case DONE: /* save in case user changed depth */ prev_depth = new_a->depth; get_new_arc_values(); if (prev_depth != new_a->depth) { remove_depth(O_ARC, prev_depth); add_depth(O_ARC, new_a->depth); } redisplay_arcs(new_a, old_a); clean_up(); old_a->next = new_a; set_latestarc(old_a); set_action_object(F_EDIT, O_ARC); set_modifiedflag(); break; case CANCEL: list_delete_arc(&objects.arcs, new_a); list_add_arc(&objects.arcs, old_a); if (saved_objects.arcs && saved_objects.arcs->next && saved_objects.arcs->next == new_a) saved_objects.arcs->next = old_a; else if (saved_objects.arcs == new_a) saved_objects.arcs = old_a; if (changed) redisplay_arcs(new_a, old_a); else toggle_arcmarker(old_a); free_arc(&new_a); break; } } void make_window_spline(F_spline *s) { set_cursor(panel_cursor); toggle_splinemarker(s); old_s = copy_spline(s); new_s = s; pen_color = new_s->pen_color; fill_color = new_s->fill_color; put_generic_vals(new_s); put_generic_arrows((F_line *) new_s); put_cap_style(new_s); switch (new_s->type) { case T_OPEN_APPROX: generic_window("SPLINE", "Open approximated spline", &spl_ic, done_spline, GENERICS, ARROWS, s->comments); points_panel(new_s->points); break; case T_CLOSED_APPROX: generic_window("SPLINE", "Closed approximated spline", &c_spl_ic, done_spline, GENERICS, NO_ARROWS, s->comments); /* no arrowheads */ points_panel(new_s->points); break; case T_OPEN_INTERP: generic_window("SPLINE", "Open interpolated spline", &intspl_ic, done_spline, GENERICS, ARROWS, s->comments); points_panel(new_s->points); break; case T_CLOSED_INTERP: generic_window("SPLINE", "Closed interpolated spline", &c_intspl_ic, done_spline, GENERICS, NO_ARROWS, s->comments); /* no arrowheads */ points_panel(new_s->points); break; case T_OPEN_XSPLINE: generic_window("SPLINE", "X-Spline open", &xspl_ic, done_spline, GENERICS, ARROWS, s->comments); points_panel(new_s->points); break; case T_CLOSED_XSPLINE: generic_window("SPLINE", "X-Spline closed", &c_xspl_ic, done_spline, GENERICS, ARROWS, s->comments); points_panel(new_s->points); break; } } static void done_spline(void) { int prev_depth; switch (button_result) { case APPLY: changed = True; list_delete_spline(&objects.splines, new_s); redisplay_spline(new_s); get_generic_vals(new_s); get_generic_arrows((F_line *) new_s); get_cap_style(new_s); get_points(new_s->points); list_add_spline(&objects.splines, new_s); redisplay_spline(new_s); toggle_splinemarker(new_s); break; case DONE: /* save in case user changed depth */ prev_depth = new_s->depth; get_generic_vals(new_s); get_generic_arrows((F_line *) new_s); get_cap_style(new_s); get_points(new_s->points); if (prev_depth != new_s->depth) { remove_depth(O_SPLINE, prev_depth); add_depth(O_SPLINE, new_s->depth); } redisplay_splines(new_s, old_s); clean_up(); old_s->next = new_s; set_latestspline(old_s); set_action_object(F_EDIT, O_SPLINE); set_modifiedflag(); break; case CANCEL: list_delete_spline(&objects.splines, new_s); list_add_spline(&objects.splines, old_s); if (saved_objects.splines && saved_objects.splines->next && saved_objects.splines->next == new_s) saved_objects.splines->next = old_s; else if (saved_objects.splines == new_s) saved_objects.splines = old_s; if (changed) redisplay_splines(new_s, old_s); else toggle_splinemarker(old_s); free_spline(&new_s); break; } } static void make_window_spline_point(F_spline *s, int x, int y) { set_cursor(panel_cursor); new_s = copy_spline(s); if (new_s == NULL) return; new_s->next = s; edited_point = search_spline_point(new_s, x, y); sub_new_s = create_subspline(&num_spline_points, new_s, edited_point, &edited_sfactor, &sub_sfactor); if (sub_new_s == NULL) return; /* make solid, black unfilled spline of thickness 1 */ s->thickness = 1; s->pen_color = BLACK; s->fill_style = UNFILLED; s->style = SOLID_LINE; sub_new_s->thickness = 1; sub_new_s->pen_color = BLACK; sub_new_s->fill_style = UNFILLED; sub_new_s->style = SOLID_LINE; redisplay_spline(s); spline_point_window(x, y); } static void done_spline_point(void) { old_s = new_s->next; /* restore original attributes */ old_s->thickness = new_s->thickness; old_s->pen_color = new_s->pen_color; old_s->fill_style = new_s->fill_style; old_s->style = new_s->style; edited_sfactor->s = sub_sfactor->s; free_subspline(num_spline_points, &sub_new_s); switch (button_result) { case DONE: new_s->next = NULL; change_spline(old_s, new_s); redisplay_spline(new_s); break; case CANCEL: if (changed) draw_spline(new_s, ERASE); redisplay_spline(old_s); new_s->next = NULL; free_spline(&new_s); break; } return; } static void new_generic_values(void) { int fill; char *val; generic_vals.thickness = atoi(panel_get_value(thickness_panel)); generic_vals.pen_color = pen_color; generic_vals.fill_color = fill_color; check_thick(); check_depth(); generic_vals.depth = atoi(panel_get_value(depth_panel)); /* get the comments */ generic_vals.comments = my_strdup(panel_get_value(comments_panel)); /* include dash length in panel, too */ generic_vals.style_val = (float) atof(panel_get_value(style_val_panel)); if (generic_vals.style == DASH_LINE || generic_vals.style == DOTTED_LINE || generic_vals.style == DASH_DOT_LINE || generic_vals.style == DASH_2_DOTS_LINE || generic_vals.style == DASH_3_DOTS_LINE ) if (generic_vals.style_val <= 0.0) { generic_vals.style_val = ((generic_vals.style == DASH_LINE || generic_vals.style == DASH_DOT_LINE || generic_vals.style == DASH_2_DOTS_LINE || generic_vals.style == DASH_3_DOTS_LINE)? cur_dashlength: cur_dotgap)* (generic_vals.thickness + 1) / 2; panel_set_float(style_val_panel, generic_vals.style_val, "%1.1f"); } if (fill_flag==1) { /* fill color */ val = panel_get_value(fill_intens_panel); if (*val >= ' ' && *val <= '9') { /* if fill value > 200%, set to 100%. Also if > 100% and fill color is black or white set to 100% */ if ((fill = atoi(val)) > 200 || (fill_color == BLACK || fill_color == DEFAULT || fill_color == WHITE) && fill > 100) fill = 100; generic_vals.fill_style = fill / (200 / (NUMSHADEPATS+NUMTINTPATS - 1)); } else { generic_vals.fill_style = 0; } fill = generic_vals.fill_style * (200 / (NUMSHADEPATS+NUMTINTPATS - 1)); panel_set_int(fill_intens_panel, fill); } else if (fill_flag==2) { /* fill pattern */ val = panel_get_value(fill_pat_panel); if (*val >= ' ' && *val <= '9') { if ((fill = atoi(val)) >= NUMPATTERNS) fill = NUMPATTERNS-1; if (fill < 0) fill = 0; generic_vals.fill_style = fill+NUMSHADEPATS+NUMTINTPATS; } else { fill = 0; generic_vals.fill_style = NUMSHADEPATS+NUMTINTPATS; } panel_set_int(fill_pat_panel, fill); } else { generic_vals.fill_style = -1; /* no fill */ } } static void new_arrow_values(void) { if (for_arrow) { generic_vals.for_arrow.thickness = (float) fabs(atof(panel_get_value(for_arrow_thick))); generic_vals.for_arrow.wd = (float) fabs(atof(panel_get_value(for_arrow_width))); generic_vals.for_arrow.ht = (float) fabs(atof(panel_get_value(for_arrow_height))); } if (back_arrow) { generic_vals.back_arrow.thickness = (float) fabs(atof(panel_get_value(back_arrow_thick))); generic_vals.back_arrow.wd = (float) fabs(atof(panel_get_value(back_arrow_width))); generic_vals.back_arrow.ht = (float) fabs(atof(panel_get_value(back_arrow_height))); } } static void done_button(Widget panel_local, XtPointer closure, XtPointer call_data) { button_result = DONE; done_proc(); reset_edit_cursor(); Quit(); } static void apply_button(Widget panel_local, XtPointer closure, XtPointer call_data) { button_result = DONE; button_result = APPLY; /* make sure current colormap is installed */ set_cmap(XtWindow(popup)); done_proc(); } static void cancel_button(Widget panel_local, XtPointer closure, XtPointer call_data) { button_result = CANCEL; done_proc(); reset_edit_cursor(); Quit(); } static void edit_done(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { done_button(w, NULL, NULL); } static void edit_apply(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { apply_button(w, NULL, NULL); } static void edit_cancel(Widget w, XButtonEvent *ev, String *params, Cardinal *num_params) { cancel_button(w, NULL, NULL); } void reset_edit_cursor(void) { if (lib_cursor) set_cursor(null_cursor); else if (dim_cursor) set_cursor(arrow_cursor); else set_cursor(pick9_cursor); lib_cursor = False; dim_cursor = False; } static void generic_window(char *object_type, char *sub_type, icon_struct *icon, void (*d_proc) (/* ??? */), Boolean generics, Boolean arrows, char *comments) { Dimension label_height, image_height; int button_distance; int i, fill; Widget image, cancel; Pixmap image_pm; XFontStruct *temp_font; FirstArg(XtNtitle, "Xfig: Edit panel"); NextArg(XtNcolormap, tool_cm); NextArg(XtNallowShellResize, True); popup = XtCreatePopupShell("edit_panel", transientShellWidgetClass, tool, Args, ArgCount); XtAugmentTranslations(popup, XtParseTranslationTable(edit_popup_translations)); init_kbd_actions(); if (!actions_added) { XtAppAddActions(tool_app, edit_actions, XtNumber(edit_actions)); XtAppAddActions(tool_app, picture_pos_actions, XtNumber(picture_pos_actions)); XtAppAddActions(tool_app, picture_size_actions, XtNumber(picture_size_actions)); XtAppAddActions(tool_app, text_actions, XtNumber(text_actions)); XtAppAddActions(tool_app, compound_actions, XtNumber(compound_actions)); actions_added = True; } form = XtCreateManagedWidget("form", formWidgetClass, popup, NULL, 0); done_proc = d_proc; /***************** LABEL and IMAGE of the object *****************/ FirstArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); image = XtCreateManagedWidget("image", labelWidgetClass, form, Args, ArgCount); /* put in the image */ /* search to see if that pixmap has already been created */ image_pm = 0; for (i = 0; i < NUM_IMAGES; i++) { if (pix_table[i].image == 0) break; if (pix_table[i].image == icon) { image_pm = pix_table[i].image_pm; break; } } /* no need for colon (:) if no sub-type */ if (strlen(sub_type) == 0) sprintf(buf, "%s", object_type); else sprintf(buf, "%s: %s", object_type, sub_type); FirstArg(XtNfromHoriz, image); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); label = XtCreateManagedWidget(buf, labelWidgetClass, form, Args, ArgCount); /* doesn't already exist, create a pixmap from the data (ala panel.c) */ /* OpenWindows bug doesn't handle a 1-plane bitmap on a n-plane display */ /* so we use CreatePixmap.... */ if (image_pm == 0) { Pixel fg, bg; /* get the foreground/background of the widget */ FirstArg(XtNforeground, &fg); NextArg(XtNbackground, &bg); GetValues(image); image_pm = XCreatePixmapFromBitmapData(tool_d, canvas_win, icon->bits, icon->width, icon->height, fg, bg, tool_dpth); pix_table[i].image_pm = image_pm; pix_table[i].image = icon; } FirstArg(XtNbitmap, image_pm); SetValues(image); /* get height of label widget and distance between widgets */ FirstArg(XtNheight, &label_height); NextArg(XtNvertDistance, &button_distance); GetValues(label); /* do the same for the image widget */ FirstArg(XtNheight, &image_height); GetValues(image); /***************** BUTTONS *****************/ FirstArg(XtNlabel, " Done "); NextArg(XtNfromHoriz, image); NextArg(XtNfromVert, label); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("done", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) done_button, (XtPointer) NULL); /* editing whole figure comments doesn't need an apply button, just done and cancel */ if (strcmp("Whole Figure", object_type)) { FirstArg(XtNlabel, "Apply "); NextArg(XtNfromHoriz, but1); NextArg(XtNfromVert, label); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("apply", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) apply_button, (XtPointer) NULL); } FirstArg(XtNlabel, "Cancel"); NextArg(XtNfromHoriz, but1); NextArg(XtNfromVert, label); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); cancel = but1 = XtCreateManagedWidget("cancel", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) cancel_button, (XtPointer) NULL); below = but1; /* add "Screen Capture" and "Edit Image" buttons if picture object */ if (!strcmp(sub_type,"Picture Object")) { FirstArg(XtNlabel,"Screen Capture"); NextArg(XtNfromHoriz, but1); NextArg(XtNfromVert, label); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("screen_capture", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) grab_button, (XtPointer) NULL); if ( cur_image_editor != NULL && *cur_image_editor != (char) NULL) { FirstArg(XtNlabel,"Edit Image"); NextArg(XtNfromHoriz, but1); NextArg(XtNfromVert, label); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("edit_image", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) image_edit_button, (XtPointer) NULL); } } /***************** COMMENTS *****************/ /* label for Comments */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainTop); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget("Comments", labelWidgetClass, form, Args, ArgCount); /* get the font of above label widget */ FirstArg(XtNfont, &temp_font); GetValues(below); /* make text widget for any comment lines */ FirstArg(XtNfromVert, below); NextArg(XtNvertDistance, 2); NextArg(XtNstring, comments); NextArg(XtNinsertPosition, 0); NextArg(XtNeditType, XawtextEdit); if (!strcmp(sub_type,"Picture Object")) { NextArg(XtNwidth, 415); /* as wide as picture filename widget below */ } else { NextArg(XtNwidth, 300); } NextArg(XtNtop, XtChainTop); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); /* allow enough height for 3 lines + scrollbar */ NextArg(XtNheight, max_char_height(temp_font) * 3 + 20); NextArg(XtNscrollHorizontal, XawtextScrollWhenNeeded); NextArg(XtNscrollVertical, XawtextScrollWhenNeeded); comments_panel = below = XtCreateManagedWidget("comments", asciiTextWidgetClass, form, Args, ArgCount); XtOverrideTranslations(comments_panel, XtParseTranslationTable(edit_comment_translations)); /***************** COMMON PARAMETERS *****************/ if (generics) { Widget lbelow, lbeside; /***************** ARC TYPE MENU *****************/ if (!strcmp(object_type,"ARC")) arc_type_menu(); /***************** LINE WIDTH *****************/ lbelow = below; (void) int_panel(generic_vals.thickness, form, "Width", (Widget) 0, &thickness_panel, 0, 1000, 1); lbeside = below; below = lbelow; /***************** OBJECT DEPTH *****************/ (void) int_panel(generic_vals.depth, form, "Depth", lbeside, &depth_panel, MIN_DEPTH, MAX_DEPTH, 1); /***************** COLOR MENUS *****************/ below = pen_color_selection_panel(); below = fill_color_selection_panel(); if (generic_vals.fill_style == -1) { fill = -1; fill_flag = 0; } else if (generic_vals.fill_style < NUMSHADEPATS+NUMTINTPATS) { fill = generic_vals.fill_style * (200 / (NUMSHADEPATS+NUMTINTPATS - 1)); fill_flag = 1; } else { /* fill pattern */ fill = generic_vals.fill_style - NUMSHADEPATS - NUMTINTPATS; fill_flag = 2; } /***************** FILL STYLE MENU *****************/ fill_style_menu(fill, fill_flag); below = fill_image; /* line style goes below fill pattern image if there is no cap style and no join style */ /***************** LINE STYLE MENU *****************/ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Line style", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNbitmap, linestyle_pixmaps[generic_vals.style]); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); line_style_panel = XtCreateManagedWidget("line_style", menuButtonWidgetClass, form, Args, ArgCount); make_pulldown_menu_images(linestyle_choices, NUM_LINESTYLE_TYPES, linestyle_pixmaps, NULL, line_style_panel, line_style_select); /* new field for style_val */ style_val = float_panel(generic_vals.style_val, form, "Dash length/\nDot gap", line_style_panel, &style_val_panel, 0.0, 1000.0, 1.0, 1); /* save pointer to dash/dot gap label panel */ style_val_label = beside; FirstArg(XtNhorizDistance, 20); SetValues(style_val_label); if (generic_vals.style == SOLID_LINE) { XtSetSensitive(style_val,False); XtSetSensitive(style_val_label,False); /* and clear any value from the dash length panel */ panel_clear_value(style_val_panel); } below = line_style_panel; /***************** CAP STYLE MENU *****************/ /* if a polyline, arc or open spline make a panel for cap style */ lbelow = below; beside = (Widget) 0; if (!strcmp(object_type,"ARC") || (!strcmp(object_type,"SPLINE") && strstr(sub_type,"Open")) || (!strcmp(object_type,"POLYLINE") && !strcmp(sub_type,"Polyline"))) { cap_style_panel_menu(); below = beside = cap_style_panel; } /***************** JOIN STYLE MENU *****************/ if (!strcmp(sub_type,"Polyline") || !strcmp(sub_type,"Polygon") || !strcmp(sub_type,"Box")) { below = lbelow; join_style_panel_menu(); below = join_style_panel; } /* save widget that is just above the arrow panels for the arc window usage */ above_arrows = below; /***************** ARROW panels *****************/ if (arrows) { int type; /****** FIRST THE FORWARD ARROW ******/ FirstArg(XtNfromVert, above_arrows); NextArg(XtNvertDistance, 2); NextArg(XtNhorizDistance, 20); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); for_aform = XtCreateManagedWidget("arrow_form", formWidgetClass, form, Args, ArgCount); FirstArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Forward\nArrow", labelWidgetClass, for_aform, Args, ArgCount); /* make pulldown arrow style menu */ if (generic_vals.for_arrow.type == -1) { type = -1; } else { type = generic_vals.for_arrow.type*2 - 1 + generic_vals.for_arrow.style; if (type < 0) type = 0; } FirstArg(XtNfromHoriz, beside); NextArg(XtNlabel, ""); NextArg(XtNinternalWidth, 0); NextArg(XtNinternalHeight, 0); NextArg(XtNbitmap, arrow_pixmaps[type+1]); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); for_arrow_type_panel = XtCreateManagedWidget("Arrowtype", menuButtonWidgetClass, for_aform, Args, ArgCount); below = for_arrow_type_panel; /* make pulldown menu with arrow type images */ make_pulldown_menu_images(dim_arrowtype_choices, NUM_ARROW_TYPES, arrow_pixmaps, NULL, for_arrow_type_panel, for_arrow_type_select); for_thick = float_panel(generic_vals.for_arrow.thickness, for_aform, "Thick ", (Widget) 0, &for_arrow_thick, 0.0, 10000.0, 1.0, 1); for_thick_label = beside; for_width = float_panel(generic_vals.for_arrow.wd, for_aform, "Width ", (Widget) 0, &for_arrow_width, 0.0, 10000.0, 1.0, 1); for_width_label = beside; for_height = float_panel(generic_vals.for_arrow.ht, for_aform, "Length", (Widget) 0, &for_arrow_height, 0.0, 10000.0, 1.0, 1); for_height_label = beside; /****** NOW THE BACK ARROW ******/ FirstArg(XtNfromVert, above_arrows); NextArg(XtNvertDistance, 2); NextArg(XtNfromHoriz, for_aform); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); back_aform = XtCreateManagedWidget("arrow_form", formWidgetClass, form, Args, ArgCount); FirstArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Backward\nArrow", labelWidgetClass, back_aform, Args, ArgCount); /* make pulldown arrow style menu */ if (generic_vals.back_arrow.type == -1) { type = -1; } else { type = generic_vals.back_arrow.type*2 - 1 + generic_vals.back_arrow.style; if (type < 0) type = 0; } FirstArg(XtNfromHoriz, beside); NextArg(XtNlabel, ""); NextArg(XtNinternalWidth, 0); NextArg(XtNinternalHeight, 0); NextArg(XtNbitmap, arrow_pixmaps[type+1]); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); back_arrow_type_panel = XtCreateManagedWidget("Arrowtype", menuButtonWidgetClass, back_aform, Args, ArgCount); below = back_arrow_type_panel; /* make pulldown menu with arrow type images */ make_pulldown_menu_images(dim_arrowtype_choices, NUM_ARROW_TYPES, arrow_pixmaps, NULL, back_arrow_type_panel, back_arrow_type_select); back_thick = float_panel(generic_vals.back_arrow.thickness, back_aform, "Thick ", (Widget) 0, &back_arrow_thick, 0.0, 10000.0, 1.0, 1); back_thick_label = beside; back_width = float_panel(generic_vals.back_arrow.wd, back_aform, "Width ", (Widget) 0, &back_arrow_width, 0.0, 10000.0, 1.0, 1); back_width_label = beside; back_height = float_panel(generic_vals.back_arrow.ht, back_aform, "Length", (Widget) 0, &back_arrow_height, 0.0, 10000.0, 1.0, 1); back_height_label = beside; below = for_aform; /* for the widget that follows us in the panel */ } } XtInstallAccelerators(form, cancel); } static void spline_point_window(int x, int y) { Widget but_spline[3]; Dimension label_height, label_width; intptr_t i; int dist; static char use_item[]="Edit the behavior\nof the control point"; /* locate the mouse in screen coords */ XtTranslateCoords(canvas_sw, ZOOMX(x), ZOOMY(y), &rootx, &rooty); /* position the window to the right of the mouse */ FirstArg(XtNx, rootx+30); NextArg(XtNy, rooty); NextArg(XtNtitle, "Edit spline point"); NextArg(XtNcolormap, tool_cm); popup = XtCreatePopupShell("edit_spline_point_panel", transientShellWidgetClass, tool, Args, ArgCount); XtAugmentTranslations(popup, XtParseTranslationTable(edit_popup_translations)); if (!actions_added) { XtAppAddActions(tool_app, edit_actions, XtNumber(edit_actions)); XtAppAddActions(tool_app, text_actions, XtNumber(text_actions)); actions_added = True; } form = XtCreateManagedWidget("form", formWidgetClass, popup, NULL, 0); done_proc = done_spline_point; FirstArg(XtNwidth, SFACTOR_BAR_WIDTH); NextArg(XtNheight, SFACTOR_BAR_HEIGHT); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); sfactor_bar= XtCreateManagedWidget("sfactor_bar", scrollbarWidgetClass, form, Args, ArgCount); XtAddCallback(sfactor_bar, XtNjumpProc, (XtCallbackProc) change_sfactor_value, (XtPointer)NULL); XtAddCallback(sfactor_bar, XtNscrollProc, (XtCallbackProc) scroll_sfactor_value, (XtPointer)NULL); XawScrollbarSetThumb(sfactor_bar, SFACTOR_TO_PERCENTAGE(sub_sfactor->s), THUMB_H); FirstArg(XtNfromHoriz, sfactor_bar); NextArg(XtNborderWidth, 0); NextArg(XtNjustify, XtJustifyLeft); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); label= XtCreateManagedWidget(use_item, labelWidgetClass, form, Args, ArgCount); /* get height and width of label widget and distance between widgets */ FirstArg(XtNheight, &label_height); NextArg(XtNwidth, &label_width); NextArg(XtNvertDistance, &dist); GetValues(label); FirstArg(XtNfromVert, label); NextArg(XtNfromHoriz, sfactor_bar); NextArg(XtNvertDistance, dist); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("Done", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) done_button, (XtPointer) NULL); below = but1; FirstArg(XtNfromHoriz, but1); NextArg(XtNfromVert, label); NextArg(XtNvertDistance, dist); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); but1 = XtCreateManagedWidget("Cancel", commandWidgetClass, form, Args, ArgCount); XtAddCallback(but1, XtNcallback, (XtCallbackProc) cancel_button, (XtPointer) NULL); /* fromVert and vertDistance must be first, for direct access to the Args array in the loop */ FirstArg(XtNfromVert, below); NextArg(XtNvertDistance, 7 * dist); /* it must be second, same reason */ NextArg(XtNfromHoriz, sfactor_bar); NextArg(XtNwidth, label_width); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); for (i=0; i<3; i++) { below = but_spline[i] = XtCreateManagedWidget(sfactor_type[i].label, commandWidgetClass, form, Args, ArgCount); XtAddCallback(but_spline[i], XtNcallback, (XtCallbackProc) toggle_sfactor_type, (XtPointer) i); XtSetArg(Args[0], XtNfromVert, below); /* here are the direct */ XtSetArg(Args[1], XtNvertDistance, 3 * dist); /* accesses to Args */ } } static void toggle_sfactor_type(Widget panel_local, XtPointer _sfactor_index, XtPointer call_data) { intptr_t sfactor_index = (intptr_t)_sfactor_index; update_sfactor_value(sfactor_type[sfactor_index].value); XawScrollbarSetThumb(sfactor_bar, SFACTOR_TO_PERCENTAGE(sub_sfactor->s), THUMB_H); } static void change_sfactor_value(Widget panel_local, XtPointer closure, XtPointer _top) { float *top = (float *) _top; update_sfactor_value(PERCENTAGE_TO_CONTROL(*top)); XawScrollbarSetThumb(panel_local, *top, THUMB_H); } static void scroll_sfactor_value(Widget panel_local, XtPointer closure, XtPointer _num_pixels) { intptr_t num_pixels = (intptr_t) _num_pixels; update_sfactor_value(sub_sfactor->s + (STEP_VALUE * SFACTOR_SIGN(num_pixels))); XawScrollbarSetThumb(panel_local, SFACTOR_TO_PERCENTAGE(sub_sfactor->s), THUMB_H); } static void update_sfactor_value(double new_value) { if (new_value < S_SPLINE_INTERP || new_value > S_SPLINE_APPROX) return; if (new_value == S_SPLINE_ANGULAR) new_value = 1.0E-5; toggle_pointmarker(edited_point->x, edited_point->y); draw_subspline(num_spline_points, sub_new_s, ERASE); sub_sfactor->s = new_value; if ((approx_spline(new_s) && new_value != S_SPLINE_APPROX) || (int_spline(new_s) && new_value != S_SPLINE_INTERP)) new_s->type = (open_spline(new_s)) ? T_OPEN_XSPLINE : T_CLOSED_XSPLINE; changed = True; draw_subspline(num_spline_points, sub_new_s, PAINT); toggle_pointmarker(edited_point->x, edited_point->y); } /* come here when the user changes either the fill or pen color */ /* update the fill intensity/pattern images */ void recolor_fill_image(void) { if (fill_style_exists) { update_fill_image((Widget) 0, (XtPointer) 0, (XtPointer) 0); } } /* update the image of the fill intensity or pattern when user presses up/down in spinner */ static void update_fill_image(Widget w, XtPointer dummy, XtPointer dummy2) { char *sval; int val; Pixel bg; /* get the background color of the main form if we haven't already done that */ if (XtIsRealized(form)) { FirstArg(XtNbackground, &form_bg); GetValues(form); } /* get current value from the fill intensity spinner */ sval = panel_get_value(fill_intens_panel); /* if there is a number there, then intensity is used */ if (sval[0]!=' ') { val = atoi(sval); /* check for min/max */ if ((fill_color == BLACK || fill_color == WHITE)? (val > 100): (val > 200) || val < 0) { if (val < 0) val = 0; else { if (fill_color == BLACK || fill_color == WHITE) val = 100; else val = 200; } panel_set_int(fill_intens_panel,val); } /* get current colors into the gc */ XSetForeground(tool_d,fill_image_gc,x_color(fill_color)); /* shade (use BLACK) or tint (use WHITE)? */ bg = (val <= 100? BLACK: WHITE); XSetBackground(tool_d,fill_image_gc,x_color(bg)); /* convert intensity to shade/tint index */ val = val / (200 / (NUMSHADEPATS+NUMTINTPATS-1)); /* update the pixmap */ set_image_pm(val); } else { /* get current value from the fill pattern spinner */ sval = panel_get_value(fill_pat_panel); /* if there is a number there, then pattern is used */ if (sval[0]==' ') { FirstArg(XtNbitmap, None); NextArg(XtNbackground, form_bg); SetValues(fill_image); } else { val = atoi(sval); /* check for min/max */ if (val >= NUMPATTERNS || val < 0) { if (val < 0) val = 0; else val = NUMPATTERNS-1; panel_set_int(fill_pat_panel,val); } val += NUMSHADEPATS+NUMTINTPATS; /* get current colors into the gc */ XSetForeground(tool_d,fill_image_gc,x_color(pen_color)); XSetBackground(tool_d,fill_image_gc,x_color(fill_color)); /* update the pixmap */ set_image_pm(val); } } } /* update the pixmap in the proper widget */ void set_image_pm(int val) { /* set stipple from the one-bit bitmap */ XSetStipple(tool_d, fill_image_gc, fill_image_bm[val]); /* stipple the bitmap into the pixmap with the desired color */ XFillRectangle(tool_d, fill_image_pm, fill_image_gc, 0, 0, FILL_SIZE, FILL_SIZE); /* put the pixmap in the widget background */ FirstArg(XtNbitmap, None); SetValues(fill_image); FirstArg(XtNbitmap, fill_image_pm); SetValues(fill_image); } /* make fill style menu and associated stuff */ /* fill = fill value, fill_flag = 0 means no fill, 1=intensity, 2=pattern */ void fill_style_menu(int fill, int fill_flag) { static char *fill_style_items[] = { "No fill", "Filled ", "Pattern"}; int i,j; Pixel fg,bg; fg = x_color(pen_color); bg = x_color(fill_color); if (!fill_image_bm_exist) { fill_image_bm_exist = True; fill_image_gc = makegc(PAINT, fg, bg); fill_image_pm = XCreatePixmap(tool_d, tool_w, FILL_SIZE, FILL_SIZE, tool_dpth); XSetFillStyle(tool_d, fill_image_gc, FillOpaqueStippled); /* make the one-bit deep bitmaps and blank pixmaps */ for (i = 0; i < NUMSHADEPATS; i++) { fill_image_bm[i] = XCreateBitmapFromData(tool_d, tool_w, (char*) shade_images[i], SHADE_IM_SIZE, SHADE_IM_SIZE); } for (i = NUMSHADEPATS; i < NUMSHADEPATS+NUMTINTPATS; i++) { j = NUMSHADEPATS+NUMTINTPATS-i-1; /* reverse the patterns */ fill_image_bm[i] = XCreateBitmapFromData(tool_d, tool_w, (char*) shade_images[j], SHADE_IM_SIZE, SHADE_IM_SIZE); } for (i = NUMSHADEPATS+NUMTINTPATS; i < NUMFILLPATS; i++) { j = i-(NUMSHADEPATS+NUMTINTPATS); fill_image_bm[i] = XCreateBitmapFromData(tool_d, tool_w, pattern_images[j].cdata, pattern_images[j].cwidth, pattern_images[j].cheight); } } FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Fill style", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); fill_style_button = XtCreateManagedWidget(fill_style_items[fill_flag], menuButtonWidgetClass, form, Args, ArgCount); below = fill_style_button; make_pulldown_menu(fill_style_items, XtNumber(fill_style_items), -1, "", fill_style_button, fill_style_select); fill_intens = int_panel_callb(fill, form, "Fill intensity %", (Widget) 0, &fill_intens_panel, 0, 200, 5, update_fill_image); fill_intens_label = beside; /* save pointer to fill label */ fill_pat = int_panel_callb(fill, form, "Fill pattern ", (Widget) 0, &fill_pat_panel, 0, NUMPATTERNS-1, 1, update_fill_image); fill_pat_label = beside; /* save pointer to fill label */ /* make fill intensity spinner widget sensitive or not */ XtSetSensitive(fill_intens,(fill_flag==1)); FirstArg(XtNhorizDistance, 20); NextArg(XtNsensitive, (fill_flag==1)); SetValues(fill_intens_label); /* and label (and position it) */ /* if fill is not a fill %, blank it out */ if (fill_flag != 1) panel_clear_value(fill_intens_panel); /* make label widget to the right of fill intensity and pattern to show chosen */ FirstArg(XtNlabel,""); NextArg(XtNwidth, FILL_SIZE); NextArg(XtNheight, FILL_SIZE); NextArg(XtNinternalWidth, 0); NextArg(XtNinternalHeight, 0); NextArg(XtNfromHoriz, fill_pat); NextArg(XtNfromVert, fill_pat); NextArg(XtNvertDistance, -FILL_SIZE-2); NextArg(XtNhorizDistance, 5); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); fill_image = XtCreateManagedWidget("fill_image", labelWidgetClass, form, Args, ArgCount); /* put the pixmap in the widget background */ if (fill_flag == 1 || fill_flag == 2) { update_fill_image((Widget) 0, (XtPointer) 0, (XtPointer) 0); } /* make fill pattern panel insensitive if not a fill pattern */ XtSetSensitive(fill_pat,(fill_flag==2)); FirstArg(XtNhorizDistance, 20); NextArg(XtNsensitive, (fill_flag==2)); SetValues(fill_pat_label); /* and blank value if not a pattern */ if (fill_flag != 2) panel_clear_value(fill_pat_panel); /* say we exist */ fill_style_exists = True; } /* make a popup arc type menu */ void arc_type_menu(void) { static char *arc_type_items[] = { "Open ", "Pie Wedge"}; FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(" Arc type", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); arc_type_panel = XtCreateManagedWidget( arc_type_items[generic_vals.arc_type], menuButtonWidgetClass, form, Args, ArgCount); below = arc_type_panel; make_pulldown_menu(arc_type_items, XtNumber(arc_type_items), -1, "", arc_type_panel, arc_type_select); } void join_style_panel_menu(void) { FirstArg(XtNfromVert, below); NextArg(XtNhorizDistance, 10); /* space it a bit from the cap style */ NextArg(XtNfromHoriz, beside); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Join style", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNinternalWidth, 0); NextArg(XtNinternalHeight, 0); NextArg(XtNbitmap, joinstyle_choices[generic_vals.join_style].pixmap); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); join_style_panel = XtCreateManagedWidget("join_style", menuButtonWidgetClass, form, Args, ArgCount); make_pulldown_menu_images(joinstyle_choices, NUM_JOINSTYLE_TYPES, joinstyle_pixmaps, NULL, join_style_panel, join_style_select); } /* make a popup cap style menu */ void cap_style_panel_menu(void) { FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Cap style", labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNinternalWidth, 0); NextArg(XtNinternalHeight, 0); NextArg(XtNbitmap, capstyle_choices[generic_vals.cap_style].pixmap); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); cap_style_panel = XtCreateManagedWidget("cap_style_image", menuButtonWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, cap_style_panel); NextArg(XtNborderWidth, 0); make_pulldown_menu_images(capstyle_choices, NUM_CAPSTYLE_TYPES, capstyle_pixmaps, NULL, cap_style_panel, cap_style_select); } /* make a button panel with the image 'pixmap' in it */ /* for the font selection */ void f_menu_popup(void); static XtCallbackRec f_sel_callback[] = { {(XtCallbackProc)f_menu_popup, NULL}, {NULL, NULL}, }; void set_font_image(Widget widget) { FirstArg(XtNbitmap, new_psflag ? psfont_menu_bitmaps[new_ps_font + 1] : latexfont_menu_bitmaps[new_latex_font]); SetValues(widget); } static void font_image_panel(Pixmap pixmap, char *label, Widget *pi_x) { FirstArg(XtNfromVert, below); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNvertDistance, 2); NextArg(XtNbitmap, pixmap); NextArg(XtNcallback, f_sel_callback); NextArg(XtNwidth, MAX_FONTIMAGE_WIDTH); NextArg(XtNinternalWidth, 2); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_x = XtCreateManagedWidget(label, commandWidgetClass, form, Args, ArgCount); below = *pi_x; } /* come here when user presses font image button */ void f_menu_popup(void) { fontpane_popup(&new_ps_font, &new_latex_font, &new_psflag, set_font_image, font_panel); } static Widget pen_color_selection_panel(void) { color_selection_panel(" Pen color","border_colors", "Pen color", form, below, beside, &pen_col_button, &pen_color_popup, generic_vals.pen_color, pen_color_select); return pen_col_button; } static Widget fill_color_selection_panel(void) { color_selection_panel("Fill color","fill_colors", "Fill color", form, below, beside, &fill_col_button, &fill_color_popup, generic_vals.fill_color, fill_color_select); return fill_col_button; } Widget color_selection_panel(char *label, char *wname, char *name, Widget parent, Widget below, Widget beside, Widget *button, Widget *popup, int color, XtCallbackProc callback) { FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, parent, Args, ArgCount); set_color_name(color,buf); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNwidth, COLOR_BUT_WID); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = *button = XtCreateManagedWidget(wname, menuButtonWidgetClass, parent, Args, ArgCount); /* * cheat a little - set the initial fore/background colors by calling the * callback */ /* also set the label */ (callback)(below, (XtPointer) color, NULL); *popup = make_color_popup_menu(below, name, callback, NO_TRANSP, NO_BACKG); return *button; } static Widget int_panel(int x, Widget parent, char *label, Widget beside, Widget *pi_x, int min, int max, int inc) { return int_panel_callb(x, parent, label, beside, pi_x, min, max, inc, (XtCallbackProc) 0); } static Widget int_panel_callb(int x, Widget parent, char *label, Widget pbeside, Widget *pi_x, int min, int max, int inc, XtCallbackProc callback) { FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, pbeside); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, parent, Args, ArgCount); sprintf(buf, "%d", x); below = MakeIntSpinnerEntry(parent, pi_x, label, below, beside, callback, buf, min, max, inc, 45); /* we want the spinner to be chained to the bottom (it's below the comments) */ FirstArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); SetValues(below); text_transl(*pi_x); return below; } static Widget float_panel(float x, Widget parent, char *label, Widget pbeside, Widget *pi_x, float min, float max, float inc, int prec) { char fmt[10]; FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, pbeside); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, parent, Args, ArgCount); /* first make format string from precision */ sprintf(fmt, "%%.%df", prec); /* now format the value */ sprintf(buf, fmt, x); below = MakeFloatSpinnerEntry(parent, pi_x, label, below, beside, (XtCallbackProc) 0, buf, min, max, inc, 50); /* we want the spinner to be chained to the bottom (it's below the comments) */ FirstArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); SetValues(below); text_transl(*pi_x); return below; } static void float_label(float x, char *label, Widget *pi_x) { FirstArg(XtNfromVert, below); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); sprintf(buf, "%1.1f", x); FirstArg(XtNfromVert, below); NextArg(XtNlabel, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNwidth, 40); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_x = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); below = *pi_x; } static void int_label(int x, char *label, Widget *pi_x) { FirstArg(XtNfromVert, below); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); sprintf(buf, "%d", x); FirstArg(XtNfromVert, below); NextArg(XtNlabel, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNwidth, 40); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_x = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); below = *pi_x; } static void str_panel(char *string, char *name, Widget *pi_x, int width, Boolean size_to_width, Boolean international) { int nlines, i; Dimension pwidth; XFontStruct *temp_font; char *labelname, *textname; /* does the user want a label beside the text widget? */ if (name && strlen(name) > 0) { /* yes, make it and manage it */ /* make the labels of the widgets xxx_label for the label part and xxx_text for the asciiwidget part */ labelname = (char *) new_string(strlen(name)+7); textname = (char *) new_string(strlen(name)+6); strcpy(labelname,name); strcat(labelname,"_label"); strcpy(textname,name); strcat(textname,"_text"); FirstArg(XtNfromVert, below); NextArg(XtNlabel, name); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(labelname, labelWidgetClass, form, Args, ArgCount); /* get the font and width of above label widget */ FirstArg(XtNfont, &temp_font); NextArg(XtNwidth, &pwidth); GetValues(beside); } else { /* no, make a widget to get the font, but don't manage it */ beside = (Widget) 0; pwidth = 0; beside = XtCreateWidget("dummy", labelWidgetClass, form, Args, ArgCount); textname = "text_text"; /* get the font of above label widget */ FirstArg(XtNfont, &temp_font); GetValues(beside); beside = 0; } /* make panel as wide as image pane above less the label widget's width */ /* but at least "width" pixels wide */ if (size_to_width) width = max2(PS_FONTPANE_WD - pwidth + 2, width); /* count number of lines in this text string */ nlines = 1; /* number of lines in string */ for (i = 0; i < strlen(string); i++) { if (string[i] == '\n') { nlines++; } } if (nlines > 4) /* limit to displaying 4 lines and show scrollbars */ nlines = 4; FirstArg(XtNfromVert, below); NextArg(XtNstring, string); NextArg(XtNinsertPosition, strlen(string)); NextArg(XtNfromHoriz, beside); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, width); /* allow enough height for scrollbar */ NextArg(XtNheight, max_char_height(temp_font) * nlines + 20); NextArg(XtNscrollHorizontal, XawtextScrollWhenNeeded); NextArg(XtNscrollVertical, XawtextScrollWhenNeeded); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainRight); #ifdef I18N if (!appres.international || !international) NextArg(XtNinternational, False); #endif /* I18N */ *pi_x = XtCreateManagedWidget(textname, asciiTextWidgetClass, form, Args, ArgCount); /* make CR do nothing for now */ text_transl(*pi_x); /* read personal key configuration */ XtOverrideTranslations(*pi_x, XtParseTranslationTable(local_translations)); below = *pi_x; if (name && strlen(name) > 0) { free((char *) textname); free((char *) labelname); } } /* call with make_unit_menu = True to make pulldown unit menu beside first label */ static void xy_panel(int x, int y, char *label, Widget *pi_x, Widget *pi_y, Boolean make_unit_menu) { Widget save_below = below; FirstArg(XtNfromVert, below); NextArg(XtNlabel, label); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); /* pulldown menu for units */ if (make_unit_menu) (void) unit_pulldown_menu(save_below, below); FirstArg(XtNfromVert, below); NextArg(XtNhorizDistance, 20); NextArg(XtNlabel, "X ="); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); cvt_to_units_str(x, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, Args, ArgCount); text_transl(*pi_x); add_to_convert(*pi_x); FirstArg(XtNfromVert, below); NextArg(XtNlabel, "Y ="); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, *pi_x); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); cvt_to_units_str(y, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, Args, ArgCount); text_transl(*pi_y); add_to_convert(*pi_y); below = *pi_x; } /* make an X= Y= pair of labels and text widgets with optional pulldown unit menu */ /* Label for X and Y are variables */ static void f_pair_panel(F_pos *fp, char *label, Widget *pi_x, char *xlabel, Widget *pi_y, char *ylabel, Boolean make_unit_menu) { Widget save_below = below; FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); below = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); /* pulldown menu for units */ if (make_unit_menu) (void) unit_pulldown_menu(save_below, below); FirstArg(XtNfromVert, below); NextArg(XtNhorizDistance, 20); NextArg(XtNlabel, xlabel); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); /* convert first number to desired units */ cvt_to_units_str(fp->x, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); *pi_x = XtCreateManagedWidget(label, asciiTextWidgetClass, form, Args, ArgCount); text_transl(*pi_x); /* add this widget to the list that get conversions */ add_to_convert(*pi_x); FirstArg(XtNfromVert, below); NextArg(XtNlabel, ylabel); NextArg(XtNborderWidth, 0); NextArg(XtNfromHoriz, *pi_x); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(label, labelWidgetClass, form, Args, ArgCount); /* convert second number to desired units */ cvt_to_units_str(fp->y, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = *pi_y = XtCreateManagedWidget(label, asciiTextWidgetClass, form, Args, ArgCount); text_transl(*pi_y); /* add this widget to the list that get conversions */ add_to_convert(*pi_y); below = *pi_x; } static void get_f_pos(F_pos *fp, Widget pi_x, Widget pi_y) { fp->x = panel_get_dim_value(pi_x); fp->y = panel_get_dim_value(pi_y); } /* this makes a scrollable panel in which the x/y points for the Fig object are displayed */ static void points_panel(struct f_point *p) { struct f_point *pts; char buf[32]; int npts, j; Widget viewp,formw,beside,npoints; /* label */ FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Points", labelWidgetClass, form, Args, ArgCount); /* number of points */ FirstArg(XtNfromVert, below); NextArg(XtNlabel, ""); NextArg(XtNfromHoriz, beside); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); npoints = XtCreateManagedWidget("num_points", labelWidgetClass, form, Args, ArgCount); /* pulldown menu for units */ below = unit_pulldown_menu(below, npoints); FirstArg(XtNallowVert, True); NextArg(XtNfromVert, below); NextArg(XtNvertDistance, 2); NextArg(XtNhorizDistance, 20); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); pts = p; for (npts = 0; pts != NULL; npts++) pts = pts->next; /* limit size of points panel and scroll if more than 140 pixels */ if (npts > 6) NextArg(XtNheight, 140); viewp = XtCreateManagedWidget("pointspanel", viewportWidgetClass, form, Args, ArgCount); formw = XtCreateManagedWidget("pointsform", formWidgetClass, viewp, NULL, 0); below = (Widget) 0; /* initialize which panels to convert */ init_convert_array(); for (j = 0; j < npts; j++) { /* limit number of points displayed to prevent system failure :-) */ if (j >= MAXDISPTS) { FirstArg(XtNfromVert, below); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); XtCreateManagedWidget("Too many points to display ", labelWidgetClass, formw, Args, ArgCount); break; } FirstArg(XtNfromVert, below); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); sprintf(buf, "X%d =", j); beside = XtCreateManagedWidget(buf, labelWidgetClass, formw, Args, ArgCount); cvt_to_units_str(p->x, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); px_panel[j] = XtCreateManagedWidget("xy", asciiTextWidgetClass, formw, Args, ArgCount); text_transl(px_panel[j]); /* this panel is also converted by units */ add_to_convert(px_panel[j]); sprintf(buf, "Y%d =", j); FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, px_panel[j]); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget(buf, labelWidgetClass, formw, Args, ArgCount); cvt_to_units_str(p->y, buf); FirstArg(XtNfromVert, below); NextArg(XtNstring, buf); NextArg(XtNfromHoriz, beside); NextArg(XtNinsertPosition, strlen(buf)); NextArg(XtNeditType, XawtextEdit); NextArg(XtNwidth, XY_WIDTH); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); py_panel[j] = XtCreateManagedWidget("xy", asciiTextWidgetClass, formw, Args, ArgCount); text_transl(py_panel[j]); /* this panel is also converted by units */ add_to_convert(py_panel[j]); below = px_panel[j]; p = p->next; } /* now put the (actual) number of points in a label */ sprintf(buf, "%d", npts); FirstArg(XtNlabel, buf); SetValues(npoints); } static void get_points(struct f_point *p) { struct f_point *q; int i; for (q = p, i = 0; q != NULL; i++) { if (i >= MAXDISPTS) break; q->x = panel_get_dim_value(px_panel[i]); q->y = panel_get_dim_value(py_panel[i]); q = q->next; } } /* make a unit pulldown menubutton and menu */ static Widget unit_pulldown_menu(Widget below, Widget beside) { /* put the current user units in unit_items[0] */ unit_items[0] = cur_fig_units; FirstArg(XtNfromVert, below); NextArg(XtNfromHoriz, beside); NextArg(XtNhorizDistance, 15); NextArg(XtNborderWidth, 0); NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); beside = XtCreateManagedWidget("Units:",labelWidgetClass, form, Args, ArgCount); FirstArg(XtNfromVert, below); NextArg(XtNwidth, 95); NextArg(XtNfromHoriz, beside); NextArg(XtNhorizDistance, 2); NextArg(XtNleftBitmap, menu_arrow); /* use menu arrow for pull-down */ NextArg(XtNtop, XtChainBottom); NextArg(XtNbottom, XtChainBottom); NextArg(XtNleft, XtChainLeft); NextArg(XtNright, XtChainLeft); unit_menu_button = XtCreateManagedWidget(unit_items[points_units], menuButtonWidgetClass, form, Args, ArgCount); /* pulldown menu for units */ make_pulldown_menu(unit_items, XtNumber(unit_items), -1, "", unit_menu_button, unit_select); return unit_menu_button; } static void init_convert_array(void) { conv_array_idx = 0; } static void add_to_convert(Widget widget) { convert_array[conv_array_idx++] = widget; } /* unit conversion for displaying coordinates */ static double cvt_to_units(int fig_unit) { if (points_units == 1) return (double) fig_unit; return (double) fig_unit / (double) (appres.INCHES? PIX_PER_INCH: PIX_PER_CM)*appres.userscale; } /* unit conversion that writes ASCII to buf */ static void cvt_to_units_str(int x, char *buf) { double dval; if (points_units) { sprintf(buf, "%d", x); } else { dval = cvt_to_units(x); sprintf(buf, "%.4lf", dval); } } static int cvt_to_fig(double real_unit) { if (points_units) return round(real_unit); return round(real_unit/appres.userscale * (appres.INCHES? PIX_PER_INCH: PIX_PER_CM)); } static void unit_select(Widget w, XtPointer new_unit, XtPointer call_data) { int i; intptr_t new_points_units; char buf[30]; int ival; double val; new_points_units = (intptr_t) new_unit; if (points_units == new_points_units) return; /* change label in menu button */ FirstArg(XtNlabel, unit_items[new_points_units]); SetValues(unit_menu_button); /* now go through the array of text widgets and convert their values */ points_units = 0; for (i=0; ipixmap); SetValues(cap_style_panel); generic_vals.cap_style = choice->value; } static void join_style_select(Widget w, XtPointer new_type, XtPointer call_data) { choice_info *choice; choice = (choice_info *) new_type; FirstArg(XtNbitmap, choice->pixmap); SetValues(join_style_panel); generic_vals.join_style = choice->value; } static void for_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data) { int choice; choice = (int) ((choice_info *) new_type)->value; FirstArg(XtNbitmap, arrow_pixmaps[choice+1]); SetValues(for_arrow_type_panel); for_arrow = (choice != -1); if (for_arrow) { generic_vals.for_arrow.type = ARROW_TYPE(choice); generic_vals.for_arrow.style = ARROW_STYLE(choice); } } static void back_arrow_type_select(Widget w, XtPointer new_type, XtPointer call_data) { int choice; choice = (int) ((choice_info *) new_type)->value; FirstArg(XtNbitmap, arrow_pixmaps[choice+1]); SetValues(back_arrow_type_panel); back_arrow = (choice != -1); if (back_arrow) { generic_vals.back_arrow.type = ARROW_TYPE(choice); generic_vals.back_arrow.style = ARROW_STYLE(choice); } } static void line_style_select(Widget w, XtPointer new_style, XtPointer call_data) { Boolean state; choice_info *choice; choice = (choice_info *) new_style; FirstArg(XtNbitmap, choice->pixmap); SetValues(line_style_panel); generic_vals.style = choice->value; switch (generic_vals.style) { case SOLID_LINE: panel_clear_value(style_val_panel); state = False; break; case DASH_LINE: /* * if style_val contains no useful value, set it to the default * dashlength, scaled by the line thickness */ if (generic_vals.style_val <= 0.0) generic_vals.style_val = cur_dashlength * (generic_vals.thickness + 1) / 2; panel_set_float(style_val_panel, generic_vals.style_val, "%1.1f"); state = True; break; default: /* DOTTED, DASH-DOTTED, and the others */ if (generic_vals.style_val <= 0.0) generic_vals.style_val = cur_dotgap * (generic_vals.thickness + 1) / 2; panel_set_float(style_val_panel, generic_vals.style_val, "%1.1f"); state = True; break; } /* make both the label and value panels sensitive or insensitive */ XtSetSensitive(style_val,state); XtSetSensitive(style_val_label,state); } static void pen_color_select(Widget w, XtPointer new_color, XtPointer call_data) { pen_color = (Color) new_color; color_select(pen_col_button, pen_color); if (pen_color_popup) { XtPopdown(pen_color_popup); } } static void fill_color_select(Widget w, XtPointer new_color, XtPointer call_data) { fill_color = (Color) new_color; color_select(fill_col_button, fill_color); if (fill_color_popup) { XtPopdown(fill_color_popup); } } void color_select(Widget w, Color color) { XFontStruct *f; /* update colors for fill image gc */ recolor_fill_image(); FirstArg(XtNlabel, XtName(w)); SetValues(w); set_color_name(color,buf); FirstArg(XtNfont, &f); GetValues(w); FirstArg(XtNlabel, buf); /* don't know why, but we *MUST* set the size again here or it will stay the width that it first had when created */ NextArg(XtNwidth, COLOR_BUT_WID); if (all_colors_available) { /* set color if possible */ XColor xcolor; Pixel col; /* background in the color selected */ col = (color < 0 || color >= NUM_STD_COLS+num_usr_cols) ? x_fg_color.pixel : colors[color]; NextArg(XtNbackground, col); xcolor.pixel = col; /* get RGB of the color to check intensity */ XQueryColor(tool_d, tool_cm, &xcolor); /* set the foreground in a contrasting color (white or black) */ if ((0.3 * xcolor.red + 0.59 * xcolor.green + 0.11 * xcolor.blue) < 0.55 * (255 << 8)) col = colors[WHITE]; else col = colors[BLACK]; NextArg(XtNforeground, col); } SetValues(w); } static void hidden_text_select(Widget w, XtPointer new_hidden_text, XtPointer call_data) { FirstArg(XtNlabel, XtName(w)); SetValues(hidden_text_panel); hidden_text_flag = (intptr_t) new_hidden_text; } static void rigid_text_select(Widget w, XtPointer new_rigid_text, XtPointer call_data) { FirstArg(XtNlabel, XtName(w)); SetValues(rigid_text_panel); rigid_text_flag = (intptr_t) new_rigid_text; } static void special_text_select(Widget w, XtPointer new_special_text, XtPointer call_data) { FirstArg(XtNlabel, XtName(w)); SetValues(special_text_panel); special_text_flag = (intptr_t) new_special_text; } static void textjust_select(Widget w, XtPointer new_textjust, XtPointer call_data) { FirstArg(XtNlabel, XtName(w)); SetValues(textjust_panel); textjust = (intptr_t) new_textjust; } static void flip_pic_select(Widget w, XtPointer new_flipflag, XtPointer call_data) { struct f_point p1, p2; int dx, dy, rotation; float ratio; FirstArg(XtNlabel, XtName(w)); SetValues(flip_pic_panel); flip_pic_flag = (intptr_t) new_flipflag; p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); /* size is upper-lower */ dx = p2.x - p1.x; dy = p2.y - p1.y; rotation = what_rotation(dx,dy); if (dx == 0 || dy == 0) ratio = 0.0; else if (((rotation == 0 || rotation == 180) && !flip_pic_flag) || (rotation != 0 && rotation != 180 && flip_pic_flag)) ratio = (float) fabs((double) dy / (double) dx); else ratio = (float) fabs((double) dx / (double) dy); sprintf(buf, "%1.1f", ratio); FirstArg(XtNlabel, buf); SetValues(hw_ratio_panel); } static void rotation_select(Widget w, XtPointer new_rotation, XtPointer call_data) { struct f_point p1, p2; int dx, dy, cur_rotation; intptr_t rotation; int x1, y1, x2, y2; FirstArg(XtNlabel, XtName(w)); SetValues(rotation_panel); /* get new rotation (0 = 0 degrees, 1 = 90, 2 = 180, 3 = 270) */ rotation = (intptr_t) new_rotation; /* get the two opposite corners */ p1.x = panel_get_dim_value(x1_panel); p1.y = panel_get_dim_value(y1_panel); p2.x = panel_get_dim_value(x2_panel); p2.y = panel_get_dim_value(y2_panel); dx = p2.x - p1.x; dy = p2.y - p1.y; /* the current rotation based on the current corners */ cur_rotation = what_rotation(dx,dy); /* adjust p2 relative to p1 to get desired rotation */ x1 = p1.x; y1 = p1.y; x2 = p2.x; y2 = p2.y; switch (cur_rotation) { case 0: switch (rotation) { case 0: /* 0 degrees */ break; case 1: /* 90 degrees */ x2 = x1 + dy; y2 = y1 - dx; break; case 2: /* 180 degrees */ x2 = x1 - dx; y2 = y1 - dy; break; case 3: /* 270 degrees */ x2 = x1 - dy; y2 = y1 + dx; break; } break; case 90: switch (rotation) { case 0: /* 0 degrees */ x2 = x1 - dy; y2 = y1 + dx; break; case 1: /* 90 degrees */ break; case 2: /* 180 degrees */ x2 = x1 + dy; y2 = y1 - dx; break; case 3: /* 270 degrees */ x2 = x1 - dx; y2 = y1 - dy; break; } break; case 180: switch (rotation) { case 0: /* 0 degrees */ x2 = x1 - dx; y2 = y1 - dy; break; case 1: /* 90 degrees */ x2 = x1 - dy; y2 = y1 + dx; break; case 2: /* 180 degrees */ break; case 3: /* 270 degrees */ x2 = x1 + dy; y2 = y1 - dx; break; } break; case 270: switch (rotation) { case 0: /* 0 degrees */ x2 = x1 + dy; y2 = y1 - dx; break; case 1: /* 90 degrees */ x2 = x1 - dx; y2 = y1 - dy; break; case 2: /* 180 degrees */ x2 = x1 - dy; y2 = y1 + dx; break; case 3: /* 270 degrees */ break; } break; } /* put them back in the panel */ panel_set_scaled_int(x2_panel, x2); panel_set_scaled_int(y2_panel, y2); /* finally, update width and height */ panel_set_scaled_int(width_panel, abs(x2-x1)); panel_set_scaled_int(height_panel, abs(y2-y1)); } static void fill_style_select(Widget w, XtPointer new_fillflag, XtPointer call_data) { int fill; char *sval; FirstArg(XtNlabel, XtName(w)); SetValues(fill_style_button); fill_flag = (intptr_t) new_fillflag; if (fill_flag == 0) { /* no fill; blank out fill density value and pattern */ panel_clear_value(fill_intens_panel); panel_clear_value(fill_pat_panel); /* make fill% panel insensitive */ fill_style_sens(False); /* and pattern */ fill_pat_sens(False); } else if (fill_flag == 1) { /* filled with color or gray */ sval = panel_get_value(fill_intens_panel); /* if there is already a number there, use it */ if (sval[0]!=' ') { fill = atoi(sval); } else { /* else use 100% */ fill = 100; } if (fill < 0) fill = 100; if (fill > 200) fill = 100; panel_set_int(fill_intens_panel, fill); /* clear value in pattern panel */ panel_clear_value(fill_pat_panel); /* make fill% panel sensitive */ fill_style_sens(True); /* make fill pattern panel insensitive */ fill_pat_sens(False); } else { /* filled with pattern */ sval = panel_get_value(fill_pat_panel); /* if there is already a number there, use it */ if (sval[0]!=' ') { fill = atoi(sval); } else { /* else use first pattern */ fill = 0; } panel_set_int(fill_pat_panel, fill); /* clear value in fill % panel */ panel_clear_value(fill_intens_panel); /* make fill pattern panel sensitive */ fill_pat_sens(True); /* make fill% panel insensitive */ fill_style_sens(False); } } void fill_style_sens(Boolean state) { XtSetSensitive(fill_intens,state); XtSetSensitive(fill_intens_label,state); update_fill_image((Widget) 0, (XtPointer) 0, (XtPointer) 0); } void fill_pat_sens(Boolean state) { XtSetSensitive(fill_pat,state); XtSetSensitive(fill_pat_label,state); update_fill_image((Widget) 0, (XtPointer) 0, (XtPointer) 0); } void clear_text_key(Widget w) { panel_set_value(w, ""); } static void get_clipboard(Widget w, XtPointer client_data, Atom *selection, Atom *type, XtPointer buf, long unsigned int *length, int *format); void paste_panel_key(Widget w, XKeyEvent *event) { Time event_time; event_time = event->time; XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, get_clipboard, w, event_time); } static void get_clipboard(Widget w, XtPointer client_data, Atom *selection, Atom *type, XtPointer buf, long unsigned int *length, int *format) { char *c, *p; int i; char s[256]; strcpy (s, panel_get_value(client_data)); p = strchr(s, '\0'); c = buf; for (i=0; i<*length; i++) { if (*c=='\0' || *c=='\n' || *c=='\r' || strlen(s)>=sizeof(s)-1) break; *p = *c; p++; *p = '\0'; c++; } XtFree(buf); panel_set_value(client_data, s); } void text_transl(Widget w) { /* make CR finish edit */ XtOverrideTranslations(w, XtParseTranslationTable(edit_text_translations)); /* enable mousefun kbd display */ XtAugmentTranslations(w, XtParseTranslationTable(kbd_translations)); } void change_sfactor(int x, int y, unsigned int button) { F_spline *spl, *spline; F_point *prev, *the_point; F_point p1, p2; F_sfactor *associated_sfactor; prev = &p1; the_point = &p2; spl = get_spline_point(x, y, &prev, &the_point); if (spl == NULL) { put_msg("Only spline points can be edited"); return; } if (open_spline(spl) && ((prev == NULL) || (the_point->next == NULL))) { put_msg("Cannot edit end-points"); return; } toggle_pointmarker(the_point->x, the_point->y); spline = copy_spline(spl); if (spline == NULL) return; associated_sfactor = search_sfactor(spline, search_spline_point(spline, the_point->x, the_point->y)); change_spline(spl, spline); draw_spline(spline, ERASE); switch (button) { case Button1: associated_sfactor->s += 2*STEP_VALUE; if (associated_sfactor->s > S_SPLINE_APPROX) associated_sfactor->s = S_SPLINE_APPROX; break; case Button2: associated_sfactor->s = (round(associated_sfactor->s)) + (S_SPLINE_APPROX - S_SPLINE_ANGULAR); if (associated_sfactor->s > S_SPLINE_APPROX) associated_sfactor->s = S_SPLINE_INTERP; break; case Button3: associated_sfactor->s -= 2*STEP_VALUE; if (associated_sfactor->s < S_SPLINE_INTERP) associated_sfactor->s = S_SPLINE_INTERP; break; } spline->type = open_spline(spline) ? T_OPEN_XSPLINE : T_CLOSED_XSPLINE; draw_spline(spline, PAINT); toggle_pointmarker(the_point->x, the_point->y); } void check_depth(void) { int depth; depth = atoi(panel_get_value(depth_panel)); if (depth >= 0 && depth <= MAX_DEPTH) return; if (depth < MIN_DEPTH) depth = MIN_DEPTH; else if (depth > MAX_DEPTH) depth = MAX_DEPTH; panel_set_int(depth_panel, depth); } void check_thick(void) { int thick; thick = atoi(panel_get_value(thickness_panel)); if (thick >= 0 && thick <= MAX_LINE_WIDTH) return; if (thick < 0) thick = 0; else if (thick > MAX_LINE_WIDTH) thick = MAX_LINE_WIDTH; panel_set_int(thickness_panel, thick); } /* these functions push_apply_button, grab_button, popup_browse_panel & image_edit_button implement gif screen capture facility note push_apply_button also called from w_browse.c */ void push_apply_button(void) { /* get rid of anything that ought to be done - X wise */ app_flush(); button_result = APPLY; done_proc(); } static void grab_button(Widget panel_local, XtPointer closure, XtPointer call_data) { time_t tim; char tmpfile[PATH_MAX],tmpname[PATH_MAX]; char *p; if (!canHandleCapture(tool_d)) { put_msg("Can't capture screen"); beep(); return; } /* build up a temporary file name from the user login name and the current time */ tim = time( (time_t*)0); /* get figure name without path */ if (*cur_filename == '\0') strcpy(tmpname, "NoName"); /* no name, use "NoName" */ else strcpy(tmpname,xf_basename(cur_filename)); /* chop off any .suffix */ if (p=strrchr(tmpname,'.')) *p='\0'; sprintf(tmpfile,"%s_%ld.png",tmpname,tim); /* capture the screen area into our tmpfile */ if (captureImage(popup, tmpfile) == True) { panel_set_value(pic_name_panel, tmpfile); push_apply_button(); } } /* Edit button has been pushed - invoke an editor on the current file */ static void image_edit_button(Widget panel_local, XtPointer closure, XtPointer call_data) { int argc; char *argv[20]; pid_t pid; char cmd[PATH_MAX]; char s[PATH_MAX]; struct stat original_stat; int err; char *cp; /* get the filename for the picture object */ strcpy(s,panel_get_value(pic_name_panel)); if (*s == '\0') /* no name, return */ return; /* uncompress the image file if it is compressed (new name returns in s) */ if (uncompress_file(s) == False) /* failed! no point in continuing */ return; /* store name back in case any .gz or .Z was removed after uncompressing */ panel_set_value(pic_name_panel,s); button_result = APPLY; strcpy(cmd, cur_image_editor); argc = 0; /* get first word from string as the program */ argv[argc++] = strtok(cmd," \t"); /* if there is more than one word, separate args */ while ((cp = strtok((char*) NULL," \t")) && argc < sizeof(argv)/sizeof(argv[0]) - 2) argv[argc++] = cp; argv[argc++] = s; /* put the filename last */ argv[argc] = NULL; /* terminate the list */ /* get the file status (to compare file modification time later) */ if (stat( s, &original_stat ) != 0 ) /* stat failed! no point in continuing */ return; pid = fork(); if ( pid == 0 ) { err = execvp(argv[0], argv); /* should only come here if an error in the execlp */ fprintf(stderr,"Error in exec'ing image editor (%s): %s\n", argv[0], strerror(errno)); exit(-1); } if ( pid > 0 ) { /* wait for the lad to finish */ int status; struct stat new_stat; (void) waitpid( pid, &status, 0 ); /* if file modification time has changed, set the changed flag - causes a reread of the file as it thinks the name has changed */ stat(s, &new_stat ); if ( original_stat.st_mtime != new_stat.st_mtime ) { new_l->pic->pic_cache->bitmap = NULL; push_apply_button(); } } else { fprintf(stderr,"Unable to fork to exec image editor (%s): %s\n", argv[0], strerror(errno)); } } static void browse_button(Widget panel_local, XtPointer closure, XtPointer call_data) { popup_browse_panel( form ); } /* collapse the depths in new_c to min_compound_depth and update the max depth value */ static void collapse_depth(Widget panel_local, XtPointer closure, XtPointer call_data) { collapse_depths(new_c); sprintf(buf,"Maximum: %d", min_compound_depth); FirstArg(XtNlabel, buf); SetValues(max_depth_w); } /* need this to recurse through compounds inside new_c */ void collapse_depths(F_compound *compound) { F_line *l; F_spline *s; F_ellipse *e; F_arc *a; F_text *t; F_compound *c; for (l = compound->lines; l != NULL; l = l->next) { remove_depth(O_POLYLINE, l->depth); l->depth = min_compound_depth; add_depth(O_POLYLINE, l->depth); } for (s = compound->splines; s != NULL; s = s->next) { remove_depth(O_SPLINE, s->depth); s->depth = min_compound_depth; add_depth(O_SPLINE, s->depth); } for (e = compound->ellipses; e != NULL; e = e->next) { remove_depth(O_ELLIPSE, e->depth); e->depth = min_compound_depth; add_depth(O_ELLIPSE, e->depth); } for (a = compound->arcs; a != NULL; a = a->next) { remove_depth(O_ARC, a->depth); a->depth = min_compound_depth; add_depth(O_ARC, a->depth); } for (t = compound->texts; t != NULL; t = t->next) { remove_depth(O_TXT, t->depth); t->depth = min_compound_depth; add_depth(O_TXT, t->depth); } for (c = compound->compounds; c != NULL; c = c->next) { collapse_depths(c); } } /* return rotation value based on the signs of dx, dy which come from the * two corners of the picture (dx = p2.x - p1.x, dy = p2.y - p1.y) */ static int what_rotation(int dx, int dy) { int rotation; rotation = 0; if (dx >= 0 && dy < 0) rotation = 90; else if (dx < 0 && dy < 0) rotation = 180; else if (dx < 0 && dy >= 0) rotation = 270; return rotation; } xfig.3.2.5c/e_flip.c0000700002656300244210000002544311641414046014766 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_rotate.h" #include "u_draw.h" #include "u_search.h" #include "u_create.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" /* EXPORTS */ int setanchor; int setanchor_x; int setanchor_y; static int flip_axis; static int copy; static void init_flip(F_line *p, int type, int x, int y, int px, int py); static void init_copynflip(F_line *p, int type, int x, int y, int px, int py); static void set_unset_anchor(int x, int y); static void init_fliparc(F_arc *old_a, int px, int py); static void init_flipcompound(F_compound *old_c, int px, int py); static void init_flipellipse(F_ellipse *old_e, int px, int py); static void init_flipline(F_line *old_l, int px, int py); static void init_flipspline(F_spline *old_s, int px, int py); static void flip_selected(void); static void flip_search(F_line *p, int type, int x, int y, int px, int py); void flip_arc (F_arc *a, int x, int y, int flip_axis); void flip_compound (F_compound *c, int x, int y, int flip_axis); void flip_ellipse (F_ellipse *e, int x, int y, int flip_axis); void flip_line (F_line *l, int x, int y, int flip_axis); void flip_spline (F_spline *s, int x, int y, int flip_axis); void flip_ud_selected(void) { flip_axis = UD_FLIP; /* erase any existing anchor */ if (setanchor) center_marker(setanchor_x, setanchor_y); /* and any center */ if (setcenter) center_marker(setcenter_x, setcenter_y); setcenter = 0; setanchor = 0; flip_selected(); reset_action_on(); } void flip_lr_selected(void) { flip_axis = LR_FLIP; /* erase any existing anchor */ if (setanchor) center_marker(setanchor_x, setanchor_y); /* and any center */ if (setcenter) center_marker(setcenter_x, setcenter_y); setcenter = 0; setanchor = 0; flip_selected(); reset_action_on(); } static void flip_selected(void) { set_mousefun("flip", "copy & flip", "set anchor", LOC_OBJ, LOC_OBJ, "set anchor"); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_flip); init_searchproc_middle(init_copynflip); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = set_unset_anchor; set_cursor(pick15_cursor); } static void set_unset_anchor(int x, int y) { if (setanchor) { set_mousefun("flip", "copy & flip", "set anchor", LOC_OBJ, LOC_OBJ, "set anchor"); draw_mousefun_canvas(); setanchor = 0; center_marker(setanchor_x,setanchor_y); /* second call to center_mark on same position deletes */ } else { set_mousefun("flip", "copy & flip", "unset anchor", LOC_OBJ, LOC_OBJ, "unset anchor"); draw_mousefun_canvas(); setanchor = 1; setanchor_x = x; setanchor_y = y; center_marker(setanchor_x,setanchor_y); } } static void init_flip(F_line *p, int type, int x, int y, int px, int py) { copy = 0; if (setanchor) flip_search(p, type, x, y,setanchor_x,setanchor_y ); /* remember rotation center, e.g for multiple rotation*/ else flip_search(p, type, x, y, px, py); } static void init_copynflip(F_line *p, int type, int x, int y, int px, int py) { copy = 1; if (setanchor) flip_search(p, type, x, y,setanchor_x,setanchor_y ); /* remember rotation center, e.g for multiple rotation*/ else flip_search(p, type, x, y, px, py); } static void flip_search(F_line *p, int type, int x, int y, int px, int py) { switch (type) { case O_POLYLINE: cur_l = (F_line *) p; init_flipline(cur_l, px, py); break; case O_ARC: cur_a = (F_arc *) p; init_fliparc(cur_a, px, py); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; init_flipellipse(cur_e, px, py); break; case O_SPLINE: cur_s = (F_spline *) p; init_flipspline(cur_s, px, py); break; case O_COMPOUND: cur_c = (F_compound *) p; init_flipcompound(cur_c, px, py); break; default: return; } } static void init_fliparc(F_arc *old_a, int px, int py) { F_arc *new_a; set_temp_cursor(wait_cursor); new_a = copy_arc(old_a); flip_arc(new_a, px, py, flip_axis); if (copy) { add_arc(new_a); } else { toggle_arcmarker(old_a); draw_arc(old_a, ERASE); change_arc(old_a, new_a); } /* redisplay objects under this object before it was rotated */ redisplay_arc(old_a); /* and this arc and any other objects on top */ redisplay_arc(new_a); reset_cursor(); } static void init_flipcompound(F_compound *old_c, int px, int py) { F_compound *new_c; set_temp_cursor(wait_cursor); new_c = copy_compound(old_c); flip_compound(new_c, px, py, flip_axis); if (copy) { add_compound(new_c); } else { toggle_compoundmarker(old_c); draw_compoundelements(old_c, ERASE); change_compound(old_c, new_c); } /* redisplay objects under this object before it was rotated */ redisplay_compound(old_c); /* and this object and any other objects on top */ redisplay_compound(new_c); reset_cursor(); } static void init_flipellipse(F_ellipse *old_e, int px, int py) { F_ellipse *new_e; new_e = copy_ellipse(old_e); flip_ellipse(new_e, px, py, flip_axis); if (copy) { add_ellipse(new_e); } else { toggle_ellipsemarker(old_e); draw_ellipse(old_e, ERASE); change_ellipse(old_e, new_e); } /* redisplay objects under this object before it was rotated */ redisplay_ellipse(old_e); /* and this object and any other objects on top */ redisplay_ellipse(new_e); } static void init_flipline(F_line *old_l, int px, int py) { F_line *new_l; new_l = copy_line(old_l); flip_line(new_l, px, py, flip_axis); if (copy) { add_line(new_l); } else { toggle_linemarker(old_l); draw_line(old_l, ERASE); change_line(old_l, new_l); } /* redisplay objects under this object before it was rotated */ redisplay_line(old_l); /* and this object and any other objects on top */ redisplay_line(new_l); } static void init_flipspline(F_spline *old_s, int px, int py) { F_spline *new_s; new_s = copy_spline(old_s); flip_spline(new_s, px, py, flip_axis); if (copy) { add_spline(new_s); } else { toggle_splinemarker(old_s); draw_spline(old_s, ERASE); change_spline(old_s, new_s); } /* redisplay objects under this object before it was rotated */ redisplay_spline(old_s); /* and this object and any other objects on top */ redisplay_spline(new_s); } void flip_line(F_line *l, int x, int y, int flip_axis) { F_point *p; switch (flip_axis) { case UD_FLIP: /* x axis */ for (p = l->points; p != NULL; p = p->next) p->y = y + (y - p->y); break; case LR_FLIP: /* y axis */ for (p = l->points; p != NULL; p = p->next) p->x = x + (x - p->x); break; } if (l->type == T_PICTURE) l->pic->flipped = 1 - l->pic->flipped; } void flip_spline(F_spline *s, int x, int y, int flip_axis) { F_point *p; switch (flip_axis) { case UD_FLIP: /* x axis */ for (p = s->points; p != NULL; p = p->next) p->y = y + (y - p->y); break; case LR_FLIP: /* y axis */ for (p = s->points; p != NULL; p = p->next) p->x = x + (x - p->x); break; } } void flip_text(F_text *t, int x, int y, int flip_axis) { double sina, cosa; while (t->angle > M_2PI) t->angle -= M_2PI; /* flip the angle around 2PI */ t->angle = M_2PI - t->angle; switch (flip_axis) { case LR_FLIP: /* left/right around the y axis */ t->base_x = x + (x - t->base_x); /* switch justification */ if (t->type == T_LEFT_JUSTIFIED) t->type = T_RIGHT_JUSTIFIED; else if (t->type == T_RIGHT_JUSTIFIED) t->type = T_LEFT_JUSTIFIED; break; case UD_FLIP: /* up/down around the x axis */ cosa = cos((double)t->angle); sina = sin((double)t->angle); t->base_x = t->base_x + round((t->ascent - t->descent)*sina); t->base_y = y + (y - t->base_y) + round((t->ascent - t->descent)*cosa); break; } } void flip_ellipse(F_ellipse *e, int x, int y, int flip_axis) { switch (flip_axis) { case UD_FLIP: /* x axis */ e->direction ^= 1; e->center.y = y + (y - e->center.y); e->start.y = y + (y - e->start.y); e->end.y = y + (y - e->end.y); break; case LR_FLIP: /* y axis */ e->direction ^= 1; e->center.x = x + (x - e->center.x); e->start.x = x + (x - e->start.x); e->end.x = x + (x - e->end.x); break; } e->angle = - e->angle; } void flip_arc(F_arc *a, int x, int y, int flip_axis) { switch (flip_axis) { case UD_FLIP: /* x axis */ a->direction ^= 1; a->center.y = y + (y - a->center.y); a->point[0].y = y + (y - a->point[0].y); a->point[1].y = y + (y - a->point[1].y); a->point[2].y = y + (y - a->point[2].y); break; case LR_FLIP: /* y axis */ a->direction ^= 1; a->center.x = x + (x - a->center.x); a->point[0].x = x + (x - a->point[0].x); a->point[1].x = x + (x - a->point[1].x); a->point[2].x = x + (x - a->point[2].x); break; } } void flip_compound(F_compound *c, int x, int y, int flip_axis) { F_line *l; F_arc *a; F_ellipse *e; F_spline *s; F_text *t; F_compound *c1; int p, q; switch (flip_axis) { case UD_FLIP: /* x axis */ p = y + (y - c->nwcorner.y); q = y + (y - c->secorner.y); c->nwcorner.y = min2(p, q); c->secorner.y = max2(p, q); break; case LR_FLIP: /* y axis */ p = x + (x - c->nwcorner.x); q = x + (x - c->secorner.x); c->nwcorner.x = min2(p, q); c->secorner.x = max2(p, q); break; } for (l = c->lines; l != NULL; l = l->next) flip_line(l, x, y, flip_axis); for (a = c->arcs; a != NULL; a = a->next) flip_arc(a, x, y, flip_axis); for (e = c->ellipses; e != NULL; e = e->next) flip_ellipse(e, x, y, flip_axis); for (s = c->splines; s != NULL; s = s->next) flip_spline(s, x, y, flip_axis); for (t = c->texts; t != NULL; t = t->next) flip_text(t, x, y, flip_axis); for (c1 = c->compounds; c1 != NULL; c1 = c1->next) flip_compound(c1, x, y, flip_axis); } xfig.3.2.5c/e_glue.c0000700002656300244210000003004411641414046014761 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_line.h" #include "f_read.h" #include "u_bound.h" #include "u_create.h" #include "u_draw.h" #include "u_elastic.h" #include "u_list.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_layers.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "d_box.h" #include "u_markers.h" #include "w_cursor.h" static void create_compoundobject(int x, int y), cancel_tag_region(void), init_tag_region(int x, int y), tag_region(int x, int y), tag_object(F_line *p, int type, int x, int y, int px, int py); static void get_arc(F_arc **list), sel_arc(int xmin, int ymin, int xmax, int ymax); static void get_compound(F_compound **list), sel_compound(int xmin, int ymin, int xmax, int ymax); static void get_ellipse(F_ellipse **list), sel_ellipse(int xmin, int ymin, int xmax, int ymax); static void get_line(F_line **list), sel_line(int xmin, int ymin, int xmax, int ymax); static void get_spline(F_spline **list), sel_spline(int xmin, int ymin, int xmax, int ymax); static void get_text(F_text **list), sel_text(int xmin, int ymin, int xmax, int ymax); void tag_obj_in_region (int xmin, int ymin, int xmax, int ymax); int compose_compound (F_compound *c); void compound_selected(void) { set_mousefun("tag object", "tag region", "compound tagged", LOC_OBJ, "", ""); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(tag_object); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = init_tag_region; canvas_rightbut_proc = create_compoundobject; set_cursor(pick9_cursor); reset_action_on(); } static void tag_object(F_line *p, int type, int x, int y, int px, int py) { switch (type) { case O_COMPOUND: cur_c = (F_compound *) p; toggle_compoundhighlight(cur_c); cur_c->tagged = 1 - cur_c->tagged; break; case O_POLYLINE: cur_l = (F_line *) p; toggle_linehighlight(cur_l); cur_l->tagged = 1 - cur_l->tagged; break; case O_TXT: cur_t = (F_text *) p; toggle_texthighlight(cur_t); cur_t->tagged = 1 - cur_t->tagged; break; case O_ELLIPSE: cur_e = (F_ellipse *) p; toggle_ellipsehighlight(cur_e); cur_e->tagged = 1 - cur_e->tagged; break; case O_ARC: cur_a = (F_arc *) p; toggle_archighlight(cur_a); cur_a->tagged = 1 - cur_a->tagged; break; case O_SPLINE: cur_s = (F_spline *) p; toggle_splinehighlight(cur_s); cur_s->tagged = 1 - cur_s->tagged; break; default: return; } } static void init_tag_region(int x, int y) { init_box_drawing(x, y); set_mousefun("", "final corner", "cancel", "", "", ""); draw_mousefun_canvas(); canvas_leftbut_proc = null_proc; canvas_middlebut_proc = tag_region; canvas_rightbut_proc = cancel_tag_region; } static void cancel_tag_region(void) { elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); compound_selected(); draw_mousefun_canvas(); } static void tag_region(int x, int y) { int xmin, ymin, xmax, ymax; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); xmin = min2(fix_x, x); ymin = min2(fix_y, y); xmax = max2(fix_x, x); ymax = max2(fix_y, y); tag_obj_in_region(xmin, ymin, xmax, ymax); compound_selected(); draw_mousefun_canvas(); } static void create_compoundobject(int x, int y) { F_compound *c; if ((c = create_compound()) == NULL) return; if (compose_compound(c) == 0) { free((char *) c); compound_selected(); draw_mousefun_canvas(); put_msg("Empty compound, ignored"); return; } /* * Make the bounding box exactly match the dimensions of the compound. */ compound_bound(c, &c->nwcorner.x, &c->nwcorner.y, &c->secorner.x, &c->secorner.y); /* if zero width or height in the compound, adjust to next positioning grid point or a few pixels if positioning grid is "ANY" */ if (c->nwcorner.x == c->secorner.x) { if (cur_pointposn != P_ANY) { c->secorner.x += posn_rnd[cur_gridunit][cur_pointposn]; c->secorner.x = ceil_coords_x(c->secorner.x,c->secorner.y); } } if (c->nwcorner.y == c->secorner.y) { if (cur_pointposn != P_ANY) { c->secorner.y += posn_rnd[cur_gridunit][cur_pointposn]; c->secorner.y = ceil_coords_y(c->secorner.x,c->secorner.y); } } c->next = NULL; clean_up(); set_action(F_GLUE); toggle_markers_in_compound(c); list_add_compound(&objects.compounds, c); mask_toggle_compoundmarker(c); set_latestcompound(c); set_modifiedflag(); compound_selected(); draw_mousefun_canvas(); } void tag_obj_in_region(int xmin, int ymin, int xmax, int ymax) { sel_ellipse(xmin, ymin, xmax, ymax); sel_line(xmin, ymin, xmax, ymax); sel_spline(xmin, ymin, xmax, ymax); sel_text(xmin, ymin, xmax, ymax); sel_arc(xmin, ymin, xmax, ymax); sel_compound(xmin, ymin, xmax, ymax); } int compose_compound(F_compound *c) { c->ellipses = NULL; c->lines = NULL; c->texts = NULL; c->splines = NULL; c->arcs = NULL; c->comments = NULL; c->compounds = NULL; /* defer updating of layer buttons until we've composed the entire compound */ defer_update_layers = True; get_ellipse(&c->ellipses); get_line(&c->lines); get_spline(&c->splines); get_text(&c->texts); get_arc(&c->arcs); get_compound(&c->compounds); /* now update the layer buttons */ defer_update_layers = False; update_layers(); if (c->ellipses != NULL) return (1); if (c->splines != NULL) return (1); if (c->lines != NULL) return (1); if (c->texts != NULL) return (1); if (c->arcs != NULL) return (1); if (c->compounds != NULL) return (1); return (0); } static void sel_ellipse(int xmin, int ymin, int xmax, int ymax) { F_ellipse *e; for (e = objects.ellipses; e != NULL; e = e->next) { if (!active_layer(e->depth)) continue; if (xmin > e->center.x - e->radiuses.x) continue; if (xmax < e->center.x + e->radiuses.x) continue; if (ymin > e->center.y - e->radiuses.y) continue; if (ymax < e->center.y + e->radiuses.y) continue; e->tagged = 1 - e->tagged; toggle_ellipsehighlight(e); } } static void get_ellipse(F_ellipse **list) { F_ellipse *e, *ee, *ellipse; for (e = objects.ellipses; e != NULL;) { if (!e->tagged) { ee = e; e = e->next; continue; } remove_depth(O_ELLIPSE, e->depth); if (*list == NULL) *list = e; else ellipse->next = e; ellipse = e; if (e == objects.ellipses) e = objects.ellipses = objects.ellipses->next; else { e = ee->next = e->next; } ellipse->next = NULL; } } static void sel_arc(int xmin, int ymin, int xmax, int ymax) { F_arc *a; int urx, ury, llx, lly; for (a = objects.arcs; a != NULL; a = a->next) { if (!active_layer(a->depth)) continue; arc_bound(a, &llx, &lly, &urx, &ury); if (xmin > llx) continue; if (xmax < urx) continue; if (ymin > lly) continue; if (ymax < ury) continue; a->tagged = 1 - a->tagged; toggle_archighlight(a); } } static void get_arc(F_arc **list) { F_arc *a, *arc, *aa; for (a = objects.arcs; a != NULL;) { if (!a->tagged) { aa = a; a = a->next; continue; } remove_depth(O_ARC, a->depth); if (*list == NULL) *list = a; else arc->next = a; arc = a; if (a == objects.arcs) a = objects.arcs = objects.arcs->next; else a = aa->next = a->next; arc->next = NULL; } } static void sel_line(int xmin, int ymin, int xmax, int ymax) { F_line *l; F_point *p; int inbound; for (l = objects.lines; l != NULL; l = l->next) { if (!active_layer(l->depth)) continue; for (inbound = 1, p = l->points; p != NULL && inbound; p = p->next) { inbound = 0; if (xmin > p->x) continue; if (xmax < p->x) continue; if (ymin > p->y) continue; if (ymax < p->y) continue; inbound = 1; } if (!inbound) continue; l->tagged = 1 - l->tagged; toggle_linehighlight(l); } } static void get_line(F_line **list) { F_line *line, *l, *ll; for (l = objects.lines; l != NULL;) { if (!l->tagged) { ll = l; l = l->next; continue; } remove_depth(O_POLYLINE, l->depth); if (*list == NULL) *list = l; else line->next = l; line = l; if (l == objects.lines) l = objects.lines = objects.lines->next; else l = ll->next = l->next; line->next = NULL; } } static void sel_spline(int xmin, int ymin, int xmax, int ymax) { F_spline *s; int urx, ury, llx, lly; for (s = objects.splines; s != NULL; s = s->next) { if (!active_layer(s->depth)) continue; spline_bound(s, &llx, &lly, &urx, &ury); if (xmin > llx) continue; if (xmax < urx) continue; if (ymin > lly) continue; if (ymax < ury) continue; s->tagged = 1 - s->tagged; toggle_splinehighlight(s); } } static void get_spline(F_spline **list) { F_spline *spline, *s, *ss; for (s = objects.splines; s != NULL;) { if (!s->tagged) { ss = s; s = s->next; continue; } remove_depth(O_SPLINE, s->depth); if (*list == NULL) *list = s; else spline->next = s; spline = s; if (s == objects.splines) s = objects.splines = objects.splines->next; else s = ss->next = s->next; spline->next = NULL; } } static void sel_text(int xmin, int ymin, int xmax, int ymax) { F_text *t; int txmin, txmax, tymin, tymax; int dum; for (t = objects.texts; t != NULL; t = t->next) { if (!active_layer(t->depth)) continue; text_bound(t, &txmin, &tymin, &txmax, &tymax, &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum); if (xmin > txmin || xmax < txmax || ymin > tymin || ymax < tymax) continue; t->tagged = 1 - t->tagged; toggle_texthighlight(t); } } static void get_text(F_text **list) { F_text *text, *t, *tt; for (t = objects.texts; t != NULL;) { if (!t->tagged) { tt = t; t = t->next; continue; } remove_depth(O_TXT, t->depth); if (*list == NULL) *list = t; else text->next = t; text = t; if (t == objects.texts) t = objects.texts = objects.texts->next; else t = tt->next = t->next; text->next = NULL; } } static void sel_compound(int xmin, int ymin, int xmax, int ymax) { F_compound *c; for (c = objects.compounds; c != NULL; c = c->next) { if (!any_active_in_compound(c)) continue; if (xmin > c->nwcorner.x) continue; if (xmax < c->secorner.x) continue; if (ymin > c->nwcorner.y) continue; if (ymax < c->secorner.y) continue; c->tagged = 1 - c->tagged; toggle_compoundhighlight(c); } } static void get_compound(F_compound **list) { F_compound *compd, *c, *cc; for (c = objects.compounds; c != NULL;) { if (!c->tagged) { cc = c; c = c->next; continue; } remove_compound_depth(c); if (*list == NULL) *list = c; else compd->next = c; compd = c; if (c == objects.compounds) c = objects.compounds = objects.compounds->next; else c = cc->next = c->next; compd->next = NULL; } } xfig.3.2.5c/e_joinsplit.c0000700002656300244210000005340611641414046016047 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "u_create.h" #include "u_draw.h" #include "u_list.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_modepanel.h" #include "w_zoom.h" #include "e_addpt.h" #include "f_util.h" #include "u_free.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" static void init_join(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void init_split(F_line *obj, int type, int x, int y, int px, int py); static void join_lines(F_line *line, F_point *prev_point, F_point *selected_point); static void join_splines(F_spline *spline, F_point *prev_point, F_point *selected_point); static void split_line(int px, int py); static void split_spline(int px, int py); static void cancel_join(void); static void join_line2(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void join_spline2(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static Boolean connect_line_points(F_line *line1, Boolean first1, F_line *line2, Boolean first2, F_line *new_line); static Boolean connect_spline_points(F_spline *spline1, Boolean first1, F_spline *spline2, Boolean first2, F_spline *new_spline); void draw_join_marker (F_point *point); void split_polygon (F_line *poly, F_line *line, F_point *point); void split_cspline (F_spline *cspline, F_spline *spline, F_point *point, F_sfactor *csf); void join_split_selected(void) { set_mousefun("Join Lines/Splines", "Split Line/Spline", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_join); init_searchproc_middle(init_split); canvas_leftbut_proc = point_search_left; /* point search for join */ canvas_middlebut_proc = object_search_middle; /* object search for split */ canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); /* set the markers to show we only allow POLYLINES and open SPLINES */ /* (the markers are originally set this way from the mode panel, but we need to set them again after the previous join/split */ update_markers(M_POLYLINE | M_SPLINE_O | M_SPLINE_C); reset_action_on(); } static void init_join(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; join_lines(cur_l, p, q); break; case O_SPLINE: cur_s = (F_spline *) obj; join_splines(cur_s, p, q); break; default: return; } } static void init_split(F_line *obj, int type, int x, int y, int px, int py) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; if (cur_l->type == T_PICTURE) { put_msg("Can't remove points from picture"); beep(); return; } split_line(px, py); break; case O_SPLINE: cur_s = (F_spline *) obj; split_spline(px, py); break; } } /************************** join lines or splines *******************************/ static F_line *line1; static F_spline *spline1; static F_point *sel_point; static Boolean first1, first2; static void join_lines(F_line *line, F_point *prev_point, F_point *selected_point) { /* can only join lines (not boxes or polygons) */ if (line->type != T_POLYLINE) return; /* only continue if the user has selected an end point */ if (prev_point != NULL && selected_point->next != NULL) return; init_searchproc_left(join_line2); canvas_leftbut_proc = point_search_left; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_join; line1 = line; sel_point = selected_point; /* set flag if this is the first point of the line */ first1 = (prev_point == NULL); set_mousefun("Choose next Line", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); draw_join_marker(sel_point); /* only want lines now */ update_markers(M_POLYLINE_LINE); } static void join_splines(F_spline *spline, F_point *prev_point, F_point *selected_point) { /* can only join open splines */ if (spline->type & 1) return; /* only continue if the user has selected an end point */ if (prev_point != NULL && prev_point != spline->points && selected_point->next != NULL) return; init_searchproc_left(join_spline2); canvas_leftbut_proc = point_search_left; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = cancel_join; /* save pointer to first line and its points */ spline1 = spline; sel_point = selected_point; /* set flag if this is the first point of the spline */ first1 = (selected_point == spline->points); set_mousefun("Choose next Spline", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); draw_join_marker(sel_point); /* only want open splines now */ update_markers(M_SPLINE_O); } void draw_join_marker(F_point *point) { int x=ZOOMX(point->x), y=ZOOMY(point->y); pw_vector(canvas_win, x-10, y-10, x-10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x-10, y+10, x+10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y+10, x+10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y-10, x-10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); } void erase_join_marker(F_point *point) { int x=ZOOMX(point->x), y=ZOOMY(point->y); if (point) { pw_vector(canvas_win, x-10, y-10, x-10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x-10, y+10, x+10, y+10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y+10, x+10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); pw_vector(canvas_win, x+10, y-10, x-10, y-10, INV_PAINT,1,PANEL_LINE,0.0,MAGENTA); } point = NULL; } static void cancel_join(void) { join_split_selected(); /* erase any marker */ erase_join_marker(sel_point); draw_mousefun_canvas(); } static void join_line2(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { F_line *line; F_point *lastp; if (type != O_POLYLINE) return; /* only continue if the user has selected an end point */ if (p != NULL && q->next != NULL) return; line = (F_line *) obj; first2 = (p == NULL); /* if user clicked on same point twice return */ if (line == line1 && first1 == first2) return; new_l = copy_line(line1); /* if user clicked on both endpoints of a line, make it a POLYGON */ if (line == line1 && first1 != first2) { new_l->type = T_POLYGON; lastp = last_point(new_l->points); append_point(new_l->points->x, new_l->points->y, &lastp); } else if (!connect_line_points(line1, first1, line, first2, new_l)) { free(new_l); return; } clean_up(); /* erase marker */ erase_join_marker(sel_point); /* delete old ones from the main list */ if (line != line1) list_delete_line(&objects.lines, line1); list_delete_line(&objects.lines, line); /* put them in the saved list */ if (line != line1) list_add_line(&saved_objects.lines, line1); list_add_line(&saved_objects.lines, line); /* and add the new one in */ list_add_line(&objects.lines, new_l); set_action_object(F_JOIN, O_POLYLINE); /* save pointer to this line for undo */ latest_line = new_l; redisplay_line(new_l); /* start over */ join_split_selected(); } static void join_spline2(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { F_spline *spline; if (type != O_SPLINE) return; /* only continue if the user has selected an end point */ if (p != NULL && q->next != NULL) return; spline = (F_spline *) obj; first2 = (q == obj->points); new_s = copy_spline(spline1); /* if user clicked on both endpoints of a spline, make it a closed SPLINE */ if (spline == spline1) { /* to make a closed spline from an open one, add one to the type */ /* no need to duplicate the first point at the end */ new_s->type++; /* set sfactors of old endpoints to sfactor of second point in spline */ new_s->sfactors->s = new_s->sfactors->next->s; last_sfactor(new_s->sfactors)->s = new_s->sfactors->s; } else if (!connect_spline_points(spline1, first1, spline, first2, new_s)) { free(new_s); return; } clean_up(); /* erase marker */ erase_join_marker(sel_point); /* delete them from the main list */ if (spline != spline1) list_delete_spline(&objects.splines, spline1); list_delete_spline(&objects.splines, spline); /* put them in the saved list */ if (spline != spline1) list_add_spline(&saved_objects.splines, spline1); list_add_spline(&saved_objects.splines, spline); /* and add the new one in */ list_add_spline(&objects.splines, new_s); set_action_object(F_JOIN, O_SPLINE); /* save pointer to this spline for undo */ latest_spline = new_s; redisplay_spline(new_s); /* start over */ join_split_selected(); } /* Connect the points from line1 and line2 in the order determined by first1 and first2, which signify whether user clicked on first point of respective line. new_line must already have a copy of line1. */ static Boolean connect_line_points(F_line *line1, Boolean first1, F_line *line2, Boolean first2, F_line *new_line) { F_point *p1,*p2; if (first1 && first2) { /* user clicked on both first points */ /* reverse order of points in first line */ reverse_points(new_line->points); /* then attach points of second line */ p1 = last_point(new_line->points); if ((p1->next = copy_points(line2->points)) == NULL) return False; } else if (first1 == False && first2) { /* user clicked on endpoint of line 1 and first point of line 2 */ /* find the end point of the new points, which is a copy of the first line */ p1 = last_point(new_line->points); if ((p1->next = copy_points(line2->points)) == NULL) return False; } else if (first1 && first2 == False) { /* user clicked on first point of line 1 and endpoint of line 2 */ /* reverse order of points in first line */ reverse_points(new_line->points); /* make copy of points in second line */ if ((p2 = copy_points(line2->points)) == NULL) return False; /* reverse them */ reverse_points(p2); /* and attach to end of first */ p1 = last_point(new_line->points); p1->next = p2; } else { /* user clicked on both end points */ /* make copy of points in second line */ if ((p2 = copy_points(line2->points)) == NULL) return False; /* reverse them */ reverse_points(p2); /* and attach to end of first */ p1 = last_point(new_line->points); p1->next = p2; } return True; } /* Connect the points from spline1 and spline2 in the order determined by first1 and first2, which signify whether user clicked on first point of respective spline. new_spline must already have a copy of spline1. */ static Boolean connect_spline_points(F_spline *spline1, Boolean first1, F_spline *spline2, Boolean first2, F_spline *new_spline) { F_point *p1, *p2; F_sfactor *sf1, *sf2; if (first1 && first2) { /* user clicked on both first points */ /* reverse order of points in first spline */ reverse_points(new_spline->points); /* and the spline factors */ reverse_sfactors(new_spline->sfactors); /* then attach points of second spline */ p1 = last_point(new_spline->points); if ((p1->next = copy_points(spline2->points)) == NULL) return False; /* don't forget sfactors */ sf1 = last_sfactor(new_spline->sfactors); if ((sf1->next = copy_sfactors(spline2->sfactors)) == NULL) return False; } else if (first1 == False && first2) { /* user clicked on endpoint of spline 1 and first point of spline 2 */ /* find the end point of the new points, which is a copy of the first spline */ p1 = last_point(new_spline->points); if ((p1->next = copy_points(spline2->points)) == NULL) return False; /* don't forget sfactors */ sf1 = last_sfactor(new_spline->sfactors); if ((sf1->next = copy_sfactors(spline2->sfactors)) == NULL) return False; } else if (first1 && first2 == False) { /* user clicked on first point of spline 1 and endpoint of spline 2 */ /* reverse order of points in first spline */ reverse_points(new_spline->points); /* and the spline factors */ reverse_sfactors(new_spline->sfactors); /* make copy of points in second spline */ if ((p2 = copy_points(spline2->points)) == NULL) return False; /* and sfactors */ if ((sf2 = copy_sfactors(spline2->sfactors)) == NULL) return False; /* reverse them */ reverse_points(p2); /* and the spline factors */ reverse_sfactors(sf2); /* and attach to end of first */ p1 = last_point(new_spline->points); p1->next = p2; /* and sfactors */ sf1 = last_sfactor(new_spline->sfactors); sf1->next = sf2; } else { /* user clicked on both end points */ /* make copy of points in second spline */ if ((p2 = copy_points(spline2->points)) == NULL) return False; /* and sfactors */ if ((sf2 = copy_sfactors(spline2->sfactors)) == NULL) return False; /* reverse them */ reverse_points(p2); /* and the spline factors */ reverse_sfactors(sf2); /* and attach to end of first */ p1 = last_point(new_spline->points); p1->next = p2; /* and sfactors */ sf1 = last_sfactor(new_spline->sfactors); sf1->next = sf2; } return True; } /************************** split line or spline *******************************/ static void split_line(int px, int py) { F_point *p; F_line *new_l1, *new_l2, *save_l; F_point *left_point, *right_point; find_endpoints(cur_l->points, px, py, &left_point, &right_point); if (cur_l->points->next == NULL) return; /* A single point line - that would be tough to split */ if (cur_l->type != T_POLYGON && cur_l->type != T_BOX && cur_l->type != T_ARCBOX) { if (left_point == NULL) /* selected_point is the first point */ return; else if (right_point == NULL) /* last point */ return; } /* copy original */ new_l1 = copy_line(cur_l); /* keep copy of original */ save_l = copy_line(cur_l); /* remove original line from the objects */ delete_line(cur_l); if (cur_l->type == T_POLYGON || cur_l->type == T_BOX || cur_l->type == T_ARCBOX) { /* change polygon or box to polyline */ /* search original for point */ if (left_point == NULL) { /* if first point, start at second */ p = cur_l->points->next; } else if (right_point == NULL) { /* if last point, start at first */ p = cur_l->points; } else { /* somewhere in the middle */ p = search_line_point(cur_l, left_point->x, left_point->y); p = p->next; } split_polygon(cur_l, new_l1, p); clean_up(); list_add_line(&objects.lines,new_l1); } else { /* split one polyline into two */ /* find the breakpoint in the line */ p = search_line_point(new_l1, left_point->x, left_point->y); new_l2 = copy_line(cur_l); free_points(new_l2->points); /* attach right side to new line 2 */ new_l2->points = p->next; /* and unlink that from new line 1 */ p->next = NULL; clean_up(); list_add_line(&objects.lines,new_l1); list_add_line(&objects.lines,new_l2); } set_modifiedflag(); /* save pointer to this(these) line(s) for undo */ latest_line = new_l1; /* put the original line in the saved lines list for undo */ saved_objects.lines = save_l; set_action_object(F_SPLIT, O_POLYLINE); /* refresh area where original line was. This is the bounding area of both new lines */ redisplay_line(save_l); /* turn back on all relevant markers */ update_markers(new_objmask); join_split_selected(); } /* turn polygon or box "poly" into polyline "line" by breaking at point "point" */ void split_polygon(F_line *poly, F_line *line, F_point *point) { F_point *splitp, *p, *q; /* we'll just copy the points from poly (the original) into line starting at point, until we hit the end of the points, then copy the points from the beginning of poly till we hit the original split point */ p = line->points; splitp = point; /* don't copy the last point because it is just a duplicate of the first */ while (point->next) { p->x = point->x; p->y = point->y; q = p; /* save pointer to current point for removing later */ p = p->next; point = point->next; } /* now do points from beginning of poly */ point = poly->points; while (point != splitp) { p->x = point->x; p->y = point->y; q = p; /* save pointer to current point for removing later */ p = p->next; point = point->next; } /* free last point from new line because we don't need it in a POLYLINE */ free_points(p); /* and disconnect it from the list */ q->next = NULL; /* last, make it a POLYLINE */ line->type = T_POLYLINE; } static void split_spline(int px, int py) { F_spline *new_spl1, *new_spl2, *save_spl; F_point *p, *cp, *left_point, *right_point; F_sfactor *sf, *csf; find_endpoints(cur_s->points, px, py, &left_point, &right_point); if ((cur_s->type & 1) == 0) { /* open spline - don't allow splitting into a spline with only one point */ if (left_point == NULL || left_point == cur_s->points || /* first point */ (right_point == NULL || right_point->next == NULL)) { /* last, OR only one point to the left */ put_msg("Cutting there would result in a spline with only one point"); beep(); return; } } /* make copy of original */ new_spl1 = copy_spline(cur_s); /* find the breakpoint in the spline */ p = new_spl1->points; sf = new_spl1->sfactors; cp = cur_s->points; csf = cur_s->sfactors; /* first point, set pointers to second point */ if (left_point == NULL && right_point != NULL) { p = new_spl1->points->next; sf = new_spl1->sfactors->next; cp = cur_s->points->next; csf = cur_s->sfactors->next; /* if not the last point, search */ } else if (right_point != NULL) { /* locate the sfactors (can't use search_sfactor() because it looks at the pointer values, which won't match because we're looking in the copy */ /* this will locate the break point itself too */ while (p->x != left_point->x || p->y != left_point->y) { p = p->next; sf = sf->next; cp = cp->next; csf = csf->next; /* sfactors are in same order in both copies */ } if ((cur_s->type & 1) == 1) { /* and advance to next if closed spline */ p = p->next; sf = sf->next; cp = cp->next; csf = csf->next; } } /* keep copy of original */ save_spl = copy_spline(cur_s); /* remove original spline from the objects */ delete_spline(cur_s); if ((cur_s->type & 1) == 1) { /* turn closed spline into open */ split_cspline(cur_s, new_spl1, cp, csf); clean_up(); list_add_spline(&objects.splines,new_spl1); } else { /* make two splines from one - make another copy */ new_spl2 = copy_spline(cur_s); free_points(new_spl2->points); free_sfactors(new_spl2->sfactors); /* attach right side to new spline 2 */ new_spl2->points = p->next; new_spl2->sfactors = sf->next; /* make new endpoint have sfactor 0.0 (sharp) */ new_spl2->sfactors->s = 0.0; /* and unlink that from new spline 1 */ p->next = NULL; sf->next = NULL; /* make this new endpoint have sfactor 0.0 (sharp) */ sf->s = 0.0; clean_up(); list_add_spline(&objects.splines,new_spl1); list_add_spline(&objects.splines,new_spl2); } set_modifiedflag(); /* save pointer to these splines for undo */ latest_spline = new_spl1; /* put the original spline in the saved splines list for undo */ saved_objects.splines = save_spl; set_action_object(F_SPLIT, O_SPLINE); /* refresh area where original spline was. This is the bounding area of both new splines */ redisplay_spline(save_spl); /* turn back on all relevant markers */ update_markers(new_objmask); join_split_selected(); } /* turn closed spline "cspline" open spline "spline" by breaking at point "point" */ void split_cspline(F_spline *cspline, F_spline *spline, F_point *point, F_sfactor *csf) { F_point *splitp, *p; F_sfactor *sf; /* we'll just copy the points (and sfactors) from cspline (the original) into spline starting at point, until we hit the end of the points, then copy the points from the beginning of cspline till we hit the original split point */ /* save split point */ splitp = point; sf = spline->sfactors; p = spline->points; while (point) { p->x = point->x; p->y = point->y; sf->s = csf->s; if (point == splitp) /* set sfactor on first point to 0.0 */ sf->s = 0.0; if (point->next == NULL && splitp == cspline->points) /* set sfactor on last point to 0.0 if next loop is not done */ sf->s = 0.0; p = p->next; point = point->next; sf = sf->next; csf = csf->next; } /* now do points from beginning of cspline */ point = cspline->points; csf = cspline->sfactors; while (point != splitp) { p->x = point->x; p->y = point->y; sf->s = csf->s; if (point->next == splitp) /* set sfactor on endpoint to 0.0 */ sf->s = 0.0; p = p->next; point = point->next; sf = sf->next; csf = csf->next; } /* last, make it a OPEN spline (closed are odd, open are even) */ spline->type--; } xfig.3.2.5c/e_measure.c0000700002656300244210000003057211641414046015474 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * This part Copyright (c) 1999-2002 Alexander Durner * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "u_search.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "u_geom.h" #include "u_markers.h" #include "w_cursor.h" #include "w_drawprim.h" #include "w_indpanel.h" /* Measuring angles, lengths and areas */ static void init_anglemeas_object(char *p, int type, int x, int y, F_point *pp, F_point *pq); static void init_anglemeas_object_m(char *p, int type, int x, int y, F_point *pp, F_point *pq); static void init_anglemeas_object_r(char *p, int type, int x, int y, F_point *pp, F_point *pq); static void init_anglemeas_threepoints(int px, int py); static void anglemeas_second(int x, int y); static void anglemeas_third(int x, int y); static void anglemeas_third_l(int x, int y); static void anglemeas_third_m(int x, int y); static void cancel_anglemeas(void); static void anglemeas_line(F_line *l, F_point *p); static void anglemeas_arc(F_arc *a); static void angle_msg(double value, char *msgtext); static void angle_save(double value); static void init_lenmeas_object(char *p, int type, int x, int y, int px, int py); static void init_lenmeas_object_l(char *p, int type, int x, int y, int px, int py); static void init_lenmeas_object_m(char *p, int type, int x, int y, int px, int py); static void clear_lenmeas_memory(void); static void init_areameas_object(char *p, int type, int x, int y, int px, int py); static void init_areameas_object_l(char *p, int type, int x, int y, int px, int py); static void init_areameas_object_m(char *p, int type, int x, int y, int px, int py); static void clear_areameas_memory(int x, int y, int arg); static void freehand_line_nomsg(int x, int y); static F_point pa, pb, pc; static int np; static int save_objmask; static int save_rotnangle; static int save_len; static float total_len = 0.0; static int save_area; static int signed_area = 0; static float total_area = 0.0; /*************************************************************************** ANGLE MEASURING ***************************************************************************/ void anglemeas_selected(void) { set_mousefun("first point", "select & save", "select object", "", LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_middle(init_anglemeas_object_m); init_searchproc_right(init_anglemeas_object_r); canvas_leftbut_proc = init_anglemeas_threepoints; canvas_middlebut_proc = point_search_middle; canvas_rightbut_proc = point_search_right; set_cursor(pick9_cursor); reset_action_on(); } static void angle_msg(double value, char *msgtext) { put_msg("%s%.2f Degrees", msgtext, value*180.0/M_PI); } static void angle_save(double value) { float degr; if (!save_rotnangle) return; degr = (float)fabs(value*180.0/M_PI); if (degr > 180.0) degr = 360.0 - degr; set_and_show_rotnangle(degr); } /* OBJECT ANGLE MEASURING */ static void init_anglemeas_object_m(char *p, int type, int x, int y, F_point *pp, F_point *pq) { save_rotnangle = 1; init_anglemeas_object(p, type, x, y, pp, pq); } static void init_anglemeas_object_r(char *p, int type, int x, int y, F_point *pp, F_point *pq) { save_rotnangle = 0; init_anglemeas_object(p, type, x, y, pp, pq); } static void init_anglemeas_object(char *p, int type, int x, int y, F_point *pp, F_point *pq) { switch(type) { case O_POLYLINE: cur_l = (F_line*)p; anglemeas_line(cur_l, pq); /* do_point_search returns `near' point in *q */ break; case O_ARC: cur_a = (F_arc*)p; anglemeas_arc(cur_a); /* point doesn't matter */ break; default: return; } } /* line angle */ static void anglemeas_line(F_line *l, F_point *p) { double lineangle; if (compute_line_angle(l, p, &lineangle)) { /* lineangle in 0..2*PI */ if (lineangle > M_PI) lineangle -= 2*M_PI; angle_msg(lineangle, "Angle at polyline corner: "); angle_save(lineangle); } else put_msg("Can't compute angle at endpoint"); } /* arc angle */ static void anglemeas_arc(F_arc *a) { double dang; if (compute_arc_angle(a, &dang)) { angle_msg(dang, "Angle at arc center: "); angle_save(dang); } else put_msg("Can't compute angle"); } /* THREE-POINT ANGLE MEASURING */ static void init_anglemeas_threepoints(int px, int py) { set_cursor(arrow_cursor); set_mousefun("angle tip", "", "cancel", "", "", LOC_OBJ); draw_mousefun_canvas(); canvas_rightbut_proc = cancel_anglemeas; pa.x = fix_x = cur_x = px; pa.y = fix_y = cur_y = py; np = 1; canvas_locmove_proc = freehand_line_nomsg; canvas_ref_proc = elastic_line; canvas_leftbut_proc = anglemeas_second; canvas_middlebut_proc = null_proc; elastic_line(); set_temp_cursor(null_cursor); save_objmask = cur_objmask; update_markers(M_NONE); set_action_on(); } static void anglemeas_second(int x, int y) { if (x == fix_x && y == fix_y) return; if (np == 1) { /* should always be! */ set_mousefun("final point","save angle","cancel", "", "", ""); draw_mousefun_canvas(); canvas_leftbut_proc = anglemeas_third_l; canvas_middlebut_proc = anglemeas_third_m; } elastic_line(); cur_x = x; cur_y = y; elastic_line(); pb.x = fix_x = x; pb.y = fix_y = y; np = 2; elastic_line(); } static void anglemeas_third_l(int x, int y) { save_rotnangle = 0; anglemeas_third(x, y); } static void anglemeas_third_m(int x, int y) { save_rotnangle = 1; anglemeas_third(x, y); } static void anglemeas_third(int x, int y) { double uangle; if (x == fix_x && y == fix_y) return; elastic_line(); pc.x = cur_x = x; pc.y = cur_y = y; elastic_line(); /* erase? */ pw_vector(canvas_win, pa.x, pa.y, pb.x, pb.y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); pw_vector(canvas_win, pb.x, pb.y, pc.x, pc.y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT); if (compute_3p_angle(&pa, &pb, &pc, &uangle)) { if (uangle > M_PI) uangle -= 2*M_PI; angle_msg(uangle, "Angle defined by three points: "); angle_save(uangle); } else put_msg("Can't compute angle"); update_markers(save_objmask); anglemeas_selected(); draw_mousefun_canvas(); } static void cancel_anglemeas(void) { elastic_line(); if (np == 2) { /* erase initial part of line */ cur_x = pa.x; cur_y = pa.y; elastic_line(); } update_markers(save_objmask); anglemeas_selected(); draw_mousefun_canvas(); } static void freehand_line_nomsg(int x, int y) { elastic_line(); cur_x = x; cur_y = y; elastic_line(); } /*************************************************************************** LENGTH MEASURING ***************************************************************************/ void lenmeas_selected(void) { set_mousefun("select object", "select & add", "reset to 0", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_lenmeas_object_l); init_searchproc_middle(init_lenmeas_object_m); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = clear_lenmeas_memory; set_cursor(pick9_cursor); /* force_nopositioning(); */ reset_action_on(); } static void init_lenmeas_object(char *p, int type, int x, int y, int px, int py) { float len; double a,b,z; int ok; char *msgtext; ok = 0; switch (type) { case O_POLYLINE: cur_l = (F_line*) p; (void) compute_poly_length(cur_l, &len); if (cur_l->type == T_BOX || cur_l->type == T_PICTURE) msgtext = "box"; else if (cur_l->type == T_ARCBOX) { msgtext = "arcbox"; /* subtract radius corners */ len -= M_PI * cur_l->radius*2.0*ZOOM_FACTOR; } else if (cur_l->type == T_POLYGON) msgtext = "polygon"; else msgtext = "polyline"; ok = 1; break; case O_ARC: cur_a = (F_arc*) p; if (compute_arc_length(cur_a, &len)) { msgtext = "arc"; ok = 1; } break; case O_ELLIPSE: cur_e = (F_ellipse*) p; /* ellipse or circle? */ if (cur_e->radiuses.x == cur_e->radiuses.y) { msgtext = "circle"; len = M_PI * cur_e->radiuses.x * 2.0; } else { msgtext = "ellipse"; /* from The Math Forum (mathforum.org) */ a = cur_e->radiuses.x; b = cur_e->radiuses.y; z = (a-b)/(a+b); len = M_PI * (a+b)*(1.0 + 3.0*z*z/(10.0 + sqrt(4.0-3.0*z*z))); } ok = 1; break; default: break; } if (ok) { if (save_len) { total_len += len; lenmeas_msg(msgtext, len, total_len); } else lenmeas_msg(msgtext, len, -1.0); } else put_msg("Sorry, can't measure length of this object"); } static void init_lenmeas_object_l(char *p, int type, int x, int y, int px, int py) { save_len = 0; init_lenmeas_object(p, type, x, y, px, py); } static void init_lenmeas_object_m(char *p, int type, int x, int y, int px, int py) { save_len = 1; init_lenmeas_object(p, type, x, y, px, py); } static void clear_lenmeas_memory(void) { total_len = 0.0; put_msg("length reset to 0"); } /*************************************************************************** AREA MEASURING ***************************************************************************/ void areameas_selected(void) { set_mousefun("select object", "select & add", "reset to 0", LOC_OBJ, LOC_OBJ, "reset to +-0"); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_areameas_object_l); init_searchproc_middle(init_areameas_object_m); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = clear_areameas_memory; set_cursor(pick9_cursor); /* force_nopositioning(); */ reset_action_on(); } static void init_areameas_object(char *p, int type, int x, int y, int px, int py) { float area; int ok; char *msgtext; ok = 0; switch (type) { case O_POLYLINE: cur_l = (F_line*) p; if (1) { compute_poly_area(cur_l, &area); if (cur_l->type == T_BOX) msgtext = "box"; else if (cur_l->type == T_ARCBOX) { /* subtract radius corners from area */ area -= M_PI*(cur_l->radius*cur_l->radius*ZOOM_FACTOR*ZOOM_FACTOR); msgtext = "arcbox"; } else { msgtext = "polygon"; } ok = 1; } break; case O_ARC: cur_a = (F_arc*) p; if (compute_arc_area(cur_a, &area)) { if (cur_a->type == T_OPEN_ARC) msgtext = "open arc"; else msgtext = "sector"; ok = 1; } break; case O_ELLIPSE: cur_e = (F_ellipse*) p; if (compute_ellipse_area(cur_e, &area)) { msgtext = "ellipse"; ok = 1; } break; default: break; } if (ok) { if (!signed_area) area = fabs(area); if (save_area) { total_area += area; areameas_msg(msgtext, area, total_area, 1); } else areameas_msg(msgtext, area, -1.0, 0); } else put_msg("Sorry, can't measure area of this object"); } static void init_areameas_object_l(char *p, int type, int x, int y, int px, int py) { save_area = 0; init_areameas_object(p, type, x, y, px, py); } static void init_areameas_object_m(char *p, int type, int x, int y, int px, int py) { save_area = 1; init_areameas_object(p, type, x, y, px, py); } static void clear_areameas_memory(int x, int y, int arg) { total_area = 0.0; signed_area = (arg != 0); if (signed_area) put_msg("signed area reset to 0"); else put_msg("area reset to 0"); } xfig.3.2.5c/e_move.c0000700002656300244210000000746111641414046015002 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "paintop.h" #include "u_drag.h" #include "u_draw.h" #include "u_elastic.h" #include "u_list.h" #include "u_search.h" #include "w_canvas.h" #include "w_mousefun.h" #include "mode.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" static void init_move(F_line *p, int type, int x, int y, int px, int py), init_arb_move(F_line *p, int type, int x, int y, int px, int py), init_constrained_move(F_line *p, int type, int x, int y, int px, int py); void move_selected(void) { set_mousefun("move object", "horiz/vert move", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; init_searchproc_left(init_arb_move); init_searchproc_middle(init_constrained_move); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = null_proc; return_proc = move_selected; set_cursor(pick9_cursor); reset_action_on(); } static void init_arb_move(F_line *p, int type, int x, int y, int px, int py) { constrained = MOVE_ARB; init_move(p, type, x, y, px, py); canvas_middlebut_proc = null_proc; set_mousefun("place object", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); } static void init_constrained_move(F_line *p, int type, int x, int y, int px, int py) { constrained = MOVE_HORIZ_VERT; init_move(p, type, x, y, px, py); canvas_middlebut_proc = canvas_leftbut_proc; canvas_leftbut_proc = null_proc; set_mousefun("", "place object", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); } static void init_move(F_line *p, int type, int x, int y, int px, int py) { /* turn off all markers */ update_markers(0); switch (type) { case O_COMPOUND: set_cursor(wait_cursor); cur_c = (F_compound *) p; list_delete_compound(&objects.compounds, cur_c); redisplay_compound(cur_c); set_cursor(null_cursor); init_compounddragging(cur_c, px, py); break; case O_POLYLINE: set_cursor(wait_cursor); cur_l = (F_line *) p; list_delete_line(&objects.lines, cur_l); redisplay_line(cur_l); set_cursor(null_cursor); init_linedragging(cur_l, px, py); break; case O_TXT: set_cursor(wait_cursor); cur_t = (F_text *) p; list_delete_text(&objects.texts, cur_t); redisplay_text(cur_t); set_cursor(null_cursor); init_textdragging(cur_t, x, y); break; case O_ELLIPSE: set_cursor(wait_cursor); cur_e = (F_ellipse *) p; list_delete_ellipse(&objects.ellipses, cur_e); redisplay_ellipse(cur_e); set_cursor(null_cursor); init_ellipsedragging(cur_e, px, py); break; case O_ARC: set_cursor(wait_cursor); cur_a = (F_arc *) p; list_delete_arc(&objects.arcs, cur_a); redisplay_arc(cur_a); set_cursor(null_cursor); init_arcdragging(cur_a, px, py); break; case O_SPLINE: set_cursor(wait_cursor); cur_s = (F_spline *) p; list_delete_spline(&objects.splines, cur_s); redisplay_spline(cur_s); set_cursor(null_cursor); init_splinedragging(cur_s, px, py); break; default: return; } } xfig.3.2.5c/e_movept.c0000700002656300244210000005545511641414046015354 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_scale.h" #include "u_draw.h" #include "u_search.h" #include "u_create.h" #include "u_elastic.h" #include "u_list.h" #include "u_markers.h" #include "u_undo.h" #include "w_canvas.h" #include "w_modepanel.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "f_util.h" #include "u_geom.h" #include "u_redraw.h" #include "w_cursor.h" /* local routine declarations */ static F_point *moved_point; static void fix_movedcompoundpoint(int x, int y); static void cancel_compound(void); static Boolean init_ellipsepointmoving(void); static void init_arcpointmoving(void); static void init_linepointmoving(void); static void init_splinepointmoving(void); static void init_compoundpointmoving(void); static void relocate_arcpoint(F_arc *arc, int x, int y, int movedpoint_num); static void relocate_ellipsepoint(F_ellipse *ellipse, int x, int y, int point_num); static void relocate_linepoint(F_line *line, int x, int y, F_point *moved_point, F_point *left_point); static void relocate_splinepoint(F_spline *s, int x, int y, F_point *moved_point); static Boolean init_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void init_arb_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void init_stretch_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q); static void fix_movedarcpoint(int x, int y); static void fix_movedellipsepoint(int x, int y); static void fix_movedsplinepoint(int x, int y); static void fix_box(int x, int y); static void fix_movedlinepoint(int x, int y); static void cancel_movedarcpoint(void); static void cancel_movedellipsepoint(void); static void cancel_movedsplinepoint(void); static void cancel_movept_box(void); static void cancel_movedlinepoint(void); void assign_newboxpoint (F_line *b, int x1, int y1, int x2, int y2); void move_point_selected(void) { set_mousefun("move point", "horiz/vert move", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_arb_move_point); init_searchproc_middle(init_stretch_move_point); canvas_leftbut_proc = point_search_left; canvas_middlebut_proc = point_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); force_anglegeom(); reset_action_on(); } static void init_arb_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { constrained = MOVE_ARB; if (!init_move_point(obj, type, x, y, p, q)) return; set_mousefun("new posn", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_middlebut_proc = null_proc; } static void init_stretch_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { constrained = MOVE_HORIZ_VERT; if (!init_move_point(obj, type, x, y, p, q)) return; set_mousefun("", "new posn", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_middlebut_proc = canvas_leftbut_proc; canvas_leftbut_proc = null_proc; } static Boolean init_move_point(F_line *obj, int type, int x, int y, F_point *p, F_point *q) { left_point = p; moved_point = q; switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; right_point = q->next; init_linepointmoving(); break; case O_SPLINE: cur_s = (F_spline *) obj; right_point = q->next; init_splinepointmoving(); break; case O_ELLIPSE: force_noanglegeom(); /* dirty trick - arcpoint_num is stored in p */ movedpoint_num = (intptr_t) p; cur_e = (F_ellipse *) obj; if (!init_ellipsepointmoving()) /* selected center, ignore */ return False; break; case O_ARC: force_noanglegeom(); /* dirty trick - arcpoint_num is stored in p */ movedpoint_num = (intptr_t) p; cur_a = (F_arc *) obj; init_arcpointmoving(); break; case O_COMPOUND: force_noanglegeom(); /* dirty trick - posn of corner is stored in p and q */ cur_x = (int) p; cur_y = (int) q; cur_c = (F_compound *) obj; init_compoundpointmoving(); break; default: return False; } return True; } static void wrapup_movepoint(void) { reset_action_on(); move_point_selected(); draw_mousefun_canvas(); } /************************* ellipse *******************************/ static Boolean init_ellipsepointmoving(void) { double dx, dy, l; if (constrained && (cur_e->type == T_CIRCLE_BY_DIA || cur_e->type == T_CIRCLE_BY_RAD)) { put_msg("Constrained move not supported for CIRCLES"); return False; /* abort - constrained move for circle not allowed */ } if (movedpoint_num == 0) { if (cur_e->type == T_ELLIPSE_BY_RAD || cur_e->type == T_CIRCLE_BY_RAD) { put_msg("Cannot move CENTER point"); return False; /* abort - center point is selected */ } cur_x = cur_e->start.x; cur_y = cur_e->start.y; fix_x = cur_e->end.x; fix_y = cur_e->end.y; } else { cur_x = cur_e->end.x; cur_y = cur_e->end.y; fix_x = cur_e->start.x; fix_y = cur_e->start.y; } if (constrained) { dx = cur_x - fix_x; dy = cur_y - fix_y; l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); } cur_angle = cur_e->angle; set_action_on(); /* turn off all markers */ update_markers(0); switch (cur_e->type) { case T_ELLIPSE_BY_RAD: canvas_locmove_proc = constrained_resizing_ebr; canvas_ref_proc = elastic_ebr; break; case T_CIRCLE_BY_RAD: canvas_locmove_proc = resizing_cbr; canvas_ref_proc = elastic_cbr; break; case T_ELLIPSE_BY_DIA: canvas_locmove_proc = constrained_resizing_ebd; canvas_ref_proc = elastic_ebd; break; case T_CIRCLE_BY_DIA: canvas_locmove_proc = resizing_cbd; canvas_ref_proc = elastic_cbd; break; } /* show current radius(ii) */ (canvas_locmove_proc)(cur_x, cur_y); from_x = cur_x; from_y = cur_y; set_cursor(crosshair_cursor); canvas_leftbut_proc = fix_movedellipsepoint; canvas_rightbut_proc = cancel_movedellipsepoint; return True; } static void cancel_movedellipsepoint(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; /* erase elastic version */ switch (cur_e->type) { case T_ELLIPSE_BY_RAD: elastic_ebr(); break; case T_CIRCLE_BY_RAD: elastic_cbr(); break; case T_ELLIPSE_BY_DIA: elastic_ebd(); break; case T_CIRCLE_BY_DIA: elastic_cbd(); break; } /* redraw original ellipse */ redisplay_ellipse(cur_e); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_movedellipsepoint(int x, int y) { switch (cur_e->type) { case T_ELLIPSE_BY_RAD: elastic_ebr(); break; case T_CIRCLE_BY_RAD: elastic_cbr(); break; case T_ELLIPSE_BY_DIA: elastic_ebd(); break; case T_CIRCLE_BY_DIA: elastic_cbd(); break; } canvas_ref_proc = canvas_locmove_proc = null_proc; adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y); new_e = copy_ellipse(cur_e); relocate_ellipsepoint(new_e, cur_x, cur_y, movedpoint_num); change_ellipse(cur_e, new_e); /* redraw anything under the old ellipse */ redisplay_ellipse(cur_e); /* and the new one */ redisplay_ellipse(new_e); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void relocate_ellipsepoint(F_ellipse *ellipse, int x, int y, int point_num) { double dx, dy; set_temp_cursor(wait_cursor); if (point_num == 0) { /* starting point is selected */ fix_x = ellipse->end.x; fix_y = ellipse->end.y; /* don't allow coincident start/end points */ if (ellipse->end.x == x && ellipse->end.y == y) return; ellipse->start.x = x; ellipse->start.y = y; } else { fix_x = ellipse->start.x; fix_y = ellipse->start.y; /* don't allow coincident start/end points */ if (ellipse->start.x == x && ellipse->start.y == y) return; ellipse->end.x = x; ellipse->end.y = y; } cur_angle = ellipse->angle; switch (ellipse->type) { case T_ELLIPSE_BY_RAD: ellipse->radiuses.x = abs(x - fix_x); ellipse->radiuses.y = abs(y - fix_y); break; case T_CIRCLE_BY_RAD: dx = fix_x - x; dy = fix_y - y; ellipse->radiuses.x = round(sqrt(dx * dx + dy * dy)); ellipse->radiuses.y = ellipse->radiuses.x; break; case T_ELLIPSE_BY_DIA: ellipse->center.x = (fix_x + x) / 2; ellipse->center.y = (fix_y + y) / 2; ellipse->radiuses.x = abs(ellipse->center.x - fix_x); ellipse->radiuses.y = abs(ellipse->center.y - fix_y); break; case T_CIRCLE_BY_DIA: dx = ellipse->center.x = round((fix_x + x) / 2); dy = ellipse->center.y = round((fix_y + y) / 2); dx -= x; dy -= y; ellipse->radiuses.x = round(sqrt(dx * dx + dy * dy)); ellipse->radiuses.y = ellipse->radiuses.x; break; } reset_cursor(); } /*************************** arc *********************************/ static void init_arcpointmoving(void) { set_action_on(); /* turn off all markers */ update_markers(0); cur_x = cur_a->point[movedpoint_num].x; cur_y = cur_a->point[movedpoint_num].y; set_cursor(crosshair_cursor); canvas_locmove_proc = reshaping_arc; canvas_ref_proc = elastic_arclink; canvas_leftbut_proc = fix_movedarcpoint; canvas_rightbut_proc = cancel_movedarcpoint; elastic_arclink(); /* show current length(s) */ (canvas_locmove_proc)(cur_x, cur_y); } static void cancel_movedarcpoint(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_arclink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_movedarcpoint(int x, int y) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_arclink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_pos(x, y, cur_a->point[movedpoint_num].x, cur_a->point[movedpoint_num].y, &x, &y); new_a = copy_arc(cur_a); relocate_arcpoint(new_a, x, y, movedpoint_num); change_arc(cur_a, new_a); /* redraw anything under the old arc */ redisplay_arc(cur_a); /* and the new one */ redisplay_arc(new_a); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void relocate_arcpoint(F_arc *arc, int x, int y, int movedpoint_num) { float xx, yy; F_pos p[3]; p[0] = arc->point[0]; p[1] = arc->point[1]; p[2] = arc->point[2]; p[movedpoint_num].x = x; p[movedpoint_num].y = y; if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) { arc->point[movedpoint_num].x = x; arc->point[movedpoint_num].y = y; arc->center.x = xx; arc->center.y = yy; arc->direction = compute_direction(p[0], p[1], p[2]); } } /************************** spline *******************************/ static void init_splinepointmoving(void) { set_action_on(); /* turn off all markers */ update_markers(0); from_x = cur_x = moved_point->x; from_y = cur_y = moved_point->y; set_cursor(crosshair_cursor); if (open_spline(cur_s)) { if (left_point == NULL || right_point == NULL) { if (left_point != NULL) { fix_x = left_point->x; fix_y = left_point->y; } else if (right_point != NULL) { fix_x = right_point->x; fix_y = right_point->y; } if (latexline_mode || latexarrow_mode) { canvas_locmove_proc = latex_line; canvas_ref_proc = elastic_line; cur_latexcursor = crosshair_cursor; } else if (mountain_mode || manhattan_mode) { canvas_locmove_proc = constrainedangle_line; canvas_ref_proc = elastic_line; } else { /* freehand line */ canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; } } else { /* linelink, always freehand */ force_noanglegeom(); canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; } } else { /* must be closed spline */ force_noanglegeom(); canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; if (left_point == NULL) { for (left_point = right_point; left_point->next != NULL; left_point = left_point->next); } if (right_point == NULL) { right_point = cur_s->points; /* take the first */ } } /* show current length(s) */ (canvas_locmove_proc)(cur_x, cur_y); elastic_linelink(); canvas_leftbut_proc = fix_movedsplinepoint; canvas_rightbut_proc = cancel_movedsplinepoint; } static void cancel_movedsplinepoint(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_linelink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_movedsplinepoint(int x, int y) { (*canvas_locmove_proc) (x, y); canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_linelink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); old_s = copy_spline(cur_s); clean_up(); set_latestspline(old_s); set_action_object(F_EDIT, O_SPLINE); old_s->next = cur_s; relocate_splinepoint(cur_s, cur_x, cur_y, moved_point); /* redraw anything under the old spline */ redisplay_spline(old_s); /* and the new one */ redisplay_spline(cur_s); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void relocate_splinepoint(F_spline *s, int x, int y, F_point *moved_point) { moved_point->x = x; moved_point->y = y; set_modifiedflag(); } /*************************** compound ********************************/ static void init_compoundpointmoving(void) { double dx, dy, l; F_line *line, *dum; set_action_on(); if (cur_x == cur_c->nwcorner.x) fix_x = cur_c->secorner.x; else fix_x = cur_c->nwcorner.x; if (cur_y == cur_c->nwcorner.y) fix_y = cur_c->secorner.y; else fix_y = cur_c->nwcorner.y; from_x = cur_x; from_y = cur_y; /* turn off all markers */ update_markers(0); set_cursor(crosshair_cursor); elastic_box(fix_x, fix_y, cur_x, cur_y); /* is this a dimension line? */ if (dimline_components(cur_c, &line, &dum, &dum, &dum) && line) { /* yes, constrain the resizing in the direction of the line */ if (line->points->x == line->points->next->x) /* vertical line */ constrained = BOX_VSTRETCH; else /* horizontal line */ constrained = BOX_HSTRETCH; } if (constrained) { dx = cur_x - fix_x; dy = cur_y - fix_y; l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); } canvas_locmove_proc = constrained_resizing_scale_box; canvas_ref_proc = elastic_fixedbox; canvas_leftbut_proc = fix_movedcompoundpoint; canvas_rightbut_proc = cancel_compound; /* show current length(s) */ (canvas_locmove_proc)(cur_x, cur_y); } static void cancel_compound(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_movedcompoundpoint(int x, int y) { float scalex, scaley; canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y); /* make a copy of the original and save as unchanged object */ old_c = copy_compound(cur_c); clean_up(); old_c->next = cur_c; set_latestcompound(old_c); set_action_object(F_EDIT, O_COMPOUND); scalex = ((float) (cur_x - fix_x)) / (from_x - fix_x); scaley = ((float) (cur_y - fix_y)) / (from_y - fix_y); /* scale the compound */ scale_compound(cur_c, scalex, scaley, fix_x, fix_y); /* redraw anything under the old compound */ redisplay_compound(old_c); /* and the new compound */ redisplay_compound(cur_c); /* turn back on all relevant markers */ update_markers(new_objmask); set_lastposition(from_x, from_y); set_newposition(cur_x, cur_y); set_modifiedflag(); wrapup_movepoint(); } /*************************** line ********************************/ static void init_linepointmoving(void) { F_point *p; set_action_on(); /* turn off all markers */ update_markers(0); from_x = cur_x = moved_point->x; from_y = cur_y = moved_point->y; set_cursor(crosshair_cursor); switch (cur_l->type) { case T_POLYGON: if (left_point == NULL) for (left_point = right_point, p = left_point->next; p->next != NULL; left_point = p, p = p->next); force_noanglegeom(); canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; break; case T_BOX: case T_ARCBOX: case T_PICTURE: if (right_point->next == NULL) { /* point 4 */ fix_x = cur_l->points->next->x; fix_y = cur_l->points->next->y; } else { fix_x = right_point->next->x; fix_y = right_point->next->y; } if (constrained) { double dx, dy, l; dx = cur_x - fix_x; dy = cur_y - fix_y; l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); } force_noanglegeom(); if (cur_l->thickness != 1) elastic_box(fix_x, fix_y, cur_x, cur_y); canvas_locmove_proc = constrained_resizing_box; canvas_ref_proc = elastic_fixedbox; canvas_leftbut_proc = fix_box; canvas_rightbut_proc = cancel_movept_box; /* show current length(s) */ (canvas_locmove_proc)(cur_x, cur_y); return; case T_POLYLINE: if (left_point == NULL || right_point == NULL) { if (left_point != NULL) { fix_x = left_point->x; fix_y = left_point->y; } else if (right_point != NULL) { fix_x = right_point->x; fix_y = right_point->y; } if (latexline_mode || latexarrow_mode) { canvas_locmove_proc = latex_line; canvas_ref_proc = elastic_line; cur_latexcursor = crosshair_cursor; } else if (mountain_mode || manhattan_mode) { canvas_locmove_proc = constrainedangle_line; canvas_ref_proc = elastic_line; } else { /* unconstrained or freehand line */ canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; } } else { /* linelink, always freehand */ force_noanglegeom(); canvas_locmove_proc = reshaping_line; canvas_ref_proc = elastic_linelink; } break; } canvas_leftbut_proc = fix_movedlinepoint; canvas_rightbut_proc = cancel_movedlinepoint; /* show current length(s) */ (canvas_locmove_proc)(cur_x, cur_y); } static void cancel_movept_box(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; /* erase the elastic box */ elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); /* redraw original box */ redisplay_line(cur_l); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_box(int x, int y) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_box_lengths(); adjust_box_pos(x, y, from_x, from_y, &x, &y); new_l = copy_line(cur_l); if (new_l->type == T_PICTURE) { if (signof(fix_x - from_x) != signof(fix_x - x)) new_l->pic->flipped = 1 - new_l->pic->flipped; if (signof(fix_y - from_y) != signof(fix_y - y)) new_l->pic->flipped = 1 - new_l->pic->flipped; } assign_newboxpoint(new_l, fix_x, fix_y, x, y); change_line(cur_l, new_l); /* redraw anything under the old line */ redisplay_line(cur_l); /* and the new line */ redisplay_line(new_l); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } void assign_newboxpoint(F_line *b, int x1, int y1, int x2, int y2) { F_point *p; p = b->points; if (p->x != x1) p->x = x2; if (p->y != y1) p->y = y2; p = p->next; if (p->x != x1) p->x = x2; if (p->y != y1) p->y = y2; p = p->next; if (p->x != x1) p->x = x2; if (p->y != y1) p->y = y2; p = p->next; if (p->x != x1) p->x = x2; if (p->y != y1) p->y = y2; p = p->next; if (p->x != x1) p->x = x2; if (p->y != y1) p->y = y2; } static void cancel_movedlinepoint(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; /* erase the elastic line */ elastic_linelink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); /* redraw original line */ redisplay_line(cur_l); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void fix_movedlinepoint(int x, int y) { (*canvas_locmove_proc) (x, y); canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_linelink(); /* erase last lengths if appres.showlengths is true */ erase_lengths(); if (cur_latexcursor != crosshair_cursor) set_cursor(crosshair_cursor); /* make a copy of the original and save as unchanged object */ old_l = copy_line(cur_l); clean_up(); set_latestline(old_l); set_action_object(F_EDIT, O_POLYLINE); old_l->next = cur_l; /* now change the original to become the new object */ relocate_linepoint(cur_l, cur_x, cur_y, moved_point, left_point); /* redraw anything under the old line */ redisplay_line(old_l); /* and the new line */ redisplay_line(cur_l); /* turn back on all relevant markers */ update_markers(new_objmask); wrapup_movepoint(); } static void relocate_linepoint(F_line *line, int x, int y, F_point *moved_point, F_point *left_point) { if (line->type == T_POLYGON) if (line->points == moved_point) { left_point->next->x = x; left_point->next->y = y; } moved_point->x = x; moved_point->y = y; set_modifiedflag(); } xfig.3.2.5c/e_placelib.c0000700002656300244210000002101311641414046015574 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "figx.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_edit.h" #include "e_placelib.h" #include "e_rotate.h" #include "u_draw.h" #include "u_elastic.h" #include "u_list.h" #include "u_search.h" #include "u_create.h" #include "w_canvas.h" #include "w_indpanel.h" #include "w_library.h" #include "w_mousefun.h" #include "w_drawprim.h" /* for max_char_height */ #include "w_dir.h" #include "w_util.h" #include "w_setup.h" #include "w_zoom.h" #include "e_flip.h" #include "e_scale.h" #include "u_redraw.h" #include "u_translate.h" #include "u_undo.h" #include "w_cursor.h" #include "w_modepanel.h" #include "w_msgpanel.h" /* EXPORTS */ int cur_library_object = -1; int old_library_object = -1; /* STATICS */ static int off_library_x,off_library_y; static void init_move_object(int x, int y),move_object(int x, int y),change_draw_mode(int x, int y); static void transform_lib_obj(XKeyEvent *kpe, unsigned char c, KeySym keysym),place_lib_object(int x, int y, unsigned int shift); static void put_draw(int paint_mode); static void sel_place_lib_obj_proc(int x, int y, int shift); static int orig_put_x, orig_put_y; static Boolean draw_box = False; void put_selected(void) { int i, x,y; char *com; set_mousefun("place object","new object","cancel library", "place and edit","change draw mode", "place at orig posn"); set_action_on(); cur_c = lib_compounds[cur_library_object]->compound; new_c = copy_compound(cur_c); /* add it to the depths so it is displayed */ add_compound_depth(new_c); /* find lower-right corner for draw_box() */ off_library_x = new_c->secorner.x; off_library_y = new_c->secorner.y; /* and upper-left in case the user wants to place it at its original position */ /* this is saved here because the compound was shifted to 0,0 when reading in */ orig_put_x = lib_compounds[cur_library_object]->corner.x; orig_put_y = lib_compounds[cur_library_object]->corner.y; canvas_locmove_proc = init_move_object; canvas_ref_proc = null_proc; canvas_leftbut_proc = place_lib_object; canvas_middlebut_proc = sel_place_lib_obj_proc; canvas_rightbut_proc = cancel_place_lib_obj; set_cursor(null_cursor); /* get the pointer position */ get_pointer_win_xy(&x, &y); /* draw the first image */ init_move_object(BACKX(x), BACKY(y)); /* message that we're placing object so and so */ com = strdup(lib_compounds[cur_library_object]->compound->comments); if (strlen(com)) { /* change newlines to blanks */ for (i=strlen(com); i>=0; i--) if (com[i] == '\n') com[i] = ' '; put_msg("Placing library object \"%s\" (%s.fig)", com, library_objects_texts[cur_library_object]); } else { put_msg("Placing library object %s.fig", library_objects_texts[cur_library_object]); } } /* allow rotation or flipping of library object before placing on canvas */ static void transform_lib_obj(XKeyEvent *kpe, unsigned char c, KeySym keysym) { int x,y; x = cur_x; y = cur_y; /* first erase the existing image */ put_draw(ERASE); if (c == 'r') { rotn_dirn = 1; act_rotnangle = 90; rotate_compound(new_c, x, y); } else if (c == 'l') { rotn_dirn = -1; act_rotnangle = 90; rotate_compound(new_c, x, y); } else if (c == 'h') { flip_compound(new_c, x, y, LR_FLIP); } else if (c == 'v') { flip_compound(new_c, x, y, UD_FLIP); } else if (c == 's') { scale_compound(new_c, 0.9, 0.9, x, y); } else if (c == 'S') { scale_compound(new_c, 1.1, 1.1, x, y); } /* if not any of the above characters, ignore it */ /* and draw the new image */ put_draw(PAINT); } static void sel_place_lib_obj_proc(int x, int y, int shift) { /* if shift-left button, change drawing mode */ if (shift) { change_draw_mode(x, y); return; } /* else popup the library panel again */ sel_place_lib_obj(); } void sel_place_lib_obj(void) { canvas_kbd_proc = (void (*)())transform_lib_obj; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; canvas_leftbut_proc = null_proc; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; /* erase any object currently being dragged around the canvas */ if (lib_compounds && action_on && new_c) put_draw(ERASE); popup_library_panel(); } static void put_draw(int paint_mode) { register int x1, y1, x2, y2; if (draw_box) { x1=cur_x; y1=cur_y; x2=cur_x+off_library_x; y2=cur_y+off_library_y; elastic_box(x1, y1, x2, y2); } else { if (paint_mode==ERASE) redisplay_compound(new_c); else redisplay_objects(new_c); } } static void change_draw_mode(int x, int y) { put_draw(ERASE); draw_box = !draw_box; translate_compound(new_c,-new_c->nwcorner.x,-new_c->nwcorner.y); if (!draw_box) translate_compound(new_c,cur_x,cur_y); put_draw(PAINT); } /* place library object at original position in its file */ static void place_lib_object_orig(int x, int y, unsigned int shift) { int dx,dy; canvas_ref_proc = null_proc; put_draw(ERASE); clean_up(); /* move back to original position */ dx = orig_put_x-x; dy = orig_put_y-y; translate_compound(new_c,dx,dy); /* remove it from the depths because it will be added when it is put in the main list */ remove_compound_depth(new_c); add_compound(new_c); set_modifiedflag(); redisplay_compound(new_c); put_selected(); } static void place_lib_object(int x, int y, unsigned int shift) { F_compound *this_c; canvas_leftbut_proc = null_proc; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; put_draw(ERASE); clean_up(); if (draw_box) translate_compound(new_c,cur_x,cur_y); /* remove it from the depths because it will be added when it is put in the main list */ remove_compound_depth(new_c); add_compound(new_c); set_modifiedflag(); redisplay_compound(new_c); if (shift) { /* temporarily turn off library place mode so we can edit the object just placed */ canvas_kbd_proc = null_proc; clear_mousefun(); set_mousefun("","","", "", "", ""); turn_off_current(); set_cursor(arrow_cursor); edit_remember_lib_mode = True; this_c = new_c; edit_item(this_c, O_COMPOUND, 0, 0); } else { put_selected(); } } static void move_object(int x, int y) { int dx,dy; void (*save_canvas_locmove_proc) (); void (*save_canvas_ref_proc) (); save_canvas_locmove_proc = canvas_locmove_proc; save_canvas_ref_proc = canvas_ref_proc; /* so we don't recurse infinitely */ canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; put_draw(ERASE); if (!draw_box) { dx=x-cur_x; dy=y-cur_y; translate_compound(new_c,dx,dy); } cur_x=x;cur_y=y; put_draw(PAINT); canvas_locmove_proc = save_canvas_locmove_proc; canvas_ref_proc = save_canvas_ref_proc; } static void init_move_object(int x, int y) { cur_x=x; cur_y=y; if (!draw_box) translate_compound(new_c,x,y); put_draw(PAINT); canvas_locmove_proc = move_object; canvas_ref_proc = move_object; } /* cancel placing a library object */ void cancel_place_lib_obj(int x, int y, int shift) { /* if shift right-button, actually do a place in original position */ if (shift) { place_lib_object_orig(x, y, shift); return; } reset_action_on(); canvas_leftbut_proc = null_proc; canvas_middlebut_proc = null_proc; canvas_rightbut_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; canvas_kbd_proc = null_proc; clear_mousefun(); set_mousefun("","","", "", "", ""); turn_off_current(); set_cursor(arrow_cursor); put_draw(ERASE); /* remove it from the depths */ remove_compound_depth(new_c); } xfig.3.2.5c/e_rotate.c0000700002656300244210000003454711641414046015337 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "e_flip.h" #include "u_draw.h" #include "u_geom.h" #include "u_search.h" #include "u_create.h" #include "u_list.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "d_text.h" #include "u_bound.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" /* EXPORTS */ int setcenter; int setcenter_x; int setcenter_y; int rotn_dirn; float act_rotnangle; /* LOCAL */ static int copy; static void init_rotate(F_line *p, int type, int x, int y, int px, int py); static void set_unset_center(int x, int y); static void init_copynrotate(F_line *p, int type, int x, int y, int px, int py); static void rotate_selected(void); static void rotate_search(F_line *p, int type, int x, int y, int px, int py); static void init_rotateline(F_line *l, int px, int py); static void init_rotatetext(F_text *t, int px, int py); void init_rotatearc (F_arc *a, int px, int py); void init_rotateellipse (F_ellipse *e, int px, int py); void init_rotatespline (F_spline *s, int px, int py); void init_rotatecompound (F_compound *c, int px, int py); void rotate_line (F_line *l, int x, int y); void rotate_text (F_text *t, int x, int y); void rotate_ellipse (F_ellipse *e, int x, int y); void rotate_arc (F_arc *a, int x, int y); void rotate_spline (F_spline *s, int x, int y); int valid_rot_angle (F_compound *c); void rotate_compound (F_compound *c, int x, int y); void rotate_point (F_point *p, int x, int y); void rotate_xy (int *orig_x, int *orig_y, int x, int y); void rotate_cw_selected(void) { rotn_dirn = 1; /* erase any existing center */ if (setcenter) center_marker(setcenter_x, setcenter_y); /* and any anchor */ if (setanchor) center_marker(setanchor_x, setanchor_y); setcenter = 0; setanchor = 0; rotate_selected(); } void rotate_ccw_selected(void) { rotn_dirn = -1; /* erase any existing center */ if (setcenter) center_marker(setcenter_x, setcenter_y); /* and any anchor */ if (setanchor) center_marker(setanchor_x, setanchor_y); setcenter = 0; setanchor = 0; rotate_selected(); } static void rotate_selected(void) { set_mousefun("rotate object", "copy & rotate", "set center", LOC_OBJ, LOC_OBJ, "set center"); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_rotate); init_searchproc_middle(init_copynrotate); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = set_unset_center; set_cursor(pick15_cursor); reset_action_on(); } static void set_unset_center(int x, int y) { if (setcenter) { set_mousefun("rotate object", "copy & rotate", "set center", LOC_OBJ, LOC_OBJ, "set center"); draw_mousefun_canvas(); setcenter = 0; center_marker(setcenter_x,setcenter_y); /* second call to center_mark on same position deletes */ } else { set_mousefun("rotate object", "copy & rotate", "unset center", LOC_OBJ, LOC_OBJ, "unset center"); draw_mousefun_canvas(); setcenter = 1; setcenter_x = x; setcenter_y = y; center_marker(setcenter_x,setcenter_y); } } static void init_rotate(F_line *p, int type, int x, int y, int px, int py) { copy = 0; act_rotnangle = cur_rotnangle; if (setcenter) rotate_search(p, type, x, y,setcenter_x,setcenter_y ); /* remember rotation center, e.g for multiple rotation*/ else rotate_search(p, type, x, y, px, py); } static void init_copynrotate(F_line *p, int type, int x, int y, int px, int py) { int i; copy = 1; act_rotnangle = cur_rotnangle; for ( i = 1; i <= cur_numcopies; act_rotnangle += cur_rotnangle, i++) { if (setcenter) rotate_search(p, type, x, y,setcenter_x,setcenter_y ); /* remember rotation center */ else rotate_search(p, type, x, y, px, py); } } static void rotate_search(F_line *p, int type, int x, int y, int px, int py) { switch (type) { case O_POLYLINE: cur_l = (F_line *) p; init_rotateline(cur_l, px, py); break; case O_ARC: cur_a = (F_arc *) p; init_rotatearc(cur_a, px, py); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; init_rotateellipse(cur_e, px, py); break; case O_SPLINE: cur_s = (F_spline *) p; init_rotatespline(cur_s, px, py); break; case O_TXT: cur_t = (F_text *) p; init_rotatetext(cur_t, px, py); break; case O_COMPOUND: cur_c = (F_compound *) p; init_rotatecompound(cur_c, px, py); break; default: return; } } static void init_rotateline(F_line *l, int px, int py) { F_line *line; set_temp_cursor(wait_cursor); line = copy_line(l); rotate_line(line, px, py); if (copy) { add_line(line); } else { toggle_linemarker(l); draw_line(l, ERASE); change_line(l, line); } /* redisplay objects under this object before it was rotated */ redisplay_line(l); /* and this line and any other objects on top */ redisplay_line(line); reset_cursor(); } static void init_rotatetext(F_text *t, int px, int py) { F_text *text; set_temp_cursor(wait_cursor); text = copy_text(t); rotate_text(text, px, py); if (copy) { add_text(text); } else { toggle_textmarker(t); draw_text(t, ERASE); change_text(t, text); } /* redisplay objects under this object before it was rotated */ redisplay_text(t); /* and this text and any other objects on top */ redisplay_text(text); reset_cursor(); } void init_rotateellipse(F_ellipse *e, int px, int py) { F_ellipse *ellipse; set_temp_cursor(wait_cursor); ellipse = copy_ellipse(e); rotate_ellipse(ellipse, px, py); if (copy) { add_ellipse(ellipse); } else { toggle_ellipsemarker(e); draw_ellipse(e, ERASE); change_ellipse(e, ellipse); } /* redisplay objects under this object before it was rotated */ redisplay_ellipse(e); /* and this ellipse and any other objects on top */ redisplay_ellipse(ellipse); reset_cursor(); } void init_rotatearc(F_arc *a, int px, int py) { F_arc *arc; set_temp_cursor(wait_cursor); arc = copy_arc(a); rotate_arc(arc, px, py); if (copy) { add_arc(arc); } else { toggle_arcmarker(a); draw_arc(a, ERASE); change_arc(a, arc); } /* redisplay objects under this object before it was rotated */ redisplay_arc(a); /* and this arc and any other objects on top */ redisplay_arc(arc); reset_cursor(); } void init_rotatespline(F_spline *s, int px, int py) { F_spline *spline; set_temp_cursor(wait_cursor); spline = copy_spline(s); rotate_spline(spline, px, py); if (copy) { add_spline(spline); } else { toggle_splinemarker(s); draw_spline(s, ERASE); change_spline(s, spline); } /* redisplay objects under this object before it was rotated */ redisplay_spline(s); /* and this spline and any other objects on top */ redisplay_spline(spline); reset_cursor(); } void init_rotatecompound(F_compound *c, int px, int py) { F_compound *compound; if (!valid_rot_angle(c)) { put_msg("Invalid rotation angle for this compound object"); return; } set_temp_cursor(wait_cursor); compound = copy_compound(c); rotate_compound(compound, px, py); if (copy) { add_compound(compound); } else { toggle_compoundmarker(c); draw_compoundelements(c, ERASE); change_compound(c, compound); } /* redisplay objects under this object before it was rotated */ redisplay_compound(c); /* and this compound and any other objects on top */ redisplay_compound(compound); reset_cursor(); } void rotate_line(F_line *l, int x, int y) { F_point *p; int dx; /* for speed we treat 90 degrees as a special case */ if (act_rotnangle == 90.0) { for (p = l->points; p != NULL; p = p->next) { dx = p->x - x; p->x = x + rotn_dirn * (y - p->y); p->y = y + rotn_dirn * dx; } } else { for (p = l->points; p != NULL; p = p->next) rotate_point(p, x, y); } } void rotate_figure(F_compound *f, int x, int y) { float old_rotn_dirn, old_act_rotnangle; old_rotn_dirn = rotn_dirn; old_act_rotnangle = act_rotnangle; rotn_dirn = -1; act_rotnangle = 90.0; rotate_compound(f,x,y); rotn_dirn = old_rotn_dirn; act_rotnangle = old_act_rotnangle; } void rotate_spline(F_spline *s, int x, int y) { F_point *p; int dx; /* for speed we treat 90 degrees as a special case */ if (act_rotnangle == 90.0) { for (p = s->points; p != NULL; p = p->next) { dx = p->x - x; p->x = x + rotn_dirn * (y - p->y); p->y = y + rotn_dirn * dx; } } else { for (p = s->points; p != NULL; p = p->next) rotate_point(p, x, y); } } void rotate_text(F_text *t, int x, int y) { int dx; if (act_rotnangle == 90.0) { /* treat 90 degs as special case for speed */ dx = t->base_x - x; t->base_x = x + rotn_dirn * (y - t->base_y); t->base_y = y + rotn_dirn * dx; } else { rotate_xy(&t->base_x, &t->base_y, x, y); } t->angle -= (float) (rotn_dirn * act_rotnangle * M_PI / 180.0); if (t->angle < 0.0) t->angle += M_2PI; else if (t->angle >= M_2PI - 0.001) t->angle -= M_2PI; reload_text_fstruct(t); } void rotate_ellipse(F_ellipse *e, int x, int y) { int dxc,dxs,dxe; if (act_rotnangle == 90.0) { /* treat 90 degs as special case for speed */ dxc = e->center.x - x; dxs = e->start.x - x; dxe = e->end.x - x; e->center.x = x + rotn_dirn * (y - e->center.y); e->center.y = y + rotn_dirn * dxc; e->start.x = x + rotn_dirn * (y - e->start.y); e->start.y = y + rotn_dirn * dxs; e->end.x = x + rotn_dirn * (y - e->end.y); e->end.y = y + rotn_dirn * dxe; } else { rotate_point((F_point *)&e->center, x, y); rotate_point((F_point *)&e->start, x, y); rotate_point((F_point *)&e->end, x, y); } e->angle -= (float) (rotn_dirn * act_rotnangle * M_PI / 180.0); if (e->angle < 0.0) e->angle += M_2PI; else if (e->angle >= M_2PI - 0.001) e->angle -= M_2PI; } void rotate_arc(F_arc *a, int x, int y) { int dx; F_pos p[3]; float xx, yy; /* for speed we treat 90 degrees as a special case */ if (act_rotnangle == 90.0) { dx = a->center.x - x; a->center.x = x + rotn_dirn * (y - a->center.y); a->center.y = y + rotn_dirn * dx; dx = a->point[0].x - x; a->point[0].x = x + rotn_dirn * (y - a->point[0].y); a->point[0].y = y + rotn_dirn * dx; dx = a->point[1].x - x; a->point[1].x = x + rotn_dirn * (y - a->point[1].y); a->point[1].y = y + rotn_dirn * dx; dx = a->point[2].x - x; a->point[2].x = x + rotn_dirn * (y - a->point[2].y); a->point[2].y = y + rotn_dirn * dx; } else { p[0] = a->point[0]; p[1] = a->point[1]; p[2] = a->point[2]; rotate_point((F_point *)&p[0], x, y); rotate_point((F_point *)&p[1], x, y); rotate_point((F_point *)&p[2], x, y); if (compute_arccenter(p[0], p[1], p[2], &xx, &yy)) { a->point[0].x = p[0].x; a->point[0].y = p[0].y; a->point[1].x = p[1].x; a->point[1].y = p[1].y; a->point[2].x = p[2].x; a->point[2].y = p[2].y; a->center.x = xx; a->center.y = yy; a->direction = compute_direction(p[0], p[1], p[2]); } } } /* checks to see if the objects within c can be rotated by act_rotnangle */ int valid_rot_angle(F_compound *c) { F_line *l; F_compound *c1; if (fabs(act_rotnangle) == 90.0 || fabs(act_rotnangle == 180.0)) return 1; /* always valid */ for (l = c->lines; l != NULL; l = l->next) if (l->type == T_ARCBOX || l->type == T_BOX) return 0; for (c1 = c->compounds; c1 != NULL; c1 = c1->next) if (!valid_rot_angle(c1)) return 0; return 1; } void rotate_compound(F_compound *c, int x, int y) { F_line *l; F_arc *a; F_ellipse *e; F_spline *s; F_text *t; F_compound *c1; for (l = c->lines; l != NULL; l = l->next) rotate_line(l, x, y); for (a = c->arcs; a != NULL; a = a->next) rotate_arc(a, x, y); for (e = c->ellipses; e != NULL; e = e->next) rotate_ellipse(e, x, y); for (s = c->splines; s != NULL; s = s->next) rotate_spline(s, x, y); for (t = c->texts; t != NULL; t = t->next) rotate_text(t, x, y); for (c1 = c->compounds; c1 != NULL; c1 = c1->next) rotate_compound(c1, x, y); /* * Make the bounding box exactly match the dimensions of the compound. */ compound_bound(c, &c->nwcorner.x, &c->nwcorner.y, &c->secorner.x, &c->secorner.y); } void rotate_point(F_point *p, int x, int y) { /* rotate point p about coordinate (x, y) */ double dx, dy; double cosa, sina, mag, theta; dx = p->x - x; dy = y - p->y; if (dx == 0 && dy == 0) return; theta = compute_angle(dx, dy); theta -= (double) (rotn_dirn * act_rotnangle * M_PI / 180.0); if (theta < 0.0) theta += M_2PI; else if (theta >= M_2PI - 0.001) theta -= M_2PI; mag = sqrt(dx * dx + dy * dy); cosa = mag * cos(theta); sina = mag * sin(theta); p->x = round(x + cosa); p->y = round(y - sina); } void rotate_xy(int *orig_x, int *orig_y, int x, int y) { /* rotate coord (orig_x, orig_y) about coordinate (x, y) */ double dx, dy; double cosa, sina, mag, theta; dx = *orig_x - x; dy = y - *orig_y; if (dx == 0 && dy == 0) return; theta = compute_angle(dx, dy); theta -= (double) (rotn_dirn * act_rotnangle * M_PI / 180.0); if (theta < 0.0) theta += M_2PI; else if (theta >= M_2PI - 0.001) theta -= M_2PI; mag = sqrt(dx * dx + dy * dy); cosa = mag * cos(theta); sina = mag * sin(theta); *orig_x = round(x + cosa); *orig_y = round(y - sina); } xfig.3.2.5c/e_scale.c0000700002656300244210000011632611641414046015124 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "d_text.h" #include "e_rotate.h" #include "e_scale.h" #include "u_create.h" #include "u_draw.h" #include "u_elastic.h" #include "u_search.h" #include "u_undo.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "e_movept.h" #include "f_util.h" #include "u_bound.h" #include "u_fonts.h" #include "u_geom.h" #include "u_list.h" #include "u_markers.h" #include "u_redraw.h" #include "w_cursor.h" static Boolean init_boxscale_ellipse(int x, int y); static Boolean init_boxscale_line(int x, int y); static Boolean init_boxscale_compound(int x, int y); static Boolean init_scale_arc(void); static Boolean init_scale_ellipse(void); static Boolean init_scale_line(void); static Boolean init_scale_spline(void); static void scale_line(F_line *l, float sx, float sy, int refx, int refy); static void scale_spline(F_spline *s, float sx, float sy, int refx, int refy); static void scale_arc(F_arc *a, float sx, float sy, int refx, int refy); static void scale_ellipse(F_ellipse *e, float sx, float sy, int refx, int refy); static void scale_text(F_text *t, float sx, float sy, int refx, int refy); static void scale_arrows(F_line *obj, float sx, float sy); static void scale_arrow(F_arrow *arrow, float sx, float sy); static void init_box_scale(F_line *obj, int type, int x, int y, int px, int py); static void boxrelocate_ellipsepoint(F_ellipse *ellipse, int x, int y); static void init_center_scale(F_line *obj, int type, int x, int y, int px, int py); static void init_scale_compound(void); static void rescale_points(F_line *obj, int x, int y); static void relocate_ellipsepoint(F_ellipse *ellipse, int x, int y); static void relocate_arcpoint(F_arc *arc, int x, int y); static void fix_scale_arc(int x, int y); static void fix_scale_spline(int x, int y); static void fix_scale_line(int x, int y); static void fix_scale_ellipse(int x, int y); static void fix_boxscale_ellipse(int x, int y); static void fix_boxscale_line(int x, int y); static void fix_scale_compound(int x, int y); static void fix_boxscale_compound(int x, int y); static void cancel_scale_arc(void); static void cancel_scale_spline(void); static void cancel_scale_line(void); static void cancel_scale_ellipse(void); static void cancel_boxscale_ellipse(void); static void cancel_boxscale_line(void); static void cancel_scale_compound(void); static void cancel_boxscale_compound(void); static void prescale_compound(F_compound *c, int x, int y); void scale_selected(void) { set_mousefun("scale box", "scale about center", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_box_scale); init_searchproc_middle(init_center_scale); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick15_cursor); reset_action_on(); } char *BOX_SCL_MSG = "Can't use box scale on selected object"; char *BOX_SCL2_MSG = "Can't use box scale on selected object; try putting it into a compound"; static void init_box_scale(F_line *obj, int type, int x, int y, int px, int py) { switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; if (!init_boxscale_line(px, py)) /* non-box line */ return; break; case O_ELLIPSE: cur_e = (F_ellipse *) obj; if (!init_boxscale_ellipse(px, py)) /* selected center, ignore */ return; break; case O_COMPOUND: cur_c = (F_compound *) obj; if (!init_boxscale_compound(px, py)) /* non-box compound */ return; break; default: put_msg(BOX_SCL2_MSG); beep(); return; } set_mousefun("new posn", "", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_middlebut_proc = null_proc; } static void init_center_scale(F_line *obj, int type, int x, int y, int px, int py) { double dx, dy, l; cur_x = from_x = px; cur_y = from_y = py; constrained = BOX_SCALE; switch (type) { case O_POLYLINE: cur_l = (F_line *) obj; if (!init_scale_line()) /* selected center */ return; break; case O_SPLINE: cur_s = (F_spline *) obj; if (!init_scale_spline()) /* selected center */ return; break; case O_ELLIPSE: cur_e = (F_ellipse *) obj; if (!init_scale_ellipse()) /* selected center */ return; break; case O_ARC: cur_a = (F_arc *) obj; if (!init_scale_arc()) /* selected center */ return; break; case O_COMPOUND: cur_c = (F_compound *) obj; init_scale_compound(); break; } dx = (double) (from_x - fix_x); dy = (double) (from_y - fix_y); l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); set_mousefun("", "new posn", "cancel", LOC_OBJ, LOC_OBJ, LOC_OBJ); draw_mousefun_canvas(); canvas_leftbut_proc = null_proc; } static void wrapup_scale(void) { reset_action_on(); scale_selected(); draw_mousefun_canvas(); } /************************* ellipse *******************************/ static Boolean init_boxscale_ellipse(int x, int y) { double dx, dy, l; if (cur_e->type == T_ELLIPSE_BY_RAD || cur_e->type == T_CIRCLE_BY_RAD) { if (x == cur_e->start.x && y == cur_e->start.y) { put_msg("Center point selected, ignored"); return False; } else { fix_x = cur_e->center.x - (x - cur_e->center.x); fix_y = cur_e->center.y - (y - cur_e->center.y); } } else { if (x == cur_e->start.x && y == cur_e->start.y) { fix_x = cur_e->end.x; fix_y = cur_e->end.y; } else { fix_x = cur_e->start.x; fix_y = cur_e->start.y; } } cur_x = from_x = x; cur_y = from_y = y; cur_angle = cur_e->angle; if (cur_x == fix_x || cur_y == fix_y) { put_msg(BOX_SCL2_MSG); beep(); return False; } set_action_on(); toggle_ellipsemarker(cur_e); constrained = BOX_SCALE; dx = (double) (cur_x - fix_x); dy = (double) (cur_y - fix_y); l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); set_cursor(crosshair_cursor); if ((cur_e->type == T_CIRCLE_BY_DIA) || (cur_e->type == T_CIRCLE_BY_RAD)) { canvas_locmove_proc = constrained_resizing_cbd; canvas_ref_proc = elastic_cbd; elastic_cbd(); } else { canvas_locmove_proc = constrained_resizing_ebd; canvas_ref_proc = elastic_ebd; elastic_ebd(); } canvas_leftbut_proc = fix_boxscale_ellipse; canvas_rightbut_proc = cancel_boxscale_ellipse; return True; } static void cancel_boxscale_ellipse(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; if ((cur_e->type == T_CIRCLE_BY_DIA) || (cur_e->type == T_CIRCLE_BY_RAD)) elastic_cbd(); else elastic_ebd(); toggle_ellipsemarker(cur_e); wrapup_scale(); } static void fix_boxscale_ellipse(int x, int y) { float dx, dy; if ((cur_e->type == T_CIRCLE_BY_DIA) || (cur_e->type == T_CIRCLE_BY_RAD)) elastic_cbd(); else elastic_ebd(); adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y); new_e = copy_ellipse(cur_e); boxrelocate_ellipsepoint(new_e, cur_x, cur_y); /* find how much the radii changed */ dx = 1.0 * new_e->radiuses.x / cur_e->radiuses.x; dy = 1.0 * new_e->radiuses.y / cur_e->radiuses.y; change_ellipse(cur_e, new_e); wrapup_scale(); /* redraw anything under the old ellipse */ redisplay_ellipse(cur_e); /* and the new one */ redisplay_ellipse(new_e); } static void boxrelocate_ellipsepoint(F_ellipse *ellipse, int x, int y) { double dx, dy; set_temp_cursor(wait_cursor); draw_ellipse(ellipse, ERASE); if ((ellipse->type == T_CIRCLE_BY_RAD) || (ellipse->type == T_ELLIPSE_BY_RAD)) { ellipse->end.x = x; ellipse->end.y = y; } else { if (ellipse->start.x == fix_x) ellipse->end.x = x; if (ellipse->start.y == fix_y) ellipse->end.y = y; if (ellipse->end.x == fix_x) ellipse->start.x = x; if (ellipse->end.y == fix_y) ellipse->start.y = y; } if ((ellipse->type == T_CIRCLE_BY_DIA) || (ellipse->type == T_CIRCLE_BY_RAD)) { dx = ellipse->center.x = round((fix_x + x) / 2); dy = ellipse->center.y = round((fix_y + y) / 2); dx -= x; dy -= y; ellipse->radiuses.x = round(sqrt(dx * dx + dy * dy)); ellipse->radiuses.y = ellipse->radiuses.x; } else { ellipse->center.x = (fix_x + x) / 2; ellipse->center.y = (fix_y + y) / 2; ellipse->radiuses.x = abs(ellipse->center.x - fix_x); ellipse->radiuses.y = abs(ellipse->center.y - fix_y); } if ((ellipse->type == T_CIRCLE_BY_RAD) || (ellipse->type == T_ELLIPSE_BY_RAD)) { ellipse->start.x = ellipse->center.x; ellipse->start.y = ellipse->center.y; } reset_cursor(); } static Boolean init_scale_ellipse(void) { fix_x = cur_e->center.x; fix_y = cur_e->center.y; cur_angle = cur_e->angle; if (from_x == fix_x && from_y == fix_y) { put_msg("Center point selected, ignored"); return False; } set_action_on(); toggle_ellipsemarker(cur_e); set_cursor(crosshair_cursor); canvas_locmove_proc = scaling_ellipse; canvas_ref_proc = elastic_scale_curellipse; elastic_scaleellipse(cur_e); canvas_middlebut_proc = fix_scale_ellipse; canvas_rightbut_proc = cancel_scale_ellipse; if (cur_e->type == T_ELLIPSE_BY_RAD) length_msg(MSG_RADIUS2); else if (cur_e->type == T_CIRCLE_BY_RAD) length_msg(MSG_RADIUS); else length_msg(MSG_DIAM); return True; /* all is Ok */ } static void cancel_scale_ellipse(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_scaleellipse(cur_e); toggle_ellipsemarker(cur_e); wrapup_scale(); } static void fix_scale_ellipse(int x, int y) { elastic_scaleellipse(cur_e); adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y); new_e = copy_ellipse(cur_e); relocate_ellipsepoint(new_e, cur_x, cur_y); change_ellipse(cur_e, new_e); wrapup_scale(); /* redraw anything under the old ellipse */ redisplay_ellipse(cur_e); /* and the new one */ redisplay_ellipse(new_e); } static void relocate_ellipsepoint(F_ellipse *ellipse, int x, int y) { double newx, newy, oldx, oldy; double newd, oldd, scalefact; set_temp_cursor(wait_cursor); draw_ellipse(ellipse, ERASE); newx = x - fix_x; newy = y - fix_y; newd = sqrt(newx * newx + newy * newy); oldx = from_x - fix_x; oldy = from_y - fix_y; oldd = sqrt(oldx * oldx + oldy * oldy); scalefact = newd / oldd; ellipse->radiuses.x = round(ellipse->radiuses.x * scalefact); ellipse->radiuses.y = round(ellipse->radiuses.y * scalefact); ellipse->end.x = fix_x + round((ellipse->end.x - fix_x) * scalefact); ellipse->end.y = fix_y + round((ellipse->end.y - fix_y) * scalefact); ellipse->start.x = fix_x + round((ellipse->start.x - fix_x) * scalefact); ellipse->start.y = fix_y + round((ellipse->start.y - fix_y) * scalefact); reset_cursor(); } /*************************** arc *********************************/ static Boolean init_scale_arc(void) { fix_x = cur_a->center.x; fix_y = cur_a->center.y; if (from_x == fix_x && from_y == fix_y) { put_msg("Center point selected, ignored"); return False; } set_action_on(); toggle_arcmarker(cur_a); elastic_scalearc(cur_a); set_cursor(crosshair_cursor); canvas_locmove_proc = scaling_arc; canvas_ref_proc = elastic_scale_curarc; canvas_middlebut_proc = fix_scale_arc; canvas_rightbut_proc = cancel_scale_arc; return True; } static void cancel_scale_arc(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_scalearc(cur_a); /* erase last lengths if appres.showlengths is true */ erase_lengths(); toggle_arcmarker(cur_a); wrapup_scale(); } static void fix_scale_arc(int x, int y) { double newx, newy, oldx, oldy; double newd, oldd, scalefact; elastic_scalearc(cur_a); adjust_box_pos(x, y, from_x, from_y, &x, &y); new_a = copy_arc(cur_a); newx = cur_x - fix_x; newy = cur_y - fix_y; newd = sqrt(newx * newx + newy * newy); oldx = from_x - fix_x; oldy = from_y - fix_y; oldd = sqrt(oldx * oldx + oldy * oldy); scalefact = newd / oldd; /* scale any arrowheads */ scale_arrows((F_line *)new_a,scalefact,scalefact); relocate_arcpoint(new_a, x, y); change_arc(cur_a, new_a); wrapup_scale(); /* redraw anything under the old arc */ redisplay_arc(cur_a); /* and the new one */ redisplay_arc(new_a); } static void relocate_arcpoint(F_arc *arc, int x, int y) { double newx, newy, oldx, oldy; double newd, oldd, scalefact; float xx, yy; F_pos p0, p1, p2; newx = x - fix_x; newy = y - fix_y; newd = sqrt(newx * newx + newy * newy); oldx = from_x - fix_x; oldy = from_y - fix_y; oldd = sqrt(oldx * oldx + oldy * oldy); scalefact = newd / oldd; p0 = arc->point[0]; p1 = arc->point[1]; p2 = arc->point[2]; p0.x = fix_x + round((p0.x - fix_x) * scalefact); p0.y = fix_y + round((p0.y - fix_y) * scalefact); p1.x = fix_x + round((p1.x - fix_x) * scalefact); p1.y = fix_y + round((p1.y - fix_y) * scalefact); p2.x = fix_x + round((p2.x - fix_x) * scalefact); p2.y = fix_y + round((p2.y - fix_y) * scalefact); if (compute_arccenter(p0, p1, p2, &xx, &yy)) { arc->point[0].x = p0.x; arc->point[0].y = p0.y; arc->point[1].x = p1.x; arc->point[1].y = p1.y; arc->point[2].x = p2.x; arc->point[2].y = p2.y; arc->center.x = xx; arc->center.y = yy; arc->direction = compute_direction(p0, p1, p2); } set_modifiedflag(); } /************************** spline *******************************/ static Boolean init_scale_spline(void) { int sumx, sumy, cnt; F_point *p; p = cur_s->points; if (closed_spline(cur_s)) p = p->next; for (sumx = 0, sumy = 0, cnt = 0; p != NULL; p = p->next) { sumx = sumx + p->x; sumy = sumy + p->y; cnt++; } fix_x = sumx / cnt; fix_y = sumy / cnt; if (from_x == fix_x && from_y == fix_y) { put_msg("Center point selected, ignored"); return False; } set_action_on(); set_cursor(crosshair_cursor); toggle_splinemarker(cur_s); elastic_scalepts(cur_s->points); canvas_locmove_proc = scaling_spline; canvas_ref_proc = elastic_scale_curspline; canvas_middlebut_proc = fix_scale_spline; canvas_rightbut_proc = cancel_scale_spline; return True; } static void cancel_scale_spline(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_scalepts(cur_s->points); toggle_splinemarker(cur_s); wrapup_scale(); } static void fix_scale_spline(int x, int y) { elastic_scalepts(cur_s->points); canvas_ref_proc = null_proc; adjust_box_pos(x, y, from_x, from_y, &x, &y); /* make a copy of the original and save as unchanged object */ old_s = copy_spline(cur_s); clean_up(); set_latestspline(old_s); set_action_object(F_EDIT, O_SPLINE); old_s->next = cur_s; /* now change the original to become the new object */ rescale_points((F_line *)cur_s, x, y); wrapup_scale(); /* redraw anything under the old spline */ redisplay_spline(old_s); /* and the new one */ redisplay_spline(cur_s); } /*************************** compound ********************************/ static Boolean init_boxscale_compound(int x, int y) { int xmin, ymin, xmax, ymax; double dx, dy, l; xmin = min2(cur_c->secorner.x, cur_c->nwcorner.x); ymin = min2(cur_c->secorner.y, cur_c->nwcorner.y); xmax = max2(cur_c->secorner.x, cur_c->nwcorner.x); ymax = max2(cur_c->secorner.y, cur_c->nwcorner.y); if (xmin == xmax || ymin == ymax) { put_msg(BOX_SCL_MSG); beep(); return False; } set_action_on(); toggle_compoundmarker(cur_c); set_cursor(crosshair_cursor); if (x == xmin) { fix_x = xmax; from_x = x; if (y == ymin) { fix_y = ymax; from_y = y; constrained = BOX_SCALE; } else if (y == ymax) { fix_y = ymin; from_y = y; constrained = BOX_SCALE; } else { fix_y = ymax; from_y = ymin; constrained = BOX_HSTRETCH; } } else if (x == xmax) { fix_x = xmin; from_x = x; if (y == ymin) { fix_y = ymax; from_y = y; constrained = BOX_SCALE; } else if (y == ymax) { fix_y = ymin; from_y = y; constrained = BOX_SCALE; } else { fix_y = ymax; from_y = ymin; constrained = BOX_HSTRETCH; } } else { if (y == ymin) { fix_y = ymax; from_y = y; fix_x = xmax; from_x = xmin; constrained = BOX_VSTRETCH; } else { /* y == ymax */ fix_y = ymin; from_y = y; fix_x = xmax; from_x = xmin; constrained = BOX_VSTRETCH; } } cur_x = from_x; cur_y = from_y; if (constrained == BOX_SCALE) { dx = (double) (cur_x - fix_x); dy = (double) (cur_y - fix_y); l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); } boxsize_scale_msg(1); elastic_box(fix_x, fix_y, cur_x, cur_y); canvas_locmove_proc = constrained_resizing_scale_box; canvas_ref_proc = elastic_fixedbox; canvas_leftbut_proc = fix_boxscale_compound; canvas_rightbut_proc = cancel_boxscale_compound; return True; } static void cancel_boxscale_compound(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); toggle_compoundmarker(cur_c); wrapup_scale(); } static void fix_boxscale_compound(int x, int y) { double scalex, scaley; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_box_pos(x, y, from_x, from_y, &x, &y); new_c = copy_compound(cur_c); scalex = (double) (x - fix_x) / (from_x - fix_x); scaley = (double) (y - fix_y) / (from_y - fix_y); scale_compound(new_c, scalex, scaley, fix_x, fix_y); change_compound(cur_c, new_c); wrapup_scale(); /* redraw anything under the old compound */ redisplay_compound(cur_c); /* and the new one */ redisplay_compound(new_c); } static void init_scale_compound(void) { fix_x = (cur_c->nwcorner.x + cur_c->secorner.x) / 2; fix_y = (cur_c->nwcorner.y + cur_c->secorner.y) / 2; set_action_on(); toggle_compoundmarker(cur_c); set_cursor(crosshair_cursor); elastic_scalecompound(cur_c); canvas_locmove_proc = scaling_compound; canvas_ref_proc = elastic_scale_curcompound; canvas_middlebut_proc = fix_scale_compound; canvas_rightbut_proc = cancel_scale_compound; } static void cancel_scale_compound(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_scalecompound(cur_c); /* erase last lengths if appres.showlengths is true */ erase_lengths(); toggle_compoundmarker(cur_c); wrapup_scale(); } static void fix_scale_compound(int x, int y) { elastic_scalecompound(cur_c); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y); /* make a copy of the original and save as unchanged object */ old_c = copy_compound(cur_c); clean_up(); set_latestcompound(old_c); set_action_object(F_EDIT, O_COMPOUND); old_c->next = cur_c; /* now change the original to become the new object */ prescale_compound(cur_c, cur_x, cur_y); wrapup_scale(); /* redraw anything under the old compound */ redisplay_compound(old_c); /* and the new one */ redisplay_compound(cur_c); } static void prescale_compound(F_compound *c, int x, int y) { double newx, newy, oldx, oldy; double newd, oldd, scalefact; newx = x - fix_x; newy = y - fix_y; newd = sqrt(newx * newx + newy * newy); oldx = from_x - fix_x; oldy = from_y - fix_y; oldd = sqrt(oldx * oldx + oldy * oldy); scalefact = newd / oldd; scale_compound(c, scalefact, scalefact, fix_x, fix_y); } void scale_compound(F_compound *c, double sx, double sy, int refx, int refy) { F_line *l; F_spline *s; F_ellipse *e; F_text *t; F_arc *a; F_compound *c1; int x1, y1, x2, y2; /* if sx and sy == 1.0, return now */ if (sx == 0.0 && sy == 0.0) return; /* check if really a dimension line */ if (rescale_dimension_line(c, sx, sy, refx, refy)) return; /* yes, return now */ x1 = round(refx + (c->nwcorner.x - refx) * sx); y1 = round(refy + (c->nwcorner.y - refy) * sy); x2 = round(refx + (c->secorner.x - refx) * sx); y2 = round(refy + (c->secorner.y - refy) * sy); c->nwcorner.x = min2(x1, x2); c->nwcorner.y = min2(y1, y2); c->secorner.x = max2(x1, x2); c->secorner.y = max2(y1, y2); for (l = c->lines; l != NULL; l = l->next) { scale_line(l, sx, sy, refx, refy); } for (s = c->splines; s != NULL; s = s->next) { scale_spline(s, sx, sy, refx, refy); } for (a = c->arcs; a != NULL; a = a->next) { scale_arc(a, sx, sy, refx, refy); } for (e = c->ellipses; e != NULL; e = e->next) { scale_ellipse(e, sx, sy, refx, refy); } for (t = c->texts; t != NULL; t = t->next) { scale_text(t, sx, sy, refx, refy); } for (c1 = c->compounds; c1 != NULL; c1 = c1->next) { scale_compound(c1, sx, sy, refx, refy); /* if there's a dimension line in this compound reset corners */ c->nwcorner.x = min2(c->nwcorner.x, c1->nwcorner.x); c->nwcorner.y = min2(c->nwcorner.y, c1->nwcorner.y); c->secorner.x = max2(c->secorner.x, c1->secorner.x); c->secorner.y = max2(c->secorner.y, c1->secorner.y); } } Boolean rescale_dimension_line(F_compound *dimline, float scalex, float scaley, int refx, int refy) { F_line *line, *box, *tick1, *tick2; F_text *text; double length, dx, dy, angle; float save_rotnangle, save_rotn_dirn; int p1x, p1y, p2x, p2y, centerx, centery; int x1, x2, y1, y2, save; int theight, tlen2, tht2; PR_SIZE tsize; char str[80], comment[100]; F_point *pnt; Boolean fixed_text; int save_lthick, save_t1thick, save_t2thick; /* locate the line components of the dimension line */ if (!dimline_components(dimline, &line, &tick1, &tick2, &box)) /* not a dimension line, return */ return False; /* see if user has deleted main line */ if (!line) return False; /* get the two endpoints and scale them */ p1x = round(refx + (line->points->x - refx) * scalex); p1y = round(refy + (line->points->y - refy) * scaley); p2x = round(refx + (line->points->next->x - refx) * scalex); p2y = round(refy + (line->points->next->y - refy) * scaley); /* put them back */ line->points->x = p1x; line->points->y = p1y; line->points->next->x = p2x; line->points->next->y = p2y; /* if drawn right to left or top to bottom at 90 degrees swap the two points */ if (p1x > p2x || (p1y < p2y && p1x == p2x)) { save = p1x; p1x = p2x; p2x = save; save = p1y; p1y = p2y; p2y = save; } dx = p2x-p1x; dy = p2y-p1y; /* get the text component */ text = dimline->texts; if (!text) { /* hmm, user must have deleted it */ text = create_text(); if (box) text->depth = box->depth-1; else text->depth = line->depth-2; add_depth(O_TXT, text->depth); text->cstring = (char *) NULL; /* the string will be put in later */ text->color = cur_dimline_textcolor; text->font = cur_dimline_font; text->size = cur_dimline_fontsize; text->flags = cur_dimline_psflag? PSFONT_TEXT: 0; text->pen_style = -1; text->type = T_CENTER_JUSTIFIED; dimline->texts = text; } fixed_text = text && text->comments && (strncasecmp(text->comments,"fixed text", 10)==0); if (!fixed_text) { /* length of the line */ length = sqrt(dx*dx + dy*dy); /* make text with the length */ make_dimension_string(length, str, False); /* put the new length in the comment */ sprintf(comment, "Dimension line: %s",str); /* free any old comment */ if (dimline->comments) free(dimline->comments); /* put in the new one */ dimline->comments = my_strdup(comment); } /* center the box for the length string */ centerx = (p1x+p2x)/2; centery = (p1y+p2y)/2; /* angle of the line */ angle = -atan2(dy, dx); /* recompute the text, text angle and text box */ /* new string, but only if comment doesn't say "fixed text" */ if (!fixed_text) { /* free any old string */ if (text->cstring) free(text->cstring); text->cstring = my_strdup(str); } /* recalculate text sizes */ text->fontstruct = lookfont(x_fontnum(text->flags, text->font), text->size); text->zoom = 1.0; tsize = textsize(text->fontstruct, strlen(text->cstring), text->cstring); text->ascent = tsize.ascent; text->descent = tsize.descent; text->length = tsize.length; theight = tsize.ascent + tsize.descent; text->angle = angle; text->base_x = centerx + sin(angle)*round(theight/2.0 - tsize.descent); text->base_y = centery + cos(angle)*round(theight/2.0 - tsize.descent); /* half the text length + a margin */ tlen2 = text->length/2 + 60; /* half the height + a margin */ tht2 = theight/2 + 60; /* save global rotation angle and direction to use our own */ save_rotnangle = act_rotnangle; save_rotn_dirn = rotn_dirn; act_rotnangle = -angle * 180.0 / M_PI; rotn_dirn = 1; /* now rescale the text box (the box) */ if (box) { pnt = box->points; pnt->x = centerx-tlen2; pnt->y = centery-tht2; pnt = pnt->next; pnt->x = centerx-tlen2; pnt->y = centery+tht2; pnt = pnt->next; pnt->x = centerx+tlen2; pnt->y = centery+tht2; pnt = pnt->next; pnt->x = centerx+tlen2; pnt->y = centery-tht2; pnt = pnt->next; pnt->x = centerx-tlen2; pnt->y = centery-tht2; /* rotate the box around the center */ rotate_line(box, centerx, centery); } /* if (box) */ /* now recalculate the end ticks */ if (tick1) { pnt = tick1->points; pnt->x = p1x; pnt->y = p1y-tht2; pnt = pnt->next; pnt->x = p1x; pnt->y = p1y+tht2; /* rotate the line around the endpoint */ rotate_line(tick1, p1x, p1y); } /* the other tick */ if (tick2) { pnt = tick2->points; pnt->x = p2x; pnt->y = p2y-tht2; pnt = pnt->next; pnt->x = p2x; pnt->y = p2y+tht2; /* rotate the line around the endpoint */ rotate_line(tick2, p2x, p2y); } /* restore original rotation angle and direction */ act_rotnangle = save_rotnangle; rotn_dirn = save_rotn_dirn; /* get the bounds of the compound */ /* but set the thicknesses of the line and ticks to 0 so they aren't taken into account */ save_lthick = line->thickness; line->thickness = 0; if (tick1) { save_t1thick = tick1->thickness; tick1->thickness = 0; } if (tick2) { save_t2thick = tick2->thickness; tick2->thickness = 0; } compound_bound(dimline, &x1, &y1, &x2, &y2); /* restore the thicknesses */ line->thickness = save_lthick; if (tick1) tick1->thickness = save_t1thick; if (tick2) tick2->thickness = save_t2thick; dimline->nwcorner.x = x1; dimline->nwcorner.y = y1; dimline->secorner.x = x2; dimline->secorner.y = y2; return True; } static void scale_line(F_line *l, float sx, float sy, int refx, int refy) { F_point *p; for (p = l->points; p != NULL; p = p->next) { p->x = round(refx + (p->x - refx) * sx); p->y = round(refy + (p->y - refy) * sy); } /* now scale the radius for an arc-box */ if (l->type == T_ARCBOX) { int h,w; /* scale by the average of height/width factor */ l->radius = round(l->radius * (sx+sy)/2); /* if the radius is larger than half the width or height, set it to the minimum of the width or heigth divided by 2 */ w = abs(l->points->x-l->points->next->next->x); h = abs(l->points->y-l->points->next->next->y); if ((l->radius > w/2) || (l->radius > h/2)) l->radius = min2(w,h)/2; /* finally, if it is 0, make it 1 */ if (l->radius == 0) l->radius = 1; } /* finally, scale any arrowheads */ scale_arrows(l,sx,sy); } static void scale_spline(F_spline *s, float sx, float sy, int refx, int refy) { F_point *p; for (p = s->points; p != NULL; p = p->next) { p->x = round(refx + (p->x - refx) * sx); p->y = round(refy + (p->y - refy) * sy); } /* scale any arrowheads */ scale_arrows((F_line *)s,sx,sy); } static void scale_arc(F_arc *a, float sx, float sy, int refx, int refy) { int i; F_point p[3]; for (i = 0; i < 3; i++) { /* save original points for co-linear check later */ p[i].x = a->point[i].x; p[i].y = a->point[i].y; a->point[i].x = round(refx + (a->point[i].x - refx) * sx); a->point[i].y = round(refy + (a->point[i].y - refy) * sy); } if (compute_arccenter(a->point[0], a->point[1], a->point[2], &a->center.x, &a->center.y) == 0) { /* the new arc is co-linear, move the middle point one pixel */ if (a->point[0].x == a->point[1].x) { /* vertical, move middle left or right */ if (p[1].x > p[0].x) a->point[1].x++; /* convex to the right -> ) */ else a->point[1].x--; /* convex to the left -> ( */ } /* check ALSO for horizontally co-linear in case all three points are equal */ if (a->point[0].y == a->point[1].y) { /* horizontal, move middle point up or down */ if (p[1].y > p[0].y) a->point[1].y++; /* curves up */ else a->point[1].y--; /* curves down */ } /* now check if the endpoints are equal, move one of them */ if (a->point[0].x == a->point[2].x && a->point[0].y == a->point[2].y) a->point[2].x++; /* make up a center */ a->center.x = a->point[1].x; a->center.y = a->point[1].y; } a->direction = compute_direction(a->point[0], a->point[1], a->point[2]); /* scale any arrowheads */ scale_arrows((F_line *)a,sx,sy); } static void scale_ellipse(F_ellipse *e, float sx, float sy, int refx, int refy) { e->center.x = round(refx + (e->center.x - refx) * sx); e->center.y = round(refy + (e->center.y - refy) * sy); e->start.x = round(refx + (e->start.x - refx) * sx); e->start.y = round(refy + (e->start.y - refy) * sy); e->end.x = round(refx + (e->end.x - refx) * sx); e->end.y = round(refy + (e->end.y - refy) * sy); e->radiuses.x = abs(round(e->radiuses.x * sx)); e->radiuses.y = abs(round(e->radiuses.y * sy)); /* if this WAS a circle and is NOW an ellipse, change type to reflect */ if (e->type == T_CIRCLE_BY_RAD || e->type == T_CIRCLE_BY_DIA) { if (e->radiuses.x != e->radiuses.y) e->type -= 2; } /* conversely, if this WAS an ellipse and is NOW a circle, change type */ else if (e->type == T_ELLIPSE_BY_RAD || e->type == T_ELLIPSE_BY_DIA) { if (e->radiuses.x == e->radiuses.y) e->type += 2; } } static void scale_text(F_text *t, float sx, float sy, int refx, int refy) { int newsize; t->base_x = round(refx + (t->base_x - refx) * sx); t->base_y = round(refy + (t->base_y - refy) * sy); if (!rigid_text(t)) { newsize = round(t->size * sx); if (newsize < MIN_FONT_SIZE) sx = (float) MIN_FONT_SIZE / t->size; else if (MAX_FONT_SIZE < newsize) sx = (float) MAX_FONT_SIZE / t->size; t->size = round(t->size * sx); t->ascent = round(t->ascent * sx); t->descent = round(t->descent * sx); t->length = round(t->length * sx); } /* rescale font */ reload_text_fstruct(t); } /*************************** line ********************************/ static Boolean init_boxscale_line(int x, int y) { int xmin, ymin, xmax, ymax; F_point *p0, *p1, *p2; double dx, dy, l; if (cur_l->type != T_BOX && cur_l->type != T_ARCBOX && cur_l->type != T_PICTURE) { put_msg(BOX_SCL2_MSG); beep(); return False; } p0 = cur_l->points; p1 = p0->next; p2 = p1->next; xmin = min3(p0->x, p1->x, p2->x); ymin = min3(p0->y, p1->y, p2->y); xmax = max3(p0->x, p1->x, p2->x); ymax = max3(p0->y, p1->y, p2->y); if (xmin == xmax || ymin == ymax) { put_msg(BOX_SCL_MSG); beep(); return False; } set_action_on(); toggle_linemarker(cur_l); if (x == xmin) { fix_x = xmax; from_x = x; if (y == ymin) { fix_y = ymax; from_y = y; constrained = BOX_SCALE; } else if (y == ymax) { fix_y = ymin; from_y = y; constrained = BOX_SCALE; } else { fix_y = ymax; from_y = ymin; constrained = BOX_HSTRETCH; } } else if (x == xmax) { fix_x = xmin; from_x = x; if (y == ymin) { fix_y = ymax; from_y = y; constrained = BOX_SCALE; } else if (y == ymax) { fix_y = ymin; from_y = y; constrained = BOX_SCALE; } else { fix_y = ymax; from_y = ymin; constrained = BOX_HSTRETCH; } } else { if (y == ymin) { fix_y = ymax; from_y = y; fix_x = xmax; from_x = xmin; constrained = BOX_VSTRETCH; } else { /* y == ymax */ fix_y = ymin; from_y = y; fix_x = xmax; from_x = xmin; constrained = BOX_VSTRETCH; } } cur_x = from_x; cur_y = from_y; set_cursor(crosshair_cursor); if (constrained == BOX_SCALE) { dx = (double) (cur_x - fix_x); dy = (double) (cur_y - fix_y); l = sqrt(dx * dx + dy * dy); cosa = fabs(dx / l); sina = fabs(dy / l); } boxsize_msg(1); elastic_box(fix_x, fix_y, cur_x, cur_y); canvas_locmove_proc = constrained_resizing_box; canvas_ref_proc = elastic_fixedbox; canvas_leftbut_proc = fix_boxscale_line; canvas_rightbut_proc = cancel_boxscale_line; return True; } static void cancel_boxscale_line(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); toggle_linemarker(cur_l); wrapup_scale(); } static void fix_boxscale_line(int x, int y) { int owd,oht, nwd, nht; float scalex, scaley; elastic_box(fix_x, fix_y, cur_x, cur_y); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_box_pos(x, y, from_x, from_y, &x, &y); new_l = copy_line(cur_l); draw_line(cur_l, ERASE); assign_newboxpoint(new_l, fix_x, fix_y, x, y); owd = abs(cur_l->points->x - cur_l->points->next->next->x); oht = abs(cur_l->points->y - cur_l->points->next->next->y); nwd = abs(new_l->points->x - new_l->points->next->next->x); nht = abs(new_l->points->y - new_l->points->next->next->y); if (new_l->type == T_PICTURE) { if (signof(fix_x - from_x) != signof(fix_x - x)) new_l->pic->flipped = 1 - new_l->pic->flipped; if (signof(fix_y - from_y) != signof(fix_y - y)) new_l->pic->flipped = 1 - new_l->pic->flipped; } else if (new_l->type == T_ARCBOX) { /* scale the radius also */ scale_radius(cur_l, new_l, owd, oht, nwd, nht); } change_line(cur_l, new_l); scalex = 1.0 * nwd/owd; scaley = 1.0 * nht/oht; wrapup_scale(); /* redraw anything under the old line */ redisplay_line(cur_l); /* and the new one */ redisplay_line(new_l); } void scale_radius(F_line *old, F_line *new, int owd, int oht, int nwd, int nht) { float wdscale, htscale; wdscale = 1.0 * nwd/owd; htscale = 1.0 * nht/oht; /* scale by the average of height/width factor */ new->radius = round(new->radius * (wdscale+htscale)/2); /* next, if the radius is larger than half the width, set it to the minimum of the width or heigth divided by 2 */ if ((new->radius > nwd/2) || (new->radius > nht/2)) new->radius = min2(nwd,nht)/2; /* finally, if it is 0, make it 1 */ if (new->radius == 0) new->radius = 1; } static Boolean init_scale_line(void) { int sumx, sumy, cnt; F_point *p; p = cur_l->points; if (cur_l->type != T_POLYLINE) p = p->next; for (sumx = 0, sumy = 0, cnt = 0; p != NULL; p = p->next) { sumx = sumx + p->x; sumy = sumy + p->y; cnt++; } fix_x = sumx / cnt; fix_y = sumy / cnt; if (from_x == fix_x && from_y == fix_y) { put_msg("Center point selected, ignored"); return False; } set_action_on(); toggle_linemarker(cur_l); set_cursor(crosshair_cursor); if (cur_l->type == T_BOX || cur_l->type == T_ARCBOX || cur_l->type == T_PICTURE) { boxsize_msg(2); /* factor of 2 because measurement is from midpoint */ } elastic_scalepts(cur_l->points); canvas_locmove_proc = scaling_line; canvas_ref_proc = elastic_scale_curline; canvas_middlebut_proc = fix_scale_line; canvas_rightbut_proc = cancel_scale_line; return True; } static void cancel_scale_line(void) { canvas_ref_proc = canvas_locmove_proc = null_proc; elastic_scalepts(cur_l->points); /* erase last lengths if appres.showlengths is true */ erase_lengths(); toggle_linemarker(cur_l); wrapup_scale(); } static void fix_scale_line(int x, int y) { int owd,oht, nwd, nht; elastic_scalepts(cur_l->points); /* erase last lengths if appres.showlengths is true */ erase_lengths(); adjust_box_pos(x, y, from_x, from_y, &x, &y); /* make a copy of the original and save as unchanged object */ old_l = copy_line(cur_l); clean_up(); set_latestline(old_l); set_action_object(F_EDIT, O_POLYLINE); old_l->next = cur_l; /* now change the original to become the new object */ rescale_points(cur_l, x, y); /* and scale the radius if ARCBOX */ if (cur_l->type == T_ARCBOX) { owd = abs(old_l->points->x - old_l->points->next->next->x); oht = abs(old_l->points->y - old_l->points->next->next->y); nwd = abs(cur_l->points->x - cur_l->points->next->next->x); nht = abs(cur_l->points->y - cur_l->points->next->next->y); scale_radius(cur_l, cur_l, owd, oht, nwd, nht); } wrapup_scale(); /* redraw anything under the old line */ redisplay_line(old_l); /* and the new one */ redisplay_line(cur_l); } static void rescale_points(F_line *obj, int x, int y) { F_point *p; double newx, newy, oldx, oldy; double newd, oldd, scalefact; newx = x - fix_x; newy = y - fix_y; newd = sqrt(newx * newx + newy * newy); oldx = from_x - fix_x; oldy = from_y - fix_y; oldd = sqrt(oldx * oldx + oldy * oldy); scalefact = newd / oldd; for (p = obj->points; p != NULL; p = p->next) { p->x = fix_x + (p->x - fix_x) * scalefact; p->y = fix_y + (p->y - fix_y) * scalefact; } /* scale any arrows */ scale_arrows(obj,scalefact,scalefact); set_modifiedflag(); } /* scale arrowheads on passed object by sx,sy */ static void scale_arrows(F_line *obj, float sx, float sy) { scale_arrow(obj->for_arrow,sx,sy); scale_arrow(obj->back_arrow,sx,sy); } /* scale arrowhead by sx,sy - for now just use average of sx,sy for scale factor */ static void scale_arrow(F_arrow *arrow, float sx, float sy) { if (arrow == 0) return; /* scale the thickness by the average of the horizontal and vertical scale factors */ sx = ((float)fabs(sx)+(float)fabs(sy))/2.0; arrow->ht *= sx; arrow->wd *= sx; return; } xfig.3.2.5c/e_tangent.c0000700002656300244210000001051611641414046015467 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * This part Copyright (c) 1999-2002 Alexander Durner * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "paintop.h" #include "u_create.h" #include "u_elastic.h" #include "u_search.h" #include "u_smartsearch.h" #include "w_canvas.h" #include "w_mousefun.h" #include "w_setup.h" #include "f_util.h" #include "u_draw.h" #include "u_list.h" #include "u_markers.h" #include "w_cursor.h" #include "w_msgpanel.h" #define ZERO_TOLERANCE 2.0 static void init_tangent_adding(char *p, int type, int x, int y, int px, int py); static void init_normal_adding(char *p, int type, int x, int y, int px, int py); static void tangent_or_normal(int x, int y, int flag); static void tangent_normal_line(int x, int y, float vx, float vy); void tangent_selected(void) { set_mousefun("add tangent", "add normal", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = smart_null_proc; canvas_ref_proc = smart_null_proc; init_smart_searchproc_left(init_tangent_adding); init_smart_searchproc_middle(init_normal_adding); canvas_leftbut_proc = smart_object_search_left; canvas_middlebut_proc = smart_object_search_middle; canvas_rightbut_proc = smart_null_proc; set_cursor(pick9_cursor); /* force_nopositioning(); */ reset_action_on(); } /* smart_point1, smart_point2 are two points of the tangent */ static void init_tangent_adding(char *p, int type, int x, int y, int px, int py) { tangent_or_normal(px, py, 0); } static void init_normal_adding(char *p, int type, int x, int y, int px, int py) { tangent_or_normal(px, py, 1); } static void tangent_or_normal(int x, int y, int flag) { float dx, dy, length, sx, sy, tanlen; dx = (float)(smart_point2.x - smart_point1.x); dy = (float)(smart_point2.y - smart_point1.y); if (dx == 0.0 && dy == 0.0) length = 0.0; else length = sqrt(dx * dx + dy * dy); if (length < ZERO_TOLERANCE) { put_msg("%s", "singularity, can't draw tangent/normal"); beep(); return; } tanlen = cur_tangnormlen * (appres.INCHES? PIX_PER_INCH: PIX_PER_CM) / 2.0; sx = dx * tanlen / length; sy = dy * tanlen / length; if (flag) { tangent_normal_line(x, y, -sy, sx); put_msg("%s", "added normal"); } else { tangent_normal_line(x, y, sx, sy); put_msg("%s", "added tangent"); } } static void tangent_normal_line(int x, int y, float vx, float vy) { int dx, dy, xl, yl, xr, yr; F_line *line; dx = round(vx); dy = round(vy); xl = x - dx; yl = y - dy; xr = x + dx; yr = y + dy; if ((first_point = create_point()) == NULL) return; cur_point = first_point; first_point->x = xl; first_point->y = yl; first_point->next = NULL; append_point(x, y, &cur_point); append_point(xr, yr, &cur_point); if ((line = create_line()) == NULL) return; /* an error occured */ line->type = T_POLYLINE; line->style = cur_linestyle; line->thickness = cur_linewidth; line->pen_color = cur_pencolor; line->fill_color = cur_fillcolor; line->depth = cur_depth; line->pen_style = -1; line->join_style = cur_joinstyle; line->cap_style = cur_capstyle; line->fill_style = cur_fillstyle; line->style_val = cur_styleval * (cur_linewidth + 1) / 2; line->points = first_point; /* polyline; draw any arrows */ if (autoforwardarrow_mode) line->for_arrow = forward_arrow(); /* arrow will be drawn in draw_line below */ if (autobackwardarrow_mode) line->back_arrow = backward_arrow(); /* arrow will be drawn in draw_line below */ draw_line(line, PAINT); /* draw final */ add_line(line); toggle_linemarker(line); } xfig.3.2.5c/e_update.c0000700002656300244210000006426011641414046015316 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1991 by Paul King * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "mode.h" #include "paintop.h" #include "d_text.h" #include "u_create.h" #include "u_list.h" #include "u_draw.h" #include "u_search.h" #include "w_canvas.h" #include "w_drawprim.h" #include "w_indpanel.h" #include "w_mousefun.h" #include "w_msgpanel.h" #include "w_setup.h" #include "w_util.h" #include "e_scale.h" #include "f_util.h" #include "u_bound.h" #include "u_fonts.h" #include "u_free.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_util.h" static void init_update_object(F_line *p, int type, int x, int y, int px, int py); static void init_update_settings(F_line *p, int type, int x, int y, int px, int py); static Boolean keep_depth = False; static int delta_depth; #define min(a,b) ((a)<(b)) ? (a) : (b) #define up_part(lv,rv,mask) \ if (cur_updatemask & (mask)) \ (lv) = (rv) #define up_depth_part(lv,rv) \ if (cur_updatemask & I_DEPTH) \ (lv) = keep_depth ? \ (min((lv)+delta_depth,MAX_DEPTH)) : (rv) void up_dashdot (float styleval, int style, unsigned int mask); void up_from_arrow (F_arrow *arrow, int thick); void update_compound (F_compound *compound); void update_line (F_line *line); void update_text (F_text *text); void update_ellipse (F_ellipse *ellipse); void update_arc (F_arc *arc); void update_spline (F_spline *spline); void fix_fillstyle (void *object); void up_arrow (F_line *object); void update_lines (F_line *lines); void update_splines (F_spline *splines); void update_ellipses (F_ellipse *ellipses); void update_arcs (F_arc *arcs); void update_texts (F_text *texts); void update_compounds (F_compound *compounds); void update_selected(void) { set_mousefun("update object", "update settings", "", LOC_OBJ, LOC_OBJ, LOC_OBJ); canvas_kbd_proc = null_proc; canvas_locmove_proc = null_proc; canvas_ref_proc = null_proc; init_searchproc_left(init_update_object); init_searchproc_middle(init_update_settings); canvas_leftbut_proc = object_search_left; canvas_middlebut_proc = object_search_middle; canvas_rightbut_proc = null_proc; set_cursor(pick9_cursor); /* manage on the update buttons */ manage_update_buts(); reset_action_on(); } static int get_arrow_mode(F_line *object) { if (!object->for_arrow && !object->back_arrow) return L_NOARROWS; else if (object->for_arrow && !object->back_arrow) return L_FARROWS; else if (!object->for_arrow && object->back_arrow) return L_BARROWS; else return L_FBARROWS; } static int get_arrow_type(F_line *object) { int type; /* have to pick one or the other */ if (object->for_arrow) type = object->for_arrow->type*2 - 1 + object->for_arrow->style; else if (object->back_arrow) type = object->back_arrow->type*2 - 1 + object->back_arrow->style; else type = 0; if (type < 0) type = 0; return type; } /* update the indicator buttons FROM the selected object */ static void init_update_settings(F_line *p, int type, int x, int y, int px, int py) { int old_psfont_flag, new_psfont_flag; F_line *dline, *dtick1, *dtick2, *dbox; F_text *dtext; switch (type) { case O_COMPOUND: cur_c = (F_compound *) p; /* if this is a dimension line, update the dimline settings from it */ if (dimline_components(cur_c, &dline, &dtick1, &dtick2, &dbox)) { if (dline) { cur_dimline_thick = dline->thickness; cur_dimline_style = dline->style; cur_dimline_color = dline->pen_color; if (dline->back_arrow) { cur_dimline_leftarrow = dline->back_arrow->type*2 - 1 + dline->back_arrow->style; cur_dimline_arrowlength = dline->back_arrow->ht; cur_dimline_arrowwidth = dline->back_arrow->wd; } else { cur_dimline_leftarrow = 0; } if (dline->for_arrow) { cur_dimline_rightarrow = dline->for_arrow->type*2 - 1 + dline->for_arrow->style; cur_dimline_arrowlength = dline->for_arrow->ht; cur_dimline_arrowwidth = dline->for_arrow->wd; } else { cur_dimline_rightarrow = 0; } cur_dimline_ticks = (dtick1 || dtick2); if (dtick1) cur_dimline_tickthick = dtick1->thickness; else cur_dimline_tickthick = dtick2->thickness; } if (dbox) { cur_dimline_boxthick = dbox->thickness; cur_dimline_boxcolor = dbox->fill_color; } if (dtext = cur_c->texts) { cur_dimline_textcolor = dtext->color; cur_dimline_font = dtext->font; cur_dimline_fontsize = dtext->size; cur_dimline_psflag = (dtext->flags & PSFONT_TEXT)? 1:0; cur_dimline_fixed = (dtext->comments && (strncasecmp(dtext->comments,"fixed text", 10)==0)); } } /* only update the depth setting from the smallest depth in the compound */ if (cur_updatemask & I_DEPTH) { cur_depth = find_smallest_depth(cur_c); } break; case O_POLYLINE: cur_l = (F_line *) p; if (cur_l->type != T_PICTURE) { up_part(cur_linewidth, cur_l->thickness, I_LINEWIDTH); up_part(cur_fillstyle, cur_l->fill_style, I_FILLSTYLE); up_part(cur_pencolor, cur_l->pen_color, I_PEN_COLOR); up_part(cur_fillcolor, cur_l->fill_color, I_FILL_COLOR); up_part(cur_linestyle, cur_l->style, I_LINESTYLE); up_part(cur_joinstyle, cur_l->join_style, I_JOINSTYLE); up_part(cur_capstyle, cur_l->cap_style, I_CAPSTYLE); up_part(cur_styleval, cur_l->style_val*2./(cur_l->thickness+1.), I_LINESTYLE); /* update the dash length/dot gap value for cur_styleval */ up_dashdot(cur_styleval, cur_l->style, I_LINESTYLE); up_part(cur_arrowmode, get_arrow_mode(cur_l), I_ARROWMODE); up_part(cur_arrowtype, get_arrow_type(cur_l), I_ARROWTYPE); if (cur_l->back_arrow) up_from_arrow(cur_l->back_arrow,cur_l->thickness); if (cur_l->for_arrow) up_from_arrow(cur_l->for_arrow,cur_l->thickness); } else if (cur_l->pic->pic_cache && cur_l->pic->pic_cache->subtype == T_PIC_XBM) { /* only XBM pictures have color */ up_part(cur_pencolor, cur_l->pen_color, I_PEN_COLOR); } up_depth_part(cur_depth, cur_l->depth); if (cur_l->type == T_ARCBOX) up_part(cur_boxradius, cur_l->radius, I_BOXRADIUS); break; case O_TXT: cur_t = (F_text *) p; up_part(cur_textjust, cur_t->type, I_TEXTJUST); up_part(cur_pencolor, cur_t->color, I_PEN_COLOR); up_depth_part(cur_depth, cur_t->depth); up_part(cur_elltextangle, cur_t->angle/M_PI*180.0, I_ELLTEXTANGLE); old_psfont_flag = (cur_textflags & PSFONT_TEXT); new_psfont_flag = (cur_t->flags & PSFONT_TEXT); up_part(cur_textflags, cur_t->flags & ~PSFONT_TEXT, I_TEXTFLAGS); /* for the LaTeX/PostScript flag use I_FONT instead of I_TEXTFLAGS so the font type will change if necessary */ if (cur_updatemask & I_FONT) cur_textflags |= new_psfont_flag; else cur_textflags |= old_psfont_flag; if (using_ps) { /* must use {} because macro has 'if' */ up_part(cur_ps_font, cur_t->font, I_FONT); } else { /* must use {} because macro has 'if' */ up_part(cur_latex_font, cur_t->font, I_FONT); } up_part(cur_fontsize, cur_t->size, I_FONTSIZE); break; case O_ELLIPSE: cur_e = (F_ellipse *) p; up_part(cur_linewidth, cur_e->thickness, I_LINEWIDTH); up_part(cur_elltextangle, cur_e->angle/M_PI*180.0, I_ELLTEXTANGLE); up_part(cur_fillstyle, cur_e->fill_style, I_FILLSTYLE); up_part(cur_pencolor, cur_e->pen_color, I_PEN_COLOR); up_part(cur_fillcolor, cur_e->fill_color, I_FILL_COLOR); up_part(cur_linestyle, cur_e->style, I_LINESTYLE); up_part(cur_styleval, (cur_e->style_val*2.)/(cur_e->thickness+1.), I_LINESTYLE); /* update the dash length/dot gap value for cur_styleval */ up_dashdot(cur_styleval, cur_e->style, I_LINESTYLE); up_depth_part(cur_depth, cur_e->depth); break; case O_ARC: cur_a = (F_arc *) p; up_part(cur_linewidth, cur_a->thickness, I_LINEWIDTH); up_part(cur_fillstyle, cur_a->fill_style, I_FILLSTYLE); up_part(cur_pencolor, cur_a->pen_color, I_PEN_COLOR); up_part(cur_fillcolor, cur_a->fill_color, I_FILL_COLOR); up_part(cur_arctype, cur_a->type, I_ARCTYPE); up_part(cur_linestyle, cur_a->style, I_LINESTYLE); up_part(cur_styleval, (cur_a->style_val*2.)/(cur_a->thickness+1.), I_LINESTYLE); /* update the dash length/dot gap value for cur_styleval */ up_dashdot(cur_styleval, cur_a->style, I_LINESTYLE); up_part(cur_capstyle, cur_a->cap_style, I_CAPSTYLE); up_depth_part(cur_depth, cur_a->depth); up_part(cur_arrowmode, get_arrow_mode((F_line *)cur_a), I_ARROWMODE); up_part(cur_arrowtype, get_arrow_type((F_line *)cur_a), I_ARROWTYPE); if (cur_a->back_arrow) up_from_arrow(cur_a->back_arrow,cur_a->thickness); if (cur_a->for_arrow) up_from_arrow(cur_a->for_arrow,cur_a->thickness); break; case O_SPLINE: cur_s = (F_spline *) p; up_part(cur_linewidth, cur_s->thickness, I_LINEWIDTH); up_part(cur_fillstyle, cur_s->fill_style, I_FILLSTYLE); up_part(cur_pencolor, cur_s->pen_color, I_PEN_COLOR); up_part(cur_fillcolor, cur_s->fill_color, I_FILL_COLOR); up_part(cur_linestyle, cur_s->style, I_LINESTYLE); up_part(cur_styleval, (cur_s->style_val*2.)/(cur_s->thickness+1.), I_LINESTYLE); /* update the dash length/dot gap value for cur_styleval */ up_dashdot(cur_styleval, cur_s->style, I_LINESTYLE); if (cur_s->type == T_OPEN_APPROX || cur_s->type == T_OPEN_INTERP) up_part(cur_capstyle, cur_s->cap_style, I_CAPSTYLE); up_depth_part(cur_depth, cur_s->depth); up_part(cur_arrowmode, get_arrow_mode((F_line *)cur_s), I_ARROWMODE); up_part(cur_arrowtype, get_arrow_type((F_line *)cur_s), I_ARROWTYPE); if (cur_s->back_arrow) up_from_arrow(cur_s->back_arrow,cur_s->thickness); if (cur_s->for_arrow) up_from_arrow(cur_s->for_arrow,cur_s->thickness); break; default: return; } update_current_settings(); if (type == O_COMPOUND) { put_msg("Note: Only the (smallest) depth is retrieved from a compound object"); beep(); } else { put_msg("Settings UPDATED"); } } void up_from_arrow(F_arrow *arrow, int thick) { up_part(cur_arrowthick, arrow->thickness,I_ARROWSIZE); up_part(cur_arrowwidth, arrow->wd,I_ARROWSIZE); up_part(cur_arrowheight,arrow->ht,I_ARROWSIZE); up_part(cur_arrow_multthick, arrow->thickness,I_ARROWSIZE); up_part(cur_arrow_multwidth, arrow->wd,I_ARROWSIZE); up_part(cur_arrow_multheight,arrow->ht,I_ARROWSIZE); if (cur_updatemask & I_ARROWSIZE) { /* now get multiple to line width of object */ cur_arrow_multthick /= thick; cur_arrow_multwidth /= thick; cur_arrow_multheight /= thick; } } /* update the selected object FROM the indicator buttons */ static void init_update_object(F_line *p, int type, int x, int y, int px, int py) { int largest; Boolean dontupdate; dontupdate = False; switch (type) { case O_COMPOUND: set_temp_cursor(wait_cursor); cur_c = (F_compound *) p; new_c = copy_compound(cur_c); /* keep the depths of the objects inside the compound the same relative to each other, setting the depth of the *most shallow* to the desired depth */ keep_depth = True; largest = find_largest_depth(cur_c); /* find delta */ delta_depth = cur_depth - find_smallest_depth(cur_c); /* if renumbering would make depths too large don't allow it */ if ((delta_depth + largest > MAX_DEPTH) && (cur_updatemask & I_DEPTH)) { if (popup_query(QUERY_YESNO, "Some depths would exceed maximum - those objects\nwill be set to maximum depth. Update anyway?") != RESULT_YES) { delta_depth = 0; dontupdate = True; } } update_compound(new_c); keep_depth = False; change_compound(cur_c, new_c); /* redraw anything near the old comound */ redisplay_compound(cur_c); /* draw the new compound */ redisplay_compound(new_c); break; case O_POLYLINE: set_temp_cursor(wait_cursor); cur_l = (F_line *) p; new_l = copy_line(cur_l); update_line(new_l); change_line(cur_l, new_l); /* redraw anything near the old line */ redisplay_line(cur_l); /* draw the new line */ redisplay_line(new_l); break; case O_TXT: set_temp_cursor(wait_cursor); cur_t = (F_text *) p; new_t = copy_text(cur_t); update_text(new_t); change_text(cur_t, new_t); /* redraw anything near the old text */ redisplay_text(cur_t); /* draw the new text */ redisplay_text(new_t); break; case O_ELLIPSE: set_temp_cursor(wait_cursor); cur_e = (F_ellipse *) p; new_e = copy_ellipse(cur_e); update_ellipse(new_e); change_ellipse(cur_e, new_e); /* redraw anything near the old ellipse */ redisplay_ellipse(cur_e); /* draw the new ellipse */ redisplay_ellipse(new_e); break; case O_ARC: set_temp_cursor(wait_cursor); cur_a = (F_arc *) p; new_a = copy_arc(cur_a); update_arc(new_a); change_arc(cur_a, new_a); /* redraw anything near the old arc */ redisplay_arc(cur_a); /* draw the new arc */ redisplay_arc(new_a); break; case O_SPLINE: set_temp_cursor(wait_cursor); cur_s = (F_spline *) p; new_s = copy_spline(cur_s); update_spline(new_s); change_spline(cur_s, new_s); /* redraw anything near the old spline */ redisplay_spline(cur_s); /* draw the new spline */ redisplay_spline(new_s); break; default: return; } reset_cursor(); if (!dontupdate) put_msg("Object(s) UPDATED"); } void update_ellipse(F_ellipse *ellipse) { draw_ellipse(ellipse, ERASE); up_part(ellipse->thickness, cur_linewidth, I_LINEWIDTH); up_part(ellipse->angle, cur_elltextangle*M_PI/180.0, I_ELLTEXTANGLE); up_part(ellipse->style, cur_linestyle, I_LINESTYLE); up_part(ellipse->style_val, cur_styleval * (cur_linewidth + 1) / 2, I_LINESTYLE); up_part(ellipse->fill_style, cur_fillstyle, I_FILLSTYLE); up_part(ellipse->pen_color, cur_pencolor, I_PEN_COLOR); up_part(ellipse->fill_color, cur_fillcolor, I_FILL_COLOR); up_depth_part(ellipse->depth, cur_depth); fix_fillstyle(ellipse); /* make sure it has legal fill style if color changed */ /* updated object will be redisplayed by init_update_xxx() */ } void update_arc(F_arc *arc) { draw_arc(arc, ERASE); up_part(arc->thickness, cur_linewidth, I_LINEWIDTH); up_part(arc->style, cur_linestyle, I_LINESTYLE); up_part(arc->style_val, cur_styleval * (cur_linewidth + 1) / 2, I_LINESTYLE); up_part(arc->fill_style, cur_fillstyle, I_FILLSTYLE); up_part(arc->type, cur_arctype, I_ARCTYPE); up_part(arc->cap_style, cur_capstyle, I_CAPSTYLE); up_part(arc->pen_color, cur_pencolor, I_PEN_COLOR); up_part(arc->fill_color, cur_fillcolor, I_FILL_COLOR); up_depth_part(arc->depth, cur_depth); /* check new type - if pie-wedge and there are any arrows, delete them */ if (arc->type == T_PIE_WEDGE_ARC) { if (arc->for_arrow) { free((char *) arc->for_arrow); arc->for_arrow = NULL; } if (arc->back_arrow) { free((char *) arc->back_arrow); arc->back_arrow = NULL; } } else { /* if not wedge type, update any arrow settings */ up_arrow((F_line *)arc); } fix_fillstyle(arc); /* make sure it has legal fill style if color changed */ /* updated object will be redisplayed by init_update_xxx() */ } void update_line(F_line *line) { draw_line(line, ERASE); up_part(line->thickness, cur_linewidth, I_LINEWIDTH); if (line->type != T_PICTURE) { up_part(line->style, cur_linestyle, I_LINESTYLE); up_part(line->style_val, cur_styleval * (cur_linewidth + 1) / 2, I_LINESTYLE); up_part(line->join_style, cur_joinstyle, I_JOINSTYLE); up_part(line->cap_style, cur_capstyle, I_CAPSTYLE); up_part(line->pen_color, cur_pencolor, I_PEN_COLOR); up_part(line->fill_color, cur_fillcolor, I_FILL_COLOR); up_part(line->radius, cur_boxradius, I_BOXRADIUS); up_part(line->fill_style, cur_fillstyle, I_FILLSTYLE); } else if (line->pic->pic_cache && line->pic->pic_cache->subtype == T_PIC_XBM) { /* only XBM pictures have color */ up_part(line->pen_color, cur_pencolor, I_PEN_COLOR); } up_depth_part(line->depth, cur_depth); /* only POLYLINES with more than one point may have arrow heads */ if (line->type == T_POLYLINE && line->points->next != NULL) up_arrow(line); fix_fillstyle(line); /* make sure it has legal fill style if color changed */ /* updated object will be redisplayed by init_update_xxx() */ } void update_text(F_text *text) { PR_SIZE size; int old_psfont_flag, new_psfont_flag; draw_text(text, ERASE); up_part(text->type, cur_textjust, I_TEXTJUST); up_part(text->font, using_ps ? cur_ps_font : cur_latex_font, I_FONT); old_psfont_flag = (text->flags & PSFONT_TEXT); new_psfont_flag = (cur_textflags & PSFONT_TEXT); /* turn off any postscript flags */ text->flags &= ~PSFONT_TEXT; /* set text flags to current settings */ up_part(text->flags, cur_textflags, I_TEXTFLAGS); /* for the LaTeX/PostScript flag use I_FONT instead of I_TEXTFLAGS so the font type will change if necessary */ /* and update with new font type */ if (cur_updatemask & I_FONT) text->flags |= new_psfont_flag; else text->flags |= old_psfont_flag; up_part(text->size, cur_fontsize, I_FONTSIZE); up_part(text->angle, cur_elltextangle*M_PI/180.0, I_ELLTEXTANGLE); up_part(text->color, cur_pencolor, I_PEN_COLOR); up_depth_part(text->depth, cur_depth); size = textsize(lookfont(x_fontnum(psfont_text(text), text->font), text->size), strlen(text->cstring), text->cstring); text->ascent = size.ascent; text->descent = size.descent; text->length = size.length; reload_text_fstruct(text); /* make sure fontstruct is current */ /* updated object will be redisplayed by init_update_xxx() */ } void update_spline(F_spline *spline) { draw_spline(spline, ERASE); up_part(spline->thickness, cur_linewidth, I_LINEWIDTH); up_part(spline->style, cur_linestyle, I_LINESTYLE); up_part(spline->style_val, cur_styleval * (cur_linewidth + 1) / 2, I_LINESTYLE); if (spline->type == T_OPEN_APPROX || spline->type == T_OPEN_INTERP) up_part(spline->cap_style, cur_capstyle, I_CAPSTYLE); up_part(spline->fill_style, cur_fillstyle, I_FILLSTYLE); up_part(spline->pen_color, cur_pencolor, I_PEN_COLOR); up_part(spline->fill_color, cur_fillcolor, I_FILL_COLOR); up_depth_part(spline->depth, cur_depth); if (open_spline(spline)) up_arrow((F_line *)spline); fix_fillstyle(spline); /* make sure it has legal fill style if color changed */ /* updated object will be redisplayed by init_update_xxx() */ } /* check that the fill style is legal for the color in the object */ /* WARNING: this procedure assumes that splines, lines, arcs and ellipses all have the same structure up to the fill_style and color */ void fix_fillstyle(void *obj) { F_line *object = obj; if (object->fill_color == BLACK || object->fill_color == DEFAULT || object->fill_color == DEFAULT) { if (object->fill_style >= NUMSHADEPATS && object->fill_style < NUMSHADEPATS+NUMTINTPATS) object->fill_style = UNFILLED; } /* a little sanity check */ if (object->fill_style < DEFAULT) object->fill_style = DEFAULT; if (object->fill_style >= NUMFILLPATS) object->fill_style = NUMFILLPATS; } void up_arrow(F_line *object) { if (object->for_arrow) { up_part(object->for_arrow->type, ARROW_TYPE(cur_arrowtype), I_ARROWTYPE); up_part(object->for_arrow->style, ARROW_STYLE(cur_arrowtype), I_ARROWTYPE); if (use_abs_arrowvals) { up_part(object->for_arrow->thickness,cur_arrowthick,I_ARROWSIZE); up_part(object->for_arrow->wd,cur_arrowwidth,I_ARROWSIZE); up_part(object->for_arrow->ht,cur_arrowheight,I_ARROWSIZE); } else { up_part(object->for_arrow->thickness, cur_arrow_multthick*object->thickness, I_ARROWSIZE); up_part(object->for_arrow->wd, cur_arrow_multwidth*object->thickness, I_ARROWSIZE); up_part(object->for_arrow->ht, cur_arrow_multheight*object->thickness, I_ARROWSIZE); } } if (object->back_arrow) { up_part(object->back_arrow->type, ARROW_TYPE(cur_arrowtype), I_ARROWTYPE); up_part(object->back_arrow->style, ARROW_STYLE(cur_arrowtype), I_ARROWTYPE); if (use_abs_arrowvals) { up_part(object->back_arrow->thickness,cur_arrowthick,I_ARROWSIZE); up_part(object->back_arrow->wd,cur_arrowwidth,I_ARROWSIZE); up_part(object->back_arrow->ht,cur_arrowheight,I_ARROWSIZE); } else { up_part(object->back_arrow->thickness, cur_arrow_multthick*object->thickness,I_ARROWSIZE); up_part(object->back_arrow->wd, cur_arrow_multwidth*object->thickness,I_ARROWSIZE); up_part(object->back_arrow->ht, cur_arrow_multheight*object->thickness, I_ARROWSIZE); } } if (! (cur_updatemask & I_ARROWMODE)) return; if (autoforwardarrow_mode) { if (object->for_arrow) { if (use_abs_arrowvals) { object->for_arrow->thickness = cur_arrowthick; object->for_arrow->wd = cur_arrowwidth; object->for_arrow->ht = cur_arrowheight; } else { object->for_arrow->thickness = cur_arrow_multthick*cur_linewidth; object->for_arrow->wd = cur_arrow_multwidth*cur_linewidth; object->for_arrow->ht = cur_arrow_multheight*cur_linewidth; } } else /* no arrowhead at all yet, create a new one */ up_part(object->for_arrow, forward_arrow(), I_ARROWMODE); } else { /* delete arrowhead if one exists */ if (object->for_arrow) { free((char *) object->for_arrow); object->for_arrow = NULL; } } if (autobackwardarrow_mode) { if (object->back_arrow) { if (use_abs_arrowvals) { object->back_arrow->thickness = cur_arrowthick; object->back_arrow->wd = cur_arrowwidth; object->back_arrow->ht = cur_arrowheight; } else { object->back_arrow->thickness = cur_arrow_multthick*cur_linewidth; object->back_arrow->wd = cur_arrow_multwidth*cur_linewidth; object->back_arrow->ht = cur_arrow_multheight*cur_linewidth; } } else { /* no arrowhead at all yet, create a new one */ up_part(object->back_arrow, backward_arrow(), I_ARROWMODE); } } else { /* delete arrowhead if one exists */ if (object->back_arrow) { free((char *) object->back_arrow); object->back_arrow = NULL; } } } void update_compound(F_compound *compound) { F_line *dline, *dtick1, *dtick2, *dbox; F_text *dtext; /* if this is a dimension line, update its settings from the dimline settings */ if (dimline_components(compound, &dline, &dtick1, &dtick2, &dbox)) { if (dline) { dline->thickness = cur_dimline_thick; dline->style = cur_dimline_style; dline->pen_color = cur_dimline_color; /* free old left arrow */ if (dline->back_arrow) { free((char *) dline->back_arrow); dline->back_arrow = NULL; } /* create new one if setting says so */ if (cur_dimline_leftarrow != -1) dline->back_arrow = backward_dim_arrow(); /* free old right arrow */ if (dline->for_arrow) { free((char *) dline->for_arrow); dline->for_arrow = NULL; } /* create new one if setting says so */ if (cur_dimline_rightarrow != -1) dline->for_arrow = forward_dim_arrow(); /* update text box */ if (dbox) { /* attach the polygon after the main line */ dline->next = dbox; dbox->thickness = cur_dimline_boxthick; dbox->fill_color = cur_dimline_boxcolor; } } /* if (dline) */ /* free any old ticks */ if (dtick1) free_linestorage(dtick1); if (dtick2) free_linestorage(dtick2); /* create new ones if user wants */ if (cur_dimline_ticks) { create_dimline_ticks(dline, &dtick1, &dtick2); /* attach it to the previous object in the compound */ if (dbox) dbox->next = dtick1; else dline->next = dtick1; dtick1->next = dtick2; } else { /* no ticks, terminate list of lines after box */ if (dbox) dbox->next = (F_line *) NULL; } /* now put the new line list into the compound */ if (dline) compound->lines = dline; else compound->lines = dbox; /* finally, the text */ if (dtext = compound->texts) { dtext->color = cur_dimline_textcolor; dtext->font = cur_dimline_font; dtext->size = cur_dimline_fontsize; dtext->flags = cur_dimline_psflag? PSFONT_TEXT: 0; /* free any comments in the text */ if (dtext->comments) free((char *) dtext->comments); if (cur_dimline_fixed) dtext->comments = my_strdup("fixed text"); } /* now update the depths of the components */ up_depth_part(dline->depth, cur_depth); if (dbox) up_depth_part(dbox->depth, cur_depth); if (dtick1) up_depth_part(dtick1->depth, cur_depth); if (dtick2) up_depth_part(dtick2->depth, cur_depth); if (dtext) up_depth_part(dtext->depth, cur_depth); /* finally, rescale if necessary */ rescale_dimension_line(compound, 1.0, 1.0, 0, 0); /* end of dimension line update */ } else { /* ordinary compound */ update_lines(compound->lines); update_splines(compound->splines); update_ellipses(compound->ellipses); update_arcs(compound->arcs); update_texts(compound->texts); update_compounds(compound->compounds); } compound_bound(compound, &compound->nwcorner.x, &compound->nwcorner.y, &compound->secorner.x, &compound->secorner.y); } void update_arcs(F_arc *arcs) { F_arc *a; for (a = arcs; a != NULL; a = a->next) update_arc(a); } void update_compounds(F_compound *compounds) { F_compound *c; for (c = compounds; c != NULL; c = c->next) update_compound(c); } void update_ellipses(F_ellipse *ellipses) { F_ellipse *e; for (e = ellipses; e != NULL; e = e->next) update_ellipse(e); } void update_lines(F_line *lines) { F_line *l; for (l = lines; l != NULL; l = l->next) update_line(l); } void update_splines(F_spline *splines) { F_spline *s; for (s = splines; s != NULL; s = s->next) update_spline(s); } void update_texts(F_text *texts) { F_text *t; for (t = texts; t != NULL; t = t->next) update_text(t); } void up_dashdot(float styleval, int style, unsigned int mask) { if ((style == DASH_LINE) || (style == DASH_DOT_LINE) || (style == DASH_2_DOTS_LINE) || (style == DASH_3_DOTS_LINE)) { cur_dashlength = styleval; } else if (style == DOTTED_LINE) { cur_dotgap = styleval; } } xfig.3.2.5c/f_load.c0000700002656300244210000002531411641414046014751 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "figx.h" #include "resources.h" #include "mode.h" #include "object.h" #include "f_read.h" #include "f_util.h" #include "u_create.h" #include "u_undo.h" #include "w_cmdpanel.h" #include "w_export.h" #include "w_file.h" #include "w_indpanel.h" #include "w_layers.h" #include "w_msgpanel.h" #include "w_rulers.h" #include "w_print.h" #include "w_util.h" #include "w_setup.h" #include "e_compound.h" #include "u_bound.h" #include "u_draw.h" #include "u_list.h" #include "u_redraw.h" #include "w_cursor.h" #include "w_grid.h" /* LOCAL declarations */ void read_fail_message(char *file, int err); /* load Fig file. Call with: file = name of Fig file xoff, yoff = offset from 0 (Fig units) */ void update_settings (fig_settings *settings); void update_recent_list (char *file); int load_file(char *file, int xoff, int yoff) { int s; F_compound c; fig_settings settings; put_msg("Loading file %s...",file); c.parent = NULL; c.GABPtr = NULL; c.arcs = NULL; c.compounds = NULL; c.ellipses = NULL; c.lines = NULL; c.splines = NULL; c.texts = NULL; c.comments = NULL; c.next = NULL; set_temp_cursor(wait_cursor); /* initialize the active_layers array */ reset_layers(); /* and depth counters */ reset_depths(); /* object counters for depths */ clearallcounts(); s = read_figc(file, &c, DONT_MERGE, REMAP_IMAGES, xoff, yoff, &settings); defer_update_layers = 1; /* so update_layers() won't update for each object */ add_compound_depth(&c); /* count objects at each depth */ defer_update_layers = 0; update_layers(); if (s == 0) { /* Successful read */ clean_up(); (void) strcpy(save_filename, cur_filename); update_cur_filename(file); /* in case the user is inside any compounds */ close_all_compounds(); saved_objects = objects; objects = c; /* update the settings in appres.xxx from the settings struct returned from read_fig */ update_settings(&settings); /* reset the grid menus in print/export panels */ reset_grid_menus(appres.INCHES); /* and draw the figure on the canvas*/ redisplay_canvas(); put_msg("Current figure \"%s\" (%d objects)", file, num_object); set_action(F_LOAD); reset_cursor(); /* reset modified flag in case any change in orientation set it */ reset_modifiedflag(); /* update the recent list */ update_recent_list(file); return 0; } else if (s == ENOENT || s == EMPTY_FILE) { char fname[PATH_MAX]; clean_up(); saved_objects = objects; objects = c; redisplay_canvas(); put_msg("Current figure \"%s\" (new file)", file); (void) strcpy(save_filename, cur_filename); /* update current file name with null */ update_cur_filename(file); /* update title bar with "(new file)" */ strcpy(fname,file); strcat(fname," (new file)"); update_wm_title(fname); set_action(F_LOAD); reset_cursor(); reset_modifiedflag(); return 0; } read_fail_message(file, s); reset_modifiedflag(); reset_cursor(); return 1; } void update_settings(fig_settings *settings) { DeclareArgs(2); char buf[30]; /* set landscape flag oppositely and change_orient() will toggle it */ if (settings->landscape != (int) appres.landscape) { /* change_orient toggles */ appres.landscape = ! ((Boolean) settings->landscape); /* now change the orientation of the canvas */ change_orient(); /* and flush to let things settle out */ app_flush(); } /* set the printer and export justification labels */ appres.flushleft = settings->flushleft; FirstArg(XtNlabel, just_items[(int)settings->flushleft]); if (export_popup) SetValues(export_just_panel); if (print_popup) SetValues(print_just_panel); /* set the rulers/grid accordingly */ if (settings->units != (int) appres.INCHES || cur_gridunit != settings->grid_unit) { /* reset the units string for the length messages */ strcpy(cur_fig_units, settings->units ? "in" : "cm"); /* and grid unit (1/16th, 1/10th, etc) */ cur_gridunit = settings->grid_unit; appres.INCHES = (Boolean) settings->units; /* PIC_FACTOR is the number of Fig units per printer points (1/72 inch) */ /* it changes with Metric and Imperial */ PIC_FACTOR = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/72.0; /* make sure we aren't previewing a figure in the file panel */ if (canvas_win == main_canvas) { reset_rulers(); init_grid(); setup_grid(); /* change the label in the units widget */ FirstArg(XtNlabel, appres.INCHES ? "in" : "cm"); SetValues(unitbox_sw); } } /* set the unit indicator in the upper-right corner */ set_unit_indicator(False); /* paper size */ if ((appres.papersize = settings->papersize) < 0) { file_msg("Illegal paper size in file, using default"); appres.papersize = (appres.INCHES? PAPER_LETTER: PAPER_A4); } /* and the print and export paper size menus */ FirstArg(XtNlabel, paper_sizes[appres.papersize].fname); if (export_popup) SetValues(export_papersize_panel); if (print_popup) SetValues(print_papersize_panel); appres.magnification = settings->magnification; /* set the magnification in the export and print panels */ sprintf(buf,"%.2f",appres.magnification); FirstArg(XtNstring, buf); if (export_popup) SetValues(export_mag_text); if (print_popup) { SetValues(print_mag_text); print_update_figure_size(); } /* multi-page setting */ appres.multiple = settings->multiple; FirstArg(XtNlabel, multiple_pages[(int)appres.multiple]); if (export_popup) SetValues(export_multiple_panel); if (print_popup) SetValues(print_multiple_panel); /* GIF transparent color */ appres.transparent = settings->transparent; /* make colorname from number */ set_color_name(appres.transparent, buf); FirstArg(XtNlabel, buf); if (export_popup) SetValues(export_transp_panel); } void merge_file(char *file, int xoff, int yoff) { F_compound *c, *c2; int s; fig_settings settings; if ((c = create_compound()) == NULL) return; c->arcs = NULL; c->compounds = NULL; c->ellipses = NULL; c->lines = NULL; c->splines = NULL; c->texts = NULL; c->comments = NULL; c->next = NULL; set_temp_cursor(wait_cursor); /* clear picture object read flag */ pic_obj_read = False; /* read merged file into compound */ s = read_figc(file, c, MERGE, DONT_REMAP_IMAGES, xoff, yoff, &settings); if (s == 0) { /* Successful read */ /* only if there are objects other than user colors */ if (c) { /* if there are no objects other than one compound, don't encapsulate it in another compound */ if (c->arcs == 0 && c->ellipses == 0 && c->lines == 0 && c->splines == 0 && c->texts == 0 && (c->compounds != 0 && c->compounds->next == 0)) { /* save ptr to embedded compound */ c2 = c->compounds; /* free the toplevel */ free((char *) c); c = c2; } compound_bound(c, &c->nwcorner.x, &c->nwcorner.y, &c->secorner.x, &c->secorner.y); clean_up(); /* add the depths of the objects besides adding the objects to the main list */ list_add_compound(&objects.compounds, c); set_latestcompound(c); } /* must remap all EPS/GIF/XPMs now if any new pic objects were read */ if (pic_obj_read) remap_imagecolors(); redraw_images(&objects); if (c) redisplay_zoomed_region(c->nwcorner.x, c->nwcorner.y, c->secorner.x, c->secorner.y); put_msg("%d object(s) read from \"%s\"", num_object, file); set_action_object(F_ADD, O_COMPOUND); reset_cursor(); set_modifiedflag(); } read_fail_message(file, s); reset_cursor(); } /* update the recent list */ void update_recent_list(char *file) { int i; char *name, path[PATH_MAX], num[3]; /* prepend path if not already in name */ if (file[0] != '/') { /* prepend path if not already there */ get_directory(path); strcat(path, "/"); strcat(path, file); file = path; } /* if this name is already in the list, delete it and move list up */ for (i=0; i0; i--) { if (i >= max_recent_files) { /* pushing one off the end, free it's name */ free(recent_files[i-1].name); continue; } /* shift down */ recent_files[i] = recent_files[i-1]; /* renumber entry */ sprintf(num,"%1d",i+1); strncpy(recent_files[i].name,num,1); } /* put new entry in first slot */ /* prepend with file number (1) */ name = new_string(strlen(file)+4); sprintf(name,"1 %s",file); recent_files[0].name = name; if (num_recent_files < max_recent_files) num_recent_files++; /* now recreate the File menu with the new filenames */ rebuild_file_menu(None); /* now update the user's .xfigrc file with the file list */ update_recent_files(); } void read_fail_message(char *file, int err) { if (err == 0) /* Successful read */ return; #ifdef ENAMETOOLONG else if (err == ENAMETOOLONG) file_msg("File name \"%s\" is too long", file); #endif /* ENAMETOOLONG */ else if (err == ENOENT) file_msg("File \"%s\" does not exist.", file); else if (err == ENOTDIR) file_msg("A name in the path \"%s\" is not a directory.", file); else if (err == EACCES) file_msg("Read access to file \"%s\" is blocked.", file); else if (err == EISDIR) file_msg("File \"%s\" is a directory.", file); else if (err == NO_VERSION) file_msg("File \"%s\" has no version number in header.", file); else if (err == EMPTY_FILE) file_msg("File \"%s\" is empty.", file); else if (err == BAD_FORMAT) /* Format error; relevant error message is already delivered */ ; else file_msg("File \"%s\" is not accessable; %s.", file, strerror(err)); } xfig.3.2.5c/f_neuclrtab.c0000700002656300244210000003451211641414046016011 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1994 Anthony Dekker * Parts Copyright (c) 1989-2007 by Brian V. Smith * * [NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. * See "Kohonen neural networks for optimal colour quantization" * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. * for a discussion of the algorithm.] * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* * Neural-Net quantization algorithm based on work of Anthony Dekker */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_neuclrtab.h" #include "f_util.h" #include static void initnet(void); static void learn(void); static void unbiasnet(void); static void cpyclrtab(void); static void inxbuild(void); static int contest(register int b, register int g, register int r); static void alterneigh(int rad, int i, register int b, register int g, register int r); static void altersingle(register int alpha, register int i, register int b, register int g, register int r); static int inxsearch(register int b, register int g, register int r); #define MAXNETSIZE 256 /* our color table (global) */ BYTE clrtab[256][3]; static int netsize; #ifndef DEFSMPFAC # ifdef SPEED # define DEFSMPFAC (240/SPEED+3) # else # define DEFSMPFAC 30 /* only sample every 30th pixel */ # endif /* SPEED */ #endif /* DEFSMPFAC */ int samplefac = DEFSMPFAC; /* sampling factor */ /* Samples array starts off holding spacing between adjacent * samples, and ends up holding actual BGR sample values. */ static BYTE *thesamples; static int nsamples; static BYTE *cursamp; static long skipcount; #define MAXSKIP (1<<24-1) #define nskip(sp) ((long)(sp)[0]<<16|(long)(sp)[1]<<8|(long)(sp)[2]) #define setskip(sp,n) ((sp)[0]=(n)>>16,(sp)[1]=((n)>>8)&255,(sp)[2]=(n)&255) /* npixels is the total number of pixels defined */ void neu_dith_colrs (register BYTE *bs, register COLR (*cs), int n); int neu_init(long int npixels) /* initialize our sample array */ { if (npixels < MIN_NEU_SAMPLES) samplefac = 1; else samplefac = DEFSMPFAC; return neu_init2(npixels); } int neu_init2(long int npixels) /* initialize our sample array */ { register int nsleft; register long sv; double rval, cumprob; long npleft; nsamples = npixels/samplefac; if (nsamples < MIN_NEU_SAMPLES) return((int)-MIN_NEU_SAMPLES/nsamples-1); /* THIS IS DIFFERENT FROM THE ORIGINAL -1 */ thesamples = (BYTE *)malloc(nsamples*3); if (thesamples == NULL) return(-1); cursamp = thesamples; npleft = npixels; nsleft = nsamples; while (nsleft) { rval = frandom(); /* random distance to next sample */ sv = 0; cumprob = 0.; while ((cumprob += (1.-cumprob)*nsleft/(npleft-sv)) < rval) sv++; if (nsleft == nsamples) skipcount = sv; else { setskip(cursamp, sv); cursamp += 3; } npleft -= sv+1; nsleft--; } setskip(cursamp, npleft); /* tag on end to skip the rest */ cursamp = thesamples; return(0); } void neu_pixel(register BYTE *col) /* add pixel to our samples */ { if (!skipcount--) { skipcount = nskip(cursamp); cursamp[0] = col[N_BLU]; cursamp[1] = col[N_GRN]; cursamp[2] = col[N_RED]; cursamp += 3; } } void neu_colrs(register COLR (*cs), register int n) /* add a scanline to our samples */ { while (n > skipcount) { cs += skipcount; n -= skipcount+1; skipcount = nskip(cursamp); cursamp[0] = cs[0][N_BLU]; cursamp[1] = cs[0][N_GRN]; cursamp[2] = cs[0][N_RED]; cs++; cursamp += 3; } skipcount -= n; } int neu_clrtab(int ncolors) /* make new color table using ncolors */ { netsize = ncolors; if (netsize > MAXNETSIZE) netsize = MAXNETSIZE; initnet(); learn(); unbiasnet(); cpyclrtab(); inxbuild(); /* we're done with our samples */ free((char *)thesamples); /* reset dithering function */ neu_dith_colrs((BYTE *)NULL, (COLR *)NULL, 0); /* return new color table size */ return(netsize); } int neu_map_pixel(register BYTE *col) /* get pixel for color */ { return(inxsearch(col[N_BLU],col[N_GRN],col[N_RED])); } void neu_map_colrs(register BYTE *bs, register COLR (*cs), register int n) /* convert a scanline to color index values */ { while (n-- > 0) { *bs++ = inxsearch(cs[0][N_BLU],cs[0][N_GRN],cs[0][N_RED]); cs++; } } void neu_dith_colrs(register BYTE *bs, register COLR (*cs), int n) /* convert scanline to dithered index values */ { static short (*cerr)[3] = NULL; static int N = 0; int err[3], errp[3]; register int x, i; if (n != N) { /* get error propogation array */ if (N) { free((char *)cerr); cerr = NULL; } if (n) cerr = (short (*)[3])malloc(3*n*sizeof(short)); if (cerr == NULL) { N = 0; neu_map_colrs(bs, cs, n); return; } N = n; bzero((char *)cerr, 3*N*sizeof(short)); } err[0] = err[1] = err[2] = 0; for (x = 0; x < n; x++) { for (i = 0; i < 3; i++) { /* dither value */ errp[i] = err[i]; err[i] += cerr[x][i]; #ifdef MAXERR if (err[i] > MAXERR) err[i] = MAXERR; else if (err[i] < -MAXERR) err[i] = -MAXERR; #endif /* MAXERR */ err[i] += cs[x][i]; if (err[i] < 0) err[i] = 0; else if (err[i] > 255) err[i] = 255; } bs[x] = inxsearch(err[N_BLU],err[N_GRN],err[N_RED]); for (i = 0; i < 3; i++) { /* propagate error */ err[i] -= clrtab[bs[x]][i]; err[i] /= 3; cerr[x][i] = err[i] + errp[i]; } } } /* The following was adapted and modified slightly from the original */ #define bool int #define false 0 #define true 1 /* network defs */ #define maxnetpos (netsize-1) #define netbiasshift 4 /* bias for colour values */ #define ncycles 100 /* no. of learning cycles */ /* defs for freq and bias */ #define intbiasshift 16 /* bias for fractions */ #define intbias (((int) 1)<>betashift) /* beta = 1/1024 */ #define betagamma (intbias<<(gammashift-betashift)) /* defs for decreasing radius factor */ #define initrad (netsize>>3) /* for 256 cols, radius starts */ #define radiusbiasshift 6 /* at 32.0 biased by 6 bits */ #define radiusbias (((int) 1)<>3]; /* radpower for precomputation */ /* initialise network in range (0,0,0) to (255,255,255) */ static void initnet(void) { register int i; register int *p; for (i=0; i>1; for (j=previouscol+1; j>1; for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; /* really 256 */ } static int inxsearch(register int b, register int g, register int r) /* accepts real BGR values after net is unbiased */ { register int i,j,dist,a,bestd; register int *p; int best; bestd = 1000; /* biggest possible dist is 256*3 */ best = -1; i = netindex[g]; /* index on g */ j = i-1; /* start at netindex[g] and work outwards */ while ((i=0)) { if (i= bestd) i = netsize; /* stop iter */ else { i++; if (dist<0) dist = -dist; a = p[0] - b; if (a<0) a = -a; dist += a; if (dist=0) { p = network[j]; dist = g - p[1]; /* inx key - reverse dif */ if (dist >= bestd) j = -1; /* stop iter */ else { j--; if (dist<0) dist = -dist; a = p[0] - b; if (a<0) a = -a; dist += a; if (dist>(intbiasshift-netbiasshift)); if (biasdist> betashift); *f++ -= betafreq; *p++ += (betafreq<netsize) hi=netsize; j = i+1; k = i-1; q = radpower; while ((jlo)) { a = (*(++q)); if (jlo) { p = network[k]; *p -= (a*(*p - b)) / alpharadbias; p++; *p -= (a*(*p - g)) / alpharadbias; p++; *p -= (a*(*p - r)) / alpharadbias; k--; } } } static void learn(void) { register int i,j,b,g,r; int radius,rad,alpha,step,delta,samplepixels; register unsigned char *p; unsigned char *lim; alphadec = 30 + ((samplefac-1)/3); p = thepicture; lim = thepicture + lengthcount; samplepixels = lengthcount/(3*samplefac); delta = samplepixels/ncycles; alpha = initalpha; radius = initradius; rad = radius >> radiusbiasshift; if (rad <= 1) rad = 0; for (i=0; i= lim) p -= lengthcount; i++; if (i%delta == 0) { alpha -= alpha / alphadec; radius -= radius / radiusdec; rad = radius >> radiusbiasshift; if (rad <= 1) rad = 0; for (j=0; j>= netbiasshift; network[i][3] = i; /* record colour no */ } } /* Don't do this until the network has been unbiased */ static void cpyclrtab(void) { register int i,j,k; for (j=0; jpic_cache pointer to that repository entry and set * "existing" to True. * If not, read the file via the relevant reader and add to the repository * and set "existing" to False. * If "force" is true, read the file unconditionally. */ void read_picobj(F_pic *pic, char *file, int color, Boolean force, Boolean *existing) { FILE *fd; int type; int i,j,c; char buf[20],realname[PATH_MAX]; Boolean found, reread; struct _pics *pics, *lastpic; time_t mtime; pic->color = color; /* don't touch the flipped flag - caller has already set it */ pic->pixmap = (Pixmap) NULL; pic->hw_ratio = 0.0; pic->pix_rotation = 0; pic->pix_width = 0; pic->pix_height = 0; pic->pix_flipped = 0; /* check if user pressed cancel button */ if (check_cancel()) return; put_msg("Reading Picture object file..."); app_flush(); /* look in the repository for this filename */ lastpic = pictures; reread = False; for (pics = pictures; pics; pics = pics->next) { if (strcmp(pics->file, file)==0) { /* found it - make sure the timestamp is >= the timestamp of the file */ /* check both the "realname" and the original name */ if ((mtime = file_timestamp(pics->realname) < 0)) mtime = file_timestamp(pics->file); if (mtime < 0) { /* oops, doesn't exist? */ file_msg("Error %s on %s",strerror(errno),file); return; } /* or if force is true then reread it */ if (force || (mtime > pics->time_stamp)) { reread = True; break; /* no, re-read the file */ } pic->pic_cache = pics; pics->refcount++; if (appres.DEBUG) fprintf(stderr,"Found stored picture %s, count=%d\n",file,pics->refcount); /* if there is a bitmap, return, otherwise fall through and reread the file */ if (pics->bitmap != NULL) { *existing = True; put_msg("Reading Picture object file...found cached picture"); /* must set the h/w ratio here */ pic->hw_ratio = (float) pic->pic_cache->bit_size.y/pic->pic_cache->bit_size.x; return; } if (appres.DEBUG) fprintf(stderr,"Re-reading file\n"); } /* keep pointer to last entry */ lastpic = pics; } *existing = False; if (reread) { if (appres.DEBUG) fprintf(stderr,"Timestamp changed, reread file %s\n",file); } else if (pics == NULL) { /* didn't find it in the repository, add it */ pics = create_picture_entry(); if (lastpic) { /* add to list */ lastpic->next = pics; pics->prev = lastpic; } else { /* first one */ pictures = pics; } pics->file = strdup(file); pics->refcount = 1; pics->bitmap = (unsigned char *) NULL; pics->subtype = T_PIC_NONE; pics->numcols = 0; pics->size_x = 0; pics->size_y = 0; pics->bit_size.x = 0; pics->bit_size.y = 0; if (appres.DEBUG) fprintf(stderr,"New picture %s\n",file); } /* put it in the pic */ pic->pic_cache = pics; pic->pixmap = (Pixmap) NULL; /* open the file and read a few bytes of the header to see what it is */ if ((fd=open_picfile(file, &type, PIPEOK, realname)) == NULL) { file_msg("No such picture file: %s",file); return; } /* get the modified time and save it */ pics->time_stamp = file_timestamp(file); /* and save the realname (it may be compressed) */ pics->realname = strdup(realname); /* read some bytes from the file */ for (i=0; i<15; i++) { if ((c=getc(fd))==EOF) break; buf[i]=(char) c; } close_picfile(fd,type); /* now find which header it is */ for (i=0; i=0; j--) if (buf[j] != headers[i].bytes[j]) { found = False; break; } if (found) break; } if (found) { if (headers[i].pipeok) { /* open it again (it may be a pipe so we can't just rewind) */ fd=open_picfile(file, &type, headers[i].pipeok, realname); if ( (*headers[i].readfunc)(fd,type,pic) == FileInvalid) { file_msg("%s: Bad %s format",file, headers[i].type); } } else { /* those routines that can't take a pipe (e.g. xpm) get the real filename */ if ( (*headers[i].readfunc)(realname,type,pic) == FileInvalid) { file_msg("%s: Bad %s format",file, headers[i].type); } } put_msg("Reading Picture object file...Done"); return; } /* none of the above */ file_msg("%s: Unknown image format",file); put_msg("Reading Picture object file...Failed"); app_flush(); } /* Open the file 'name' and return its type (pipe or real file) in 'type'. Return the full name in 'retname'. This will have a .gz or .Z if the file is zipped/compressed. The return value is the FILE stream. */ FILE * open_picfile(char *name, int *type, Boolean pipeok, char *retname) { char unc[PATH_MAX+20]; /* temp buffer for gunzip command */ FILE *fstream; /* handle on file */ struct stat status; char *gzoption; *type = 0; *retname = '\0'; if (pipeok) gzoption = "-c"; /* tell gunzip to output to stdout */ else gzoption = ""; /* see if the filename ends with .Z or with .z or .gz */ /* if so, generate gunzip command and use pipe (filetype = 1) */ if ((strlen(name) > 3 && !strcmp(".gz", name + (strlen(name)-3))) || (strlen(name) > 2 && !strcmp(".Z", name + (strlen(name)-3))) || (strlen(name) > 2 && !strcmp(".z", name + (strlen(name)-2)))) { sprintf(unc,"gunzip -q %s %s",gzoption,name); *type = 1; /* none of the above, see if the file with .Z or .gz or .z appended exists */ } else { strcpy(retname, name); strcat(retname, ".Z"); if (!stat(retname, &status)) { sprintf(unc, "gunzip %s %s",gzoption,retname); *type = 1; name = retname; } else { strcpy(retname, name); strcat(retname, ".z"); if (!stat(retname, &status)) { sprintf(unc, "gunzip %s %s",gzoption,retname); *type = 1; name = retname; } else { strcpy(retname, name); strcat(retname, ".gz"); if (!stat(retname, &status)) { sprintf(unc, "gunzip %s %s",gzoption,retname); *type = 1; name = retname; } } } } /* if a pipe, but the caller needs a file, uncompress the file now */ if (*type == 1 && !pipeok) { char *p; system(unc); if (p=strrchr(name,'.')) { *p = '\0'; /* terminate name before last .gz, .z or .Z */ } strcpy(retname, name); /* force to plain file now */ *type = 0; } /* no appendages, just see if it exists */ /* and restore the original name */ strcpy(retname, name); if (stat(name, &status) != 0) { fstream = NULL; } else { switch (*type) { case 0: fstream = fopen(name, "rb"); break; case 1: fstream = popen(unc,"r"); break; } } return fstream; } void close_picfile(FILE *file, int type) { char line[MAX_SIZE]; int stat; if (file == 0) return; if (type == 0) { if ((stat=fclose(file)) != 0) file_msg("Error closing picture file: %s",strerror(errno)); } else { /* for a pipe, must read everything or we'll get a broken pipe message */ while(fgets(line,MAX_SIZE,file)) ; pclose(file); } } xfig.3.2.5c/f_read.c0000700002656300244210000015231211641414046014744 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "figx.h" #include "resources.h" #include "object.h" #include "mode.h" #include "f_read.h" #include "u_fonts.h" #include "u_create.h" #include "version.h" #include "w_drawprim.h" #include "w_export.h" #include "w_file.h" #include "w_print.h" #include "w_indpanel.h" #include "w_color.h" #include "w_msgpanel.h" #include "w_setup.h" #include "w_util.h" #include "w_zoom.h" #include "d_spline.h" #include "e_update.h" #include "f_picobj.h" #include "f_readold.h" #include "f_util.h" #include "u_bound.h" #include "u_free.h" #include "u_scale.h" #include "u_translate.h" #include "w_util.h" #include "w_layers.h" /* EXPORTS */ int defer_update_layers = 0; /* if != 0, update_layers() doesn't update */ int line_no, save_line; /* current input line number */ int num_object; /* current number of objects */ char *read_file_name; /* current input file name */ /* LOCAL */ static char Err_incomp[] = "Incomplete %s object at line %d."; static void read_colordef(FILE *fp); static F_ellipse *read_ellipseobject(void); static F_line *read_lineobject(FILE *fp); static F_text *read_textobject(FILE *fp); static F_spline *read_splineobject(FILE *fp); static F_arc *read_arcobject(FILE *fp); static F_compound *read_compoundobject(FILE *fp); static char *attach_comments(void); static void count_lines_correctly(FILE *fp); static int read_return(int status); static Boolean contains_picture(F_compound *compound); #define FILL_CONVERT(f) \ ((proto >= 22) ? (f): \ (((proto>=20) || (f) == 0 || !TFX) ? \ (f-1) : (!TFX? (NUMFILLPATS-1) - ((f)-1)*5: UNFILLED))) /* max number of comments that can be stored with each object */ #define MAXCOMMENTS 100 /* input buffer length */ #define BUF_SIZE 1024 char buf[BUF_SIZE]; /* input buffer */ char *comments[MAXCOMMENTS]; /* comments saved for current object */ int numcom; /* current comment index */ Boolean com_alloc = False; /* whether or not the comment array has been init. */ int TFX; /* true for 1.4TFX protocol */ int proto; /* file protocol*10 */ float fproto, xfigproto; /* floating values for protocol of figure file and current protocol */ /* initialize the user color counter - then read figure file. Called from load_file(), merge_file(), preview_figure(), load_lib_obj(), and paste(), but NOT from read_figure() (import Fig as picture) */ void merge_colors (F_compound *objects); void swap_colors (void); int readfp_fig (FILE *fp, F_compound *obj, Boolean merge, int xoff, int yoff, fig_settings *settings); int read_line (FILE *fp); int read_objects (FILE *fp, F_compound *obj, int *res); void scale_figure (F_compound *obj, float mul, int offset); void shift_figure (F_compound *obj); void fix_depth (int *depth); void check_color (int *color); void convert_arrow (int *type, float *wd, float *ht); void fix_angle (float *angle); void skip_line (FILE *fp); int backslash_count (char *cp, int start); int save_comment (FILE *fp); void renumber_comp (F_compound *compound); void renumber (int *color); int read_figc(char *file_name, F_compound *obj, Boolean merge, Boolean remapimages, int xoff, int yoff, fig_settings *settings) { int i,status; n_num_usr_cols = -1; for (i=0; icompounds; c != NULL; c = c->next) { if (contains_picture(c)) return True; } for (l = compound->lines; l != NULL; l = l->next) { if (l->type == T_PICTURE) return True; } return False; } /********************************************************** Read_fig returns : 0 : successful read. BAD_FORMAT : File is in incorrect format EMPTY_FILE : File is empty NO_VERSION : No version was found in "#FIG" header err_no : if file can not be read for various reasons (from /usr/include/sys/errno.h) The resolution (ppi) is stored in resolution. The coordinate system is 1 for lower left at 0,0 and 2 for upper left at 0,0, but this value is not used, because xfig only uses 2 for the coordinate system. If "merge" is True, the user colors are merged into the color set, else they replace the current user colors. Also, if merging, if the file being merged into the main figure has different units (inches/cm) it is rescaled to match the main figure. If update_figs is false, any imported images are read in, otherwise they are not. The latter case is used for the -update command-line option where the user just wants to read and re-write Fig files to bring them up-to-date. **********************************************************/ int read_fig(char *file_name, F_compound *obj, Boolean merge, int xoff, int yoff, fig_settings *settings) { FILE *fp; int status; read_file_name = file_name; first_file_msg = True; if (uncompress_file(file_name) == False) return ENOENT; /* doesn't exist */ if ((fp = fopen(file_name, "r")) == NULL) return errno; else { if (!update_figs) put_msg("Reading objects from \"%s\" ...", file_name); #ifdef I18N /* set the numeric locale to C so we get decimal points for numbers */ setlocale(LC_NUMERIC, "C"); #endif /* I18N */ status = readfp_fig(fp, obj, merge, xoff, yoff, settings); #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ fclose(fp); /* so subsequent file_msg() calls don't print wrong file name */ first_file_msg = False; return status; } } int readfp_fig(FILE *fp, F_compound *obj, Boolean merge, int xoff, int yoff, fig_settings *settings) { int status; int i; int resolution; char versstring[10]; defer_update_layers = 1; /* prevent update_layers() from updating */ /* initialize settings structure in case we read an older Fig format */ settings->landscape = appres.landscape; settings->flushleft = appres.flushleft; settings->units = appres.INCHES; settings->papersize = appres.papersize; settings->magnification = appres.magnification; settings->multiple = appres.multiple; settings->transparent = appres.transparent; num_object = 0; /* reset comment number */ numcom = 0; /* initialize the comment array */ if (!com_alloc) for (i=0; i xfigproto) { file_msg("You must have a NEWER version of Xfig to load this figure (%.1f).", fproto); return read_return(BAD_FORMAT); } /* Protocol 2.2 was only beta test - 3.0 is the release (and is identical) */ if (proto == 22) proto = 30; TFX = False; if (strstr(buf, "TFX") != NULL) TFX = True; if (proto >= 30) { /* read Portrait/Landscape indicator now */ if (read_line(fp) < 0) { file_msg("No Portrait/Landscape specification"); return read_return(BAD_FORMAT); /* error */ } settings->landscape = (strncasecmp(buf,"landscape",9) == 0); /* read Centering indicator now */ if (read_line(fp) < 0) { file_msg("No Center/Flushleft specification"); return read_return(BAD_FORMAT); /* error */ } if ((strncasecmp(buf,"center",6) == 0) || (strncasecmp(buf,"flush",5) == 0)) { /* use negative to ensure 1/0 (strcmp may return 3 or 4 for false) */ settings->flushleft = !strncasecmp(buf,"flush",5); /* NOW read metric/inches indicator */ if (read_line(fp) < 0) { file_msg("No Metric/Inches specification"); return read_return(BAD_FORMAT); /* error */ } } /* set metric/inches mode appropriately */ settings->units = (strncasecmp(buf,"metric",5) != 0); /* paper size, magnification, multiple page flag and transparent color (for GIF export) new in 3.2 */ if (proto >= 32) { /* read paper size now */ if (read_line(fp) < 0) { file_msg("No Paper size specification"); return read_return(BAD_FORMAT); /* error */ } /* parse the paper size */ settings->papersize = parse_papersize(buf); /* read magnification now */ if (read_line(fp) < 0) { file_msg("No Magnification specification"); return read_return(BAD_FORMAT); /* error */ } settings->magnification = atoi(buf); /* read multiple page flag now */ if (read_line(fp) < 0) { file_msg("No Multiple page flag specification"); return read_return(BAD_FORMAT); /* error */ } if (strncasecmp(buf,"multiple",8) != 0 && strncasecmp(buf,"single",6) != 0) { file_msg("No Multiple page flag specification"); return read_return(BAD_FORMAT); } settings->multiple = (strncasecmp(buf,"multiple",8) == 0); /* read transparent color now */ if (read_line(fp) < 0) { file_msg("No Transparent color specification"); return read_return(BAD_FORMAT); /* error */ } settings->transparent = atoi(buf); } } /* now read the figure itself */ status = read_objects(fp, obj, &resolution); } else { file_msg("Seeing if this figure is Fig format 1.3"); file_msg("If this doesn't work then this is not a Fig file."); proto = 13; status = read_1_3_objects(fp, buf, obj); } /* don't go any further if there was an error in reading the figure */ if (status != 0) { return read_return(status); } n_num_usr_cols++; /* number of user colors = max index + 1 */ /******************************************************************************* The older versions of xfig (1.3 to 2.1) used values that ended in 4 or 9 for coordinates on the "grid". When multiplied by 15 for the 3.0 resolution these values ended up 14 "new" pixels off the grid. For 3.0 files, 1 is added to the coordinates, and in addition, the USER is supposed to set the x and y offset in the file panel both to the amount necessary to correct the problem. For older files 1 is first added to coordinates then they are multiplied by 15. ********************************************************************************/ if (proto == 30) { scale_figure(obj,((float)PIX_PER_INCH)/resolution,0); } else if (resolution != PIX_PER_INCH) { if (proto == 21 && resolution == 76 && !settings->units) scale_figure(obj,((float)PIX_PER_INCH)/80,15); /* for 2.1.8S, HWS */ else scale_figure(obj,((float)PIX_PER_INCH)/resolution,15); } /* if merging a figure with different units, rescale for mixed units, HWS */ if (merge && (proto >= 30)) { if (!appres.INCHES && settings->units) read_scale_compound(obj,(2.54*PIX_PER_CM)/((float)PIX_PER_INCH),0); if (appres.INCHES && !settings->units) read_scale_compound(obj,((float)PIX_PER_INCH)/(2.54*PIX_PER_CM),0); } /* if the user wants to scale the figure */ if (scale_factor != 1.0) read_scale_compound(obj, scale_factor, 0); /* shift the figure by the amount in the x and y offsets from the file panel */ translate_compound(obj, xoff, yoff); /* get bounding box of whole figure */ compound_bound(obj,&obj->nwcorner.x,&obj->nwcorner.y,&obj->secorner.x,&obj->secorner.y); /* ask the user if the figure should be shifted if there are negative coords */ if (!update_figs) shift_figure(obj); /* now update the grid/ruler units */ if (settings->units) { /* inches */ if (strcasecmp(appres.tgrid_unit, "default") != 0) { /* the user specified a units when he started, try to keep it */ if (strcasecmp(appres.tgrid_unit, "tenth") == 0 || strcasecmp(appres.tgrid_unit, "ten") == 0 || strcasecmp(appres.tgrid_unit, "1/10") == 0 || strcasecmp(appres.tgrid_unit, "10") == 0) settings->grid_unit = TENTH_UNIT; else settings->grid_unit = FRACT_UNIT; } else { settings->grid_unit = FRACT_UNIT; } } else { /* metric, only choice */ settings->grid_unit = MM_UNIT; } /* return with status */ return read_return(status); } /* clear defer_update_layers counter, update the layer buttons and return status */ static int read_return(int status) { defer_update_layers = 0; if (!update_figs) update_layers(); return status; } int read_objects(FILE *fp, F_compound *obj, int *res) { F_ellipse *e, *le = NULL; F_line *l, *ll = NULL; F_text *t, *lt = NULL; F_spline *s, *ls = NULL; F_arc *a, *la = NULL; F_compound *c, *lc = NULL; int object, ppi, coord_sys; if (read_line(fp) < 0) { file_msg("No Resolution specification; figure is empty"); return BAD_FORMAT; } /* read the resolution (ppi) and the coordinate system used (upper-left or lower-left) */ if (sscanf(buf, "%d%d\n", &ppi, &coord_sys) != 2) { file_msg("Figure resolution or coordinate specifier missing in line %d.", line_no); return BAD_FORMAT; } /* attach any comments found thus far to the whole figure */ obj->comments = attach_comments(); /* save the resolution for caller */ *res = ppi; while (read_line(fp) > 0) { if (sscanf(buf, "%d", &object) != 1) { file_msg("Incorrect format at line %d.", line_no); return (num_object != 0? 0: BAD_FORMAT); /* ok if any objects have been read */ } switch (object) { case O_COLOR_DEF: read_colordef(fp); if (num_object) { file_msg("Color definitions must come before other objects (line %d).", line_no); } break; case O_POLYLINE: if ((l = read_lineobject(fp)) == NULL) continue; if (ll) ll = (ll->next = l); else ll = obj->lines = l; num_object++; break; case O_SPLINE: if ((s = read_splineobject(fp)) == NULL) continue; if (ls) ls = (ls->next = s); else ls = obj->splines = s; num_object++; break; case O_ELLIPSE: if ((e = read_ellipseobject()) == NULL) continue; if (le) le = (le->next = e); else le = obj->ellipses = e; num_object++; break; case O_ARC: if ((a = read_arcobject(fp)) == NULL) continue; if (la) la = (la->next = a); else la = obj->arcs = a; num_object++; break; case O_TXT: if ((t = read_textobject(fp)) == NULL) continue; if (lt) lt = (lt->next = t); else lt = obj->texts = t; num_object++; break; case O_COMPOUND: if ((c = read_compoundobject(fp)) == NULL) continue; if (lc) lc = (lc->next = c); else lc = obj->compounds = c; num_object++; break; default: file_msg("Incorrect object code at line %d.", line_no); continue; } /* switch */ } /* while */ if (feof(fp)) return 0; else return errno; } /* read_objects */ int parse_papersize(char *size) { int i,len; char *c; /* first get rid of trailing newline */ if (size[strlen(size)-1]=='\n') size[strlen(size)-1]='\0'; /* then truncate at first space or parenthesis "(" in passed size */ if (((c=strchr(size,' '))!= NULL)||((c=strchr(size,'(')) != NULL)) { *c ='\0'; } len = strlen(size); /* change ledger (deprecated) to tabloid */ if (strncasecmp(size,"ledger",len) == 0) strcpy(size,"tabloid"); for (i=0; i= NUMPAPERSIZES) return 0; return i; } static void read_colordef(FILE *fp) { int c,r,g,b; if ((sscanf(buf, "%*d %d #%02x%02x%02x", &c, &r, &g, &b) != 4) || (c < NUM_STD_COLS) || (c >= MAX_USR_COLS+NUM_STD_COLS)) { buf[strlen(buf)-1]='\0'; /* remove the newline */ file_msg("Invalid color definition: %s, setting to black (#00000).",buf); r=g=b=0; c = NUM_STD_COLS; } /* make in the range 0...MAX_USR_COLS */ c -= NUM_STD_COLS; n_user_colors[c].red = r*256; n_user_colors[c].green = g*256; n_user_colors[c].blue = b*256; n_colorFree[c] = False; /* keep track of highest color number */ n_num_usr_cols = max2(c, n_num_usr_cols); } static F_arc * read_arcobject(FILE *fp) { F_arc *a; int n, fa, ba; int type, style; float thickness, wd, ht; if ((a = create_arc()) == NULL) return NULL; save_line = line_no; a->next = NULL; a->for_arrow = a->back_arrow = NULL; if (proto >= 30) { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%d%f%d%d%d%d%f%f%d%d%d%d%d%d\n", &a->type, &a->style, &a->thickness, &a->pen_color, &a->fill_color, &a->depth, &a->pen_style, &a->fill_style, &a->style_val, &a->cap_style, &a->direction, &fa, &ba, &a->center.x, &a->center.y, &a->point[0].x, &a->point[0].y, &a->point[1].x, &a->point[1].y, &a->point[2].x, &a->point[2].y); } else { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d%f%f%d%d%d%d%d%d\n", &a->type, &a->style, &a->thickness, &a->pen_color, &a->depth, &a->pen_style, &a->fill_style, &a->style_val, &a->direction, &fa, &ba, &a->center.x, &a->center.y, &a->point[0].x, &a->point[0].y, &a->point[1].x, &a->point[1].y, &a->point[2].x, &a->point[2].y); a->fill_color = a->pen_color; a->cap_style = CAP_BUTT; /* butt line cap */ } a->type--; /* internally, 0=open arc, 1=pie wedge */ if (((proto < 22) && (n != 19)) || ((proto >= 30) && (n != 21))) { file_msg(Err_incomp, "arc", save_line); free((char *) a); return NULL; } a->fill_style = FILL_CONVERT(a->fill_style); fix_depth(&a->depth); check_color(&a->pen_color); check_color(&a->fill_color); fix_fillstyle(a); /* make sure that black/white have legal fill styles */ a->comments = attach_comments(); /* attach any comments */ /* forward arrow */ if (fa) { if (read_line(fp) == -1) return a; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "arc", save_line); return a; } /* throw away any arrow heads on pie-wedge arcs */ if (a->type == T_OPEN_ARC) { /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); a->for_arrow = new_arrow(type, style, thickness, wd, ht); } } /* backward arrow */ if (ba) { if (read_line(fp) == -1) return a; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "arc", save_line); return a; } /* throw away any arrow heads on pie-wedge arcs */ if (a->type == T_OPEN_ARC) { /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); a->back_arrow = new_arrow(type, style, thickness, wd, ht); } } return a; } static F_compound * read_compoundobject(FILE *fp) { F_arc *a, *la = NULL; F_ellipse *e, *le = NULL; F_line *l, *ll = NULL; F_spline *s, *ls = NULL; F_text *t, *lt = NULL; F_compound *com, *c, *lc = NULL; int n, object; if ((com = create_compound()) == NULL) return NULL; com->arcs = NULL; com->ellipses = NULL; com->lines = NULL; com->splines = NULL; com->texts = NULL; com->compounds = NULL; com->next = NULL; com->comments = attach_comments(); /* attach any comments */ save_line = line_no; /* read bounding info for compound */ n = sscanf(buf, "%*d%d%d%d%d\n", &com->nwcorner.x, &com->nwcorner.y, &com->secorner.x, &com->secorner.y); /* if compound spec has no bounds, set to 0 and calculate later */ if (n <= 0) { com->nwcorner.x =com->nwcorner.y = com->secorner.x = com->secorner.y = 0; } else if (n != 4) { /* otherwise, if there aren't 4 numbers, complain */ file_msg(Err_incomp, "compound", save_line); free((char *) com); return NULL; } while (read_line(fp) > 0) { if (sscanf(buf, "%d", &object) != 1) { file_msg(Err_incomp, "compound", save_line); free((char *) com); return NULL; } switch (object) { case O_POLYLINE: if ((l = read_lineobject(fp)) == NULL) continue; if (ll) ll = (ll->next = l); else ll = com->lines = l; break; case O_SPLINE: if ((s = read_splineobject(fp)) == NULL) continue; if (ls) ls = (ls->next = s); else ls = com->splines = s; break; case O_ELLIPSE: if ((e = read_ellipseobject()) == NULL) continue; if (le) le = (le->next = e); else le = com->ellipses = e; break; case O_ARC: if ((a = read_arcobject(fp)) == NULL) continue; if (la) la = (la->next = a); else la = com->arcs = a; break; case O_TXT: if ((t = read_textobject(fp)) == NULL) continue; if (lt) lt = (lt->next = t); else lt = com->texts = t; break; case O_COMPOUND: if ((c = read_compoundobject(fp)) == NULL) continue; if (lc) lc = (lc->next = c); else lc = com->compounds = c; break; case O_END_COMPOUND: /* if compound def had no bounds or all zeroes, calculate bounds now */ if (com->nwcorner.x == 0 && com->nwcorner.x == 0 && com->nwcorner.x == 0 && com->nwcorner.x == 0) compound_bound(com, &com->nwcorner.x, &com->nwcorner.y, &com->secorner.x, &com->secorner.y); return com; default: file_msg("Incorrect object code at line %d.", save_line); continue; } /* switch */ } /* while (read_line(fp) > 0) */ if (feof(fp)) { compound_bound(com, &com->nwcorner.x, &com->nwcorner.y, &com->secorner.x, &com->secorner.y); return com; } else { return NULL; } } static F_ellipse * read_ellipseobject(void) { F_ellipse *e; int n; if ((e = create_ellipse()) == NULL) return NULL; save_line = line_no; e->next = NULL; if (proto >= 30) { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n", &e->type, &e->style, &e->thickness, &e->pen_color, &e->fill_color, &e->depth, &e->pen_style, &e->fill_style, &e->style_val, &e->direction, &e->angle, &e->center.x, &e->center.y, &e->radiuses.x, &e->radiuses.y, &e->start.x, &e->start.y, &e->end.x, &e->end.y); } else { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%f%d%d%d%d%d%d%d%d\n", &e->type, &e->style, &e->thickness, &e->pen_color, &e->depth, &e->pen_style, &e->fill_style, &e->style_val, &e->direction, &e->angle, &e->center.x, &e->center.y, &e->radiuses.x, &e->radiuses.y, &e->start.x, &e->start.y, &e->end.x, &e->end.y); e->fill_color = e->pen_color; } if (((proto < 22) && (n != 18)) || ((proto >= 30) && (n != 19))) { file_msg(Err_incomp, "ellipse", save_line); free((char *) e); return NULL; } e->fill_style = FILL_CONVERT(e->fill_style); fix_angle(&e->angle); /* make sure angle is 0 to 2PI */ fix_depth(&e->depth); check_color(&e->pen_color); check_color(&e->fill_color); fix_fillstyle(e); /* make sure that black/white have legal fill styles */ e->comments = attach_comments(); /* attach any comments */ return e; } static F_line * read_lineobject(FILE *fp) { F_line *l; F_point *p, *q; int n, x, y, fa, ba, npts, cnpts; int type, style, radius_flag; float thickness, wd, ht; int ox, oy; char picfile[PATH_MAX]; Boolean dum; if ((l = create_line()) == NULL) return NULL; save_line = line_no; l->points = NULL; l->for_arrow = l->back_arrow = NULL; l->next = NULL; sscanf(buf, "%*d%d", &l->type); /* 2.0 has radius parm only for arc-box objects */ /* 2.1 or later has radius parm for all line objects */ /* 3.0(experimental 2.2) or later additionally has number of points parm for all line objects and fill color separate from border color */ radius_flag = ((proto >= 21) || (l->type == T_ARCBOX && proto == 20)); if (proto >= 30) { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%d%f%d%d%d%d%d%d", &l->type, &l->style, &l->thickness, &l->pen_color, &l->fill_color, &l->depth, &l->pen_style, &l->fill_style, &l->style_val, &l->join_style, &l->cap_style, &l->radius, &fa, &ba, &npts); } else { /* v2.1 and earlier */ if (radius_flag) { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d%d", &l->type, &l->style, &l->thickness, &l->pen_color, &l->depth, &l->pen_style, &l->fill_style, &l->style_val, &l->radius, &fa, &ba); } else { /* old format uses pen for radius of arc-box * corners */ n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d", &l->type, &l->style, &l->thickness, &l->pen_color, &l->depth, &l->pen_style, &l->fill_style, &l->style_val, &fa, &ba); if (l->type == T_ARCBOX) { l->radius = l->pen_style; l->pen_style = -1; } else l->radius = DEFAULT; } l->fill_color = l->pen_color; l->join_style = JOIN_MITER; /* miter joint */ l->cap_style = CAP_BUTT; /* butt line cap */ } if ((!radius_flag && n != 10) || (radius_flag && ((proto == 21 && n != 11) || ((proto >= 30) && n != 15)))) { file_msg(Err_incomp, "line", save_line); free((char *) l); return NULL; } l->fill_style = FILL_CONVERT(l->fill_style); fix_depth(&l->depth); check_color(&l->pen_color); check_color(&l->fill_color); fix_fillstyle(l); /* make sure that black/white have legal fill styles */ /* forward arrow */ if (fa) { if (read_line(fp) == -1) return NULL; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "line", save_line); return NULL; } /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); l->for_arrow = new_arrow(type, style, thickness, wd, ht); } /* backward arrow */ if (ba) { if (read_line(fp) == -1) return NULL; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "line", save_line); return NULL; } /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); l->back_arrow = new_arrow(type, style, thickness, wd, ht); } if (l->type == T_PICTURE) { char s1[PATH_MAX]; if (read_line(fp) == -1) { free((char *) l); return NULL; } if ((l->pic = create_pic()) == NULL) { free((char *) l); return NULL; } if (sscanf(buf, "%d %[^\n]", &l->pic->flipped, s1) != 2) { file_msg(Err_incomp, "Picture Object", save_line); free((char *) l); return NULL; } /* if path is relative convert it to absolute path */ if (s1[0] != '/') sprintf(picfile, "%s/%s", cur_file_dir, s1); else strcpy(picfile, s1); if (!update_figs) { /* only read in the image if update_figs is False */ read_picobj(l->pic, picfile, l->pen_color, False, &dum); } else { /* otherwise just make a pseudo entry with the filename */ l->pic->pic_cache = create_picture_entry(); l->pic->pic_cache->file = strdup(picfile); } /* we've read in a pic object - merge_file uses this info to decide whether or not to remap any picture colors in first figure */ pic_obj_read = True; } else l->pic = NULL; if ((p = create_point()) == NULL) { free((char *) l); return NULL; } l->points = p; p->next = NULL; /* read first point */ line_no++; if (fscanf(fp, "%d%d", &p->x, &p->y) != 2) { file_msg(Err_incomp, "line", save_line); free_linestorage(l); return NULL; } ox = p->x; oy = p->y; /* read subsequent points */ if (proto < 22) npts = 1000000; /* loop until we find 9999 9999 for previous fig files */ cnpts = 1; /* keep track of actual number of points read */ for (--npts; npts > 0; npts--) { count_lines_correctly(fp); if (fscanf(fp, "%d%d", &x, &y) != 2) { file_msg(Err_incomp, "line", save_line); free_linestorage(l); return NULL; } if (proto < 22 && x == 9999) break; /* ignore identical consecutive points */ if (ox == x && oy == y) continue; ox = x; oy = y; if ((q = create_point()) == NULL) { free_linestorage(l); return NULL; } q->x = x; q->y = y; q->next = NULL; p->next = q; p = q; cnpts++; } /* also, if it has fewer than 5 points and is a box, picture, or arcbox, or if it has fewer than 3 points and it is a polygon remove it */ if ((cnpts < 5 && (l->type == T_BOX || l->type == T_ARCBOX || l->type == T_PICTURE)) || (cnpts < 3 && l->type == T_POLYGON)) { if (l->type == T_POLYGON) { file_msg("Deleting polygon containing fewer than 3 points at line %d", save_line); } else { file_msg("Deleting zero-size %s at line %d", l->type==T_BOX? "box" : l->type==T_ARCBOX? "arcbox" : "picture", save_line); } free_linestorage(l); return NULL; } /* if the line has only one point, delete any arrowheads it might have now */ if (l->points->next == NULL) { if (l->for_arrow) { free((char *) l->for_arrow); l->for_arrow = (F_arrow *) NULL; } if (l->back_arrow) { free((char *) l->back_arrow); l->back_arrow = (F_arrow *) NULL; } } l->comments = attach_comments(); /* attach any comments */ /* skip to the next line */ skip_line(fp); return l; } static F_spline * read_splineobject(FILE *fp) { F_spline *s; F_point *p, *q; F_sfactor *cp, *cq; int c, n, x, y, fa, ba, npts, numpts; int type, style; float thickness, wd, ht; double s_param; float lx, ly, rx, ry; if ((s = create_spline()) == NULL) return NULL; save_line = line_no; s->points = NULL; s->sfactors = NULL; s->for_arrow = s->back_arrow = NULL; s->next = NULL; /* 3.0(experimental 2.2) or later has number of points parm for all spline objects and fill color separate from border color */ if (proto >= 30) { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%d%f%d%d%d%d", &s->type, &s->style, &s->thickness, &s->pen_color, &s->fill_color, &s->depth, &s->pen_style, &s->fill_style, &s->style_val, &s->cap_style, &fa, &ba, &npts); } else { n = sscanf(buf, "%*d%d%d%d%d%d%d%d%f%d%d", &s->type, &s->style, &s->thickness, &s->pen_color, &s->depth, &s->pen_style, &s->fill_style, &s->style_val, &fa, &ba); s->fill_color = s->pen_color; s->cap_style = CAP_BUTT; /* butt line cap */ } if (((proto < 22) && (n != 10)) || ((proto >= 30) && n != 13)) { file_msg(Err_incomp, "spline", save_line); free((char *) s); return NULL; } s->fill_style = FILL_CONVERT(s->fill_style); fix_depth(&s->depth); check_color(&s->pen_color); check_color(&s->fill_color); fix_fillstyle(s); /* make sure that black/white have legal fill styles */ /* forward arrow */ if (fa) { if (read_line(fp) == -1) return NULL; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "spline", save_line); return NULL; } /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); s->for_arrow = new_arrow(type, style, thickness, wd, ht); } /* backward arrow */ if (ba) { if (read_line(fp) == -1) return NULL; if (sscanf(buf, "%d%d%f%f%f", &type, &style, &thickness, &wd, &ht) != 5) { file_msg(Err_incomp, "spline", save_line); return NULL; } /* make sure arrowhead is legal and convert units */ convert_arrow(&type, &wd, &ht); s->back_arrow = new_arrow(type, style, thickness, wd, ht); } /* read first point */ line_no++; if ((n = fscanf(fp, "%d%d", &x, &y)) != 2) { file_msg(Err_incomp, "spline", save_line); free_splinestorage(s); return NULL; }; if ((p = create_point()) == NULL) { free_splinestorage(s); return NULL; } s->points = p; p->x = x; p->y = y; c = 1; /* read subsequent points */ if (proto < 22) npts = 1000000; /* loop until we find 9999 9999 for previous fig files */ numpts = 1; for (--npts; npts > 0; npts--) { count_lines_correctly(fp); if (fscanf(fp, "%d%d", &x, &y) != 2) { file_msg(Err_incomp, "spline", save_line); p->next = NULL; free_splinestorage(s); return NULL; }; if (proto < 22 && x == 9999) break; if ((q = create_point()) == NULL) { free_splinestorage(s); return NULL; } q->x = x; q->y = y; p->next = q; p = q; c++; numpts++; } p->next = NULL; if (proto <= 31) { /* to read files from version 3.1 and older */ if int_spline(s) { /* 2 control points per point given by user in version 3.1 and older : don't read them */ while (c--) { count_lines_correctly(fp); if (fscanf(fp, "%f%f%f%f", &lx, &ly, &rx, &ry) != 4) { file_msg(Err_incomp, "spline", save_line); free_splinestorage(s); return NULL; } } } if (closed_spline(s)) { F_point *ptr = s->points; s->points = s->points->next; free (ptr); } if (! make_sfactors(s)) { free_splinestorage(s); return NULL; } return s; } /* Read sfactors - the s parameter for splines */ count_lines_correctly(fp); if ((n = fscanf(fp, "%lf", &s_param)) != 1) { file_msg(Err_incomp, "spline", save_line); free_splinestorage(s); return NULL; }; if ((cp = create_sfactor()) == NULL) { free_splinestorage(s); return NULL; } s->sfactors = cp; cp->s = s_param; while (--c) { count_lines_correctly(fp); if (fscanf(fp, "%lf", &s_param) != 1) { file_msg(Err_incomp, "spline", save_line); cp->next = NULL; free_splinestorage(s); return NULL; }; if ((cq = create_sfactor()) == NULL) { cp->next = NULL; free_splinestorage(s); return NULL; } cq->s=s_param; cp->next = cq; cp = cq; } if (closed_spline(s) && numpts < 3) { file_msg("Closed splines must have 3 or more points, removing spline at line %d", save_line); free_splinestorage(s); return NULL; } else if (numpts < 2) { file_msg("Open splines must have 2 or more points, removing spline at line %d", save_line); free_splinestorage(s); return NULL; } cp->next = NULL; s->comments = attach_comments(); /* attach any comments */ /* skip to the end of the line */ skip_line(fp); return s; } static F_text * read_textobject(FILE *fp) { F_text *t; int l,n,len; int ignore = 0; char s[BUF_SIZE], s_temp[BUF_SIZE], junk[2]; float tx_size; float length, height; Boolean more; PR_SIZE tx_dim; if ((t = create_text()) == NULL) return NULL; save_line = line_no; t->next = NULL; /* * The text object is terminated by a CONTROL-A, so we read everything up * to the CONTROL-A and then read that character. If we do not find the * CONTROL-A on this line then this must be a multi-line text object and * we will have to read more. * * We read text size, height and length as floats because TransFig uses * floats for these, but they are rounded to ints internally to xfig. */ /* read the leading blanks for the string, but delete the first one later */ /* * NOTE: The height, length and descent will be recalculated from the * actual font structure in read_scale_text(). */ if (proto >= 30) { /* order of parms is more like other objects now; string is now terminated with the literal '\001', and 8-bit characters are represented as \xxx */ n = sscanf(buf, "%*d%d%d%d%d%d%f%f%d%f%f%d%d%[^\n]", &t->type, &t->color, &t->depth, &t->pen_style, &t->font, &tx_size, &t->angle, &t->flags, &height, &length, &t->base_x, &t->base_y, s); } else { n = sscanf(buf, "%*d%d%d%f%d%d%d%f%d%f%f%d%d%[^\1]%[\1]", &t->type, &t->font, &tx_size, &t->pen_style, &t->color, &t->depth, &t->angle, &t->flags, &height, &length, &t->base_x, &t->base_y, s, junk); } /* remove newline */ buf[strlen(buf)-1] = '\0'; if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = '\0'; /* remove any trailing carriage returns (^M, possibly from a PC) */ if (s[strlen(s)-1] == '\r') s[strlen(s)-1] = '\0'; /* use these for now, but recalculate later in read_scale_text if not update_figs */ t->ascent = round(height); t->descent = 0; t->length = round(length); if (n < 11) { file_msg(Err_incomp, "text", save_line); free((char *) t); return NULL; } /* now round size to int */ /* change DEFAULT (-1) or 0 size to default size */ if ((int) tx_size == DEFAULT || (int) tx_size == 0) t->size = DEF_FONTSIZE; else t->size = round(tx_size); /* set some limits */ if (t->size < MIN_FONT_SIZE) t->size = MIN_FONT_SIZE; else if (t->size > MAX_FONT_SIZE) t->size = MAX_FONT_SIZE; /* make sure angle is 0 to 2PI */ fix_angle(&t->angle); /* convert all pre-2.1 NON-TFX text flags (used to be font_style) to PostScript and all pre-2.1 TFX flags to PostScript + Special */ if (proto <= 20) { t->flags = PSFONT_TEXT; if (TFX) t->flags |= SPECIAL_TEXT; } /* check for valid font number */ if (t->font >= MAXFONT(t)) { file_msg("Invalid text font (%d) at line %d, setting to DEFAULT.", t->font, save_line); t->font = DEFAULT; } /* get the UNZOOMED font struct */ if (!update_figs) t->fontstruct = lookfont(x_fontnum(psfont_text(t), t->font), t->size); fix_depth(&t->depth); check_color(&t->color); more = False; if (proto < 22 && n == 13) more = True; /* in older xfig there is more if ^A wasn't found yet */ else if (proto >= 30) { /* in 3.0(2.2) there is more if \001 wasn't found */ len = strlen(s); if ((strcmp(&s[len-4],"\\001") == 0) && /* if we find '\000' */ !(backslash_count(s, len-5) % 2)) { /* and not '\\000' */ more = False; /* then there are no more lines */ s[len-4]='\0'; /* and get rid of the '\001' */ } else { more = True; s[len++]='\n'; /* put back the end of line char */ s[len] = '\0'; /* and terminate it */ } } if (more) { /* Read in the subsequent lines of the text object if there is more than one. */ do { line_no++; /* As is done in read_line */ if (fgets(buf, BUF_SIZE, fp) == NULL) break; /* remove newline */ buf[strlen(buf)-1] = '\0'; if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = '\0'; if (proto < 22) { n = sscanf(buf, "%[^\1]%[\1]", s_temp, junk); } else { strcpy(s_temp,buf); len = strlen(s_temp); if ((strncmp(&s_temp[len-4],"\\001",4) == 0) && !(backslash_count(s, len-5) % 2)) { n=0; /* found the '\001', set n to stop */ s_temp[len-4]='\0'; /* and get rid of the '\001' */ } else { n=1; /* keep going (more lines) */ } } /* Safety check */ if (strlen(s) + 1 + strlen(s_temp) + 1 > BUF_SIZE) { /* Too many characters. Ignore the rest. */ if (!ignore) file_msg("Truncating TEXT object to %d chars in line %d.", BUF_SIZE, save_line); ignore = 1; } if (!ignore) strcat(s, s_temp); } while (n == 1); } if (proto >= 30) { /* now convert any \xxx to ascii characters */ if (strchr(s,'\\')) { int num; len = strlen(s); for (l=0,n=0; l < len; l++) { if (s[l]=='\\') { /* a backslash, see if a digit follows */ if (l < len && isdigit(s[l+1])) { /* yes, allow exactly 3 digits following the \ for the octal value */ if (sscanf(&s[l+1],"%3o",&num)!=1) { file_msg("Error in parsing text string on line.", save_line); free((char *) t); return NULL; } buf[n++]= (unsigned char) num; /* put char in */ l += 3; /* skip over digits */ } else { buf[n++] = s[++l]; /* some other escaped character */ } } else { buf[n++] = s[l]; /* ordinary character */ } } buf[n]='\0'; /* terminate */ strcpy(s,buf); /* copy back to s */ } } if (t->type > T_RIGHT_JUSTIFIED) { file_msg("Invalid text justification at line %d, setting to LEFT.", save_line); t->type = T_LEFT_JUSTIFIED; } if (strlen(s) <= 1) { s[0]=' ';s[1]=0; } /* skip first blank from input file by starting at s[1] */ if ((t->cstring = new_string(strlen(&s[1]))) == NULL) { free((char *) t); return NULL; } /* copy string to text object */ (void) strcpy(t->cstring, &s[1]); if (!update_figs) { /* now calculate the actual length and height of the string in fig units */ tx_dim = textsize(t->fontstruct, strlen(t->cstring), t->cstring); t->length = round(tx_dim.length); t->ascent = round(tx_dim.ascent); t->descent = round(tx_dim.descent); /* now get the zoomed font struct */ t->zoom = zoomscale; if (display_zoomscale != 1.0) t->fontstruct = lookfont(x_fontnum(psfont_text(t), t->font), round(t->size*display_zoomscale)); } t->comments = attach_comments(); /* attach any comments */ return t; } /* akm 28/2/95 - count consecutive backslashes backwards */ int backslash_count(char *cp, int start) { int i, count = 0; for(i=start; i>=0; i--) { if (cp[i] == '\\') count++; else break; } return count; } /* attach comments together */ static char * attach_comments(void) { int i,len; char *comp; if (appres.DEBUG && (numcom > 0)) fprintf(stderr,"Comments:\n"); /* add up length of all comment lines */ len = 0; for (i=0; i= M_2PI) *angle -= M_2PI; } void fix_depth(int *depth) { if (*depth>MAX_DEPTH) { *depth=MAX_DEPTH; file_msg("Depth > Maximum allowed (%d), setting to %d in line %d.", MAX_DEPTH, save_line, MAX_DEPTH); } else if (*depth<0 || proto<21) { *depth=0; if (proto>=21) file_msg("Depth < 0, setting to 0 in line %d.", save_line); } } char shift_msg[] = "The figure has objects which have negative coordinates,\ndo you wish to shift it back on the page?"; void shift_figure(F_compound *obj) { F_ellipse *e; F_arc *a; F_line *l; F_spline *s; F_compound *c; F_text *t; int lowx,lowy,dx,dy; int rnd; /* if user is allowing negative coords, return */ if (appres.allownegcoords) return; lowx = obj->nwcorner.x; lowy = obj->nwcorner.y; /* check if any part of the figure has negative coords */ if (lowx >= 0 && lowy >= 0) return; /* no, ok */ /* ask the user */ if (!preview_in_progress && (popup_query(QUERY_YESNO, shift_msg)==RESULT_NO)) return; /* shift the whole figure to keep it "on the page" */ dx = dy = 0; rnd = posn_rnd[cur_gridunit][cur_pointposn]; if (lowx < 0) { dx = -lowx+rnd; /* and round up to small grid */ } if (lowy < 0) { dy = -lowy+rnd; } if (!preview_in_progress) file_msg("Shifting entire figure %d units right and %d units down to keep on page.", dx,dy); for (e = obj->ellipses; e != NULL; e = e->next) translate_ellipse(e, dx, dy); for (a = obj->arcs; a != NULL; a = a->next) translate_arc(a, dx, dy); for (l = obj->lines; l != NULL; l = l->next) translate_line(l, dx, dy); for (s = obj->splines; s != NULL; s = s->next) translate_spline(s, dx, dy); for (c = obj->compounds; c != NULL; c = c->next) translate_compound(c, dx, dy); for (t = obj->texts; t != NULL; t = t->next) translate_text(t, dx, dy); } void scale_figure(F_compound *obj, float mul, int offset) { /* scale the whole figure for new pixels per inch */ if (mul != 1.0) put_msg("Scaling figure by a factor of %.1f for new %d pixel per inch resolution.", mul,PIX_PER_INCH); read_scale_ellipses(obj->ellipses, mul, offset); read_scale_arcs(obj->arcs, mul, offset); read_scale_lines(obj->lines, mul, offset); read_scale_splines(obj->splines, mul, offset); read_scale_compounds(obj->compounds, mul, offset); read_scale_texts(obj->texts, mul, offset); } /* check if user color is defined */ void check_color(int *color) { if (*color < NUM_STD_COLS) return; if (!n_colorFree[*color-NUM_STD_COLS]) return; file_msg("Cannot locate user color %d, using default color for line %d.", *color,line_no); *color = DEFAULT; return; } /* swap new colors (n_...) with current for file load or undo load */ void swap_colors(void) { int i,num; Boolean saveFree[MAX_USR_COLS]; if (appres.DEBUG) fprintf(stderr,"Swapping colors. Before: colors_are_swapped = %d\n",colors_are_swapped); colors_are_swapped = True; /* first save the current colors because del_color_cell destroys them */ for (i=0; i 0) { num = num_usr_cols; num_usr_cols = 0; /* fill the colormap and the color memories */ for (i=0; i>8 == n_user_colors[i].red>>8) && (user_colors[j].green>>8 == n_user_colors[i].green>>8) && (user_colors[j].blue>>8 == n_user_colors[i].blue>>8)) { renum[i] = j; /* yes, use it */ found_exist=True; break; /* skip to next */ } if (!found_exist) { if (newval == -1) { renum[i] = 0; /* out of user colors, use 0 */ } else { renum[i] = newval; /* assign it a new color number */ /* find the next free color number */ while (newval < MAX_USR_COLS) { newval++; if (colorFree[newval]) break; } if (newval >= MAX_USR_COLS) newval = -1; } x_colorFree[renum[i]] = -1; /* we are using this number now */ n_user_colors[renum[i]] = n_user_colors[i]; /* copy rgb values */ } } } /* renumber them now */ n_num_usr_cols = max2(newval,num_usr_cols); /* new upper limit on color number */ renumber_comp(objects); /* now create colorcells for the new colors */ for (i=0; icompounds; c != NULL; c = c->next) renumber_comp(c); /* now the primitives */ for (a = compound->arcs; a != NULL; a = a->next) { renumber(&a->fill_color); renumber(&a->pen_color); } for (t = compound->texts; t != NULL; t = t->next) { renumber(&t->color); } for (e = compound->ellipses; e != NULL; e = e->next) { renumber(&e->fill_color); renumber(&e->pen_color); } for (l = compound->lines; l != NULL; l = l->next) { renumber(&l->fill_color); renumber(&l->pen_color); } for (s = compound->splines; s != NULL; s = s->next) { renumber(&s->fill_color); renumber(&s->pen_color); } } void renumber(int *color) { if (*color < NUM_STD_COLS) return; if (renum[*color-NUM_STD_COLS] != -1) *color = renum[*color-NUM_STD_COLS]+NUM_STD_COLS; } /* this function is to count line numbers correctly while reading * input files. * It skips all tabs and spaces and increments the global * variable line_no if a newline was found. * If any other character is read, it is put back to the input * stream and the function returns. * It should be called from within the point reading loops * in the read_{line,spline}object functions, where the point * coordinates may be given in an arbitrary number of lines. * Added by Andreas_Bagge@maush2.han.de (A.Bagge), 14.12.94 */ static void count_lines_correctly(FILE *fp) { int cc; do{ cc=getc(fp); if (cc=='\n') { line_no++; cc=getc(fp); } } while (cc==' '||cc=='\t'); ungetc(cc,fp); } /* make sure arrow style value is legal and convert arrow width and height to * same units as thickness in V4.0 and later we will save the values in these units */ void convert_arrow(int *type, float *wd, float *ht) { if (*type >= NUM_ARROW_TYPES/2) *type = 0; if (proto < 40) { *wd /= ZOOM_FACTOR; *ht /= ZOOM_FACTOR; } } xfig.3.2.5c/f_readeps.c0000700002656300244210000003164311641414046015457 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1992 by Brian Boyter * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_picobj.h" #include "w_msgpanel.h" #include "w_setup.h" #include "w_util.h" int _read_pcx(FILE *pcxfile, F_pic *pic); Boolean bitmap_from_gs(); /* read a PDF file */ int read_epsf_pdf (FILE *file, int filetype, F_pic *pic, Boolean pdf_flag); void lower (char *buf); int hex (char c); int read_pdf(FILE *file, int filetype, F_pic *pic) { return read_epsf_pdf(file, filetype, pic, True); } /* read an EPS file */ /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ int read_epsf(FILE *file, int filetype, F_pic *pic) { return read_epsf_pdf(file, filetype, pic, False); } int read_epsf_pdf(FILE *file, int filetype, F_pic *pic, Boolean pdf_flag) { int nbitmap; Boolean bitmapz; Boolean foundbbx; int nested; char *cp; unsigned char *mp; unsigned int hexnib; int flag; char buf[300]; int llx, lly, urx, ury, bad_bbox; unsigned char *last; Boolean useGS; useGS = False; llx = lly = urx = ury = 0; foundbbx = False; nested = 0; while (fgets(buf, 300, file) != NULL) { /* look for /MediaBox for pdf file */ if (pdf_flag) { if (!strncmp(buf, "/MediaBox", 8)) { /* look for the MediaBox spec */ char *c; c = strchr(buf, '[') + 1; if (c && sscanf(c, "%d %d %d %d", &llx, &lly, &urx, &ury) < 4) { llx = lly = 0; urx = paper_sizes[0].width * 72 / PIX_PER_INCH; ury = paper_sizes[0].height * 72 / PIX_PER_INCH; file_msg("Bad MediaBox in header, assuming %s size", appres.INCHES ? "Letter" : "A4"); app_flush(); } } /* look for bounding box */ } else if (!nested && !strncmp(buf, "%%BoundingBox:", 14)) { if (!strstr(buf, "(atend)")) { /* make sure doesn't say (atend) */ float rllx, rlly, rurx, rury; if (sscanf(strchr(buf, ':') + 1, "%f %f %f %f", &rllx, &rlly, &rurx, &rury) < 4) { file_msg("Bad EPS file: %s", file); close_picfile(file,filetype); return FileInvalid; } foundbbx = True; llx = round(rllx); lly = round(rlly); urx = round(rurx); ury = round(rury); break; } } else if (!strncmp(buf, "%%Begin", 7)) { ++nested; } else if (nested && !strncmp(buf, "%%End", 5)) { --nested; } } if (!pdf_flag && !foundbbx) { file_msg("No bounding box found in EPS file"); close_picfile(file,filetype); return FileInvalid; } if ((urx - llx) == 0) { llx = lly = 0; urx = (appres.INCHES ? LETTER_WIDTH : A4_WIDTH) * 72 / PIX_PER_INCH; ury = (appres.INCHES ? LETTER_HEIGHT : A4_HEIGHT) * 72 / PIX_PER_INCH; file_msg("Bad %s, assuming %s size", pdf_flag ? "/MediaBox" : "EPS bounding box", appres.INCHES ? "Letter" : "A4"); app_flush(); } pic->hw_ratio = (float) (ury - lly) / (float) (urx - llx); pic->pic_cache->size_x = round((urx - llx) * PIC_FACTOR); pic->pic_cache->size_y = round((ury - lly) * PIC_FACTOR); /* make 2-entry colormap here if we use monochrome */ pic->pic_cache->cmap[0].red = pic->pic_cache->cmap[0].green = pic->pic_cache->cmap[0].blue = 0; pic->pic_cache->cmap[1].red = pic->pic_cache->cmap[1].green = pic->pic_cache->cmap[1].blue = 255; pic->pic_cache->numcols = 0; if ((bad_bbox = (urx <= llx || ury <= lly))) { file_msg("Bad values in %s", pdf_flag ? "/MediaBox" : "EPS bounding box"); close_picfile(file,filetype); return FileInvalid; } bitmapz = False; /* look for a preview bitmap */ if (!pdf_flag) { while (fgets(buf, 300, file) != NULL) { lower(buf); if (!strncmp(buf, "%%beginpreview", 14)) { sscanf(buf, "%%%%beginpreview: %d %d %*d", &pic->pic_cache->bit_size.x, &pic->pic_cache->bit_size.y); bitmapz = True; break; } } } #ifdef GSBIT /* if monochrome and a preview bitmap exists, don't use gs */ if ((!appres.monochrome || !bitmapz) && !bad_bbox) { useGS = bitmap_from_gs(file, filetype, pic, urx, llx, ury, lly, pdf_flag); } #endif /* GSBIT */ if (!useGS) { if (!bitmapz) { file_msg("EPS object read OK, but no preview bitmap found/generated"); close_picfile(file,filetype); return PicSuccess; } else if (pic->pic_cache->bit_size.x <= 0 || pic->pic_cache->bit_size.y <= 0) { file_msg("Strange bounding-box/bitmap-size error, no bitmap found/generated"); close_picfile(file,filetype); return FileInvalid; } else { nbitmap = (pic->pic_cache->bit_size.x + 7) / 8 * pic->pic_cache->bit_size.y; pic->pic_cache->bitmap = (unsigned char *) malloc(nbitmap); if (pic->pic_cache->bitmap == NULL) { file_msg("Could not allocate %d bytes of memory for %s bitmap\n", pdf_flag ? "PDF" : "EPS", nbitmap); close_picfile(file,filetype); return PicSuccess; } /* for whatever reason, ghostscript wasn't available or didn't work but there * is a preview bitmap - use that */ mp = pic->pic_cache->bitmap; bzero((char *) mp, nbitmap); /* init bitmap to zero */ last = pic->pic_cache->bitmap + nbitmap; flag = True; while (fgets(buf, 300, file) != NULL && mp < last) { lower(buf); if (!strncmp(buf, "%%endpreview", 12) || !strncmp(buf, "%%endimage", 10)) break; cp = buf; if (*cp != '%') break; cp++; while (*cp != '\0') { if (isxdigit(*cp)) { hexnib = hex(*cp); if (flag) { flag = False; *mp = hexnib << 4; } else { flag = True; *mp = *mp + hexnib; mp++; if (mp >= last) break; } } cp++; } } } } /* put in type */ pic->pic_cache->subtype = T_PIC_EPS; close_picfile(file,filetype); return PicSuccess; } int hex(char c) { if (isdigit(c)) return (c - 48); else return (c - 87); } void lower(char *buf) { while (*buf) { if (isupper(*buf)) *buf = (char) tolower(*buf); buf++; } } #ifdef GSBIT /* if GhostScript */ /* Read bitmap from gs, return True if success */ Boolean bitmap_from_gs(file, filetype, pic, urx, llx, ury, lly, pdf_flag) FILE *file; int filetype; F_pic *pic; int urx, llx, ury, lly; int pdf_flag; { char buf[300]; FILE *tmpfp, *pixfile, *gsfile; char *driver; int status, wid, ht, nbitmap, fd; char tmpfile[PATH_MAX], pixnam[PATH_MAX], errnam[PATH_MAX], gscom[2 * PATH_MAX], psnam[PATH_MAX]; wid = urx - llx; ht = ury - lly; strcpy(tmpfile, pic->pic_cache->file); /* is the file a pipe? (This would mean that it is compressed) */ if (filetype == 1) { /* yes, now we have to uncompress the file into a temp * file */ /* re-open the pipe */ close_picfile(file, filetype); file = open_picfile(tmpfile, &filetype, PIPEOK, pixnam); snprintf(tmpfile, sizeof(tmpfile), "%s/xfig-eps.XXXXXX", TMPDIR); if ((fd = mkstemp(tmpfile)) == -1 || (tmpfp = fdopen(fd, "wb")) == NULL) { if (fd != -1) { unlink(tmpfile); close(fd); } file_msg("Couldn't open tmp file %s, %s", tmpfile, strerror(errno)); return False; } while (fgets(buf, 300, file) != NULL) fputs(buf, tmpfp); fclose(tmpfp); } /* make name /TMPDIR/xfig-pic######.pix */ snprintf(pixnam, sizeof(pixnam), "%s/xfig-pic.XXXXXX", TMPDIR); if ((fd = mkstemp(pixnam)) == -1) { file_msg("Couldn't open tmp file %s, %s", pixnam, strerror(errno)); return False; } close(fd); /* and file name for any error messages from gs */ snprintf(errnam, sizeof(errnam), "%s/xfig-picerr.XXXXXX", TMPDIR); if ((fd = mkstemp(errnam)) == -1) { file_msg("Couldn't open tmp file %s, %s", errnam, strerror(errno)); return False; } close(fd); /* generate gs command line */ /* for monochrome, use pbm */ if (tool_cells <= 2 || appres.monochrome) { /* monochrome output */ driver = "pbmraw"; } else { /* for color, use pcx */ driver = "pcx24b"; } /* Canonicalize the eps file filename, needed to "defeat" -dSAFER */ if (!realpath(tmpfile, psnam)) { file_msg("Cannot canonicalize %s: %s\n", tmpfile, strerror(errno)); return False; } sprintf(gscom, "%s -r72x72 -sDEVICE=%s -g%dx%d -sOutputFile=%s -dDELAYSAFER -c '<< /PermitFileReading [ (%s)] >> setuserparams .locksafe' -dSAFER -q - > %s 2>&1", appres.ghostscript, driver, wid, ht, pixnam, psnam, errnam); if (appres.DEBUG) fprintf(stderr,"calling: %s\n",gscom); if ((gsfile = popen(gscom, "w")) == 0) { file_msg("Cannot open pipe with command: %s\n", gscom); return False; } /********************************************* gs commands (New method) W is the width in pixels and H is the height gs -dSAFER -sDEVICE=pbmraw(or pcx24b) -gWxH -sOutputFile=/tmp/xfig-pic%%%.pix -q - -llx -lly translate % mark dictionary (otherwise fails for tiger.ps (e.g.): % many ps files don't 'end' their dictionaries) countdictstack mark /oldshowpage {showpage} bind def /showpage {} def /initgraphics {} def <<< this nasty command should never be used! /initmmatrix {} def <<< this one too (psfile) run oldshowpage % clean up stacks and dicts cleartomark countdictstack exch sub { end } repeat quit *********************************************/ fprintf(gsfile, "%d %d translate\n", -llx, -lly); fprintf(gsfile, "countdictstack\n"); fprintf(gsfile, "mark\n"); fprintf(gsfile, "/oldshowpage {showpage} bind def\n"); fprintf(gsfile, "/showpage {} def\n"); fprintf(gsfile, "/initgraphics {} def\n"); fprintf(gsfile, "/initmatrix {} def\n"); fprintf(gsfile, "(%s) run\n", psnam); fprintf(gsfile, "oldshowpage\n"); fprintf(gsfile, "cleartomark\n"); fprintf(gsfile, "countdictstack exch sub { end } repeat\n"); fprintf(gsfile, "quit\n"); status = pclose(gsfile); if (filetype == 1) unlink(tmpfile); /* error return from ghostscript, look in error file */ if (status != 0 || (pixfile = fopen(pixnam, "rb")) == NULL) { FILE *errfile = fopen(errnam, "r"); file_msg("Could not parse %s file with ghostscript: %s", pdf_flag ? "PDF" : "EPS", file); if (errfile) { file_msg("ERROR from ghostscript:"); while (fgets(buf, 300, errfile) != NULL) { buf[strlen(buf) - 1] = '\0'; /* strip newlines */ file_msg("%s", buf); } fclose(errfile); unlink(errnam); } unlink(pixnam); return False; } pic->pic_cache->bit_size.x = wid; pic->pic_cache->bit_size.y = ht; if (tool_cells <= 2 || appres.monochrome) { pic->pic_cache->numcols = 0; nbitmap = (pic->pic_cache->bit_size.x + 7) / 8 * pic->pic_cache->bit_size.y; pic->pic_cache->bitmap = (unsigned char *) malloc(nbitmap); if (pic->pic_cache->bitmap == NULL) { file_msg("Could not allocate %d bytes of memory for %s bitmap\n", pdf_flag ? "PDF" : "EPS", nbitmap); return False; } fgets(buf, 300, pixfile); /* skip any comments */ /* the last line read is the image size */ do fgets(buf, 300, pixfile); while (buf[0] == '#'); if (fread(pic->pic_cache->bitmap, nbitmap, 1, pixfile) != 1) { file_msg("Error reading output (%s problems?): %s", pdf_flag ? "PDF" : "EPS", pixnam); file_msg("Look in %s for errors", errnam); fclose(pixfile); unlink(pixnam); pic->pic_cache->bitmap = NULL; return False; } } else { FILE *pcxfile; int filtyp; /* now read the pcx file just produced by gs */ /* don't need bitmap - _read_pcx() will allocate a new one */ /* save picture width/height because read_pcx will overwrite it */ wid = pic->pic_cache->size_x; ht = pic->pic_cache->size_y; pcxfile = open_picfile(pixnam, &filtyp, PIPEOK, tmpfile); status = _read_pcx(pcxfile, pic); /* restore width/height */ pic->pic_cache->size_x = wid; pic->pic_cache->size_y = ht; if (status != 1) { file_msg("Error reading output from ghostscript (%s problems?): %s", pdf_flag ? "PDF" : "EPS", pixnam); file_msg("Look in %s for errors", errnam); unlink(pixnam); if (pic->pic_cache->bitmap) free((char *) pic->pic_cache->bitmap); pic->pic_cache->bitmap = NULL; return False; } } fclose(pixfile); unlink(pixnam); unlink(errnam); return True; /* Success */ } #endif /* GSBIT */ xfig.3.2.5c/f_readgif.c0000700002656300244210000002106411641414046015431 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Parts Copyright (c) 1990 David Koblas * Parts Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_picobj.h" #include "w_msgpanel.h" #include "f_readpcx.h" #define BUFLEN 1024 /* Some of the following code is extracted from giftopnm.c, from the netpbm package */ /* +-------------------------------------------------------------------+ */ /* | Copyright 1990, David Koblas. | */ /* | Permission to use, copy, modify, and distribute this software | */ /* | and its documentation for any purpose and without fee is hereby | */ /* | granted, provided that the above copyright notice appear in all | */ /* | copies and that both that copyright notice and this permission | */ /* | notice appear in supporting documentation. This software is | */ /* | provided "as is" without express or implied warranty. | */ /* +-------------------------------------------------------------------+ */ static Boolean ReadColorMap(FILE *fd, unsigned int number, struct Cmap *cmap); static Boolean DoGIFextension(FILE *fd, int label); static int GetDataBlock(FILE *fd, unsigned char *buf); #define LOCALCOLORMAP 0x80 #define ReadOK(file,buffer,len) (fread((void *) buffer, (size_t) len, (size_t) 1, (FILE *) file) != 0) #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) #define LM_to_uint(a,b) (((b)<<8)|(a)) struct { unsigned int Width; unsigned int Height; struct Cmap ColorMap[MAX_COLORMAP_SIZE]; unsigned int BitPixel; unsigned int ColorResolution; unsigned int Background; unsigned int AspectRatio; } GifScreen; struct { int transparent; int delayTime; int inputFlag; int disposal; } Gif89 = { -1, -1, -1, 0 }; /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ int read_gif(FILE *file, int filetype, F_pic *pic) { char buf[BUFLEN],pcxname[PATH_MAX]; FILE *giftopcx; struct Cmap localColorMap[MAX_COLORMAP_SIZE]; int i, stat, size, fd; int useGlobalColormap; unsigned int bitPixel, red, green, blue; unsigned char c; char version[4]; /* first read header to look for any transparent color extension */ if (! ReadOK(file,buf,6)) { return FileInvalid; } if (strncmp((char*)buf,"GIF",3) != 0) { return FileInvalid; } strncpy(version, (char*)(buf + 3), 3); version[3] = '\0'; if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { file_msg("Unknown GIF version %s",version); return FileInvalid; } if (! ReadOK(file,buf,7)) { return FileInvalid; /* failed to read screen descriptor */ } GifScreen.Width = LM_to_uint(buf[0],buf[1]); GifScreen.Height = LM_to_uint(buf[2],buf[3]); GifScreen.BitPixel = 2<<(buf[4]&0x07); GifScreen.ColorResolution = (((((int)buf[4])&0x70)>>3)+1); GifScreen.Background = (unsigned int) buf[5]; GifScreen.AspectRatio = (unsigned int) buf[6]; if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (!ReadColorMap(file,GifScreen.BitPixel,GifScreen.ColorMap)) { return FileInvalid; /* error reading global colormap */ } } if (GifScreen.AspectRatio != 0 && GifScreen.AspectRatio != 49) { if (appres.DEBUG) fprintf(stderr,"warning - non-square pixels\n"); } /* assume no transparent color for now */ Gif89.transparent = TRANSP_NONE; /* read the full header to get any transparency information */ for (;;) { if (! ReadOK(file,&c,1)) { return FileInvalid; /* EOF / read error on image data */ } if (c == ';') { /* GIF terminator, finish up */ return PicSuccess; /* all done */ } if (c == '!') { /* Extension */ if (! ReadOK(file,&c,1)) file_msg("GIF read error on extension function code"); (void) DoGIFextension(file, c); continue; } if (c != ',') { /* Not a valid start character */ continue; } if (! ReadOK(file,buf,9)) { return FileInvalid; /* couldn't read left/top/width/height */ } useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); bitPixel = 1<<((buf[8]&0x07)+1); if (! useGlobalColormap) { if (!ReadColorMap(file, bitPixel, localColorMap)) { file_msg("error reading local GIF colormap" ); return PicSuccess; } } break; /* image starts here, header is done */ } /* save transparent indicator */ pic->pic_cache->transp = Gif89.transparent; /* close it and open it again (it may be a pipe so we can't just rewind) */ close_picfile(file, filetype); file = open_picfile(pic->pic_cache->file, &filetype, PIPEOK, pcxname); /* now call giftopnm and ppmtopcx */ /* make name for temp output file */ snprintf(pcxname, sizeof(pcxname), "%s/xfig-pcx.XXXXXX", TMPDIR); if ((fd = mkstemp(pcxname)) == -1) { file_msg("Cannot create temporary file\n"); return FileInvalid; } close(fd); /* make command to convert gif to pcx into temp file */ sprintf(buf, "giftopnm -quiet | ppmtopcx -quiet > %s", pcxname); if ((giftopcx = popen(buf,"w" )) == 0) { file_msg("Cannot open pipe to giftopnm or ppmtopcx\n"); close_picfile(file,filetype); return FileInvalid; } while ((size=fread(buf, 1, BUFLEN, file)) != 0) { fwrite(buf, size, 1, giftopcx); } /* close pipe */ pclose(giftopcx); if ((giftopcx = fopen(pcxname, "rb")) == NULL) { file_msg("Can't open temp output file\n"); close_picfile(file,filetype); return FileInvalid; } /* now call read_pcx to read the pcx file */ stat = read_pcx(giftopcx, filetype, pic); pic->pic_cache->subtype = T_PIC_GIF; /* remove temp file */ unlink(pcxname); /* now match original transparent colortable index with possibly new colortable from ppmtopcx */ if (pic->pic_cache->transp != TRANSP_NONE) { if (useGlobalColormap) { red = GifScreen.ColorMap[pic->pic_cache->transp].red; green = GifScreen.ColorMap[pic->pic_cache->transp].green; blue = GifScreen.ColorMap[pic->pic_cache->transp].blue; } else { red = localColorMap[pic->pic_cache->transp].red; green = localColorMap[pic->pic_cache->transp].green; blue = localColorMap[pic->pic_cache->transp].blue; } for (i=0; ipic_cache->numcols; i++) { if (pic->pic_cache->cmap[i].red == red && pic->pic_cache->cmap[i].green == green && pic->pic_cache->cmap[i].blue == blue) break; } if (i < pic->pic_cache->numcols) pic->pic_cache->transp = i; } return stat; } static Boolean ReadColorMap(FILE *fd, unsigned int number, struct Cmap *cmap) { int i; unsigned char rgb[3]; for (i = 0; i < number; ++i) { if (! ReadOK(fd, rgb, sizeof(rgb))) { file_msg("bad GIF colormap" ); return False; } cmap[i].red = rgb[0]; cmap[i].green = rgb[1]; cmap[i].blue = rgb[2]; } return True; } static Boolean DoGIFextension(FILE *fd, int label) { static unsigned char buf[256]; char *str; switch (label) { case 0x01: /* Plain Text Extension */ str = "Plain Text Extension"; break; case 0xff: /* Application Extension */ str = "Application Extension"; break; case 0xfe: /* Comment Extension */ str = "Comment Extension"; while (GetDataBlock(fd, buf) != 0) { ; /* GIF comment */ } return False; case 0xf9: /* Graphic Control Extension */ str = "Graphic Control Extension"; (void) GetDataBlock(fd, (unsigned char*) buf); Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint(buf[1],buf[2]); if ((buf[0] & 0x1) != 0) Gif89.transparent = buf[3]; while (GetDataBlock(fd, buf) != 0) ; return False; default: str = (char *) buf; sprintf(str, "UNKNOWN (0x%02x)", label); break; } if (appres.DEBUG) fprintf(stderr,"got a '%s' extension\n", str ); while (GetDataBlock(fd, buf) != 0) ; return False; } int ZeroDataBlock = False; static int GetDataBlock(FILE *fd, unsigned char *buf) { unsigned char count; /* error in getting DataBlock size */ if (! ReadOK(fd,&count,1)) { return -1; } ZeroDataBlock = count == 0; /* error in reading DataBlock */ if ((count != 0) && (! ReadOK(fd, buf, count))) { return -1; } return count; } xfig.3.2.5c/f_readjpg.c0000700002656300244210000002332511641414046015446 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * This software is copyright (C) 1991-1996, Thomas G. Lane. * Parts Copyright (c) 1989-2007 by Brian V. Smith * All Rights Reserved except as specified below. * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ /* The following code is from the example.c file in the JPEG distribution */ /* Here is their copyright notice: * * The authors make NO WARRANTY or representation, either express or implied, * with respect to this software, its quality, accuracy, merchantability, or * fitness for a particular purpose. This software is provided "AS IS", and you, * its user, assume the entire risk as to its quality and accuracy. * * This software is copyright (C) 1991-1996, Thomas G. Lane. * All Rights Reserved except as specified below. * * Permission is hereby granted to use, copy, modify, and distribute this * software (or portions thereof) for any purpose, without fee, subject to these * conditions: * (1) If any part of the source code for this software is distributed, then this * README file must be included, with this copyright and no-warranty notice * unaltered; and any additions, deletions, or changes to the original files * must be clearly indicated in accompanying documentation. * (2) If only executable code is distributed, then the accompanying * documentation must state that "this software is based in part on the work of * the Independent JPEG Group". * (3) Permission for use of this software is granted only if the user accepts * full responsibility for any undesirable consequences; the authors accept * NO LIABILITY for damages of any kind. * * These conditions apply to any software derived from or based on the IJG code, * not just to the unmodified library. If you use our work, you ought to * acknowledge us. * * Permission is NOT granted for the use of any IJG author's name or company name * in advertising or publicity relating to this software or products derived from * it. This software may be referred to only as "the Independent JPEG Group's * software". * * We specifically permit and encourage the use of this software as the basis of * commercial products, provided that all warranty or liability claims are * assumed by the product vendor. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_picobj.h" #include "f_util.h" #include "w_msgpanel.h" #include "w_setup.h" #include #include static Boolean read_JPEG_file(FILE *file); static F_pic *pict; static unsigned char *bitmapptr; /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ int read_jpg(FILE *file, int filetype, F_pic *pic) { /* make scale factor smaller for metric */ float scale = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH; pict = pic; if (!read_JPEG_file(file)) { close_picfile(file,filetype); return FileInvalid; } /* number of colors is put in by read_JPEG_file() */ pic->pixmap = None; pic->pic_cache->subtype = T_PIC_JPEG; pic->pic_cache->size_x = pic->pic_cache->bit_size.x * scale; pic->pic_cache->size_y = pic->pic_cache->bit_size.y * scale; pic->hw_ratio = (float) pic->pic_cache->bit_size.y/pic->pic_cache->bit_size.x; /* we have the image here, see if we need to map it to monochrome display */ if (tool_cells <= 2 || appres.monochrome) map_to_mono(pic); close_picfile(file,filetype); return PicSuccess; } /* These static variables are needed by the error routines. */ static jmp_buf setjmp_buffer; /* for return to caller */ static void error_exit(j_common_ptr cinfo); static void error_output(j_common_ptr cinfo); struct error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct error_mgr * error_ptr; /* * OK, here is the main function that actually causes everything to happen. * We assume here that the JPEG file is already open and that all * decompression parameters can be default values. * The routine returns True if successful, False if not. */ static Boolean read_JPEG_file (FILE *file) { int i; /* This struct contains the JPEG decompression parameters and pointers to * working space (which is allocated as needed by the JPEG library). */ struct jpeg_decompress_struct cinfo; JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ struct error_mgr jerr; /* error handler */ /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = error_exit; jerr.pub.output_message = error_output; /* Establish the setjmp return context for error_exit to use. */ if (setjmp(jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object and return. */ jpeg_destroy_decompress(&cinfo); return False; } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress(&cinfo); /* Step 2: specify data source (i.e. our file) */ jpeg_stdio_src(&cinfo, file); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header(&cinfo, True); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and * (b) we passed TRUE to reject a tables-only JPEG file as an error. * See libjpeg.doc for more info. */ /* We want a colormapped color space */ /* Let the jpeg library do a two-pass over the image to make nice colors */ cinfo.quantize_colors = True; /* Now fill in the pict parameters */ pict->pic_cache->bit_size.x = cinfo.image_width; pict->pic_cache->bit_size.y = cinfo.image_height; if ((pict->pic_cache->bitmap = (unsigned char *) malloc(cinfo.image_width * cinfo.image_height)) == NULL) { file_msg("Can't alloc memory for JPEG image"); longjmp(jerr.setjmp_buffer, 1); } bitmapptr = pict->pic_cache->bitmap; /* Step 4: set parameters for decompression */ /* In this example, we don't need to change any of the defaults set by * jpeg_read_header(), so we do nothing here. */ /* Step 5: Start decompressor */ jpeg_start_decompress(&cinfo); /* We may need to do some setup of our own at this point before reading * the data. After jpeg_start_decompress() we have the correct scaled * output image dimensions available, as well as the output colormap * if we asked for color quantization. * In this example, we need to make an output work buffer of the right size. */ /* JSAMPLEs per row in output buffer */ row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that will go away when done with image */ buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ /* Here we use the library's state variable cinfo.output_scanline as the * loop counter, so that we don't have to keep track ourselves. */ while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); for (i = 0; i < row_stride; i++) *bitmapptr++ = (unsigned char) buffer[0][i]; } /* Step 7: fill up the colortable in the pict object */ /* (Must do this before jpeg_finish_decompress or jpeg_destroy_decompress) */ pict->pic_cache->numcols = cinfo.actual_number_of_colors; for (i = 0; i < pict->pic_cache->numcols; i++) { pict->pic_cache->cmap[i].red = cinfo.colormap[0][i]; /* set other colors to first if grayscale */ if (cinfo.jpeg_color_space == JCS_GRAYSCALE) { pict->pic_cache->cmap[i].green = pict->pic_cache->cmap[i].blue = pict->pic_cache->cmap[i].red; } else { pict->pic_cache->cmap[i].green = cinfo.colormap[1][i]; pict->pic_cache->cmap[i].blue = cinfo.colormap[2][i]; } } /* Step 8: Finish decompression */ (void) jpeg_finish_decompress(&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* Step 9: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress(&cinfo); /* At this point you may want to check to see whether any corrupt-data * warnings occurred (test whether jerr.pub.num_warnings is nonzero). */ /* And we're done! */ return True; } /* * Here's the routine that will replace the standard error_exit method: */ static void error_exit (j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; /* cinfo->err really points to a error_mgr struct, so coerce pointer */ error_ptr err = (error_ptr) cinfo->err; /* Display the message if it is NOT "Not a JPEG file" */ /* However, since the error number is not public we have to parse the string */ /* Format the message */ (*cinfo->err->format_message) (cinfo, buffer); if (strncmp(buffer,"Not a JPEG file",15)!=0) file_msg("%s", buffer); /* Return control to the setjmp point */ longjmp(err->setjmp_buffer, 1); } static void error_output(j_common_ptr cinfo) { char buffer[JMSG_LENGTH_MAX]; (*cinfo->err->format_message)(cinfo, buffer); file_msg("%s", buffer); } xfig.3.2.5c/f_readold.c0000700002656300244210000003054311641414046015444 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_read.h" #include "f_util.h" #include "u_create.h" #include "u_fonts.h" #include "w_drawprim.h" #include "w_msgpanel.h" #include "w_zoom.h" #include "d_spline.h" #include "u_free.h" /******* Fig 1.3 subtype of objects *******/ #define DRAW_ELLIPSE_BY_RAD 1 #define DRAW_ELLIPSE_BY_DIA 2 #define DRAW_CIRCLE_BY_RAD 3 #define DRAW_CIRCLE_BY_DIA 4 #define DRAW_CIRCULAR_ARC 5 #define DRAW_POLYLINE 6 #define DRAW_BOX 7 #define DRAW_POLYGON 8 #define DRAW_TEXT 9 #define DRAW_SPLINE 10 #define DRAW_CLOSEDSPLINE 11 #define DRAW_COMPOUND 13 static F_ellipse *read_1_3_ellipseobject(FILE *fp); static F_line *read_1_3_lineobject(FILE *fp); static F_text *read_1_3_textobject(FILE *fp); static F_spline *read_1_3_splineobject(FILE *fp); static F_arc *read_1_3_arcobject(FILE *fp); static F_compound *read_1_3_compoundobject(FILE *fp); int read_1_3_objects(FILE *fp, char *buf, F_compound *obj) { F_ellipse *e, *le = NULL; F_line *l, *ll = NULL; F_text *t, *lt = NULL; F_spline *s, *ls = NULL; F_arc *a, *la = NULL; F_compound *c, *lc = NULL; int n; int object, pixperinch, canvaswid, canvasht, coord_sys; n = sscanf(buf, "%d%d%d%d\n", &pixperinch, &coord_sys, &canvaswid, &canvasht); if (n != 4) { file_msg("Incorrect format in the first line in input file"); return (-1); } obj->nwcorner.x = pixperinch; obj->nwcorner.y = coord_sys; while (fscanf(fp, "%d", &object) == 1) { switch (object) { case O_POLYLINE: if ((l = read_1_3_lineobject(fp)) == NULL) return (-1); if (ll) ll = (ll->next = l); else ll = obj->lines = l; num_object++; break; case O_SPLINE: if ((s = read_1_3_splineobject(fp)) == NULL) return (-1); if (ls) ls = (ls->next = s); else ls = obj->splines = s; num_object++; break; case O_ELLIPSE: if ((e = read_1_3_ellipseobject(fp)) == NULL) return (-1); if (le) le = (le->next = e); else le = obj->ellipses = e; num_object++; break; case O_ARC: if ((a = read_1_3_arcobject(fp)) == NULL) return (-1); if (la) la = (la->next = a); else la = obj->arcs = a; num_object++; break; case O_TXT: if ((t = read_1_3_textobject(fp)) == NULL) return (-1); if (lt) lt = (lt->next = t); else lt = obj->texts = t; num_object++; break; case O_COMPOUND: if ((c = read_1_3_compoundobject(fp)) == NULL) return (-1); if (lc) lc = (lc->next = c); else lc = obj->compounds = c; num_object++; break; default: file_msg("Incorrect object code %d", object); return (-1); } /* switch */ } /* while */ if (feof(fp)) return (0); else return (errno); } static F_arc * read_1_3_arcobject(FILE *fp) { F_arc *a; int f, b, h, w, n; if ((a = create_arc()) == NULL) return (NULL); a->pen_color = a->fill_color = BLACK; a->depth = 0; a->pen_style = -1; a->cap_style = CAP_BUTT; a->for_arrow = NULL; a->back_arrow = NULL; a->next = NULL; n = fscanf(fp, " %d %d %d %f %d %d %d %d %d %f %f %d %d %d %d %d %d\n", &a->type, &a->style, &a->thickness, &a->style_val, &a->direction, &f, &b, &h, &w, &a->center.x, &a->center.y, &a->point[0].x, &a->point[0].y, &a->point[1].x, &a->point[1].y, &a->point[2].x, &a->point[2].y); a->type = T_OPEN_ARC; if (n != 17) { file_msg("Incomplete arc data"); free((char *) a); return (NULL); } if (f) { a->for_arrow = forward_arrow(); a->for_arrow->wd = w; a->for_arrow->ht = h; } if (b) { a->back_arrow = backward_arrow(); a->back_arrow->wd = w; a->back_arrow->ht = h; } return (a); } static F_compound * read_1_3_compoundobject(FILE *fp) { F_arc *a, *la = NULL; F_ellipse *e, *le = NULL; F_line *l, *ll = NULL; F_spline *s, *ls = NULL; F_text *t, *lt = NULL; F_compound *com, *c, *lc = NULL; int n, object; if ((com = create_compound()) == NULL) return (NULL); com->arcs = NULL; com->ellipses = NULL; com->lines = NULL; com->splines = NULL; com->texts = NULL; com->comments = NULL; com->compounds = NULL; com->next = NULL; n = fscanf(fp, " %d %d %d %d\n", &com->nwcorner.x, &com->nwcorner.y, &com->secorner.x, &com->secorner.y); if (n != 4) { file_msg("Incorrect compound object format"); return (NULL); } while (fscanf(fp, "%d", &object) == 1) { switch (object) { case O_POLYLINE: if ((l = read_1_3_lineobject(fp)) == NULL) { free_line(&l); return (NULL); } if (ll) ll = (ll->next = l); else ll = com->lines = l; break; case O_SPLINE: if ((s = read_1_3_splineobject(fp)) == NULL) { free_spline(&s); return (NULL); } if (ls) ls = (ls->next = s); else ls = com->splines = s; break; case O_ELLIPSE: if ((e = read_1_3_ellipseobject(fp)) == NULL) { free_ellipse(&e); return (NULL); } if (le) le = (le->next = e); else le = com->ellipses = e; break; case O_ARC: if ((a = read_1_3_arcobject(fp)) == NULL) { free_arc(&a); return (NULL); } if (la) la = (la->next = a); else la = com->arcs = a; break; case O_TXT: if ((t = read_1_3_textobject(fp)) == NULL) { free_text(&t); return (NULL); } if (lt) lt = (lt->next = t); else lt = com->texts = t; break; case O_COMPOUND: if ((c = read_1_3_compoundobject(fp)) == NULL) { free_compound(&c); return (NULL); } if (lc) lc = (lc->next = c); else lc = com->compounds = c; break; case O_END_COMPOUND: return (com); } /* switch */ } if (feof(fp)) return (com); else { file_msg("Format error: %s", strerror(errno)); return (NULL); } } static F_ellipse * read_1_3_ellipseobject(FILE *fp) { F_ellipse *e; int n, t; if ((e = create_ellipse()) == NULL) return (NULL); e->pen_color = e->fill_color = BLACK; e->angle = 0.0; e->depth = 0; e->pen_style = -1; e->fill_style = UNFILLED; e->next = NULL; n = fscanf(fp, " %d %d %d %f %d %d %d %d %d %d %d %d %d\n", &t, &e->style, &e->thickness, &e->style_val, &e->direction, &e->center.x, &e->center.y, &e->radiuses.x, &e->radiuses.y, &e->start.x, &e->start.y, &e->end.x, &e->end.y); if (n != 13) { file_msg("Incomplete ellipse data"); free((char *) e); return (NULL); } if (t == DRAW_ELLIPSE_BY_RAD) e->type = T_ELLIPSE_BY_RAD; else if (t == DRAW_ELLIPSE_BY_DIA) e->type = T_ELLIPSE_BY_DIA; else if (t == DRAW_CIRCLE_BY_RAD) e->type = T_CIRCLE_BY_RAD; else e->type = T_CIRCLE_BY_DIA; return (e); } static F_line * read_1_3_lineobject(FILE *fp) { F_line *l; F_point *p, *q; int f, b, h, w, n, t, x, y; if ((l = create_line()) == NULL) return (NULL); l->pen_color = l->fill_color = DEFAULT; l->depth = 0; l->pen_style = -1; l->join_style = JOIN_MITER; l->cap_style = CAP_BUTT; l->fill_style = UNFILLED; l->for_arrow = NULL; l->back_arrow = NULL; l->next = NULL; if ((p = create_point()) == NULL) { free((char *) l); return (NULL); } l->points = p; n = fscanf(fp, " %d %d %d %f %d %d %d %d %d %d", &t, &l->style, &l->thickness, &l->style_val, &f, &b, &h, &w, &p->x, &p->y); if (n != 10) { file_msg("Incomplete line data"); free((char *) l); return (NULL); } if (t == DRAW_POLYLINE) l->type = T_POLYLINE; else if (t == DRAW_POLYGON) l->type = T_POLYGON; else l->type = T_BOX; if (f) { l->for_arrow = forward_arrow(); l->for_arrow->wd = w; l->for_arrow->ht = h; } if (b) { l->back_arrow = backward_arrow(); l->back_arrow->wd = w; l->back_arrow->ht = h; } for (;;) { if (fscanf(fp, " %d %d", &x, &y) != 2) { file_msg("Incomplete line object"); free_linestorage(l); return (NULL); } if (x == 9999) break; if ((q = create_point()) == NULL) return (NULL); q->x = x; q->y = y; q->next = NULL; p->next = q; p = q; } return (l); } static F_spline * read_1_3_splineobject(FILE *fp) { F_spline *s; F_point *p, *q; int f, b, h, w, n, t, x, y; if ((s = create_spline()) == NULL) return (NULL); s->pen_color = s->fill_color = BLACK; s->depth = 0; s->pen_style = -1; s->fill_style = UNFILLED; s->cap_style = CAP_BUTT; s->for_arrow = NULL; s->back_arrow = NULL; s->sfactors = NULL; s->next = NULL; if ((p = create_point()) == NULL) { free((char *) s); return (NULL); } s->points = p; n = fscanf(fp, " %d %d %d %f %d %d %d %d %d %d", &t, &s->style, &s->thickness, &s->style_val, &f, &b, &h, &w, &p->x, &p->y); if (n != 10) { file_msg("Incomplete spline data"); free((char *) s); return (NULL); } if (t == DRAW_CLOSEDSPLINE) s->type = T_CLOSED_APPROX; else s->type = T_OPEN_APPROX; if (f) { s->for_arrow = forward_arrow(); s->for_arrow->wd = w; s->for_arrow->ht = h; } if (b) { s->back_arrow = backward_arrow(); s->back_arrow->wd = w; s->back_arrow->ht = h; } for (;;) { if (fscanf(fp, " %d %d", &x, &y) != 2) { file_msg("Incomplete spline object"); free_splinestorage(s); return (NULL); }; if (x == 9999) break; if ((q = create_point()) == NULL) { free_splinestorage(s); return (NULL); } q->x = x; q->y = y; q->next = NULL; p->next = q; p = q; } if closed_spline(s) { /* get rid of the first point (the last one has the same coordinates) */ F_point *ptr =s->points; s->points=s->points->next; free(ptr); } if (! make_sfactors(s)) { free_splinestorage(s); return (NULL); } return (s); } static F_text * read_1_3_textobject(FILE *fp) { F_text *t; int n; int dum; char buf[512]; PR_SIZE tx_dim; if ((t = create_text()) == NULL) return (NULL); t->type = T_LEFT_JUSTIFIED; t->size = 18; /* size field wasn't used in version 1.3 */ t->flags = RIGID_TEXT; /* same with flags (called style) */ t->color = BLACK; t->depth = 0; t->pen_style = -1; t->angle = 0.0; t->next = NULL; if (!fgets(buf, sizeof(buf), fp)) { file_msg("Incomplete text data"); free((char *) t); return (NULL); } /* Note using strlen(buf) here will waste a few bytes, as the various text attributes are counted into this length too. */ if ((t->cstring = new_string(strlen(buf))) == NULL) return (NULL); /* ascent and length will be recalculated later */ n = sscanf(buf, " %d %d %d %d %d %d %d %[^\n]", &t->font, &dum, &dum, &t->ascent, &t->length, &t->base_x, &t->base_y, t->cstring); if (n != 8) { file_msg("Incomplete text data"); free(t->cstring); free((char *) t); return (NULL); } if (!strlen(t->cstring)) { free(t->cstring); free((char *) t); file_msg("Empty text string at line %d.", line_no); return (NULL); } /* get the font struct */ t->zoom = zoomscale; t->fontstruct = lookfont(x_fontnum(psfont_text(t), t->font), round(t->size*display_zoomscale)); if (t->font >= MAXFONT(t)) { file_msg("Invalid text font (%d) at line %d, setting to DEFAULT.", t->font, line_no); t->font = DEFAULT; } /* now calculate the actual length and height of the string in fig units */ tx_dim = textsize(t->fontstruct, strlen(t->cstring), t->cstring); t->length = round(tx_dim.length); t->ascent = round(tx_dim.ascent); t->descent = round(tx_dim.descent); return (t); } xfig.3.2.5c/f_readpcx.c0000700002656300244210000001761111641414046015461 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Based on (public domain) code from Russell Marks * Parts Copyright (c) 2000-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_neuclrtab.h" #include "f_picobj.h" #include "f_util.h" #include "w_indpanel.h" #include "w_color.h" #include "w_msgpanel.h" #include "w_setup.h" /* This is based on: */ /* pcx2ppm 1.2 - convert pcx to ppm * based on zgv's readpcx.c * public domain by RJM * * this is incredibly messy * * 1999-03-16 updated to support 24-bit. */ typedef unsigned char byte; struct pcxhed { byte manuf,ver,encod,bpp; /* 0 - 3 gen format */ byte x1lo,x1hi,y1lo,y1hi; /* 4 - 11 size */ byte x2lo,x2hi,y2lo,y2hi; byte unused1[4]; /* 12 - 15 scrn size */ byte pal16[48]; /* 16 - 63 4-bit palette */ byte reserved; /* 64 reserved */ byte nplanes; /* 65 num of bitplanes */ byte bytelinelo,bytelinehi; /* 66 - 67 bytes per line */ byte unused2[60]; /* 68 - 127 unused */ }; /* palette info is after image data */ /* prototypes */ void dispbyte(unsigned char *ptr,int *xp,int *yp,int c,int w,int h, int real_bpp,int byteline,int *planep,int *pmaskp); int _read_pcx(FILE *pcxfile, F_pic *pic); int read_pcx(FILE *file, int filetype, F_pic *pic) { int status; /* make scale factor smaller for metric */ float scale = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH; status = _read_pcx(file,pic); if (status != 1) { close_picfile(file,filetype); return FileInvalid; } pic->pixmap = None; pic->hw_ratio = (float) pic->pic_cache->bit_size.y / pic->pic_cache->bit_size.x; pic->pic_cache->subtype = T_PIC_PCX; pic->pic_cache->size_x = pic->pic_cache->bit_size.x * scale; pic->pic_cache->size_y = pic->pic_cache->bit_size.y * scale; /* if monochrome display map bitmap */ if (tool_cells <= 2 || appres.monochrome) map_to_mono(pic); close_picfile(file,filetype); return PicSuccess; } /* _read_pcx() is called from read_pcx() and read_epsf(). The latter is because the output of ghostscript is to a PCX file (actually a pipe). */ void pcx_decode(); int _read_pcx(FILE *pcxfile, F_pic *pic) { int i,w,h,bytepp,x,y,yy,byteline,plane,pmask; unsigned char *pal; struct pcxhed header; int count, cnt; long bytemax,bytesdone; byte inbyte; int real_bpp; /* how many bpp file really is */ pic->pic_cache->bitmap=NULL; fread(&header,1,sizeof(struct pcxhed),pcxfile); if (header.manuf!=10 || header.encod!=1) return FileInvalid; /* header.bpp=1, header.nplanes=1 = 1-bit. * header.bpp=1, header.nplanes=2 = 2-bit. - added B.V.Smith 6/00 * header.bpp=1, header.nplanes=3 = 3-bit. - added B.V.Smith 6/00 * header.bpp=1, header.nplanes=4 = 4-bit. * header.bpp=8, header.nplanes=1 = 8-bit. * header.bpp=8, header.nplanes=3 = 24-bit. * anything else gives an `unsupported' error. */ real_bpp=0; bytepp = 1; switch(header.bpp) { case 1: switch(header.nplanes) { case 1: real_bpp=1; break; case 2: real_bpp=2; break; case 3: real_bpp=3; break; case 4: real_bpp=4; break; } break; case 8: switch(header.nplanes) { case 1: real_bpp=8; break; case 3: real_bpp=24; bytepp = 3; break; } break; } if (!real_bpp) return FileInvalid; if ((pal=calloc(768,1))==NULL) return FileInvalid; w=(header.x2lo+256*header.x2hi)-(header.x1lo+256*header.x1hi)+1; h=(header.y2lo+256*header.y2hi)-(header.y1lo+256*header.y1hi)+1; byteline=header.bytelinelo+256*header.bytelinehi; if (w==0 || h==0) return FileInvalid; x=0; y=0; bytemax=w*h; if (real_bpp==1 || real_bpp==4) bytemax=(1<<30); /* we use a 'ypic_cache->bitmap=malloc(w*(h+2)*bytepp))==NULL) return FileInvalid; /* need this if more than one bitplane */ memset(pic->pic_cache->bitmap,0,w*h*bytepp); bytesdone=0; /* start reading image */ for (yy=0; yypic_cache->bitmap,&x,&y,inbyte,w,h,real_bpp, byteline,&plane,&pmask); bytesdone++; } else { cnt = inbyte & 0x3F; inbyte = fgetc(pcxfile); for (count=0; countpic_cache->bitmap,&x,&y,inbyte,w,h,real_bpp, byteline,&plane,&pmask); bytesdone += cnt; } } } pic->pic_cache->bit_size.x = w; pic->pic_cache->bit_size.y = h; /* read palette */ switch(real_bpp) { case 1: pic->pic_cache->cmap[0].red = pic->pic_cache->cmap[0].green = pic->pic_cache->cmap[0].blue = 0; pic->pic_cache->cmap[1].red = pic->pic_cache->cmap[1].green = pic->pic_cache->cmap[1].blue = 255; pic->pic_cache->numcols = 2; break; case 2: case 3: case 4: /* 2-,3-, and 4-bit, palette is embedded in header */ pic->pic_cache->numcols = (1<pic_cache->numcols; x++) { pic->pic_cache->cmap[x].red = header.pal16[x*3 ]; pic->pic_cache->cmap[x].green = header.pal16[x*3+1]; pic->pic_cache->cmap[x].blue = header.pal16[x*3+2]; } break; case 8: /* 8-bit */ fseek(pcxfile, -768L, SEEK_END);/* locate colormap in last 768 bytes of file */ for (x=0; x<256; x++) { pic->pic_cache->cmap[x].red = fgetc(pcxfile); pic->pic_cache->cmap[x].green = fgetc(pcxfile); pic->pic_cache->cmap[x].blue = fgetc(pcxfile); } /* start with 256 */ pic->pic_cache->numcols = 256; /* ignore duplicate white entries after real colors */ for (i = pic->pic_cache->numcols-1; i >=0 ; i--) { if (pic->pic_cache->cmap[i].red != 255 || pic->pic_cache->cmap[i].green != 255 || pic->pic_cache->cmap[i].blue != 255) break; } if (i < pic->pic_cache->numcols-2) pic->pic_cache->numcols = i+2; break; case 24: /* no palette, must use neural net to reduce to 256 colors with palette */ if (!map_to_palette(pic)) return FileInvalid; /* out of memory or something */ break; } return PicSuccess; } void dispbyte(unsigned char *ptr,int *xp,int *yp,int c,int w,int h, int real_bpp,int byteline,int *planep,int *pmaskp) { int f; unsigned char *dstptr; switch(real_bpp) { case 1: case 2: case 3: case 4: /* mono or 4-bit */ if ((*yp)>=h) return; dstptr=ptr+(*yp)*w+*xp; w=byteline*8; for (f=0; f<8; f++) { *dstptr++|=(c&(0x80>>(f&7)))?(*pmaskp):0; (*xp)++; if (*xp>=w) { if (real_bpp==1) { (*xp)=0,(*yp)++; return; } (*xp)=0; (*planep)++; (*pmaskp)<<=1; if (real_bpp==2) { if (*planep==2) { (*yp)++; return; } } else if (real_bpp==3) { if (*planep==3) { (*yp)++; return; } } else { /* otherwise, it's 4 bpp */ if (*planep==4) { (*yp)++; return; } } } if ((*yp)>=h) return; } break; case 8: *(ptr+(*yp)*w+*xp)=c; (*xp)++; if (*xp>=byteline) { (*xp)=0; (*yp)++; } break; case 24: *(ptr+((*yp)*w+*xp)*3+(2-(*planep)))=c; (*xp)++; if (*xp>=byteline) { (*xp)=0; (*planep)++; /* no need to change pmask */ if (*planep==3) { (*yp)++; return; } } break; } } xfig.3.2.5c/f_readpng.c0000700002656300244210000001564211641414046015455 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 2000-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_neuclrtab.h" #include "f_util.h" #include "w_indpanel.h" #include "w_color.h" #include "w_msgpanel.h" #include "w_setup.h" #include "f_picobj.h" #include int read_png(FILE *file, int filetype, F_pic *pic) { register int i, j; png_structp png_ptr; png_infop info_ptr; png_infop end_info; png_uint_32 w, h, rowsize; int bit_depth, color_type, interlace_type; int compression_type, filter_type; png_bytep *row_pointers; char *ptr; int num_palette; png_colorp palette; png_color_16 background; /* make scale factor smaller for metric */ float scale = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH; /* read the png file here */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL); if (!png_ptr) { close_picfile(file,filetype); return FileInvalid; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); close_picfile(file,filetype); return FileInvalid; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); close_picfile(file,filetype); return FileInvalid; } /* set long jump recovery here */ if (setjmp(png_jmpbuf(png_ptr))) { /* if we get here there was a problem reading the file */ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); close_picfile(file,filetype); return FileInvalid; } /* set up the input code */ png_init_io(png_ptr, file); /* now read the file info */ png_read_info(png_ptr, info_ptr); /* get width, height etc */ png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); png_fixed_point gamma = 0.45; png_get_gAMA_fixed(png_ptr,info_ptr,&gamma); png_set_gamma(png_ptr, 2.2, gamma); if (png_get_valid(png_ptr,info_ptr,PNG_INFO_bKGD)) { /* set the background to the one supplied */ png_color_16p background; png_get_bKGD(png_ptr,info_ptr,&background); png_set_background(png_ptr, background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); } else { /* blend the canvas background using the alpha channel */ background.red = x_bg_color.red >> 8; background.green = x_bg_color.green >> 8; background.blue = x_bg_color.blue >> 8; background.gray = 0; png_set_background(png_ptr, &background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 2.2); } /* set order to BGR (default is RGB) */ if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); /* strip 16-bit RGB values down to 8-bit */ if (bit_depth == 16) png_set_strip_16(png_ptr); /* force to 8-bits per pixel if less than 8 */ if (bit_depth < 8) png_set_packing(png_ptr); /* dither rgb files down to 8 bit palette */ num_palette = 0; pic->pic_cache->transp = TRANSP_NONE; if (color_type & PNG_COLOR_MASK_COLOR) { png_uint_16p histogram; #ifdef USE_ALPHA /* we need to somehow give libpng a background color that it can combine with the alpha information in each pixel to make the image */ if (color_type & PNG_COLOR_MASK_ALPHA) pic->pic_cache->transp = TRANSP_BACKGROUND; #endif /* USE_ALPHA */ if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) { png_get_hIST(png_ptr, info_ptr, &histogram); #if (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && (PNG_LIBPNG_VER_MINOR > 4))) || defined(png_set_quantize) png_set_quantize(png_ptr, palette, num_palette, 256, histogram, 0); #else png_set_dither(png_ptr, palette, num_palette, 256, histogram, 0); #endif } } if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* expand to full range */ png_set_expand(png_ptr); /* make a gray colormap */ num_palette = 256; for (i = 0; i < num_palette; i++) pic->pic_cache->cmap[i].red = pic->pic_cache->cmap[i].green = pic->pic_cache->cmap[i].blue = i; } else { /* transfer the palette to the object's colormap */ for (i=0; ipic_cache->cmap[i].red = palette[i].red; pic->pic_cache->cmap[i].green = palette[i].green; pic->pic_cache->cmap[i].blue = palette[i].blue; } } rowsize = w; if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) rowsize = w*3; /* allocate the row pointers and rows */ row_pointers = (png_bytep *) malloc(h*sizeof(png_bytep)); for (i=0; ipic_cache->bitmap=malloc(rowsize*h))==NULL) { close_picfile(file,filetype); return FileInvalid; } /* copy it to our bitmap */ ptr = pic->pic_cache->bitmap; for (i=0; ipic_cache->bit_size.x = w; pic->pic_cache->bit_size.y = h; if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { /* no palette, must use neural net to reduce to 256 colors with palette */ if (!map_to_palette(pic)) { close_picfile(file,filetype); return FileInvalid; /* out of memory or something */ } pic->pic_cache->numcols = 256; } else { pic->pic_cache->numcols = num_palette; } /* clean up */ png_read_end(png_ptr, end_info); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); for (i=0; ipic_cache->subtype = T_PIC_PNG; pic->pixmap = None; pic->hw_ratio = (float) pic->pic_cache->bit_size.y / pic->pic_cache->bit_size.x; pic->pic_cache->size_x = pic->pic_cache->bit_size.x * scale; pic->pic_cache->size_y = pic->pic_cache->bit_size.y * scale; /* if monochrome display map bitmap */ if (tool_cells <= 2 || appres.monochrome) map_to_mono(pic); close_picfile(file,filetype); return PicSuccess; } xfig.3.2.5c/f_readppm.c0000700002656300244210000000404211641414046015455 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1999-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_picobj.h" #include "w_msgpanel.h" #include "f_readpcx.h" #define BUFLEN 1024 /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ int read_ppm(FILE *file, int filetype, F_pic *pic) { char buf[BUFLEN],pcxname[PATH_MAX]; FILE *giftopcx; int stat, size, fd; /* make name for temp output file */ snprintf(pcxname, sizeof(pcxname), "%s/xfig-pcx.XXXXXX", TMPDIR); if ((fd = mkstemp(pcxname)) == -1) { file_msg("Cannot open temp file %s: %s\n", pcxname, strerror(errno)); return FileInvalid; } close(fd); /* make command to convert gif to pcx into temp file */ sprintf(buf, "ppmtopcx > %s 2> /dev/null", pcxname); if ((giftopcx = popen(buf,"w" )) == 0) { file_msg("Cannot open pipe to ppmtopcx\n"); close_picfile(file,filetype); return FileInvalid; } while ((size=fread(buf, 1, BUFLEN, file)) != 0) { fwrite(buf, size, 1, giftopcx); } /* close pipe */ pclose(giftopcx); if ((giftopcx = fopen(pcxname, "rb")) == NULL) { file_msg("Can't open temp output file\n"); close_picfile(file,filetype); return FileInvalid; } /* now call read_pcx to read the pcx file */ stat = read_pcx(giftopcx, filetype, pic); pic->pic_cache->subtype = T_PIC_PPM; /* remove temp file */ unlink(pcxname); close_picfile(file,filetype); return stat; } xfig.3.2.5c/f_readtif.c0000700002656300244210000000416511641414046015451 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1999-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "w_msgpanel.h" #include "f_readpcx.h" /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ /* for some reason, tifftopnm requires a file and can't work in a pipe */ int read_tif(char *filename, int filetype, F_pic *pic) { char buf[2*PATH_MAX+40],pcxname[PATH_MAX]; FILE *tiftopcx; int stat, fd; /* make name for temp output file */ snprintf(pcxname, sizeof(pcxname), "%s/xfig-pcx.XXXXXX", TMPDIR); if ((fd = mkstemp(pcxname)) == -1) { file_msg("Cannot open temp file %s: %s\n", pcxname, strerror(errno)); return FileInvalid; } close(fd); /* make command to convert tif to pnm then to pcx into temp file */ /* for some reason, tifftopnm requires a file and can't work in a pipe */ sprintf(buf, "tifftopnm %s 2> /dev/null | ppmtopcx > %s 2> /dev/null", filename, pcxname); if ((tiftopcx = popen(buf,"w" )) == 0) { file_msg("Cannot open pipe to tifftopnm or ppmtopcx\n"); /* remove temp file */ unlink(pcxname); return FileInvalid; } /* close pipe */ pclose(tiftopcx); if ((tiftopcx = fopen(pcxname, "rb")) == NULL) { file_msg("Can't open temp output file\n"); /* remove temp file */ unlink(pcxname); return FileInvalid; } /* now call read_pcx to read the pcx file */ stat = read_pcx(tiftopcx, filetype, pic); pic->pic_cache->subtype = T_PIC_TIF; /* remove temp file */ unlink(pcxname); return stat; } xfig.3.2.5c/f_readxbm.c0000700002656300244210000002011711641414046015450 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright, 1987, Massachusetts Institute of Technology * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_picobj.h" #include "w_setup.h" /* attempt to read a bitmap file */ /* return codes: PicSuccess (1) : success FileInvalid (-2) : invalid file */ int ReadDataFromBitmapFile (FILE *file, unsigned int *width, unsigned int *height, char **data_ret); int read_xbm(FILE *file, int filetype, F_pic *pic) { int status; unsigned int x, y; /* make scale factor smaller for metric */ float scale = (appres.INCHES ? (float)PIX_PER_INCH : 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH; /* first try for a X Bitmap file format */ status = ReadDataFromBitmapFile(file, &x, &y, &pic->pic_cache->bitmap); if (status == BitmapSuccess) { pic->pic_cache->subtype = T_PIC_XBM; pic->hw_ratio = (float) y / x; pic->pic_cache->numcols = 0; pic->pic_cache->bit_size.x = x; pic->pic_cache->bit_size.y = y; pic->pic_cache->size_x = x * scale; pic->pic_cache->size_y = y * scale; close_picfile(file,filetype); return PicSuccess; } close_picfile(file,filetype); /* Non Bitmap file */ return FileInvalid; } /* The following is a modified version of the XReadBitmapFromFile() routine from the X11R5 distribution. This version reads the XBM file into a data array rather than creating the pixmap directly. Also, it will uncompress or gunzip the file if necessary. */ /* $XConsortium: XRdBitF.c,v 1.15 91/02/01 16:34:46 gildea Exp $ */ /* Copyright, 1987, Massachusetts Institute of Technology */ /* * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and * documentation files (the "Software"), including without limitation the * rights to use, copy, modify, merge, publish and/or distribute copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that this copyright * notice remain intact. */ /* * Code to read bitmaps from disk files. Interprets * data from X10 and X11 bitmap files. * * Modified for speedup by Jim Becker, changed image * data parsing logic (removed some fscanf()s). * Aug 5, 1988 * * Note that this file and ../Xmu/RdBitF.c look very similar.... Keep them * that way (but don't use common source code so that people can have one * without the other). */ #define MAX_SIZE 255 /* shared data for the image read/parse logic */ static short hexTable[256]; /* conversion value */ static Bool initialized = False; /* easier to fill in at run time */ /* * Table index for the hex values. Initialized once, first time. * Used for translation value or delimiter significance lookup. */ static void initHexTable(void) { /* * We build the table at run time for several reasons: * * 1. portable to non-ASCII machines. * 2. still reentrant since we set the init flag after setting table. * 3. easier to extend. * 4. less prone to bugs. */ hexTable['0'] = 0; hexTable['1'] = 1; hexTable['2'] = 2; hexTable['3'] = 3; hexTable['4'] = 4; hexTable['5'] = 5; hexTable['6'] = 6; hexTable['7'] = 7; hexTable['8'] = 8; hexTable['9'] = 9; hexTable['A'] = 10; hexTable['B'] = 11; hexTable['C'] = 12; hexTable['D'] = 13; hexTable['E'] = 14; hexTable['F'] = 15; hexTable['a'] = 10; hexTable['b'] = 11; hexTable['c'] = 12; hexTable['d'] = 13; hexTable['e'] = 14; hexTable['f'] = 15; /* delimiters of significance are flagged w/ negative value */ hexTable[' '] = -1; hexTable[','] = -1; hexTable['}'] = -1; hexTable['\n'] = -1; hexTable['\t'] = -1; initialized = True; } /* * read next hex value in the input stream, return -1 if EOF */ static int NextInt(FILE *fstream) { int ch; int value = 0; int ret_value = 0; int gotone = 0; int done = 0; /* loop, accumulate hex value until find delimiter */ /* skip any initial delimiters found in read stream */ while (!done) { ch = getc(fstream); if (ch == EOF) { value = -1; done++; } else { /* trim high bits, check type and accumulate */ ch &= 0xff; if (isascii(ch) && isxdigit(ch)) { value = (value << 4) + hexTable[ch]; gotone++; } else if ((hexTable[ch]) < 0 && gotone) done++; } } ret_value = 0; if (value & 0x80) ret_value |= 0x01; if (value & 0x40) ret_value |= 0x02; if (value & 0x20) ret_value |= 0x04; if (value & 0x10) ret_value |= 0x08; if (value & 0x08) ret_value |= 0x10; if (value & 0x04) ret_value |= 0x20; if (value & 0x02) ret_value |= 0x40; if (value & 0x01) ret_value |= 0x80; return ret_value; } int ReadDataFromBitmapFile(FILE *file, unsigned int *width, unsigned int *height, char **data_ret) /* RETURNED */ /* RETURNED */ { char *data = NULL; /* working variable */ char line[MAX_SIZE]; /* input line from file */ int size; /* number of bytes of data */ char name_and_type[MAX_SIZE]; /* an input line */ char *type; /* for parsing */ int value; /* from an input line */ int version10p; /* boolean, old format */ int padding; /* to handle alignment */ int bytes_per_line; /* per scanline of data */ unsigned int ww = 0; /* width */ unsigned int hh = 0; /* height */ /* first time initialization */ if (initialized == False) initHexTable(); /* error cleanup and return macro */ #define RETURN(code) { if (data) free (data); \ return code; } while (fgets(line, MAX_SIZE, file)) { if (strlen(line) == MAX_SIZE-1) { RETURN (BitmapFileInvalid); } if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) { if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (!strcmp("width", type)) ww = (unsigned int) value; if (!strcmp("height", type)) hh = (unsigned int) value; continue; } if (sscanf(line, "static short %s = {", name_and_type) == 1) version10p = 1; else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1) version10p = 0; else if (sscanf(line, "static char %s = {", name_and_type) == 1) version10p = 0; else continue; if (!(type = strrchr(name_and_type, '_'))) type = name_and_type; else type++; if (strcmp("bits[]", type)) continue; if (!ww || !hh) RETURN (BitmapFileInvalid); if ((ww % 16) && ((ww % 16) < 9) && version10p) padding = 1; else padding = 0; bytes_per_line = (ww+7)/8 + padding; size = bytes_per_line * hh; data = (char *) malloc ((unsigned int) size); if (!data) RETURN (BitmapNoMemory); if (version10p) { char *ptr; int bytes; for (bytes=0, ptr=data; bytes> 8; } } else { char *ptr; int bytes; for (bytes=0, ptr=data; bytesc_color; if (c == NULL || *c == '\0') { /* use white for null color */ c = "white"; file_msg("white used for *NULL color"); } if (XParseColor(tool_d, tool_cm, c, &exact_def) == 0) { file_msg("Error parsing color %s",c); exact_def.red = exact_def.green = exact_def.blue = 65535; } pic->pic_cache->cmap[i].red = exact_def.red >> 8; pic->pic_cache->cmap[i].green = exact_def.green >> 8; pic->pic_cache->cmap[i].blue = exact_def.blue >> 8; } pic->pic_cache->subtype = T_PIC_XPM; pic->pic_cache->numcols = image.ncolors; pic->pixmap = None; pic->pic_cache->bitmap = (unsigned char *) malloc(image.width*image.height*sizeof(unsigned char)); if (pic->pic_cache->bitmap == NULL) { file_msg("cannot allocate space for XPM image"); return PicSuccess; } for (i=0; ipic_cache->bitmap[i] = (unsigned char) image.data[i]; /* int to unsigned char */ pic->hw_ratio = (float) image.height / image.width; pic->pic_cache->bit_size.x = image.width; pic->pic_cache->bit_size.y = image.height; pic->pic_cache->size_x = image.width * scale; pic->pic_cache->size_y = image.height * scale; XpmFreeXpmImage(&image); /* get rid of the image */ /* if monochrome display map bitmap */ if (tool_cells <= 2 || appres.monochrome) map_to_mono(pic); return PicSuccess; } return FileInvalid; } xfig.3.2.5c/f_save.c0000700002656300244210000004051011641414046014763 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1985-1988 by Supoj Sutanthavibul * Parts Copyright (c) 1989-2007 by Brian V. Smith * Parts Copyright (c) 1991 by Paul King * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "mode.h" #include "object.h" #include "patchlevel.h" #include "version.h" #include "f_read.h" #include "f_util.h" #include "u_create.h" #include "w_export.h" #include "w_indpanel.h" #include "w_msgpanel.h" #include "w_setup.h" #include "w_util.h" #include "w_zoom.h" #include "e_compound.h" #include "f_load.h" #include "u_bound.h" static int write_tmpfile = 0; static char save_cur_dir[PATH_MAX]; /* Prototypes */ static void write_arrows(FILE *fp, F_arrow *f, F_arrow *b); int write_objects (FILE *fp); void write_fig_header (FILE *fp); void write_arc (FILE *fp, F_arc *a); void write_compound (FILE *fp, F_compound *com); void write_ellipse (FILE *fp, F_ellipse *e); void write_line (FILE *fp, F_line *l); void write_spline (FILE *fp, F_spline *s); void write_text (FILE *fp, F_text *t); void write_comments (FILE *fp, char *com); void write_colordefs (FILE *fp); void init_write_tmpfile(void) { write_tmpfile=1; /* save current file directory */ strcpy(save_cur_dir, cur_file_dir); /* and set to TMPDIR to preserver absolute paths of any imported pictures */ strcpy(cur_file_dir, TMPDIR); } void end_write_tmpfile(void) { write_tmpfile=0; /* restore current file directory */ strcpy(cur_file_dir, save_cur_dir); } int write_file(char *file_name, Boolean update_recent) { FILE *fp; if (!ok_to_write(file_name, "SAVE")) return (-1); if ((fp = fopen(file_name, "wb")) == NULL) { file_msg("Couldn't open file %s, %s", file_name, strerror(errno)); beep(); return (-1); } num_object = 0; if (write_objects(fp)) { file_msg("Error writing file %s, %s", file_name, strerror(errno)); beep(); exit (2); return (-1); } if (!update_figs) put_msg("%d object(s) saved in \"%s\"", num_object, file_name); /* update the recent list if caller desires */ if (update_recent) update_recent_list(file_name); return (0); } /* for fig2dev */ int write_objects(FILE *fp) { F_arc *a; F_compound *c; F_ellipse *e; F_line *l; F_spline *s; F_text *t; /* * A 2 for the orientation means that the origin (0,0) is at the upper * left corner of the screen (2nd quadrant). */ if (!update_figs) put_msg("Writing . . ."); #ifdef I18N /* set the numeric locale to C so we get decimal points for numbers */ setlocale(LC_NUMERIC, "C"); #endif /* I18N */ write_fig_header(fp); for (a = objects.arcs; a != NULL; a = a->next) { num_object++; write_arc(fp, a); } for (c = objects.compounds; c != NULL; c = c->next) { num_object++; write_compound(fp, c); } for (e = objects.ellipses; e != NULL; e = e->next) { num_object++; write_ellipse(fp, e); } for (l = objects.lines; l != NULL; l = l->next) { num_object++; write_line(fp, l); } for (s = objects.splines; s != NULL; s = s->next) { num_object++; write_spline(fp, s); } for (t = objects.texts; t != NULL; t = t->next) { num_object++; write_text(fp, t); } #ifdef I18N /* reset to original locale */ setlocale(LC_NUMERIC, ""); #endif /* I18N */ if (ferror(fp)) { fclose(fp); return (-1); } if (fclose(fp) == EOF) return (-1); return (0); } void write_fig_header(FILE *fp) { char str[40], *com; int i, len; if (appres.write_v40) { fprintf(fp, "#FIG 4.0 Produced by xfig version %s.%s\n",FIG_VERSION,PATCHLEVEL); compound_bound(&objects, &objects.nwcorner.x, &objects.nwcorner.y, &objects.secorner.x, &objects.secorner.y); fprintf(fp, "Header {\n"); fprintf(fp, " Resolution %d\n", appres.INCHES? PIX_PER_INCH: PIX_PER_CM); fprintf(fp, " Bounds %d %d %d %d\n", objects.nwcorner.x, objects.nwcorner.y, objects.secorner.x, objects.secorner.y); fprintf(fp, " Orient %s\n", appres.landscape? "Landscape": "Portrait"); fprintf(fp, " Units %s\n", appres.INCHES? "Inches": "Metric"); fprintf(fp, " Uscale %.3f%s=1%s\n", appres.userscale, appres.INCHES? "in":"cm", cur_fig_units); fprintf(fp, " Pagejust %s\n", appres.flushleft? "Flush left": "Center"); fprintf(fp, " Pagesize %s\n", paper_sizes[appres.papersize].sname); fprintf(fp, " Pages %s\n", appres.multiple? "Multiple": "Single"); fprintf(fp, " Mag %.2f\n", appres.magnification); get_grid_spec(str, export_grid_minor_text, export_grid_major_text); fprintf(fp, " PGrid %s\n", str); fprintf(fp, " SGrid %d\n", cur_gridmode); fprintf(fp, " Smoothing %d\n", appres.smooth_factor); fprintf(fp, " ExportBgColor %d\n", export_background_color); fprintf(fp, " Transp %d\n", appres.transparent); fprintf(fp, " Margin %d\n", appres.export_margin); #ifdef DONT_SHOW_DEPTHS if (dont_show_depths) { fprintf(fp, " DontShowDepths {%s}\n", ......); } #endif /* DONT_SHOW_DEPTHS */ if (objects.comments) { fprintf(fp, " Description {\n"); /* escape any '{' we may find in the comments */ com = objects.comments; len = strlen(com); for (i=0; icomments); if (appres.write_v40) { fprintf(fp, "Arc {\n"); switch (a->type) { case T_OPEN_ARC: fprintf(fp, " Open"); break; case T_PIE_WEDGE_ARC: fprintf(fp, " PieWedge"); break; case T_ELLIPTICAL: fprintf(fp, " Ellip"); break; default: /* arc is corrupt, close off */ fprintf(fp, "\n}\n"); return; } fprintf(fp, " %d %d %d %d %d %d %d %.3f %d %d %.3f %.3f %d %d %d %d %d %d %.4f\n", a->style, a->thickness, a->pen_color, a->fill_color, a->depth, a->pen_style, a->fill_style, a->style_val, a->cap_style, a->direction, a->center.x, a->center.y, a->point[0].x, a->point[0].y, a->point[1].x, a->point[1].y, a->point[2].x, a->point[2].y, a->angle); fprintf(fp, "\n"); /* finish with any arrowheads */ write_arrows(fp, a->for_arrow, a->back_arrow); fprintf(fp, "}\n"); } else { /* V3.2 */ /* externally, type 1=open arc, 2=pie wedge */ fprintf(fp, "%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %.3f %.3f %d %d %d %d %d %d\n", O_ARC, a->type+1, a->style, a->thickness, a->pen_color, a->fill_color, a->depth, a->pen_style, a->fill_style, a->style_val, a->cap_style, a->direction, a->for_arrow ? 1 : 0, a->back_arrow ? 1 : 0, a->center.x, a->center.y, a->point[0].x, a->point[0].y, a->point[1].x, a->point[1].y, a->point[2].x, a->point[2].y); /* write any arrowheads */ write_arrows(fp, a->for_arrow, a->back_arrow); } /* V4.0/3.2 */ } void write_compound(FILE *fp, F_compound *com) { F_arc *a; F_compound *c; F_ellipse *e; F_line *l; F_spline *s; F_text *t; /* any comments first */ write_comments(fp, com->comments); if (appres.write_v40) { fprintf(fp, "Compound (%d %d %d %d) {\n", com->nwcorner.x, com->nwcorner.y, com->secorner.x, com->secorner.y); } else { /* V3.2 */ fprintf(fp, "%d %d %d %d %d\n", O_COMPOUND, com->nwcorner.x, com->nwcorner.y, com->secorner.x, com->secorner.y); } for (a = com->arcs; a != NULL; a = a->next) write_arc(fp, a); for (c = com->compounds; c != NULL; c = c->next) write_compound(fp, c); for (e = com->ellipses; e != NULL; e = e->next) write_ellipse(fp, e); for (l = com->lines; l != NULL; l = l->next) write_line(fp, l); for (s = com->splines; s != NULL; s = s->next) write_spline(fp, s); for (t = com->texts; t != NULL; t = t->next) write_text(fp, t); /* close off the compound */ if (appres.write_v40) { fprintf(fp, "}\n"); } else { /* V3.2 */ fprintf(fp, "%d\n", O_END_COMPOUND); } } void write_ellipse(FILE *fp, F_ellipse *e) { /* get rid of any evil ellipses which have either radius = 0 */ if (e->radiuses.x == 0 || e->radiuses.y == 0) return; /* any comments first */ write_comments(fp, e->comments); if (appres.write_v40) { fprintf(fp, "Ellipse {\n"); if (e->type == T_ELLIPSE_BY_RAD) fprintf(fp, " ByRad {\n"); else fprintf(fp, " ByDia {\n"); fprintf(fp, "%d %d %d %d %d %d %d %.3f %d %.4f %d %d %d %d %d %d %d %d\n", e->style, e->thickness, e->pen_color, e->fill_color, e->depth, e->pen_style, e->fill_style, e->style_val, e->direction, e->angle, e->center.x, e->center.y, e->radiuses.x, e->radiuses.y, e->start.x, e->start.y, e->end.x, e->end.y); fprintf(fp, " }\n"); fprintf(fp, "}\n"); } else { /* V3.2 */ fprintf(fp, "%d %d %d %d %d %d %d %d %d %.3f %d %.4f %d %d %d %d %d %d %d %d\n", O_ELLIPSE, e->type, e->style, e->thickness, e->pen_color, e->fill_color, e->depth, e->pen_style, e->fill_style, e->style_val, e->direction, e->angle, e->center.x, e->center.y, e->radiuses.x, e->radiuses.y, e->start.x, e->start.y, e->end.x, e->end.y); } /* V4.0/3.2 */ } void write_line(FILE *fp, F_line *l) { F_point *p; int npts; char *picfile; if (l->points == NULL) return; /* any comments first */ write_comments(fp, l->comments); /* count number of points and put it in the object */ for (npts=0, p = l->points; p != NULL; p = p->next) npts++; if (appres.write_v40) { fprintf(fp, "Polyline {\n"); switch (l->type) { case T_POLYLINE: fprintf(fp, " Line "); break; case T_BOX: fprintf(fp, " Box "); break; case T_POLYGON: fprintf(fp, " Polygon "); break; case T_ARCBOX: fprintf(fp, " Arcbox "); break; case T_PICTURE: fprintf(fp, " Picture "); break; } fprintf(fp, "\n"); /* finish with any arrowheads */ write_arrows(fp, l->for_arrow, l->back_arrow); fprintf(fp, "}\n"); } else { /* V3.2 */ fprintf(fp, "%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d %d %d\n", O_POLYLINE, l->type, l->style, l->thickness, l->pen_color, l->fill_color, l->depth, l->pen_style, l->fill_style, l->style_val, l->join_style, l->cap_style, l->radius, l->for_arrow ? 1 : 0, l->back_arrow ? 1 : 0, npts); /* write any arrowheads */ write_arrows(fp, l->for_arrow, l->back_arrow); /* handle picture stuff */ if (l->type == T_PICTURE) { char *s1; picfile = NULL; if (l->pic->pic_cache) picfile = l->pic->pic_cache->file; if (picfile == NULL || strlen(picfile) == 0) { s1 = ""; } else if (strncmp(picfile, cur_file_dir, strlen(cur_file_dir))==0 && strlen(picfile) > strlen(cur_file_dir) && picfile[strlen(cur_file_dir)] == '/') { /* use relative path if the file is under current directory */ s1 = &picfile[strlen(cur_file_dir)+1]; } else { /* use full path */ s1 = picfile; } fprintf(fp, "\t%d %s\n", l->pic->flipped, s1); } fprintf(fp, "\t"); npts=0; for (p = l->points; p != NULL; p = p->next) { fprintf(fp, " %d %d", p->x, p->y); if (++npts >= 6 && p->next != NULL) { fprintf(fp,"\n\t"); npts=0; } } fprintf(fp, "\n"); } /* if V4.0 */ } void write_spline(FILE *fp, F_spline *s) { F_sfactor *cp; F_point *p; int npts; if (s->points == NULL) return; /* any comments first */ write_comments(fp, s->comments); /* count number of points and put it in the object */ for (npts=0, p = s->points; p != NULL; p = p->next) npts++; fprintf(fp, "%d %d %d %d %d %d %d %d %d %.3f %d %d %d %d\n", O_SPLINE, s->type, s->style, s->thickness, s->pen_color, s->fill_color, s->depth, s->pen_style, s->fill_style, s->style_val, s->cap_style, s->for_arrow ? 1 : 0, s->back_arrow ? 1 : 0, npts); /* write any arrowheads */ write_arrows(fp, s->for_arrow, s->back_arrow); fprintf(fp, "\t"); npts=0; for (p = s->points; p != NULL; p = p->next) { fprintf(fp, " %d %d", p->x, p->y); if (++npts >= 6 && p->next != NULL) { fprintf(fp,"\n\t"); npts=0; } }; fprintf(fp, "\n"); if (s->sfactors == NULL) return; /* save new shape factor */ fprintf(fp, "\t"); npts=0; for (cp = s->sfactors; cp != NULL; cp = cp->next) { fprintf(fp, " %.3f",cp->s); if (++npts >= 8 && cp->next != NULL) { fprintf(fp,"\n\t"); npts=0; } } fprintf(fp, "\n"); } void write_text(FILE *fp, F_text *t) { int l, len; unsigned char c; if (t->length == 0) return; /* any comments first */ write_comments(fp, t->comments); fprintf(fp, "%d %d %d %d %d %d %d %.4f %d %d %d %d %d ", O_TXT, t->type, t->color, t->depth, t->pen_style, t->font, t->size, t->angle, t->flags, t->ascent+t->descent, t->length, t->base_x, t->base_y); len = strlen(t->cstring); for (l=0; lcstring[l]; if (c == '\\') fprintf(fp,"\\\\"); /* escape a '\' with another one */ else if (c < 0x80) putc(c,fp); /* normal 7-bit ASCII */ else fprintf(fp, "\\%o", c); /* 8-bit, make \xxx (octal) */ } fprintf(fp,"\\001\n"); /* finish off with '\001' string */ } /* write any arrow heads */ static void write_arrows(FILE *fp, F_arrow *f, F_arrow *b) { if (appres.write_v40) { if (f) fprintf(fp, " ForwardArrow { %d %d %.2f %.2f %.2f }\n", f->type, f->style, f->thickness, f->wd*15.0, f->ht*15.0); if (b) fprintf(fp, " BackwardArrow { %d %d %.2f %.2f %.2f }\n", b->type, b->style, b->thickness, b->wd*15.0, b->ht*15.0); } else { /* V3.2 */ if (f) fprintf(fp, "\t%d %d %.2f %.2f %.2f\n", f->type, f->style, f->thickness, f->wd*15.0, f->ht*15.0); if (b) fprintf(fp, "\t%d %d %.2f %.2f %.2f\n", b->type, b->style, b->thickness, b->wd*15.0, b->ht*15.0); } /* V4.0/V3.2 */ } void write_comments(FILE *fp, char *com) { char last; if (!com || !*com) return; fprintf(fp,"# "); while (*com) { last = *com; fputc(*com,fp); if (*com == '\n' && *(com+1) != '\0') fprintf(fp,"# "); com++; } /* add newline if last line of comment didn't have one */ if (last != '\n') fputc('\n',fp); } int emergency_save(char *file_name) { FILE *fp; if ((fp = fopen(file_name, "wb")) == NULL) return (-1); /* first close any open compounds */ close_all_compounds(); num_object = 0; if (write_objects(fp)) return (-1); if (file_name[0] != '/') { (void) fprintf(stderr, "xfig: %d object(s) saved in \"%s/%s\"\n", num_object, cur_file_dir, file_name); } else { (void) fprintf(stderr, "xfig: %d object(s) saved in \"%s\"\n", num_object, file_name); } return (0); } xfig.3.2.5c/f_util.c0000700002656300244210000010775411641414046015020 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "mode.h" #include "f_neuclrtab.h" #include "f_read.h" #include "f_util.h" #include "u_create.h" #include "w_file.h" #include "w_indpanel.h" #include "w_color.h" #include "w_util.h" #include "w_icons.h" #include "w_msgpanel.h" #include "version.h" #include "f_save.h" #include "u_fonts.h" #include "w_cursor.h" /* LOCALS */ int count_colors(void); int count_pixels(void); /* PROCEDURES */ void beep (void); void alloc_imagecolors (int num); void add_all_pixels (void); void remap_image_colormap (void); void extract_cmap (void); void readjust_cmap (void); void free_pixmaps (F_compound *obj); void add_recent_file (char *file); int strain_out (char *name); void finish_update_xfigrc (void); int emptyname(char *name) { if (name == NULL || *name == '\0') { return (1); } else { return (0); } } int emptyname_msg(char *name, char *msg) { int returnval; if (returnval = emptyname(name)) { put_msg("No file name specified, %s command ignored", msg); beep(); } return (returnval); } int emptyfigure(void) { if (objects.texts != NULL) return (0); if (objects.lines != NULL) return (0); if (objects.ellipses != NULL) return (0); if (objects.splines != NULL) return (0); if (objects.arcs != NULL) return (0); if (objects.compounds != NULL) return (0); return (1); } int emptyfigure_msg(char *msg) { int returnval; if (returnval = emptyfigure()) { put_msg("Empty figure, %s command ignored", msg); beep(); } return (returnval); } int change_directory(char *path) { if (path == NULL || *path == '\0') return 0; if (chdir(path) == -1) { file_msg("Can't go to directory %s, : %s", path, strerror(errno)); return 1; } return 0; } int get_directory(char *direct) { #if defined(SYSV) || defined(SVR4) || defined(_POSIX_SOURCE) extern char *getcwd(char *, size_t); #else extern char *getwd(); #endif /* defined(SYSV) || defined(SVR4) || defined(_POSIX_SOURCE) */ #if defined(SYSV) || defined(SVR4) || defined(_POSIX_SOURCE) if (getcwd(direct, PATH_MAX) == NULL) { /* get current working dir */ file_msg("Can't get current directory"); beep(); #else if (getwd(direct) == NULL) { /* get current working dir */ file_msg("%s", direct); /* err msg is in direct var */ beep(); #endif /* defined(SYSV) || defined(SVR4) || defined(_POSIX_SOURCE) */ *direct = '\0'; return 0; } return 1; } #ifndef S_IWUSR #define S_IWUSR 0000200 #endif /* S_IWUSR */ #ifndef S_IWGRP #define S_IWGRP 0000020 #endif /* S_IWGRP */ #ifndef S_IWOTH #define S_IWOTH 0000002 #endif /* S_IWOTH */ int ok_to_write(char *file_name, char *op_name) { struct stat file_status; char string[180]; if (stat(file_name, &file_status) == 0) { /* file exists */ if (file_status.st_mode & S_IFDIR) { put_msg("\"%s\" is a directory", file_name); beep(); return 0; } if (file_status.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) { /* writing is permitted by SOMEONE */ if (access(file_name, W_OK)) { put_msg("Write permission for \"%s\" is denied", file_name); beep(); return 0; } else { if (warnexist) { sprintf(string, "\"%s\" already exists.\nDo you want to overwrite it?", file_name); if (popup_query(QUERY_YESNO, string) != RESULT_YES) { put_msg("%s cancelled", op_name); return 0; } } else { return 1; } } } else { put_msg("\"%s\" is read only", file_name); beep(); return 0; } } else { if (errno != ENOENT) return 0; /* file does exist but stat fails */ } return 1; } /* for systems without basename() (e.g. SunOS 4.1.3) */ /* strip any path from filename */ char * xf_basename(char *filename) { char *p; if (filename == NULL || *filename == '\0') return filename; if (p=strrchr(filename,'/')) { return ++p; } else { return filename; } } static int scol, ncolors; static int num_oldcolors = -1; static Boolean usenet; static int npixels; #define REMAP_MSG "Remapping picture colors..." #define REMAP_MSG2 "Remapping picture colors...Done" /* remap the colors for all the pictures in the picture repository */ void remap_imagecolors(void) { int i; /* if monochrome, return */ if (tool_cells <= 2 || appres.monochrome) return; npixels = 0; /* first see if there are enough colorcells for all image colors */ usenet = False; /* see if the total number of colors will fit without using the neural net */ ncolors = count_colors(); if (ncolors == 0) return; put_msg(REMAP_MSG); set_temp_cursor(wait_cursor); app_flush(); if (ncolors > appres.max_image_colors) { if (appres.DEBUG) fprintf(stderr,"More colors (%d) than allowed (%d), using neural net\n", ncolors,appres.max_image_colors); ncolors = appres.max_image_colors; usenet = True; } /* if this is the first image, allocate the number of colorcells we need */ if (num_oldcolors != ncolors) { if (num_oldcolors != -1) { unsigned long pixels[MAX_USR_COLS]; for (i=0; i avail_image_cols) { usenet = True; if (appres.DEBUG) fprintf(stderr,"More colors (%d) than available (%d), using neural net\n", ncolors,avail_image_cols); } num_oldcolors = avail_image_cols; if (avail_image_cols < 2 && ncolors >= 2) { file_msg("Cannot allocate even 2 colors for pictures"); reset_cursor(); num_oldcolors = -1; reset_cursor(); put_msg(REMAP_MSG2); app_flush(); return; } } reset_cursor(); if (usenet) { int stat; int mult = 1; /* check if user pressed cancel button (in file preview) */ if (check_cancel()) return; /* count total number of pixels in all the pictures */ npixels = count_pixels(); /* check if user pressed cancel button */ if (check_cancel()) return; /* initialize the neural network */ /* -1 means can't alloc memory, -2 or more means must have that many times as many pixels */ set_temp_cursor(wait_cursor); if ((stat=neu_init(npixels)) <= -2) { mult = -stat; npixels *= mult; /* try again with more pixels */ stat = neu_init2(npixels); } if (stat == -1) { /* couldn't alloc memory for network */ fprintf(stderr,"Can't alloc memory for neural network\n"); reset_cursor(); put_msg(REMAP_MSG2); app_flush(); return; } /* now add all pixels to the samples */ for (i=0; inext) if (pics->bitmap != NULL) ncolors += pics->numcols; return ncolors; } int count_pixels(void) { int npixels; struct _pics *pics; npixels = 0; for (pics = pictures; pics; pics = pics->next) if (pics->bitmap != NULL && pics->numcols > 0) npixels += pics->bit_size.x * pics->bit_size.y; return npixels; } void readjust_cmap(void) { struct _pics *pics; int i, j; /* first adjust the colormaps in the repository */ for (pics = pictures; pics; pics = pics->next) if (pics->bitmap != NULL && pics->numcols > 0) { for (i=0; inumcols; i++) { j = pics->cmap[i].pixel; pics->cmap[i].pixel = image_cells[j].pixel; scol++; } } /* now free up all pixmaps in picture objects */ /* start with main list */ free_pixmaps(&objects); } void free_pixmaps(F_compound *obj) { F_line *l; F_compound *c; /* traverse the compounds in this compound */ for (c = obj->compounds; c != NULL; c = c->next) { free_pixmaps(c); } for (l = obj->lines; l != NULL; l = l->next) { if (l->type == T_PICTURE) { if (l->pic->pixmap != (Pixmap) NULL) { if (l->pic->pixmap) XFreePixmap(tool_d, l->pic->pixmap); l->pic->pixmap = 0; /* this will force regeneration of the pixmap */ if (l->pic->mask != 0) XFreePixmap(tool_d, l->pic->mask); l->pic->mask = 0; } } } } void extract_cmap(void) { struct _pics *pics; int i; /* extract the colormaps in the repository */ for (pics = pictures; pics; pics = pics->next) if (pics->bitmap != NULL && pics->numcols > 0) { for (i=0; inumcols; i++) { image_cells[scol].red = pics->cmap[i].red << 8; image_cells[scol].green = pics->cmap[i].green << 8; image_cells[scol].blue = pics->cmap[i].blue << 8; pics->cmap[i].pixel = scol; scol++; } } /* now free up the pixmaps */ free_pixmaps(&objects); } void add_all_pixels(void) { struct _pics *pics; BYTE col[3]; int i, npix; register unsigned char byte; for (pics = pictures; pics; pics = pics->next) if (pics->bitmap != NULL && pics->numcols > 0) { /* now add each pixel to the sample list */ npix = pics->bit_size.x * pics->bit_size.y; for (i=0; i < npix; i++) { /* check if user pressed cancel button */ if (i%1000==0 && check_cancel()) return; byte = pics->bitmap[i]; col[N_RED] = pics->cmap[byte].red; col[N_GRN] = pics->cmap[byte].green; col[N_BLU] = pics->cmap[byte].blue; neu_pixel(col); } } } void remap_image_colormap(void) { struct _pics *pics; BYTE col[3]; int i; int p; for (pics = pictures; pics; pics = pics->next) if (pics->bitmap != NULL && pics->numcols > 0) { for (i=0; inumcols; i++) { /* real color from the image */ col[N_RED] = pics->cmap[i].red; col[N_GRN] = pics->cmap[i].green; col[N_BLU] = pics->cmap[i].blue; /* X color index from the mapping */ p = neu_map_pixel(col); pics->cmap[i].pixel = image_cells[p].pixel; } } free_pixmaps(&objects); } /* map the bytes in pic->pic_cache->bitmap to bits for monochrome display */ /* DESTROYS original pic->pic_cache->bitmap */ /* uses a Floyd-Steinberg algorithm from the pbmplus package */ /* Here is the copyright notice: ** ** Copyright (C) 1989 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** */ #define FS_SCALE 1024 #define HALF_FS_SCALE 512 #define MAXVAL (256*256) void map_to_mono(F_pic *pic) { unsigned char *dptr = pic->pic_cache->bitmap; /* 8-bit wide data pointer */ unsigned char *bptr; /* 1-bit wide bitmap pointer */ int bitp; int col, row, limitcol; int width, height; long grey, threshval, sum; long *thiserr, *nexterr, *temperr; unsigned char *cP, *bP; Boolean fs_direction; int sbit; width = pic->pic_cache->bit_size.x; height = pic->pic_cache->bit_size.y; /* allocate space for 1-bit bitmap */ if ((bptr = (unsigned char*) malloc(sizeof(unsigned char) * (width+7)/8*height)) == NULL) return; thiserr = (long *) malloc(sizeof(long) * (width+2)); nexterr = (long *) malloc(sizeof(long) * (width+2)); /* initialize random seed */ srandom( (int) (time(0)^getpid()) ); for (col=0; colpic_cache->cmap[*cP].red * 77 + /* 0.30 * 256 */ pic->pic_cache->cmap[*cP].green * 151 + /* 0.59 * 256 */ pic->pic_cache->cmap[*cP].blue * 28; /* 0.11 * 256 */ sum = ( grey * FS_SCALE ) / MAXVAL + thiserr[col+1]; if (sum >= threshval) { *bP |= bitp; /* white bit */ sum = sum - threshval - HALF_FS_SCALE; } else { *bP &= ~bitp; /* black bit */ } if (fs_direction) { bitp >>= 1; if (bitp <= 0) { bP++; bitp = 0x80; } } else { bitp <<= 1; if (bitp > 0x80) { bP--; bitp = 0x01; } } if ( fs_direction ) { thiserr[col + 2] += ( sum * 7 ) / 16; nexterr[col ] += ( sum * 3 ) / 16; nexterr[col + 1] += ( sum * 5 ) / 16; nexterr[col + 2] += ( sum ) / 16; ++col; ++cP; } else { thiserr[col ] += ( sum * 7 ) / 16; nexterr[col + 2] += ( sum * 3 ) / 16; nexterr[col + 1] += ( sum * 5 ) / 16; nexterr[col ] += ( sum ) / 16; --col; --cP; } } while ( col != limitcol ); temperr = thiserr; thiserr = nexterr; nexterr = temperr; fs_direction = ! fs_direction; } free((char *) pic->pic_cache->bitmap); free((char *) thiserr); free((char *) nexterr); pic->pic_cache->bitmap = bptr; /* monochrome */ pic->pic_cache->numcols = 0; return; } void beep(void) { XBell(tool_d,0); } #ifdef NOSTRSTR char *strstr(s1, s2) char *s1, *s2; { int len2; char *stmp; len2 = strlen(s2); for (stmp = s1; *stmp != NULL; stmp++) if (strncmp(stmp, s2, len2)==0) return stmp; return NULL; } #endif /* NOSTRSTR */ /* strncasecmp and strcasecmp by Fred Appelman (Fred.Appelman@cv.ruu.nl) */ #ifdef HAVE_NO_STRNCASECMP int strncasecmp(const char* s1, const char* s2, int n) { char c1,c2; while (--n>=0) { /* Check for end of string, if either of the strings * is ended, we can terminate the test */ if (*s1=='\0' && *s2!='\0') return -1; /* s1 ended premature */ if (*s1!='\0' && *s2=='\0') return +1; /* s2 ended premature */ c1=toupper(*s1++); c2=toupper(*s2++); if (c1c2) return +1; /* s2 is "smaller" */ } return 0; } #endif /* HAVE_NO_STRNCASECMP */ #ifdef HAVE_NO_STRCASECMP int strcasecmp(const char* s1, const char* s2) { char c1,c2; while (*s1 && *s2) { c1=toupper(*s1++); c2=toupper(*s2++); if (c1c2) return +1; /* s2 is "smaller" */ } /* Check for end of string, if not both the strings ended they are * not the same. */ if (*s1=='\0' && *s2!='\0') return -1; /* s1 ended premature */ if (*s1!='\0' && *s2=='\0') return +1; /* s2 ended premature */ return 0; } #endif /* HAVE_NO_STRCASECMP */ /* this routine will safely copy overlapping strings */ /* p2 is copied to p1 and p1 is returned */ /* p1 must be < p2 */ char * safe_strcpy(char *p1, char *p2) { char *c1; c1 = p1; for ( ; *p2; ) *p1++ = *p2++; *p1 = '\0'; return c1; } /* gunzip file if necessary */ Boolean uncompress_file(char *name) { char plainname[PATH_MAX]; char dirname[PATH_MAX]; char tmpfile[PATH_MAX]; char unc[PATH_MAX+20]; /* temp buffer for uncompress/gunzip command */ char *c; struct stat status; strcpy(tmpfile, name); /* save original name */ strcpy(plainname, name); c = strrchr(plainname, '.'); if (c) { if (strcmp(c, ".gz") == 0 || strcmp(c, ".Z") == 0 || strcmp(c, ".z") == 0) *c = '\0'; } if (stat(name, &status)) { /* first see if file exists AS NAMED */ /* no, try without .gz etc suffix */ strcpy(name, plainname); if (stat(name, &status)) { /* no, try with a .z */ sprintf(name, "%s.z", plainname); if (stat(name, &status)) { /* no, try with .Z suffix */ sprintf(name, "%s.Z", plainname); if (stat(name, &status)) { /* no, try .gz */ sprintf(name, "%s.gz", plainname); if (stat(name, &status)) { /* none of the above, return original name and False status */ strcpy(name, tmpfile); return False; } } } } } /* file doesn't have .gz etc suffix anymore, return modified name */ if (strcmp(name, plainname) == 0) return True; strcpy(dirname, name); c = strrchr(dirname, '/'); if (c) *c = '\0'; else strcpy(dirname, "."); if (access(dirname, W_OK) == 0) { /* OK - the directory is writable */ sprintf(unc, "gunzip -q %s", name); if (system(unc) != 0) file_msg("Couldn't uncompress the file: \"%s\"", unc); strcpy(name, plainname); } else { /* the directory is not writable */ /* create a path to TMPDIR in case we need to uncompress a read-only file to there */ c = strrchr(plainname, '/'); if (c) sprintf(tmpfile, "%s%s", TMPDIR, c); else sprintf(tmpfile, "%s/%s", TMPDIR, plainname); sprintf(unc, "gunzip -q -c %s > %s", name, tmpfile); if (system(unc) != 0) file_msg("Couldn't uncompress the file: \"%s\"", unc); file_msg ("Uncompressing file %s in %s because it is in a read-only directory", name, TMPDIR); strcpy(name, tmpfile); } return True; } /*************************************************************/ /* Read the user's .xfigrc file in his home directory to get */ /* settings from previous session. */ /*************************************************************/ #define RC_BUFSIZ 1000 void read_xfigrc(void) { char line[RC_BUFSIZ+1], *word, *opnd; int i, len; FILE *xfigrc; num_recent_files = 0; max_recent_files = DEF_RECENT_FILES; /* default if none found in .xfigrc */ /* make the filename from the user's home path and ".xfigrc" */ strcpy(xfigrc_name,userhome); strcat(xfigrc_name,"/.xfigrc"); xfigrc = fopen(xfigrc_name,"r"); if (xfigrc == 0) return; /* no .xfigrc file */ /* there must not be any whitespace between word and ":" */ while (fgets(line, RC_BUFSIZ, xfigrc) != NULL) { word = strtok(line, ": \t"); opnd = strtok(NULL, "\n"); /* parse operand and remove newline */ if (!word || !opnd) continue; /* find first non-blank */ for (i=0, len=strlen(opnd); i= MAX_RECENT_FILES || num_recent_files >= max_recent_files) return; name = new_string(strlen(file)+3); /* allow for file number (1), blank (1) and NUL */ sprintf(name,"%1d %s",num_recent_files+1,file); recent_files[num_recent_files].name = name; num_recent_files++; } static FILE *xfigrc, *tmpf; static char tmpname[PATH_MAX]; /* rewrite .xfigrc file with current list of recent files */ void update_recent_files(void) { int i; /* copy all lines without the "file" spec into a temp file */ if (strain_out("file") != 0) { if (tmpf != 0) fclose(tmpf); if (xfigrc != 0) fclose(xfigrc); return; /* problem creating temp file */ } /* now append file list */ for (i=0; i= 1.0) cur_fontsize = round(appres.startfontsize); /* allow "Modern" for "Sans Serif" and allow "SansSerif" (no space) */ if (appres.startlatexFont) { if (strcmp(appres.startlatexFont,"Modern")==0 || strcmp(appres.startlatexFont,"SansSerif")==0) cur_latex_font = latexfontnum ("Sans Serif"); } else { cur_latex_font = latexfontnum (appres.startlatexFont); } cur_ps_font = psfontnum (appres.startpsFont); if (appres.startarrowtype >= 0) cur_arrowtype = appres.startarrowtype; if (appres.startarrowthick > 0.0) { use_abs_arrowvals = True; cur_arrowthick = appres.startarrowthick; } if (appres.startarrowwidth > 0.0) { use_abs_arrowvals = True; cur_arrowwidth = appres.startarrowwidth; } if (appres.startarrowlength > 0.0) { use_abs_arrowvals = True; cur_arrowheight = appres.startarrowlength; } if (appres.starttextstep > 0.0) cur_textstep = appres.starttextstep; if (appres.startfillstyle >= 0) cur_fillstyle = min2(appres.startfillstyle,NUMFILLPATS-1); if (appres.startlinewidth >= 0) cur_linewidth = min2(appres.startlinewidth,MAX_LINE_WIDTH); if (appres.startgridmode >= 0) cur_gridmode = min2(appres.startgridmode,GRID_ISO_4); if (appres.startgridtype >= 0) // isometric grid cur_gridtype = min2(appres.startgridtype,GRID_ISO); if (appres.startposnmode >= 0) cur_pointposn = min2(appres.startposnmode,P_GRID4); /* choose grid units (1/16", 1/10", MM) */ /* default */ grid_unit = FRACT_UNIT; /* if inches is desired set grid unit to user spec (1/16" or 1/10") */ if (appres.INCHES) { /* make sure user specified one */ if (strcasecmp(appres.tgrid_unit, "default") != 0) { if (strcasecmp(appres.tgrid_unit, "tenth") == 0 || strcasecmp(appres.tgrid_unit, "ten") == 0 || strcasecmp(appres.tgrid_unit, "1/10") == 0 || strcasecmp(appres.tgrid_unit, "10") == 0) grid_unit = TENTH_UNIT; else grid_unit = FRACT_UNIT; } } else { grid_unit = MM_UNIT; } /* set current and "old" grid unit */ old_gridunit = cur_gridunit = grid_unit; /* turn off PSFONT_TEXT flag if user specified -latexfonts */ if (appres.latexfonts) cur_textflags = cur_textflags & (~PSFONT_TEXT); if (appres.specialtext) cur_textflags = cur_textflags | SPECIAL_TEXT; if (appres.rigidtext) cur_textflags = cur_textflags | RIGID_TEXT; if (appres.hiddentext) cur_textflags = cur_textflags | HIDDEN_TEXT; /* turn off PSFONT_TEXT flag if user specified -latexfonts */ if (appres.latexfonts) cur_textflags = cur_textflags & (~PSFONT_TEXT); if (appres.userunit) strncpy(cur_fig_units, appres.userunit, sizeof(cur_fig_units)-1); else cur_fig_units[0] = '\0'; strcpy(cur_library_dir, appres.library_dir); strcpy(cur_spellchk, appres.spellcheckcommand); strcpy(cur_image_editor, appres.image_editor); strcpy(cur_browser, appres.browser); strcpy(cur_pdfviewer, appres.pdf_viewer); /* assume color to start */ all_colors_available = True; /* check if monochrome screen */ if (tool_cells == 2 || appres.monochrome) all_colors_available = False; } /* init_settings() */ /* This is called to read a list of Fig files specified in the command line and write them back (renaming the original to xxxx.fig.bak) so that they are updated to the current version. If the file is already in the current version it is untouched. */ int update_fig_files(int argc, char **argv) { fig_settings settings; char file[PATH_MAX]; int i,col; Boolean status; int allstat; /* overall status - if any one file can't be read, return status is 1 */ allstat = 0; update_figs = True; for (i=1; i /dev/null" to send stderr to /dev/null and "&" to run in background */ strcat(cmd," 2> /dev/null &"); return cmd; } /* define the strerror() function to return str_errlist[] if the system doesn't have the strerror() function already */ #ifdef NEED_STRERROR char * strerror(e) int e; { return sys_errlist[e]; } #endif /* NEED_STRERROR */ /**************************************************************************/ /* Routine to mimic `my_strdup()' (some machines don't have it) */ /**************************************************************************/ char *my_strdup(char *str) { char *s; if (str==NULL) return NULL; s = new_string(strlen(str)+1); if (s!=NULL) strcpy(s, str); return s; } /* for images with no palette, we'll use neural net to reduce to 256 colors with palette */ Boolean map_to_palette(F_pic *pic) { int w,h,x,y; int mult, neu_stat, size; unsigned char *old; BYTE col[3]; w = pic->pic_cache->bit_size.x; h = pic->pic_cache->bit_size.y; mult = 1; if ((neu_stat=neu_init(w*h)) <= -2) { mult = -neu_stat; /* try again with more pixels */ neu_stat = neu_init2(w*h*mult); } if (neu_stat == -1) { /* couldn't alloc memory for network */ fprintf(stderr,"Can't alloc memory for neural network\n"); free(pic->pic_cache->bitmap); return False; } /* now add all pixels to the samples */ size = w*h*3; for (x=0; xpic_cache->bitmap[x++]; col[N_GRN] = pic->pic_cache->bitmap[x++]; col[N_RED] = pic->pic_cache->bitmap[x++]; for (y=0; ypic_cache->numcols = neu_clrtab(256); /* now change the color cells with the new colors */ /* clrtab[][] is the colormap produced by neu_clrtab */ for (x=0; xpic_cache->numcols; x++) { pic->pic_cache->cmap[x].red = (unsigned short) clrtab[x][N_RED]; pic->pic_cache->cmap[x].green = (unsigned short) clrtab[x][N_GRN]; pic->pic_cache->cmap[x].blue = (unsigned short) clrtab[x][N_BLU]; } /* now alloc a 1-byte/per/pixel array for the final colormapped image */ /* save orig */ old = pic->pic_cache->bitmap; if ((pic->pic_cache->bitmap=malloc(w*(h+2)))==NULL) return False; /* and change the 3-byte pixels to the 1-byte */ for (x=0, y=0; xpic_cache->bitmap[y] = neu_map_pixel(col); } /* free 3-byte/pixel array */ free(old); return True; } /* return pointers to the line components of a dimension line. If passed dimline is not a dimension line, the result is False */ Boolean dimline_components(F_compound *dimline, F_line **line, F_line **tick1, F_line **tick2, F_line **poly) { F_line *l; if (!dimline->comments || strncmp(dimline->comments,"Dimension line:",15) !=0 ) return False; *line = *tick1 = *tick2 = *poly = (F_line *) NULL; for (l = dimline->lines; l; l=l->next) { if (!l->comments) continue; if (strcmp(l->comments,"main dimension line")==0) *line = l; else if (strcmp(l->comments,"text box")==0) *poly = l; else if (strcmp(l->comments,"tick")==0) { if (*tick1 == 0) *tick1 = l; else *tick2 = l; } } return True; } int find_smallest_depth(F_compound *compound) { F_line *l; F_spline *s; F_ellipse *e; F_arc *a; F_text *t; F_compound *c; int smallest, d1; smallest = MAX_DEPTH; for (l = compound->lines; l != NULL; l = l->next) { if (l->depth < smallest) smallest = l->depth; } for (s = compound->splines; s != NULL; s = s->next) { if (s->depth < smallest) smallest = s->depth; } for (e = compound->ellipses; e != NULL; e = e->next) { if (e->depth < smallest) smallest = e->depth; } for (a = compound->arcs; a != NULL; a = a->next) { if (a->depth < smallest) smallest = a->depth; } for (t = compound->texts; t != NULL; t = t->next) { if (t->depth < smallest) smallest = t->depth; } for (c = compound->compounds; c != NULL; c = c->next) { d1 = find_smallest_depth(c); if (d1 < smallest) smallest = d1; } return smallest; } int find_largest_depth(F_compound *compound) { F_line *l; F_spline *s; F_ellipse *e; F_arc *a; F_text *t; F_compound *c; int largest, d1; largest = MIN_DEPTH; for (l = compound->lines; l != NULL; l = l->next) { if (l->depth > largest) largest = l->depth; } for (s = compound->splines; s != NULL; s = s->next) { if (s->depth > largest) largest = s->depth; } for (e = compound->ellipses; e != NULL; e = e->next) { if (e->depth > largest) largest = e->depth; } for (a = compound->arcs; a != NULL; a = a->next) { if (a->depth > largest) largest = a->depth; } for (t = compound->texts; t != NULL; t = t->next) { if (t->depth > largest) largest = t->depth; } for (c = compound->compounds; c != NULL; c = c->next) { d1 = find_largest_depth(c); if (d1 > largest) largest = d1; } return largest; } /* get grid params and assemble into fig2dev parm */ void get_grid_spec(char *grid, Widget minor_grid_panel, Widget major_grid_panel) { char *c1; /* if panel hasn't been up yet */ if (minor_grid_panel == (Widget) 0 || major_grid_panel == (Widget) 0) { sprintf(grid,"%s:%s%s", strlen(minor_grid)==0? "0": minor_grid, strlen(major_grid)==0? "0": major_grid, appres.INCHES? "in":"mm"); return; } /* get minor grid spec from panel */ strcpy(grid, panel_get_value(minor_grid_panel)); if (strcasecmp(grid,"none") == 0) { grid[0]='\0'; } /* now major */ c1 = panel_get_value(major_grid_panel); if (strcasecmp(c1,"none") != 0 && strlen(c1)) { strcat(grid,":"); strcat(grid,c1); } if (strlen(grid)) strcat(grid,appres.INCHES? "in":"mm"); } /* get the timestamp (mtime) of the filename passed */ time_t file_timestamp(char *file) { struct stat file_status; if (stat(file, &file_status) != 0) return -1; return file_status.st_mtime; } xfig.3.2.5c/f_wrpcx.c0000700002656300244210000001244011641414046015171 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 1989-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "pcx.h" static void create_pcx_head(pcxheadr *pcxhead, int width, int height); static void write_pcx_head(FILE *file, pcxheadr *pcx_hd); static void pcx_enc_scan(FILE *file, unsigned char *inbuffer, int bufsize); void _write_pcx(FILE *file, unsigned char *data, unsigned char *Red, unsigned char *Green, unsigned char *Blue, int numcols, int width, int height) { pcxheadr pcxhead; int i; /* create the pcx header */ create_pcx_head(&pcxhead,width,height); /* now write the header */ write_pcx_head(file, &pcxhead); /* encode and write each scanline out */ for (i=0; iid = 0x0a; /* always 0x0a */ pcxhead->vers = 5; /* includes VGA plaette */ pcxhead->format = 1; /* 1 = RLE */ pcxhead->bppl = 8; /* 8 bits per pixel per plane (we'll use one plane) */ pcxhead->xmin = 0; /* this is stupid, make it relative to 0 */ pcxhead->xmax = width-1; pcxhead->ymin = 0; pcxhead->ymax = height-1; pcxhead->hdpi = 100; /* horiz. dpi (not really used) */ pcxhead->vdpi = 100; /* vert. dpi (not really used) */ for (i=0; i<48; i++) pcxhead->egapal[i] = 0; /* zero the EGA palette */ pcxhead->nplanes = 1; /* use one plane of 8-bits per pixel */ pcxhead->blp = width; /* bytes per scanline */ pcxhead->palinfo = 1; /* color */ pcxhead->hscrnsiz = 0; /* don't worry about horizontal/vertical screen size */ pcxhead->vscrnsiz = 0; for (i=0; i<54; i++) pcxhead->fill[0]=0; } static void putword(short unsigned int w, FILE *file) { putc((unsigned char) (w&255), file); putc((unsigned char) ((w>>8)&255), file); } static void write_pcx_head(FILE *file, pcxheadr *pcx_hd) { register int i; putc(pcx_hd->id, file); putc(pcx_hd->vers, file); putc(pcx_hd->format, file); putc(pcx_hd->bppl, file); putword(pcx_hd->xmin, file); putword(pcx_hd->ymin, file); putword(pcx_hd->xmax, file); putword(pcx_hd->ymax, file); putword(pcx_hd->hdpi, file); putword(pcx_hd->vdpi, file); /* Write the EGA Palette */ for (i = 0; i < sizeof(pcx_hd->egapal); i++) putc(pcx_hd->egapal[i], file); putc(pcx_hd->reserv, file); putc(pcx_hd->nplanes, file); putword(pcx_hd->blp, file); putword(pcx_hd->palinfo, file); putword(pcx_hd->hscrnsiz, file); putword(pcx_hd->vscrnsiz, file); /* Write the reserved area at the end of the header */ for (i = 0; i < sizeof(pcx_hd->fill); i++) putc(pcx_hd->fill[i], file); } static void pcx_enc_scan(FILE *file, unsigned char *inbuffer, int bufsize) /* Pointer to buffer holding unencoded data */ /* Size of buffer holding unencoded data */ { register int index = 0; /* Index into uncompressed data buffer */ unsigned char runcount; /* Length of encoded pixel run */ unsigned char runvalue; /* Value of encoded pixel run */ while (index < bufsize) { /* ** Get the run count of the next pixel value run. ** ** Pixel value runs are encoded until a different pixel value ** is encountered, the end of the scan line is reached, or 63 ** pixel values have been counted. */ for (runcount = 1, runvalue = inbuffer[index]; runvalue == inbuffer[index + runcount] && index + runcount < bufsize && runcount < 63; runcount++) ; /* ** Encode the run into a one or two-byte code. ** ** Multiple pixel runs are stored in two-byte codes. If a single ** pixel run has a value of less than 64 then it is stored in a ** one-byte code. If a single pixel run has a value of 64 to 255 ** then it is stored in a two-byte code. */ if (runcount > 1) { /* Multiple pixel run */ putc(runcount | 0xC0, file); putc(runvalue, file); } else { /* Single pixel run */ if (inbuffer[index] < 64) { /* Value is 0 to 63 */ putc(runvalue, file); } else { /* Value is 64 to 255 */ putc(runcount | 0xC0, file); putc(runvalue, file); } } index += runcount; /* Jump ahead to next pixel run value */ } } xfig.3.2.5c/f_wrpng.c0000700002656300244210000000662011641414046015166 0ustar bvsmithDomain Users/* * FIG : Facility for Interactive Generation of figures * Copyright (c) 2001-2007 by Brian V. Smith * * Any party obtaining a copy of these files is granted, free of charge, a * full and unrestricted irrevocable, world-wide, paid up, royalty-free, * nonexclusive right and license to deal in this software and documentation * files (the "Software"), including without limitation the rights to use, * copy, modify, merge, publish distribute, sublicense and/or sell copies of * the Software, and to permit persons who receive copies from any such * party to do so, with the only requirement being that the above copyright * and this permission notice remain intact. * */ #include "fig.h" #include "resources.h" #include "object.h" #include "f_neuclrtab.h" #include "w_msgpanel.h" #include "w_setup.h" #include #include /* * Write PNG file from rgb data * * Call with: * * file - handle opened for writing * data - pointer to data (index values for IMAGE_PALETTE, * rgb triples for IMAGE_RGB) * type - IMAGE_PALETTE, IMAGE_RGB * Red, Green, Blue - colormap values for IMAGE_PALETTE type * numcols - number of colors for IMAGE_PALETTE type * width, height of image */ Boolean write_png(FILE *file, unsigned char *data, int type, unsigned char *Red, unsigned char *Green, unsigned char *Blue, int numcols, int width, int height) { register int i; png_structp png_ptr; png_infop info_ptr; int bit_depth, color_type, interlace_type; int bytes_per_pixel; png_colorp palette; /* create the png structure */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, NULL, NULL); if (!png_ptr) return False; info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); return False; } /* set long jump recovery here */ if (setjmp(png_jmpbuf(png_ptr))) { /* if we get here there was a problem reading the file */ png_destroy_write_struct(&png_ptr, &info_ptr); return False; } /* set up the output code */ png_init_io(png_ptr, file); /* set info for the header */ bit_depth = 8; interlace_type = PNG_INTERLACE_NONE; if (type == IMAGE_PALETTE) { color_type = PNG_COLOR_TYPE_PALETTE; bytes_per_pixel = 1; } else { color_type = PNG_COLOR_TYPE_RGB; bytes_per_pixel = 3; } /* set best compression */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* write the header info */ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if (type == IMAGE_PALETTE) { palette = (png_color *) malloc(sizeof(png_color)*numcols); for (i=0; i #endif /* I18N */ #include /* EXPORTS */ Boolean geomspec; /* LOCALS */ int update_fig_files(); static int screen_res; static void make_cut_buf_name(void); static void check_resource_ranges(void); static void set_icon_geom(void); static void set_max_image_colors(void); static void parse_canvas_colors(void); static void set_xpm_icon(void); static void resize_canvas(void); static void check_refresh(XtPointer client_data, XtIntervalId *id); /************** FIG options ******************/ DeclareStaticArgs(10); char *arg_filename = NULL; static Boolean true = True; static Boolean false = False; static float Fzero = 0.0; static float Fone = 1.0; static float F100 = 100.0; static float FDef_arrow_wd = DEF_ARROW_WID; static float FDef_arrow_ht = DEF_ARROW_HT; /* actions so that we may install accelerators at the top level */ static XtActionsRec main_actions[] = { {"LoadRecent", (XtActionProc) acc_load_recent_file}, {"DoSave", (XtActionProc) do_save}, {"Quit", (XtActionProc) quit}, {"New", (XtActionProc) new}, {"DeleteAll", (XtActionProc) delete_all_cmd}, {"SaveAs", (XtActionProc) popup_saveas_panel}, {"OpenFile", (XtActionProc) popup_open_panel}, {"MergeFile", (XtActionProc) popup_merge_panel}, {"PopupDigitize", (XtActionProc) popup_digitize_panel}, {"PopupExport", (XtActionProc) popup_export_panel}, {"ExportFile", (XtActionProc) do_export}, {"PopupPrint", (XtActionProc) popup_print_panel}, {"PrintFile", (XtActionProc) do_print}, {"PopupCharmap", (XtActionProc) popup_character_map}, {"PopupGlobals", (XtActionProc) show_global_settings}, {"Undo", (XtActionProc) undo}, {"Paste", (XtActionProc) paste}, {"SpellCheck", (XtActionProc) spell_check}, {"Search", (XtActionProc) popup_search_panel}, {"ChangeOrient", (XtActionProc) change_orient}, {"Redraw", (XtActionProc) redisplay_canvas}, {"LeaveCmdSw", (XtActionProc) clear_mousefun}, {"RefMan", (XtActionProc) launch_refman}, {"Man", (XtActionProc) launch_man}, {"HowToGuide", (XtActionProc) launch_howto}, {"AboutXfig", (XtActionProc) launch_about}, {"SpinnerUpDown", (XtActionProc) spinner_up_down}, }; static XtResource application_resources[] = { {"geometry", "XtCGeometry", XtRString, sizeof(char *), XtOffset(appresPtr, geometry), XtRString, (caddr_t) NULL}, {"version", "version", XtRString, sizeof(char *), XtOffset(appresPtr,version), XtRString, (caddr_t) NULL}, {"zoom", "Zoom", XtRFloat, sizeof(float), XtOffset(appresPtr, zoom), XtRFloat, (caddr_t) & Fone}, {"allownegcoords", "NegativeCoordinates", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, allownegcoords), XtRBoolean, (caddr_t) & true}, {"showaxislines", "Axis", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, showaxislines), XtRBoolean, (caddr_t) & true}, {"smallicons", "Icons", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, smallicons), XtRBoolean, (caddr_t) & false}, {"canvasbackground", "Background", XtRString, sizeof(char *), XtOffset(appresPtr,canvasbackground), XtRString, (caddr_t) NULL}, {"canvasforeground", "Foreground", XtRString, sizeof(char *), XtOffset(appresPtr,canvasforeground), XtRString, (caddr_t) NULL}, {"iconGeometry", "IconGeometry", XtRString, sizeof(char *), XtOffset(appresPtr,iconGeometry), XtRString, (caddr_t) NULL}, {"showallbuttons", "ShowAllButtons", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, showallbuttons), XtRBoolean, (caddr_t) & false}, {XtNjustify, XtCJustify, XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, RHS_PANEL), XtRBoolean, (caddr_t) & false}, {"landscape", XtCOrientation, XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, landscape), XtRBoolean, (caddr_t) & true}, {"pwidth", XtCWidth, XtRFloat, sizeof(float), XtOffset(appresPtr, tmp_width), XtRFloat, (caddr_t) & Fzero}, {"pheight", XtCHeight, XtRFloat, sizeof(float), XtOffset(appresPtr, tmp_height), XtRFloat, (caddr_t) & Fzero}, {"trackCursor", "Track", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, tracking), XtRBoolean, (caddr_t) & true}, {"inches", "Inches", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, INCHES), XtRBoolean, (caddr_t) & true}, {"boldFont", "Font", XtRString, sizeof(char *), XtOffset(appresPtr, boldFont), XtRString, (caddr_t) NULL}, {"normalFont", "Font", XtRString, sizeof(char *), XtOffset(appresPtr, normalFont), XtRString, (caddr_t) NULL}, {"buttonFont", "Font", XtRString, sizeof(char *), XtOffset(appresPtr, buttonFont), XtRString, (caddr_t) NULL}, {"startarrowtype", "StartArrowType", XtRInt, sizeof(int), XtOffset(appresPtr, startarrowtype), XtRImmediate, (caddr_t) 0}, {"startarrowthick", "StartArrowThick", XtRFloat, sizeof(float), XtOffset(appresPtr, startarrowthick), XtRFloat, (caddr_t) & Fone}, {"startarrowwidth", "StartArrowWidth", XtRFloat, sizeof(float), XtOffset(appresPtr, startarrowwidth), XtRFloat, (caddr_t) & FDef_arrow_wd}, {"startarrowlength", "StartArrowLength", XtRFloat, sizeof(float), XtOffset(appresPtr, startarrowlength), XtRFloat, (caddr_t) & FDef_arrow_ht}, {"startlatexFont", "StartlatexFont", XtRString, sizeof(char *), XtOffset(appresPtr, startlatexFont), XtRString, (caddr_t) NULL}, {"startpsFont", "StartpsFont", XtRString, sizeof(char *), XtOffset(appresPtr, startpsFont), XtRString, (caddr_t) NULL}, {"startfontsize", "StartFontSize", XtRFloat, sizeof(float), XtOffset(appresPtr, startfontsize), XtRFloat, (caddr_t) & Fzero}, {"internalborderwidth", "InternalBorderWidth", XtRInt, sizeof(int), XtOffset(appresPtr, internalborderwidth), XtRImmediate, (caddr_t) 0}, {"starttextstep", "StartTextStep", XtRFloat, sizeof(float), XtOffset(appresPtr, starttextstep), XtRFloat, (caddr_t) & Fzero}, {"startfillstyle", "StartFillStyle", XtRInt, sizeof(int), XtOffset(appresPtr, startfillstyle), XtRImmediate, (caddr_t) DEFAULT}, {"startlinewidth", "StartLineWidth", XtRInt, sizeof(int), XtOffset(appresPtr, startlinewidth), XtRImmediate, (caddr_t) 1}, {"grid_color", "Color", XtRString, sizeof(char *), XtOffset(appresPtr, grid_color), XtRImmediate, (caddr_t) "#ffcccc"}, {"grid_unit", "UnitType", XtRString, sizeof(char *), XtOffset(appresPtr, tgrid_unit), XtRImmediate, (caddr_t) "default"}, {"startgridmode", "StartGridMode", XtRInt, sizeof(int), XtOffset(appresPtr, startgridmode), XtRImmediate, (caddr_t) 0}, {"startgridtype", "StartGridType", XtRInt, sizeof(int), // isometric grid XtOffset(appresPtr, startgridtype), XtRImmediate, (caddr_t) 0}, {"startposnmode", "StartPosnMode", XtRInt, sizeof(int), XtOffset(appresPtr, startposnmode), XtRImmediate, (caddr_t) 1 }, {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false}, {"hiddentext", "HiddenText", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, hiddentext), XtRBoolean, (caddr_t) & false}, {"rigidtext", "RigidText", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, rigidtext), XtRBoolean, (caddr_t) & false}, {"specialtext", "SpecialText", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, specialtext), XtRBoolean, (caddr_t) & false}, {"scalablefonts", "ScalableFonts", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, scalablefonts), XtRBoolean, (caddr_t) & true}, {"monochrome", "Monochrome", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, monochrome), XtRBoolean, (caddr_t) & false}, {"latexfonts", "Latexfonts", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, latexfonts), XtRBoolean, (caddr_t) & false}, {"keyFile", "KeyFile", XtRString, sizeof(char *), XtOffset(appresPtr, keyFile), XtRString, (caddr_t) "CompKeyDB"}, {"exportLanguage", "ExportLanguage", XtRString, sizeof(char *), XtOffset(appresPtr, exportLanguage), XtRString, (caddr_t) "eps"}, {"flushleft", "FlushLeft", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, flushleft), XtRBoolean, (caddr_t) & false}, {"userscale", "UserScale", XtRFloat, sizeof(float), XtOffset(appresPtr, userscale), XtRFloat, (caddr_t) & Fone}, {"userunit", "UserUnit", XtRString, sizeof(char *), XtOffset(appresPtr, userunit), XtRString, (caddr_t) ""}, {"but_per_row", "But_per_row", XtRInt, sizeof(int), XtOffset(appresPtr, but_per_row), XtRImmediate, (caddr_t) 0}, {"max_image_colors", "Max_image_colors", XtRInt, sizeof(int), XtOffset(appresPtr, max_image_colors), XtRImmediate, (caddr_t) 0}, {"installowncmap", "Installcmap", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, installowncmap), XtRBoolean, (caddr_t) & false}, {"dontswitchcmap", "Dontswitchcmap", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, dontswitchcmap), XtRBoolean, (caddr_t) & false}, {"tablet", "Tablet", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, tablet), XtRBoolean, (caddr_t) & false}, {"rulerthick", "RulerThick", XtRInt, sizeof(int), XtOffset(appresPtr, rulerthick), XtRImmediate, (caddr_t) 0}, {"image_editor", "ImageEditor", XtRString, sizeof(char *), XtOffset(appresPtr, image_editor), XtRString, (caddr_t) "xv"}, {"magnification", "Magnification", XtRFloat, sizeof(float), XtOffset(appresPtr, magnification), XtRFloat, (caddr_t) & F100}, {"paper_size", "Papersize", XtRString, sizeof(char *), XtOffset(appresPtr, paper_size), XtRString, (caddr_t) NULL}, {"multiple", XtCOrientation, XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, multiple), XtRBoolean, (caddr_t) & false}, {"overlap", XtCOrientation, XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, overlap), XtRBoolean, (caddr_t) & false}, {"showballoons", "ShowBalloons", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, showballoons), XtRBoolean, (caddr_t) & true}, {"balloon_delay", "balloonDelay", XtRInt, sizeof(int), XtOffset(appresPtr, balloon_delay), XtRImmediate, (caddr_t) 500}, {"spellcheckcommand", "spellCheckCommand", XtRString, sizeof(char *), XtOffset(appresPtr, spellcheckcommand), XtRString, (caddr_t) "spell %f"}, {"jpeg_quality", "Quality", XtRInt, sizeof(int), XtOffset(appresPtr, jpeg_quality), XtRImmediate, (caddr_t) 0}, {"transparent", "Transparent", XtRInt, sizeof(int), XtOffset(appresPtr, transparent), XtRImmediate, (caddr_t) TRANSP_NONE }, {"library_dir", "Directory", XtRString, sizeof(char *), XtOffset(appresPtr, library_dir), XtRString, (caddr_t) OBJLIBDIR}, {"debug", "Debug", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, DEBUG), XtRBoolean, (caddr_t) & false}, {"showlengths", "Debug", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, showlengths), XtRBoolean, (caddr_t) & false}, {"shownums", "Debug", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, shownums), XtRBoolean, (caddr_t) & false}, {"showpageborder", "Debug", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, show_pageborder), XtRBoolean, (caddr_t) & true}, {"pageborder", "Color", XtRString, sizeof(char *), XtOffset(appresPtr, pageborder), XtRString, (caddr_t) "lightblue"}, {"browser", "Browser", XtRString, sizeof(char *), XtOffset(appresPtr, browser), XtRString, (caddr_t) "firefox"}, {"pdfviewer", "Viewer", XtRString, sizeof(char *), XtOffset(appresPtr, pdf_viewer), XtRString, (caddr_t) "acroread"}, {"spinner_delay", "spinnerDelay", XtRInt, sizeof(int), XtOffset(appresPtr, spinner_delay), XtRImmediate, (caddr_t) 500}, {"spinner_rate", "spinnerRate", XtRInt, sizeof(int), XtOffset(appresPtr, spinner_rate), XtRImmediate, (caddr_t) 100}, {"export_margin", "Margin", XtRInt, sizeof(int), XtOffset(appresPtr, export_margin), XtRImmediate, (caddr_t) DEF_EXPORT_MARGIN}, {"showdepthmanager", "Hints", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, showdepthmanager), XtRBoolean, (caddr_t) & true}, {"flipvisualhints", "Hints", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, flipvisualhints), XtRBoolean, (caddr_t) & false}, {"smooth_factor", "Smooth", XtRInt, sizeof(int), XtOffset(appresPtr, smooth_factor), XtRImmediate, (caddr_t) 0}, {"icon_view", "View", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, icon_view), XtRBoolean, (caddr_t) & true}, {"library_icon_size", "Dimension", XtRInt, sizeof(int), XtOffset(appresPtr, library_icon_size), XtRImmediate, (caddr_t) DEF_ICON_SIZE}, {"splash", "View", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, splash), XtRBoolean, (caddr_t) & true}, {"axislines", "Color", XtRString, sizeof(char *), XtOffset(appresPtr, axislines), XtRString, (caddr_t) "pink"}, {"freehand_resolution", "Hints", XtRInt, sizeof(int), XtOffset(appresPtr, freehand_resolution), XtRImmediate, (caddr_t) 25}, {"ghostscript", "Ghostscript", XtRString, sizeof(char *), XtOffset(appresPtr, ghostscript), XtRString, (caddr_t) "gs"}, {"correct_font_size", "Size", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, correct_font_size), XtRBoolean, (caddr_t) & true}, {"encoding", "Encoding", XtRInt, sizeof(int), XtOffset(appresPtr, encoding), XtRImmediate, (caddr_t) 1}, {"write_v40", "Format", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, write_v40), XtRBoolean, (caddr_t) & false}, {"crosshair", "Crosshair", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, crosshair), XtRBoolean, (caddr_t) & false}, {"autorefresh", "Refresh", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, autorefresh), XtRBoolean, (caddr_t) & false}, {"write_bak", "Refresh", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, write_bak), XtRBoolean, (caddr_t) & true}, #ifdef I18N {"international", "International", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, international), XtRBoolean, (caddr_t) & false}, {"fontMenulanguage", "Language", XtRString, sizeof(char *), XtOffset(appresPtr, font_menu_language), XtRString, (caddr_t) ""}, {"eucEncoding", "EucEncoding", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, euc_encoding), XtRBoolean, (caddr_t) & true}, {"localeEncoding", "LocaleEncoding", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, locale_encoding), XtRBoolean, (caddr_t) & true}, {"latinKeyboard", "Latinkeyboard", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, latin_keyboard), XtRBoolean, (caddr_t) & false}, {"alwaysUseFontSet", "AlwaysUseFontSet", XtRBoolean, sizeof(Boolean), XtOffset(appresPtr, always_use_fontset), XtRBoolean, (caddr_t) & false}, {"fixedFontSet", "FontSet", XtRFontSet, sizeof(XFontSet), XtOffset(appresPtr, fixed_fontset), XtRString, (caddr_t) "-*-times-medium-r-normal--16-*-*-*-*-*-*-*," "-*-*-medium-r-normal--16-*-*-*-*-*-*-*,*--16-*" }, {"fontSetSize", "FontSetSize", XtRInt, sizeof(int), XtOffset(appresPtr, fontset_size), XtRImmediate, (caddr_t)0 }, {"inputStyle", "InputStyle", XtRString, sizeof(char *), XtOffset(appresPtr, xim_input_style), XtRString, (caddr_t) "OffTheSpot"}, {"fig2devLocalizeOption", "Fig2devLocalizeOption", XtRString, sizeof(char *), XtOffset(appresPtr, fig2dev_localize_option), XtRString, (caddr_t) "-j"}, #ifdef I18N_USE_PREEDIT {"textPreedit", "TextPreedit", XtRString, sizeof(char *), XtOffset(appresPtr, text_preedit), XtRString, (caddr_t) ""}, #endif /* I18N_USE_PREEDIT */ #endif /* I18N */ }; /* BE SURE TO UPDATE THE -help COMMAND OPTION LIST IF ANY CHANGES ARE MADE HERE */ XrmOptionDescRec options[] = { {"-visual", "*visual", XrmoptionSepArg, NULL}, {"-depth", "*depth", XrmoptionSepArg, NULL}, {"-allownegcoords", ".allownegcoords", XrmoptionNoArg, "True"}, {"-autorefresh", ".autorefresh", XrmoptionNoArg, "True"}, {"-balloon_delay", ".balloon_delay", XrmoptionSepArg, 0}, {"-boldFont", ".boldFont", XrmoptionSepArg, 0}, {"-buttonFont", ".buttonFont", XrmoptionSepArg, 0}, {"-but_per_row", ".but_per_row", XrmoptionSepArg, 0}, {"-cbg", ".canvasbackground", XrmoptionSepArg, (caddr_t) NULL}, {"-center", ".flushleft", XrmoptionNoArg, "False"}, {"-centimeters", ".inches", XrmoptionNoArg, "False"}, {"-cfg", ".canvasforeground", XrmoptionSepArg, (caddr_t) NULL}, {"-correct_font_size", ".correct_font_size", XrmoptionNoArg, "True"}, {"-crosshair", ".crosshair", XrmoptionNoArg, "True"}, {"-debug", ".debug", XrmoptionNoArg, "True"}, {"-dontallownegcoords", ".allownegcoords", XrmoptionNoArg, "False"}, {"-dontshowaxislines", ".showaxislines", XrmoptionNoArg, "False"}, {"-dontshowballoons", ".showballoons", XrmoptionNoArg, "False"}, {"-dontshowlengths", ".showlengths", XrmoptionNoArg, "False"}, {"-dontshownums", ".shownums", XrmoptionNoArg, "False"}, {"-dontshowpageborder", ".showpageborder", XrmoptionNoArg, "False"}, {"-dontswitchcmap", ".dontswitchcmap", XrmoptionNoArg, "True"}, {"-encoding", ".encoding", XrmoptionSepArg, 0}, {"-exportLanguage", ".exportLanguage", XrmoptionSepArg, 0}, {"-export_margin", ".export_margin", XrmoptionSepArg, 0}, {"-flipvisualhints", ".flipvisualhints", XrmoptionNoArg, "True"}, {"-noflipvisualhints", ".flipvisualhints", XrmoptionNoArg, "False"}, {"-flushleft", ".flushleft", XrmoptionNoArg, "True"}, {"-freehand_resolution", ".freehand_resolution", XrmoptionSepArg, 0}, {"-ghostscript", ".ghostscript", XrmoptionSepArg, "gs"}, {"-grid_color", ".grid_color", XrmoptionSepArg, "lightblue"}, {"-grid_unit", ".grid_unit", XrmoptionSepArg, "default"}, {"-hiddentext", ".hiddentext", XrmoptionNoArg, "True"}, {"-dontshowdepthmanager", ".showdepthmanager", XrmoptionNoArg, "False"}, {"-iconGeometry", ".iconGeometry", XrmoptionSepArg, (caddr_t) NULL}, {"-icon_view", ".icon_view", XrmoptionNoArg, "True"}, {"-image_editor", ".image_editor", XrmoptionSepArg, 0}, {"-imperial", ".inches", XrmoptionNoArg, "True"}, {"-inches", ".inches", XrmoptionNoArg, "True"}, {"-installowncmap", ".installowncmap", XrmoptionNoArg, "True"}, {"-internalBW", ".internalborderwidth", XrmoptionSepArg, 0}, {"-jpeg_quality", ".jpeg_quality", XrmoptionSepArg, 0}, {"-keyFile", ".keyFile", XrmoptionSepArg, 0}, {"-Landscape", ".landscape", XrmoptionNoArg, "True"}, {"-landscape", ".landscape", XrmoptionNoArg, "True"}, {"-latexfonts", ".latexfonts", XrmoptionNoArg, "True"}, {"-left", ".justify", XrmoptionNoArg, "False"}, {"-library_dir", ".library_dir", XrmoptionSepArg, 0}, {"-library_icon_size", ".library_icon_size", XrmoptionSepArg, 0}, {"-list_view", ".icon_view", XrmoptionNoArg, "False"}, {"-magnification", ".magnification", XrmoptionSepArg, 0}, {"-max_image_colors", ".max_image_colors", XrmoptionSepArg, 0}, {"-metric", ".inches", XrmoptionNoArg, "False"}, {"-monochrome", ".monochrome", XrmoptionNoArg, "True"}, {"-multiple", ".multiple", XrmoptionNoArg, "True"}, {"-nooverlap", ".overlap", XrmoptionNoArg, "False"}, {"-normalFont", ".normalFont", XrmoptionSepArg, 0}, {"-noscalablefonts", ".scalablefonts", XrmoptionNoArg, "False"}, {"-nosplash", ".splash", XrmoptionNoArg, "False"}, {"-notrack", ".trackCursor", XrmoptionNoArg, "False"}, {"-nowrite_bak", ".write_bak", XrmoptionNoArg, "False"}, {"-overlap", ".overlap", XrmoptionNoArg, "True"}, {"-pageborder", ".pageborder", XrmoptionSepArg, (caddr_t) NULL}, {"-paper_size", ".paper_size", XrmoptionSepArg, (caddr_t) NULL}, {"-pheight", ".pheight", XrmoptionSepArg, 0}, {"-Portrait", ".landscape", XrmoptionNoArg, "False"}, {"-portrait", ".landscape", XrmoptionNoArg, "False"}, {"-pwidth", ".pwidth", XrmoptionSepArg, 0}, {"-right", ".justify", XrmoptionNoArg, "True"}, {"-rigidtext", ".rigidtext", XrmoptionNoArg, "True"}, {"-rulerthick", ".rulerthick", XrmoptionSepArg, 0}, {"-scalablefonts", ".scalablefonts", XrmoptionNoArg, "True"}, {"-scale_factor", ".scale_factor", XrmoptionSepArg, 0}, {"-showallbuttons", ".showallbuttons", XrmoptionNoArg, "True"}, {"-showballoons", ".showballoons", XrmoptionNoArg, "True"}, {"-showdepthmanager", ".showdepthmanager", XrmoptionNoArg, "True"}, {"-showlengths", ".showlengths", XrmoptionNoArg, "True"}, {"-shownums", ".shownums", XrmoptionNoArg, "True"}, {"-showpageborder", ".showpageborder", XrmoptionNoArg, "True"}, {"-showaxislines", ".showaxislines", XrmoptionNoArg, "True"}, {"-single", ".multiple", XrmoptionNoArg, "False"}, {"-smooth_factor", ".smooth_factor", XrmoptionSepArg, 0}, {"-smallicons", ".smallicons", XrmoptionNoArg, "True"}, {"-specialtext", ".specialtext", XrmoptionNoArg, "True"}, {"-spellcheckcommand", ".spellcheckcommand", XrmoptionSepArg, 0}, {"-spinner_delay", ".spinner_delay", XrmoptionSepArg, 0}, {"-spinner_rate", ".spinner_rate", XrmoptionSepArg, 0}, {"-splash", ".splash", XrmoptionNoArg, "True"}, {"-startfillstyle", ".startfillstyle", XrmoptionSepArg, 0}, {"-startarrowtype", ".startarrowtype", XrmoptionSepArg, 0}, {"-startarrowthick", ".startarrowthick", XrmoptionSepArg, 0}, {"-startarrowwidth", ".startarrowwidth", XrmoptionSepArg, 0}, {"-startarrowlength", ".startarrowlength", XrmoptionSepArg, 0}, {"-startFontSize", ".startfontsize", XrmoptionSepArg, 0}, {"-startfontsize", ".startfontsize", XrmoptionSepArg, 0}, {"-startgridmode", ".startgridmode", XrmoptionSepArg, 0}, {"-startgridtype", ".startgridtype", XrmoptionSepArg, 0}, // isometric grid {"-startlatexFont", ".startlatexFont", XrmoptionSepArg, 0}, {"-startlinewidth", ".startlinewidth", XrmoptionSepArg, 0}, {"-startposnmode", ".startposnmode", XrmoptionSepArg, 0}, {"-startpsFont", ".startpsFont", XrmoptionSepArg, 0}, {"-starttextstep", ".starttextstep", XrmoptionSepArg, 0}, {"-tablet", ".tablet", XrmoptionNoArg, "True"}, {"-track", ".trackCursor", XrmoptionNoArg, "True"}, {"-transparent_color", ".transparent", XrmoptionSepArg, 0}, {"-userscale", ".userscale", XrmoptionSepArg, 0}, {"-write_v40", ".write_v40", XrmoptionNoArg, "True"}, {"-write_bak", ".write_bak", XrmoptionNoArg, "True"}, {"-userunit", ".userunit", XrmoptionSepArg, 0}, {"-axislines", ".axislines", XrmoptionSepArg, "pink"}, {"-zoom", ".zoom", XrmoptionSepArg, 0}, #ifdef I18N {"-international", ".international", XrmoptionNoArg, "True"}, {"-inputStyle", ".inputStyle", XrmoptionSepArg, 0}, #endif /* I18N */ }; char *help_list[] = { "[-allownegcoords] ", "[-autorefresh] ", "[-axislines ] ", "[-balloon_delay ] ", "[-boldFont ] ", "[-but_per_row ] ", "[-buttonFont ] ", "[-cbg ] ", "[-center] ", "[-cfg ] ", "[-centimeters] ", "[-correct_font_size] ", "[-debug] ", "[-depth ] ", "[-dontallownegcoords] ", "[-dontshowaxislines] ", "[-dontshowballoons] ", "[-dontshowlengths] ", "[-dontshowpageborder] ", "[-dontshownums] ", "[-dontswitchcmap] ", "[-encoding ] ", "[-exportLanguage ] ", "[-export_margin ] ", "[-flipvisualhints] ", "[-flushleft] ", "[-freehand_resolution ] ", "[-geometry] ", "[-ghostscript ] ", "[-grid_color ] ", "[-grid_unit ] ", "[-hiddentext] ", "[-dontshowdepthmanager] ", "[-iconGeometry ] ", "[-icon_view] ", "[-image_editor ] ", "[-imperial] ", "[-inches] ", "[-installowncmap] ", "[-internalBW ] ", "[-jpeg_quality ] ", "[-keyFile ] ", "[-landscape] ", "[-latexfonts] ", "[-left] ", "[-library_dir ] ", "[-library_icon_size ] ", "[-list_view] ", "[-magnification ] ", "[-max_image_colors ] ", "[-metric] ", "[-monochrome] ", "[-multiple] ", "[-normalFont ] ", "[-noscalablefonts] ", "[-nosplash] ", "[-notrack] ", "[-nowrite_bak] ", "[-overlap] ", "[-pageborder ] ", "[-paper_size ] ", "[-pheight ] ", "[-portrait] ", "[-pwidth ] ", "[-right] ", "[-rigidtext] ", "[-rulerthick ] ", "[-scale_factor ] ", "[-scalablefonts] ", "[-showallbuttons] ", "[-showballoons] ", "[-showdepthmanager] ", "[-showlengths] ", "[-shownums] ", "[-showpageborder] ", "[-showaxislines] ", "[-single] ", "[-smallicons] ", "[-smooth_factor ] ", "[-specialtext] ", "[-spellcheckcommand ] ", "[-spinner_delay ] ", "[-spinner_rate ] ", "[-splash] ", "[-startfillstyle