From: <ai...@us...> - 2009-03-09 05:29:29
|
Revision: 9682 http://plplot.svn.sourceforge.net/plplot/?rev=9682&view=rev Author: airwin Date: 2009-03-09 05:29:26 +0000 (Mon, 09 Mar 2009) Log Message: ----------- Change from treating libcd as an external library to building it internally as libnistcd. Modified Paths: -------------- trunk/cmake/modules/cgm.cmake trunk/cmake/modules/plplot_version.cmake trunk/drivers/CMakeLists.txt trunk/lib/CMakeLists.txt Added Paths: ----------- trunk/lib/nistcd/ trunk/lib/nistcd/CMakeLists.txt trunk/lib/nistcd/README_plplot_nistcd trunk/lib/nistcd/cd.announce trunk/lib/nistcd/cd.c trunk/lib/nistcd/cd.h trunk/lib/nistcd/cd.html trunk/lib/nistcd/cd1.3.lsm trunk/lib/nistcd/cddll.h trunk/lib/nistcd/cdexp1.cgm trunk/lib/nistcd/cdexpert.c trunk/lib/nistcd/cdmulti.c trunk/lib/nistcd/cdmulti.cgm trunk/lib/nistcd/cdout.cgm trunk/lib/nistcd/cdsimple.c trunk/lib/nistcd/cdsimple.cgm trunk/lib/nistcd/cdtest.c trunk/lib/nistcd/cdtext.c trunk/lib/nistcd/cdtext.cgm trunk/lib/nistcd/color16.c trunk/lib/nistcd/color16.cgm trunk/lib/nistcd/defines.h trunk/lib/nistcd/readme Removed Paths: ------------- trunk/cmake/external/libcd/ trunk/cmake/modules/FindCD.cmake Deleted: trunk/cmake/modules/FindCD.cmake =================================================================== --- trunk/cmake/modules/FindCD.cmake 2009-03-09 04:54:25 UTC (rev 9681) +++ trunk/cmake/modules/FindCD.cmake 2009-03-09 05:29:26 UTC (rev 9682) @@ -1,38 +0,0 @@ -# Find cd header and library. This is the public domain library -# (see http://prdownloads.sourceforge.net/plplot/cd1.3.tar.gz?download -# for a copy) for creating CGM (Computer Graphics Metafile, see -# http://www.agocg.ac.uk/train/cgm/cgm.htm) files. -# - -# This module defines the following uncached variables: -# CD_FOUND, if false, do not try to use CD. -# CD_INCLUDE_DIRS, where to find cd.h. -# CD_LIBRARIES, the libraries to link against to use libcd.a -# CD_LIBRARY_DIRS, the directory where libcd.a is found. - -find_path(CD_INCLUDE_DIR cd.h /usr/local/include /usr/include) - -if(CD_INCLUDE_DIR) - find_library(CD_LIBRARY - NAMES cd - PATHS /usr/local/lib /usr/lib - ) - if(CD_LIBRARY) - set(CD_LIBRARY_DIR "") - get_filename_component(CD_LIBRARY_DIRS ${CD_LIBRARY} PATH) - # Set uncached variables as per standard. - set(CD_FOUND ON) - set(CD_INCLUDE_DIRS ${CD_INCLUDE_DIR}) - set(CD_LIBRARIES ${CD_LIBRARY}) - endif(CD_LIBRARY) -endif(CD_INCLUDE_DIR) - -if(CD_FOUND) - if(NOT CD_FIND_QUIETLY) - message(STATUS "FindCD: Found both cd.h and libcd.a") - endif(NOT CD_FIND_QUIETLY) -else(CD_FOUND) - if(CD_FIND_REQUIRED) - message(FATAL_ERROR "FindCD: Could not find cd.h and/or libcd.a") - endif(CD_FIND_REQUIRED) -endif(CD_FOUND) Modified: trunk/cmake/modules/cgm.cmake =================================================================== --- trunk/cmake/modules/cgm.cmake 2009-03-09 04:54:25 UTC (rev 9681) +++ trunk/cmake/modules/cgm.cmake 2009-03-09 05:29:26 UTC (rev 9682) @@ -21,28 +21,12 @@ # # The following variables are set / modified # -# PLD_cgm - ON means the cgm devic is enabled. -# cgm_COMPILE_FLAGS - COMPILE_FLAGS (string) required to compile cgm -# device driver. -# cgm_LINK_FLAGS - LINK_FLAGS (string) for dynamic cgm device driver. -# DRIVERS_LINK_FLAGS - list of LINK_FLAGS for all static device drivers. -# -# Include file searches use FindPath. To add extra search directories -# set the environment variable CMAKE_INCLUDE_PATH. -# Library searches use FindLibrary. To add extra search directories -# set the environment variable CMAKE_LIBRARY_PATH. -# See cmake documentation for further details. +# cgm_TARGETS - list of targets which the cgm dynamic device +# depends on. +# DRIVERS_LINK_FLAGS - list of targets which the cgm static device +# depends on. if(PLD_cgm) - find_package(CD) - if(CD_FOUND) - set(cgm_COMPILE_FLAGS "-I${CD_INCLUDE_DIRS}") - set(cgm_LINK_FLAGS ${CD_LIBRARIES}) - set(DRIVERS_LINK_FLAGS ${DRIVERS_LINK_FLAGS} ${cgm_LINK_FLAGS}) - else(CD_FOUND) - message(STATUS - "WARNING: cd.h and/or libcd.a not found. Setting PLD_cgm to OFF." - ) - set(PLD_cgm OFF CACHE BOOL "Enable cgm device" FORCE) - endif(CD_FOUND) + set(cgm_TARGETS nistcd) + set(DRIVERS_LINK_FLAGS ${DRIVERS_LINK_FLAGS} nistcd) endif(PLD_cgm) Modified: trunk/cmake/modules/plplot_version.cmake =================================================================== --- trunk/cmake/modules/plplot_version.cmake 2009-03-09 04:54:25 UTC (rev 9681) +++ trunk/cmake/modules/plplot_version.cmake 2009-03-09 05:29:26 UTC (rev 9682) @@ -27,6 +27,9 @@ # (4) If there are no library source code changes at all, then leave all # library version numbers the same for the release. +set(nistcd_SOVERSION 0) +set(nistcd_VERSION ${nist_SOVERSION}.0.1) + set(csirocsa_SOVERSION 0) set(csirocsa_VERSION ${csirocsa_SOVERSION}.0.1) Modified: trunk/drivers/CMakeLists.txt =================================================================== --- trunk/drivers/CMakeLists.txt 2009-03-09 04:54:25 UTC (rev 9681) +++ trunk/drivers/CMakeLists.txt 2009-03-09 05:29:26 UTC (rev 9682) @@ -41,6 +41,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/lib/qsastime + ${CMAKE_SOURCE_DIR}/lib/nistcd ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ) Modified: trunk/lib/CMakeLists.txt =================================================================== --- trunk/lib/CMakeLists.txt 2009-03-09 04:54:25 UTC (rev 9681) +++ trunk/lib/CMakeLists.txt 2009-03-09 05:29:26 UTC (rev 9682) @@ -1,3 +1,4 @@ add_subdirectory(csa) add_subdirectory(nn) add_subdirectory(qsastime) +add_subdirectory(nistcd) Added: trunk/lib/nistcd/CMakeLists.txt =================================================================== --- trunk/lib/nistcd/CMakeLists.txt (rev 0) +++ trunk/lib/nistcd/CMakeLists.txt 2009-03-09 05:29:26 UTC (rev 9682) @@ -0,0 +1,70 @@ +# lib/nistcd/CMakeLists.txt for PLplot +### +### Process this file with cmake to produce Makefile +### +# Copyright (C) 2006 Alan W. Irwin +# +# This file is part of PLplot. +# +# PLplot is free software; you can redistribute it and/or modify +# it under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; version 2 of the License. +# +# PLplot is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with PLplot; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# build nistcd library (a.k.a., "cd" library put into the public domain by +# NIST) required by the PLplot cgm device. +if(PLD_cgm) + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ) + + set( cd_LIB_SRCS cd.c ) + set( cd_LIB_HDRS cd.h defines.h ) + + if(BUILD_SHARED_LIBS) + set_source_files_properties( ${cd_LIB_SRCS} + PROPERTIES COMPILE_FLAGS "-DUSINGDLL" + ) + endif(BUILD_SHARED_LIBS) + + add_library( nistcd ${cd_LIB_SRCS} ) + set_target_properties( + nistcd + PROPERTIES + SOVERSION ${nistcd_SOVERSION} + VERSION ${nistcd_VERSION} + INSTALL_NAME_DIR "${LIB_DIR}" + ) + + option(TEST_NISTCD "Test libnistcd" ON) + if(TEST_NISTCD) + # build and run applications to test libnistcd. + set( cd_EXE color16 cdsimple cdtext cdmulti cdexpert ) + foreach(EXE ${cd_EXE}) + add_executable( ${EXE} ${EXE}.c ) + target_link_libraries( ${EXE} nistcd ) + endforeach(EXE ${cd_EXE}) + endif(TEST_NISTCD) + + # install library and binaries + install( TARGETS + nistcd + ARCHIVE DESTINATION ${LIB_DIR} + LIBRARY DESTINATION ${LIB_DIR} + RUNTIME DESTINATION ${BIN_DIR} + ) + + # install library header files. + install( + FILES ${cd_LIB_HDRS} + DESTINATION ${INCLUDE_DIR} + ) +endif(PLD_cgm) Property changes on: trunk/lib/nistcd/CMakeLists.txt ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/lib/nistcd/README_plplot_nistcd =================================================================== --- trunk/lib/nistcd/README_plplot_nistcd (rev 0) +++ trunk/lib/nistcd/README_plplot_nistcd 2009-03-09 05:29:26 UTC (rev 9682) @@ -0,0 +1,10 @@ +Most of these files were obtained (as of 2001-12-09) from +http://www.pa.msu.edu/ftp/pub/unix/cd1.3.tar.gz + +This software was written originally by G. Edward Johnson at NIST, but it is +no longer maintained by him. It is public-domain software except for the +small part licensed under the libgd license (see his documentation). + +The PLplot developer's contribution is CMakeLists.txt, cddll.h, and some +small visibility modifications to cd.h. We call the resulting library, +libnistcd to distinguish it from all the other "libcd" libraries out there. Property changes on: trunk/lib/nistcd/README_plplot_nistcd ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/lib/nistcd/cd.announce =================================================================== --- trunk/lib/nistcd/cd.announce (rev 0) +++ trunk/lib/nistcd/cd.announce 2009-03-09 05:29:26 UTC (rev 9682) @@ -0,0 +1,56 @@ + + +Announcing the release of CGM Draw 1.3. + +CGM Draw is a freely available library for generating CGM files from a +C program. It has been tested on Solaris, Ultrix, Linux, IRIX, AIX, +OpenVMS, and DOS. CGM (Computer Graphics Metafile) is a vector +graphics format that can be read by many popular packages. With CGM +Draw your code can quickly draw images complete with lines, arcs, +rectangles, polygons, and text. CGM Draw is ideal for creating CGM +files on the fly when you have a rapidly changing data set (such as in +response to database queries.) + + +Documentation for cd is included with the package, and is available from +http://speckle.ncsl.nist.gov/~lorax/cgm/cd.html +General information about CGM is available many places on the web, including +http://speckle.ncsl.nist.gov/~lsr/cgm.htm +This distribution may be retrieved via ftp from +zing.ncsl.nist.gov in the directory "cgm" It will have the +name cd followed by the version number. +The current version is 1.3 and is at: +ftp://zing.ncsl.nist.gov/cgm/cd1.3.tar.gz + + +Whats new in this version: +-Polygon Sets, you can define multiple polygons and draw them all with + one simple command. +-Markers, set points in CGM's +-Expert functions, to give you more control of the final CGM if you need it. + + +What is CGM: +CGM is a widely used method for representing 2D vector +pictures. Many industry users have decided to use CGM as the means of +representing, storing, and interchanging pictures in all their documentation +(e.g., Air Transport Association will use CGM to represent illustrations, US +Petroleum industry has also adopted it). +CGM is already and established, open standard. In 1987 +ISO approved the first version as an international standard, and the +current version (which extends the original) was approved in 1992 (ISO +8632.) Many programs are already capable of creating CGM files. Major +illustration packages already can save their files in the CGM format +(CorelDraw is one example) and many word processing programs (WordPerfect +and Word) can include CGM files in their documents. + + +What types of pictures is CGM suited for: +CGM is ideally suited for pictures with geometric shapes, line drawings, +and text. Here are some particular applications that CGM would do well +with: + Charts and Graphs--For instance charts of recent stock market data, or +graphs of web server usage. + Technical illustrations--Diagrams for products or engineering drawings. +CGM pictures can be zoomed in on to show small details. + General illustrations--Such as those you see in books or comic strips. Property changes on: trunk/lib/nistcd/cd.announce ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/lib/nistcd/cd.c =================================================================== --- trunk/lib/nistcd/cd.c (rev 0) +++ trunk/lib/nistcd/cd.c 2009-03-09 05:29:26 UTC (rev 9682) @@ -0,0 +1,2911 @@ + +/* cd.c main file for cgmdraw module. + + Written by G. Edward Johnson <mailto:lo...@ni...> + Date: April 1996 + Copyright: cd software produced by NIST, an agency of the + U.S. government, is by statute not subject to copyright + in the United States. Recipients of this software assume all + responsibilities associated with its operation, modification + and maintenance. + + Portions of this package are from the gd package written by + Thomas Boutell and are copyright 1994, 1995, Quest Protein + Database Center, Cold Spring Harbor Labs. They are marked in the + source code. +*/ + +#ifndef NOMALLOCH +#include <malloc.h> +#endif +#include <stdio.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include "defines.h" +#include "cd.h" + + +static int cdImageAddColor(cdImagePtr im, int si, int ei); + +cdImagePtr cdImageCreate(int sx, int sy) +/* Creates a new image of size (sx,sy). Most people should always + * start by calling this function */ +{ + cdImagePtr im; + + im = cdImageStartCgm(); + if (!im) return 0; /* memory allocation failed */ + if (!cdImageSetSize(im, sx,sy)) {free (im);return 0;} + + if (!cdCgmHeader(im)) {free (im);return 0;} + + if (cdCgmPic(im, 0)) { + return im; + } + else { + free(im); + return 0; + } +} + +static int cdAppNull(unsigned char *es, int x) { +/* put x nulls in the string. + * return value is number of octets added (1) */ + int y; + + for(y=0; y<x; y++) { + *es = '\0'; + es++; + } + return x; +} + +static int cdAppByte(unsigned char *es, short int addme) { +/* Append an octet to the end of es + * Return value is number of octets added + * for internal cd functions only, do not call + */ + *es = (unsigned char) addme & 0377; + return 1; +} + +static int cdAppShort(unsigned char *es, short int addme) { +/* Append a short to the end of es + * return value is number of octets added + * For internal cd functions only, do not call! + */ + short int temp; + + temp = addme >> 8; + *es = (unsigned char) temp & 0377; + es++; + *es = (unsigned char) addme & 0377; + return 2; +} + +/* static int cdAppWord(unsigned char *es, int addme){ */ +/* Append an word to es + * Return value is number of octets added + * For internal cd functions only, do not call! + */ +/* + int temp; + temp = addme >> 24; + *es = (unsigned char) temp & 0377; + es++; + temp = addme >> 16; + *es = (unsigned char) temp & 0377; + es++; + temp = addme >> 8; + *es = (unsigned char) temp & 0377; + es++; + *es = (unsigned char) addme & 0377; + es++; + return 4; +} +*/ + +static int cdcomhead(unsigned char *es, int elemclass, int id, int len) { +/* sets the command header in the first two bytes of string es + * element class is in bits 15-12 + * element id is in bits 11-5 + * parameter list length is in bits 4-0 + */ + int temp; + + if (!es) return 0; /* the string must be allocated first */ + + /* set the element class */ + *es = (unsigned char) elemclass << 4; + /* set the element id */ + temp = 0177 & id ; + temp = temp >> 3; + *es = *es | temp; + es++; + id = id << 5; + *es = (unsigned char) id; + *es = *es | (unsigned char) ( 037 & len ); + + return 1; +} + +static int cdcomheadlong(unsigned char *es, int elemclass, int id, int len) { +/* sets the command header for the long form. + * first 16 bits: + * element class is in bits 15-12 + * element id is in bits 11-5 + * parameter list length is in bits 4-0 = 31 + * second 16 bits: + * bit 15 = 0 (for last partition) + * bit 14-0 param list len + */ + + /* I'm lazy, call cdcomhead to set the first two bytes */ + if (!cdcomhead(es, elemclass, id, 31)) return 0; + es += 2; + + /* now set the second two bytes */ + cdAppShort(es, (short int) len); + *es = *es & 0177; /* make bit 15 = 0 */ + es += 2; + + return 1; +} + +static int cdAddElem(cdImagePtr im, unsigned char *es, int octet_count) +/* adds a string, which is a CGM element to the elemlist. + * This function is called by other functions in this library and + * should NOT be called by users of the library + * For internal cd functions only, do not call! + */ +{ + unsigned char *newlist; /* in case memory allocation fails */ + int x; /* counter */ + + while ((octet_count + 1) >= im->bytestoend) { + /* not enough space, must grow elemlist */ + im->listlen = im->listlen + CDGROWLISTSIZE; + newlist = (unsigned char *) realloc(im->elemlist, SIZEOF(unsigned char ) * im->listlen); + if (newlist) { + /* successfully allocated memory */ + im->elemlist = newlist; + im->bytestoend = im->bytestoend + CDGROWLISTSIZE; + im->curelemlist = im->elemlist + (im->listlen - im->bytestoend); + } + else { + /* memory allocation failed, save yurself */ + im->listlen = im->listlen - CDGROWLISTSIZE; + return 0; + } + } + + /* ok, if we get to here, there is enough space, so add it. */ + for (x=0; x < octet_count; x++) { + *im->curelemlist = (unsigned char) *es; + im->curelemlist++; + es++; + } + im->bytestoend = im->bytestoend - octet_count; + return 1; +} + +int cdCgmHeader(cdImagePtr im) { +/* add the cgm header to the imagepointer's element list + * do it all in a string than call cdAddElem on it + * For internal cd functions only, do not call! + */ + unsigned char *headerp; + unsigned char *head; + const unsigned char *buf, *buf2; + int octet_count=0; + int blen; /* length of buf */ + int curly; + int fontlistlen; /* each font in the font list is stored as a string, + with a single octet in front of the string + giving its length, fontlistlen is the sum of + the lengths of all the font strings + the + length octets. */ + + if (im->state != 0) return 0; + headerp = (unsigned char *) calloc(1024, SIZEOF(unsigned char )); + if (!headerp) return 0; /* memory allocation failed */ + head=headerp; + + /*** Attribute: BegMF; Elem Class 0; Elem ID 1 */ + buf = (const unsigned char *) "cd: CgmDraw Library"; + blen = strlen( (const char *) buf); + cdcomhead(head, 0, 1, blen+1); + head += 2; + head += cdAppByte(head, (short int) blen); + buf2 = buf; + while (*buf2) { + *head++ = *buf2++; + } + octet_count += (blen + 3); + curly = 4 - (octet_count % 4); + if (curly % 4) { + octet_count += curly; + head += cdAppNull(head, curly); + } + + /*** Attribute: MFVersion; Elem Class 1; Elem ID 1 */ + cdcomhead(head, 1, 1, 2); + head += 2; + head += cdAppShort(head, (short int) 1); + octet_count += 4; + + /*** Attribute: MFDesc; Elem Class 1; Elem ID 2 */ + blen = strlen( (char *) im->desc); + cdcomheadlong(head, 1, 2, blen+1); + head += 4; + head += cdAppByte(head, (short int) blen); + buf2 = im->desc; + while (*buf2) { + *head++ = *buf2++; + } + octet_count += (blen + 5); + curly = 4 - (octet_count % 4); + if (curly % 4) { + octet_count += curly; + head += cdAppNull(head, curly); + } + + /*** Attribute: ColrPrec; Elem Class 1; Elem ID 7 */ + cdcomhead(head, 1, 7, 2); + head += 2; + head += cdAppShort(head, (short int) 8); + octet_count += 4; + + /*** Attribute: ColrIndexPrec; Elem Class 1; Elem ID 8 */ + cdcomhead(head, 1, 8, 2); + head += 2; + head += cdAppShort(head, (short int) 8); + octet_count += 4; + + /*** Attribute: MaxColrIndex; Elem Class 1; Elem ID 9 */ + cdcomhead(head, 1, 9, 1); + head += 2; + head += cdAppByte(head, (short int) 255); + octet_count += 4; head++; + + /*** Attribute: MFElemList; Elem Class 1; Elem ID 11 */ + /* shorthand here. 1 means 1 element specified, (-1,1) + * means drawing-plus-control set */ + cdcomhead(head, 1, 11, 6); + head += 2; + head += cdAppShort(head, (short int) 1); + head += cdAppShort(head, (short int) -1); + head += cdAppShort(head, (short int) 1); + octet_count += 8; + + /*** Attribute: FontList; Elem Class 1; Elem ID 13 */ + /* im->fontlist contains a comma separated list of font names + * since we don't need the commas, and every font except one has + * a comma, and we do need a length octet, that means that + * taking the string length will give us one less than the + * correct length. */ + buf = im->fontlist; + if (buf) { /* don't do this if there aren't any fonts */ + fontlistlen = strlen( (const char *) buf) + 1; + cdcomheadlong(head, 1, 13, fontlistlen); + head +=4; + + while (*buf) { + blen = 0; + buf2 = buf; + while ((*buf) && (*buf != ',')) { + buf++; + blen++; + } + head += cdAppByte(head, (short int) blen); + while (buf2 < buf) { + *head++ = *buf2++; + } + if (*buf) { + buf++; + } + } + octet_count += (4 + fontlistlen); + curly = 4 - (octet_count % 4); + if (curly % 4) { + octet_count += curly; + head += cdAppNull(head, curly); + } + } /* end of check to see if any fonts */ + + if (cdAddElem(im, headerp, octet_count)) { + free(headerp); + headerp = 0; + return 1; + } + else { + free(headerp); + return 0; + } +} + + +int cdCgmPic(cdImagePtr im, int sticky) { +/* Start the picture. if the sticky bit is set, set and use the defaults + * of the previous picture. Otherwise, reset all defaults. + * Gej: sticky = 0 reset defaults, 1 dont reset anything, 2 only + * reset the color table + */ + unsigned char *headerp; + unsigned char *head; + unsigned char *buf, *buf2; + char *tb; + int octet_count=0; + int blen; /* length of buf */ + int x1,x2,x3,x4; /* needed for setting defaults */ + + if ((im->state != 0) && (im->state != 2)) return 0; + if ((sticky > 2) || (sticky < 0)) return 0; /* invalid sticky bit */ + /* increment the picture number */ + im->picnum++; + tb = (char *) calloc(4*4, SIZEOF(char) ); + headerp = (unsigned char *) calloc(1024, SIZEOF(unsigned char )); + if (!headerp) return 0; /* memory allocation failed */ + head=headerp; + + /*** Attribute: BegPic; Elem Class 0; Elem ID 3 */ + sprintf(tb, "picture %d", im->picnum); + buf = (unsigned char*) tb; + /* buf = (unsigned char *) "picture 1"; */ + blen = strlen( (char *) buf); + cdcomhead(head, 0, 3, blen+1); + head += 2; + head += cdAppByte(head, (short int) blen); + buf2 = buf; + while (*buf2) { + *head++ = *buf2++; + } + free(tb); + octet_count += (blen + 3); + if (!(blen % 2)) { + octet_count++; + head += cdAppNull(head, 1); + } + if (octet_count % 4) { + octet_count +=2; + head += cdAppNull(head, 2); + } + + /*** Attribute: ColrMode; Elem Class 2; Elem ID 2 */ + cdcomhead(head, 2, 2, 2); + head += 2; + head += cdAppShort(head, (short int) 0); + octet_count += 4; + /* Picture Descriptor: Line Width Specification Mode; + * Elem Class 2; Elem ID 3*/ + if (sticky && (im->linespec != CDLINESPEC)) { + cdcomhead(head, 2, 3, 2); + head += 2; + head += cdAppShort(head, (short int) im->linespec); + octet_count += 4; + } + /* Picture Descriptor: Marker Size Specification Mode; + * Elem Class 2; Elem ID 4*/ + if (sticky && (im->markerspec != CDMARKERSPEC)) { + cdcomhead(head, 2, 4, 2); + head += 2; + head += cdAppShort(head, (short int) im->markerspec); + octet_count += 4; + } + /* Picture Descriptor: Edge Width Specification Mode; + * Elem Class 2; Elem ID 5*/ + if (sticky && (im->edgespec != CDEDGESPEC)) { + cdcomhead(head, 2, 5, 2); + head += 2; + head += cdAppShort(head, (short int) im->edgespec); + octet_count += 4; + } + + /*** Attribute: VDCExt; Elem Class 2; Elem ID 6 */ + cdcomhead(head, 2, 6, 8); + head += 2; + head += cdAppShort(head, (short int) 0); + head += cdAppShort(head, (short int) 0); + head += cdAppShort(head, (short int) im->sx); + head += cdAppShort(head, (short int) im->sy); + octet_count += 10; + + /*** Attribute: Begin Picture Body; Elem Class 0; Elem ID 4 */ + cdcomhead(head, 0, 4, 0); + head += 2; + octet_count += 2; + + if (cdAddElem(im, headerp, octet_count)) { + free(headerp); + } + else { + free(headerp); + return 0; + } + + if (sticky) { + /* keep defaults the way they are */ + if (sticky == 1) { + /* keep the color table */ + if(cdImageAddColor(im, 0, im->colorsTotal - 1) == -1) { + /* no colortable */ + return 1; + } + } + else { + /* Nuke the color table if there is one */ + cdImageColorClear(im); + } + im->state = 1; + x1=im->ltype; x2=im->lwidth; x3=im->lcolor; + im->ltype=CDLTYPE; im->lwidth=CDLWIDTH; im->lcolor=CDLCOLOR; + if(!cdSetLineAttrib(im, x1, x2, x3)) return 0; + + x1=im->shapestyle; x2=im->shapecolor; x3=im->shapehatch; + im->shapestyle=CDSHAPESTYLE; im->shapecolor=CDSHAPECOLOR; + im->shapehatch=CDSHAPEHATCH; + if (!cdSetShapeFillAttrib(im, x1, x2, x3)) return 0; + + x1=im->edgetype; x2=im->edgewidth; + x3=im->edgecolor; x4=im->edgevis; + im->edgetype=CDEDGETYPE; im->edgewidth=CDEDGEWIDTH; + im->edgecolor=CDEDGECOLOR; im->edgevis=CDEDGEVIS; + if (!cdSetShapeEdgeAttrib(im, x1, x2, x3, x4)) return 0; + + x1=im->textfont; x2=im->textcolor; x3=im->textheight; + im->textfont=CDTEXTFONT; im->textcolor=CDTEXTCOLOR; + im->textheight=CDTEXTHEIGHT; + if(!cdSetTextAttrib(im, x1, x2, x3)) return 0; + + x1=im->textpath; im->textpath = CDTEXTPATH; + if (!cdSetTextPath(im, x1)) return 0; + + x1=im->mtype; x2=im->msize; x3=im->mcolor; + im->ltype=CDMTYPE; im->lwidth=CDMSIZE; im->lcolor=CDMCOLOR; + if(!cdSetMarkerAttrib(im, x1, x2, x3)) return 0; + } + else { + /* reset all the defaults */ + cdImageSetDefaults(im); + /* Nuke the color table if there is one */ + cdImageColorClear(im); + im->state = 1; /* now we are officially in the picture */ + } + return 1; +} + +int cdCgmNewPic(cdImagePtr im, int sticky) +/* The CGM standard allows multiple images in a single file. This function + * will close the current picture, then open a new one. + * if sticky is 0 then all attributes will be reset to the defaults + * if sticky is 1 then all attributes will be inherited from the prevous + * picture. + * if sticky is 2 all attributes except the color table will be inherited + * from the previous picture + */ +{ + /* close the current picture */ + if (!cdImageEndPic(im)) return 0; + + /* now start the new picture */ + return(cdCgmPic(im, sticky)); +} + +int cdImageCgm(cdImagePtr im, FILE *out) +/* Gej: Write the image to file *out, which must be open already + * does not close the file */ +{ +/* + if (out) { + im->outfile = out; + } +*/ + cdImageSetOutput(im, out); + return cdImageEndCgm(im); +} + + +int cdSetLineType(cdImagePtr im, int lntype) { +/* Attribute: Line Type; Elem Class 5; Elem ID 2 + * Set the line type. Possible values are: + * 1=solid, 2=dash, 3=dot, 4=dash-dot, 5=dash-dot-dot + * Even though new ones can be defined, I am limiting lntype to these values + * If you really need more, you can make the proper changes. + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (lntype == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (lntype == im->ltype) + return 1; + + /* Make sure that lntype is between 1 and 5 */ + if ((lntype < 1) || (lntype > 5)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if (!cdcomhead(es, 5, 2, 2)) {free(esp); return 0;} + es += 2; + /* set Param_List_Len to 2 (signed int at index precision) */ + + /* add in the value of lntype */ + es += cdAppShort(es, (short int) lntype); + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->ltype = (short int) lntype; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetLineWidth(cdImagePtr im, int lnwidth) { +/* Attribute: Line Width; Elem Class 5; Elem ID 3 + * sets the line width. with an image of height X with line width 1 + * the displayed width will be 1/X%. as an example, if you image is + * x=5, y=10, and you set line width = 1, and draw a vertical line, the + * resulting line will cover 20% of horizontal area. + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (lnwidth == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (lnwidth == im->lwidth) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + + /*gej: line width is 32 bit floating point number, 16 bits before the + * decimal, 16 bits after if Line Spec is default (1, scaled) + * if Line Spec is 0 (0, absolute) then it is 16 bit SI */ + if (im->linespec) { + if (!cdcomhead(es, 5, 3, 4)) {free(esp);return 0;} + es += 2; + octet_count = 2; + es += cdAppShort(es, (short int) lnwidth); + octet_count += 2; + /* the next two (after decimal point) will always be zero */ + es += cdAppNull(es, 2); + octet_count += 2; + } + else { + if (!cdcomhead(es, 5, 3, 2)) {free(esp);return 0;} + octet_count = 2; + es += 2; + es += cdAppShort(es, (short int) lnwidth); + octet_count += 2; + } + + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->lwidth = lnwidth; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetLineColor(cdImagePtr im, int lncolor) { +/* Attribute: Line Colour; Elem Class 5; Elem ID 4 + * Sets the line color. lncolor should be an index into the color + * table that you have previously allocated. + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (lncolor == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (lncolor == im->lcolor) + return 1; + + /* Make sure the color they want to use has been allocated. + * also, that color must be non-negative */ + if ((lncolor >= im->colorsTotal ) || (lncolor < 0)) + return 0; /* you must allocate a color before you use it */ + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + + if (!cdcomhead(es, 5, 4, 1)) {free (esp);return 0;} + es += 2; + + *es = 0377 & lncolor; /* mask off last 8 bits and put in es */ + es++; + + es += cdAppNull(es, 1); + + octet_count = 4; /* we just know this; 2 octets of header, + * 1 octet of data, 1 octet of null data */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->lcolor = (short int) lncolor; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetFillStyle(cdImagePtr im, int instyle) { +/* set the style of the interior of filled area elements. + * Attribute: Interior Style; Elem Class 5; Elem ID 22 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Interior Style: (integers 0-6, corresponding to: hollow, solid, + * [not pattern], hatch, empty, [not geometric pattern], + * interpolated.) + * attribute is 16 bit signed int + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (instyle == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (instyle == im->shapestyle) + return 1; + + /* Make sure that lnhatch is between 0 and 6, but not + * 2, 5, or 6 */ + if ((instyle < 0) || (instyle > 4) || (instyle == 2)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + /* set the header to Class 5, ID 22, Length 2 */ + if (!cdcomhead(es, 5, 22, 2)) {free (esp);return 0;} + es += 2; + + /* add in the value of inhatch */ + es += cdAppShort(es, (short int) instyle); + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->shapestyle = (short int) instyle; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetFillColor(cdImagePtr im, int incolor) { +/* set the color of the interior of filled area elements + * Attribute: Fill Colour; Elem Class 5; Elem ID 23 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Fill Colour: (index into the color table) + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (incolor == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (incolor == im->shapecolor) + return 1; + + /* Make sure the color they want to use has been allocated. + * also, that color must be non-negative */ + if ((incolor >= im->colorsTotal ) || (incolor < 0)) + return 0; /* you must allocate a color before you use it */ + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if (!cdcomhead(es, 5, 23, 1)) {free(esp);return 0;} + es += 2; + + *es = 0377 & incolor; /* mask off last 8 bits and put in es */ + es++; + es += cdAppNull(es, 1); + + octet_count = 4; /* we just know this; 2 octets of header, + * 1 octet of data, 1 octet of null data */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->shapecolor = (short int) incolor; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetFillHatch(cdImagePtr im, int inhatch) { +/* Set the hatch pattern for the interior of filled-area elements + * the fill style must be set to hatch for this to have an effect. + * Attribute: Hatch Index; Elem Class 5; Elem ID 24 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Hatch Index: (integers 1-6, corresponding to: horizontal lines, + * vertical lines, pos. slope parallel lines, + * neg. slope parallel lines, horizontal/vertical + * crosshatch, positive/negative slope crosshatch) + */ + + unsigned char *es, *esp; + int octet_count, temp; + + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (inhatch == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (inhatch == im->shapehatch) + return 1; + + /* Make sure that lnhatch is between 1 and 6 */ + if ((inhatch < 1) || (inhatch > 6)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + /* set the command header to class 5, id 24, length 2 */ + if (!cdcomhead (es, 5, 24, 2)) {free(esp);return 0;} + es += 2; + + /* add in the value of inhatch */ + temp = inhatch >> 8; + *es = *es | (temp & 0377); + es++; + *es = *es | (inhatch & 0377); + es++; + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->shapehatch = (short int) inhatch; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetEdgeType(cdImagePtr im, int edtype) { +/* set the type of the edge of filled-area elements. + * Attribute: Edge Type; Elem Class 5; Elem ID 27 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Edge Type (integers 1-5, corresponding to: solid, dash, dot, + * dash-dot, dash-dot-dot. These are the same as those used + * for line type.) + * In Part 3 of the standard (Binary Encoding) on page 47 it says that + * edge type is integer. This is incorrect. Edge type is Index, just + * like line type. + * Even though new ones can be defined, I am limiting lntype to these values + * If you really need more, you can make the proper changes. + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (edtype == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (edtype == im->edgetype) + return 1; + + /* Make sure that lntype is between 1 and 5 */ + if ((edtype < 1) || (edtype > 5)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if(!cdcomhead(es, 5, 27, 2)) {free(esp);return 0;} + es += 2; + + /* add in the value of edtype */ + es += cdAppShort(es, (short int) edtype); + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->edgetype = (short int) edtype; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetEdgeWidth(cdImagePtr im, int edwidth) { +/* Set the width of the edge of filled-area elements. + * Attribute: Edge Width; Elem Class 5; Elem ID 28 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Edge Width (should be the same as line width) + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (edwidth == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (edwidth == im->edgewidth) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + /*gej: edge width is 32 bit floating point number, 16 bits before the + * decimal, 16 bits after for default edge spec (1, scaled) if + * edge spec is absolute (0) then just 16 bit SI */ + if (im->edgespec) { + if (!cdcomhead(es, 5, 28, 4)) {free(esp);return 0;} + es += 2; + octet_count = 2; + es+= cdAppShort(es, edwidth); + octet_count+=2; + /* the next two (after decimal point) will always be zero */ + es += cdAppNull(es, 2); + octet_count += 2; + } + else { + if (!cdcomhead(es, 5, 28, 2)) {free(esp);return 0;} + es += 2; + octet_count = 2; + es+= cdAppShort(es, edwidth); + octet_count+=2; + } + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->edgewidth = edwidth; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetEdgeColor(cdImagePtr im, int edcolor) { +/* Set the color of the edge of filled-area elements. + * Attribute: Edge Color; Elem Class 5; Elem ID 29 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Edge Colour (index into the color table) + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (edcolor == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (edcolor == im->edgecolor) + return 1; + + /* Make sure the color they want to use has been allocated. + * also, that color must be non-negative */ + if ((edcolor >= im->colorsTotal ) || (edcolor < 0)) + return 0; /* you must allocate a color before you use it */ + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + if (!cdcomhead(es, 5, 29, 1)) {free(esp);return 0;} + es += 2; + + *es = 0377 & edcolor; /* mask off last 8 bits and put in es */ + es++; + es += cdAppNull(es, 1); + + octet_count = 4; /* we just know this; 2 octets of header, + * 1 octet of data, 1 octet of null data */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->edgecolor = (short int) edcolor; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetEdgeVis(cdImagePtr im, int edvis) { +/* Set the visibility of the edge of filled-area elements. + * Attribute: Edge Visibility; Elem Class 5; Elem ID 30 + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Edge Visibility (integer 0 or 1, corresponding to: Off, On) + * Attribute is 16 bit signed int. + */ + unsigned char *es, *esp; + int octet_count, temp; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (edvis == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (edvis == im->edgevis) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if (!cdcomhead(es, 5, 30, 2)) {free(esp);return 0;} + es +=2; octet_count = 2; + temp = edvis >> 8; + *es = *es | (temp & 0377); + es++; + *es = *es | (edvis & 0377); + es++; + octet_count += 2; + + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->edgevis = (short int) edvis; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetTextFont(cdImagePtr im, int font) { +/* Attribute: Text Font Index; Elem Class 5; Elem ID 10 + * font is an index into the font table. it can have one of the following + * values: + * 1 Times Roman + * 2 Times Bold + * 3 Times Italic + * 4 Times Bold Italic + * 5 Helvetica + * 6 Helvetica Bold + * 7 Helvetica Italic + * 8 Helvetica Bold Italic + * 9 Courier + * 10 Courier Bold + * 11 Courier Italic + * 12 Courier Bold Italic + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (font == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (font == im->textfont) + return 1; + + /* Make sure that font is between 1 and the number of fonts */ + if ((font < 1) || (font > im->numfonts)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if(!cdcomhead(es, 5, 10, 2)) {free(esp);return 0;} + es += 2; + + es += cdAppShort(es, (short int) font); + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->textfont = (short int) font; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetTextColor(cdImagePtr im, int color) { +/* Attribute: Text Colour ; Elem Class 5; Elem ID 14 + * set the forground color of text + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (color == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (color == im->textcolor) + return 1; + + /* Make sure the color they want to use has been allocated. + * also, that color must be non-negative */ + if ((color >= im->colorsTotal ) || (color < 0)) + return 0; /* you must allocate a color before you use it */ + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if(!cdcomhead(es, 5, 14, 1)) {free(esp);return 0;} + es += 2; + + *es = 0377 & color; /* mask off last 8 bits and put in es */ + es++; + + octet_count = 4; /* we just know this; 2 octets of header, + * 1 octet of data, 1 octet of null data */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->textcolor = (short int) color; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetTextHeight(cdImagePtr im, int height) { +/* Attribute: Character Height; Elem Class 5; Elem ID 15 + * the height is in the same units as line width + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (height == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (height == im->textheight) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if(!cdcomhead(es, 5, 15, 2)) {free(esp);return 0;} + octet_count = 2; es += 2; + + es += cdAppShort(es, height); + octet_count += 2; + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->textheight = height; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetTextPath(cdImagePtr im, int tpath) { +/* Attribute: Text Path; Elem Class 5; Elem ID 17 + * Is one of: + * 0 right -- Means the direction of the character base vector + * 1 left -- means 180 degrees from the character base vector + * 2 up -- means the direction of the character up vector + * 3 down -- means 180 degrees from the character up vector + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (tpath == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (tpath == im->textpath) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + octet_count = 0; + + if (!cdcomhead(es, 5, 17, 2)) {free(esp);return 0;} + es +=2; octet_count = 2; + + es += cdAppShort(es, (short int) tpath); + octet_count += 2; + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->textpath = (short int) tpath; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetTextOrient(cdImagePtr im, int xup, int yup, int xbase, int ybase) { +/* Attribute: Character Orientation; Elem Class 5; Elem ID 16 + * (xbase,ybase) is the run and the rise of the line that the text is + * written along. For regular text at an angle, set xup = -ybase + * and yup = xbase. Setting it to something different will result in + * skewed text (which may be what you want.) Text written from bottom to + * top at a 90 degree angle would have the following parameters + * xup=-1, yup=0, xbase=0, ybase=1 + * + * This function adds the Orientation to the metafile every time. + * It does not follow the normal -1 for no change, although if you + * put in the same numbers it won't re-add it to the meta file. + */ + unsigned char *es, *esp; + int octet_count; + + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + octet_count = 0; + + if (!cdcomhead(es, 5, 16, 8)) {free(esp);return 0;} + es +=2; octet_count += 2; + + /* In the metafile it is a 16 bit signed integer */ + /* add xup */ + es += cdAppShort(es, (short int) xup); + octet_count += 2; + /* add the rest */ + es += cdAppShort(es, (short int) yup); + octet_count += 2; + es += cdAppShort(es, (short int) xbase); + octet_count += 2; + es += cdAppShort(es, (short int) ybase); + octet_count += 2; + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetMarkerType(cdImagePtr im, int mtype) { +/* Attribute: Marker Type; Elem Class 5; Elem ID 6 + * Set the Marker type. Possible values are: + * 1=dot, 2=plus, 3=asterisk, 4=circle, 5=cross + * Even though new ones can be defined, I am limiting lntype to these values + * If you really need more, you can make the proper changes. + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (mtype == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (mtype == im->mtype) + return 1; + + /* Make sure that mtype is between 1 and 5 */ + if ((mtype < 1) || (mtype > 5)) + return 0; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + if (!cdcomhead(es, 5, 6, 2)) {free(esp); return 0;} + es += 2; + /* set Param_List_Len to 2 (signed int at index precision) */ + + /* add in the value of mtype */ + es += cdAppShort(es, (short int) mtype); + + octet_count = 4; /* we just know this */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->mtype = (short int) mtype; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetMarkerSize(cdImagePtr im, int msize) { +/* Attribute: Marker Size; Elem Class 5; Elem ID 7 + * sets the marker size. with an image of height X with marker size 1 + * the displayed size will be 1/X%. as an example, if you image is + * x=5, y=10, and you set marker size = 1, and draw a marker, the + * resulting marker will cover 20% of horizontal area. + */ + unsigned char *es, *esp; + int octet_count; + + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (msize == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (msize == im->msize) + return 1; + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + + /*gej: marker size is 32 bit floating point number, 16 bits before the + * decimal, 16 bits after if marker spec is default (1, scaled) + * for absolute mode (0, absolute) it is 16 bit SI */ + if (im->markerspec) { + if (!cdcomhead(es, 5, 7, 4)) {free(esp);return 0;} + octet_count = 2; + es += 2; + es += cdAppShort(es, (short int) msize); + octet_count += 2; + /* the next two (after decimal point) will always be zero */ + es += cdAppNull(es, 2); + octet_count += 2; + } + else { + if (!cdcomhead(es, 5, 7, 4)) {free(esp);return 0;} + octet_count = 2; + es += 2; + es += cdAppShort(es, (short int) msize); + octet_count += 2; + } + + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->msize = msize; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetMarkerColor(cdImagePtr im, int mcolor) { +/* Attribute: Marker Colour; Elem Class 5; Elem ID 8 + * Sets the marker color. mcolor should be an index into the color + * table that you have previously allocated. + */ + unsigned char *es, *esp; + int octet_count; + /* First check and see if the user doesn't want any changes, + * if so, just return success */ + if (mcolor == -1) + return 1; + + /* Check and see if the value it is being set to is the current + * value, if so, don't make any changes, just return 1 */ + if (mcolor == im->mcolor) + return 1; + + /* Make sure the color they want to use has been allocated. + * also, that color must be non-negative */ + if ((mcolor >= im->colorsTotal ) || (mcolor < 0)) + return 0; /* you must allocate a color before you use it */ + + /* allocate sufficent space. should be 32 bits * 4 to be safe */ + es = (unsigned char *) calloc(4*4, SIZEOF(unsigned char ) ); + if (!es) return 0; /* memory allocation failed */ + esp=es; + + + if (!cdcomhead(es, 5, 8, 1)) {free (esp);return 0;} + es += 2; + + *es = 0377 & mcolor; /* mask off last 8 bits and put in es */ + es++; + + es += cdAppNull(es, 1); + + octet_count = 4; /* we just know this; 2 octets of header, + * 1 octet of data, 1 octet of null data */ + + /* add it to the buffer */ + if (cdAddElem(im, esp, octet_count)) { + im->mcolor = (short int) mcolor; + free(esp); + return 1; + } + else { + free(esp); + return 0; + } +} + +int cdSetLineAttrib(cdImagePtr im, int lntype, int lnwidth, int lncolor) { +/* Spits out the attributes of lines. These attributes stay in effect + * until changed, so you don't have to output them every time. + */ + + if (!cdSetLineType(im, lntype)) return 0; + if (!cdSetLineWidth(im, lnwidth)) return 0; + if (!cdSetLineColor(im, lncolor)) return 0; + + return 1; +} + +int cdSetShapeFillAttrib(cdImagePtr im, int instyle, int incolor, int inhatch) { +/* Spits out the attributes for the interior of filled-area elements. + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Set the following attributes: + * Interior Style: (integers 0-6, corresponding to: hollow, solid, + * [not pattern], hatch, empty, [not geometric pattern], + * interpolated.) + * Fill Colour: (index into the color table) + * Hatch Index: (integers 1-6, corresponding to: horizontal lines, + * vertical lines, pos. slope parallel lines, + * neg. slope parallel lines, horizontal/vertical + * crosshatch, positive/negative slope crosshatch) + */ + if (!cdSetFillStyle(im, instyle)) return 0; + if (!cdSetFillColor(im, incolor)) return 0; + if (!cdSetFillHatch(im, inhatch)) return 0; + + return 1; +} + +int cdSetShapeEdgeAttrib(cdImagePtr im, int edtype, int edwidth, int edcolor, int edvis) { +/* Spits out the attributes for the edges of filled-area elements. It may + * seem logical that these would be the same as the corresponding line + * attributes, but this is not the case. + * These attributes stay in effect until changed, so you don't have to output + * them every time. + * Set the following attributes: + * Edge Type (integers 1-5, corresponding to: solid, dash, dot, + * dash-dot, dash-dot-dot. These are the same as those used + * for line type.) + * Edge Width (should be the same as line width) + * Edge Colour (index into the color table) + * Edge Visibility (integer 0 or 1, corresponding to: Off, On) + */ + if (!cdSetEdgeType(im, edtype)) return 0; + if (!cdSetEdgeWidth(im, edwidth)) return 0; + if (!cdSetEdgeColor(im, edcolor)) return 0; + if (!cdSetEdgeVis(im, edvis)) return 0; + + return 1; +} + +int cdSetTextAttrib(cdImagePtr im, int font, int color, int height) { +/* Set the attributes of text. the font is an integer pointer into the + * font list where: + * 1 Times + * 2 Times Bold + * 3 Times Italic + * 4 Times Bold Italic + * 5 Helvetica + * 6 Helvetica Bold + * 7 Helvetica Italic + * 8 Helvetica Bold Italic + * 9 Courier + * 10 Courier Bold + * 11 Courier Italic + * 12 Courier Bold Italic + * color is an index into the colortable which is the color of the text + * size is the approximate size you want the text written in. + */ + + if(!cdSetTextFont(im, font)) return 0; + if(!cdSetTextColor(im, color)) return 0; + if(!cdSetTextHeight(im, height)) return 0; + + return 1; +} + +int cdSetMarkerAttrib(cdImagePtr im, int mtype, int msize, int mcolor) { +/* Spits out the attributes of Markers. These attributes stay in effect + * until changed, so you don't have to output them every time. + */ + + if (!cdSetMarkerType(im, mtype)) return 0; + if (!cdSetMarkerSize(im, msize)) return 0; + if (!cdSetMarkerColor(im, mcolor)) return 0; + + return 1; +} + +int cdImageDestroy(cdImagePtr im) +/* gej: should work, unless I make changes to cdImage Struct */ +{ + if (im->elemlist) { + free(im->elemlist); + } + if (im->desc) { + free(im->desc); + } + if (im->fontlist) { + free(im->fontlist); + } + free(im); + + return 1; +} + +int cdImageColorClosest(cdImagePtr im, int r, int g, int b) +/* From gd library, see README file for copyright information */ +/* gej: should work unchanged */ +/* gej: 5/96, changed the colors to use short int */ +{ + short int i; + long rd, gd, bd; + int ct = (-1); + long mindist = 0; + for (i=0; (i<(im->colorsTotal)); i++) { + long dist; + if (im->open[i]) { + continue; + } + rd = (im->red[i] - r); + gd = (im->green[i] - g); + bd = (im->blue[i] - b); + dist = rd * rd + gd * gd + bd * bd; + if ((i == 0) || (dist < mindist)) { + mindist = dist; + ct = i; + } + } + return ct; +} + +int cdImageColorClear(cdImagePtr im) { +/* mark all entries in the color table as open */ + short int i; + for (i=0; (i<(cdMaxColors)); i++) { + im->open[i] = 1; + } + return 1; +} + +int cdImageColorExact(cdImagePtr im, int r, int g, int b) +/* From gd library, see README file for copyright information */ +/* gej: should work unchanged */ +/* gej: 5/96, changed colors to work with short ints */ +{ + short int i; + for (i=0; (i<(im->colorsTotal)); i++) { + if (im->open[i]) { + continue; + } + if ((im->red[i] == r) && + (im->green[i] == g) && + (im->blue[i] == b)) { + return i; + } + } + return -1; +} + +static int cdImageAddColorIndex(cdImagePtr im, int r, int g, int b) +/* adds the specified color to the colortable in the cdImagePtr. + * does not add it to the cgm file, cdImageAddColor does. + * do not use either of these two functions, use cdImageColorAllocate. + */ +{ + short int i; + short int ct = (-1); + for (i=0; (i<(im->colorsTotal)); i++) { + if (im->open[i]) { + ct = i; + break; + } + } + if (ct == (-1)) { + ct = im->colorsTotal; + if (ct == cdMaxColors) { + return -1; + } + im->colorsTotal++; + } + im->red[ct] = (short int) r; + im->green[ct] = (short int) g; + im->blue[ct] = (short int) b; + im->open[ct] = (short int) 0; + + return ct; +} + +static int cdImageAddColor(cdImagePtr im, int si, int ei) +/* adds colors to the cgm file, gets values from the color table. + * adds all colors from si to ei inclusive. + * Use cdImageColorAllocate, not this one. + */ +{ + unsigned char *cts, *ctsp; /* GEJ: color table attribute */ + int octet_count; /* GEJ: octet count */ + int numco, curly; + octet_count =... [truncated message content] |