Project BDE2GIF
FINAL REPORT
Yu-Kwong Wong
May 5, 1997
97s523: Software Engineering I Spring 1997
Instructor: Professor Robert Lechner
Department of Computer Science
University of Massachusetts at Lowell
Final Report of Project BDE2GIF
Principal Author: Yu-Kwong Wong
Instructor: Professor Robert Lechner
Course: 91.523 Software Engineering I, Spring 1997
Project: BDE2GIF
Team member: Yu-Kwong Wong
Path: /usr/proj3/case/97s523/bde2ht1/yuwong/bde
Date: May 5 1997
Abstract
The Block Diagram Edit (BDE) is an interactive graphics (GUI-based) application developed in the Department of Computer Science, University of Massachusetts at Lowell in projects led by Professor Robert Lechner. This report describes one specific improvement of BDE: conversion of BDE diagrams to Graphics Interchange Format (GIF) files, as an option for BDE users to generate output files.
Previous versions of BDE saved PostScript versions of diagrams and converted Postcript to HTML using public-domain utilities. The two-person BDE2GIF team in 91.523 Spring 1997 worked on two direct conversion projects: one in the C/C++/X11 version of BDE, and another in the Java version of BDE. This is the final report on the C/C++ version by Yu-Kwong Wong.
Table of Contents
1. Introduction
2. Objective and Design of the Project
3. Implementation
4. Improvements
5. Testing
6. Testing Data
7. Flow Chart
8. Summary
Appendix A: Addendum to BDE User Guide
Appendix B: Changes to Source Code
Appendix C: Structure Chart Diagram
1. Introduction
The Block Diagram Edit (BDE) is a graphic user interface (GUI) based
application developed in the Department of Computer Science, University of
Massachusetts at Lowell leaded by Professor Robert Lechner. It is a powerful tool for
generating data and state models to describe object-oriented software designs graphically.
Graphics Interchange Format (GIF) is a graphics format adopted by many
applications. It is CompuServe's standard for defining generalized color raster images.
GIF allows graphics to be saved with 8-bit color and in good quality. Typical GIF file sizes are rather small compared to bitmap (BMP) or PostScript (PS) files. More
significant is that GIF is among a few default graphics formats adopted in popular web browsers.
BDE2GIF is a new menu option within BDE. It provides a crucial part of the interface between BDE and another project called bde2ht. Bde2ht converts a database of block diagrams into hyper-linked HTML files and image maps, which are linked to the images produced by BD2GIF and to other forms of documentation. This enables Web browsers to inspect, distribute and evemtually edit graphic documentation of program designs.
2. Objective and Design of the Project
The objective of Project BDE2GIF is to add new options to BDE's FILE menu that enable users to save either the currently displayed BDE diagram or the whole set of BDE diagrams as GIF files. The saved files should be in the correct format to be opened by any graphics viewer that supports GIF (all HTML browsers do).
. The menu options should be as easy to use as possible. BDE can store multiple related diagrams in a single file. GIF file names should permit identifying corresponding BDE data file and diagram names.
The project was designed to be implemented in the following steps:
(1) Modify an existed GIF encoder or write one to convert standard RGB bitmapped arrays into GIF format;
(2) Rewrite related classes and methods and add new methods to define and access the bitmapped images displayed in BDE's canvas window as RGB or Image arrays in memory for converting to GIF;
(3) Rewrite menu-related classes and methods for selecting new GIF print options.
3. Implementation
3.1 GIF Encoder:
Because C++/C/X11/Xm/Xt lib do not suport support any direct GIF file access
through pixel grab procedure and does not have funtions for direct encoding to graphics
format, Internet become a selected place to find some useful tools. A function called "GIFEncoder" was eventually found (in www.netcom.com). It was written by David Koblas (koblas@netcom.com) based upon ANSI C, After fixed some incompatiblity, it works well.
GIFEncoder is a funtion which takes either three byte arrays storing red (R), green
(G), and blue (B) or an Image class then retrieve RGB byte arrays. The RGB byte array then will be encoded into GIF format and saved to a stream. Several methods can be called inside application classes. Since the image need to be fully loaded to start and the conversion as well as encoding are actually processed in a pixel-grab way, the speed is comparably slower than PS saving where only strings are used.
3.2 Write new methods and modify old classes and methods to use GIFEncoder
The most important step to use GIFEncoder is to retrieve an Image class or to
derive RGB arrays directly. Because BDE is an interactive drawing application, this
Image or the RGB arrays must be able to access the most recently updated information based on user actions or any other events.
Based on these methods described above, therefore, new menu option Print_to_GIF was implemented by an action routine called print_gif(). Because it uses C instead of C++, it was written as a extern 'C' function and added to the BDE source code. It is called from method eventHandle() in class bdeAppletFrame. In this method, the current image or (optionally) a complete sequence of images is displayed on the screen. For each image the GIFEncoder is called to write the image to a separate output file in GIF format.
When "Print to GIF" is chosen, method print_gif will get images through a loop on the bdeGraph index and generate an associated GIF file inside the loop, then save each graph into its related GIF file respectively. These files are in GIF87a standard format.
The GIF file name is the BDE input diagram file name with the diagram number appended.This number has the form "HGvvnnnn" where vv is a version number and nnnn is a diagram number.
The utility GIFEncoder has to be listed as an imported library, and it will be automatically linked into the executable in BDE's Makefile.
3.3 Rearrange new items in menu bars and add event handling:
(1) Rearrange menu bars:
The original "Print..."(bde2java 96s523) was just for writing PS ( post script)
file. In the new version, Print... has two sub cascademenu bars:
Print To GIF
Print To PS
(2) Function:
call print_gif() and to print all graphs
(3) Others:
Message gave status of GIF saving has been added into the code so that user will
be informed when either the saving procedure starts or saving accomplished. Since GIF
file may need quite much time to process, this type of information displayed in terminal
or console seems very informative.
4 Improvement
Comparing with the prior method that used ps2gif:
(1) the new method fixed a 30 pixel offset in (x,y) coordinates from the "real gif".
(2) "arrow-heads now appear in the GIF diagram; these were previously missing due to a deficiency in the bde2PostScript converter).
5. Testing
The revised bde program was tested on the host 'neptune' (a vax platform) only. It is completely corrected. and the 97s523 bde2ht1 project team used this modified version to test their project.
6. Test data file: A BDE .dat file with 3 HG diagrams
Three sample GIF images were generated using the new BDE version as revised in this BDE2GIF project: The BDE data file defining these diagrams is in
/usr/proj3/case/97s523/bde2ht1/yuwong/bde/test/StateD.dat
The three output gif files are:
/usr/proj3/case/97s523/bde2ht1/yuwong/bde/test/StateDHG000001.gif
/usr/proj3/case/97s523/bde2ht1/yuwong/bde/test/StateDHG000002.gif
/usr/proj3/case/97s523/bde2ht1/yuwong/bde/test/StateDHG000003.gif
All file can be read in "xv" and netscape correctly , and these file are used in bde2ht1
project, which also works correctly.
7. Structure Chart Diagram
sld001.htmfSee /usr/proj3/case/97s523/bde2ht1/yuwong/bde/doc/flowHG000001.ps
8. Summary
GIF-saving capability has been added into BDE by the BDE2GIF project.
The revised program allow users to save any BDE graph interactively into GIF
format. Besides implementing GIF conversion, several other piece of code have been also
rewritten or modified to fix some problems.
Appendix A - Addendum to BDE User Guide
These instructions are complementary to the BDE User Guide and assume you already know how to use BDE.
1. Print Diagram(s) to GIF File:
Under menubar "File/Print" chose "Print to GIF": Bde then prompts the user to save the current diagram or to save all diagrams.
Both save procedures will name GIF files as data-file-nameHG#.gif, where data-file-name is the name of the BDE source data file without its '.dat' extension, and HG# is the diagram identifier that appears in bde's window during graphic browsing or editing.
Appendix B - Changes to Source Code
In menubar.cc, I modified following :
file = XmVaCreateSimplePulldownMenu(menubar,
"file_menu", 0, file_cb,
XmVaPUSHBUTTON, str1, 'N', "Ctrl<Key>n", str7,
XmVaPUSHBUTTON, str2, 'O', "Ctrl<Key>o", str8,
XmVaPUSHBUTTON, str3, 'S', "Ctrl<Key>s", str9,
XmVaPUSHBUTTON, str4, 'A', "Ctrl<Key>a", str10,
XmVaCASCADEBUTTON, str5, 'P',
//XmVaPUSHBUTTON, str5, 'P', "Ctrl<Key>p", str11,
XmVaSEPARATOR,
XmVaPUSHBUTTON, str6, 'E', "Ctrl<Key>q", str12,
NULL);
In menubar_cb.cc , I add following function
//////////////////////////////////////////////////////////////////////////////////////// // //
// Name : print_cb //
// Function : Call back for the `file' menu print-selection //
// //
////////////////////////////////////////////////////////////////////////////////////////
print_cb (Widget, XtPointer data, XmAnyCallbackStruct *)
{
char message[256];
int item = (int) data;
char *temp, hg_string[9];
hcg_key temp_key;
struct HG *HGcurr1;
switch(item){
case 0:
doPRINT(menubar, NULL , 0);
break;
case 1:
// following code copied from DisplayGraph function
// TBD: factor this out into a shared subroutine, if possible - RJL
node *lastnode;
hlink *lastlink;
caption *lastcaption;
caption *lastcaption;
HGcurr1 = HGcurr; //remember the current diagram
table_loop("94sbdeview", HG) {
clearObjects();
child_loop(HG,HN,HNid,HGid){
lastnode = new node(HNcurr);
child_loop(HN,HL,HLid1,HNid1){
lastlink = new hlink(HLcurr);
}
}
child_loop(HG,CG,CGid,HGid) {
lastcaption = new caption(CGcurr);
}
(void) new graph(HGcurr);
ReDraw();
SetStateOfGraphExistence( 1 );
UpdateTitleOfBDEWindow( current_filename, HGcurr->HGtitle );
print_gif(); // save this diagram as a .gif file
}
HGcurr = HGcurr1; // restore Hgcurr.
// TBChecked: I don't think HGcurr has changed - RJL
clearObjects();
: child_loop(HG,HN,HNid,HGid){
lastnode = new node(HNcurr);
child_loop(HN,HL,HLid1,HNid1){
lastlink = new hlink(HLcurr);
}
}
child_loop(HG,CG,CGid,HGid) {
lastcaption = new caption(CGcurr);
}
(void) new graph(HGcurr);
ReDraw();
SetStateOfGraphExistence( 1 );
UpdateTitleOfBDEWindow( current_filename, HGcurr->HGtitle );
break;
}
}
In fileio.cc, I added
int create_dialogbox()
{ XmString str1, str2;
void doPRINT();
str1 = XmStringCreateSimple("PS File Format");
str2 = XmStringCreateSimple("GIF File Format");
prndialog = XmVaCreateSimplePulldownMenu(fIle,
"PrintTo", 4, print,
XmVaPUSHBUTTON, str1, "G",NULL,NULL,
XmVaPUSHBUTTON, str2, "P",NULL,NULL,
NULL);
XmStringFree(str1); XmStringFree(str2);
}
Appendix C: Structure Chart Diagram