cdesktopenv/cde/programs/dtdocbook/infolib/GraphicsTask.C

319 lines
7.7 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: GraphicsTask.cc /main/8 1996/08/14 16:59:38 rcs $ */
#include <assert.h>
#include <sstream>
#include <iostream>
using namespace std;
#include <sys/types.h>
#include <netinet/in.h>
#include "GraphicsTask.h"
#include "Dispatch.h"
#include "FlexBuffer.h"
#include "OLAF.h"
#include "OL_Data.h"
#include "Token.h"
#include "SearchEng.h"
#include "BookTasks.h"
#include "NodeData.h"
#include "NodeTask.h"
#include "DataBase.h"
#include "BookCaseDB.h"
#ifndef DtinfoClient
#include "PostScript.h"
#endif
#include "SearchPath.h"
#include "utility/funcs.h"
#include <X11/XWDFile.h>
GR_TYPE gtype;
extern FILE *graphics_taskin;
extern void get_type ();
const int GR_ENCODING_TEXT = 1;
//-------------------------------------------------------------------------
#if __GNUC__ == 4 && __GNUC_MINOR__ == 4
GR_TYPE __attribute__((optimize("O0")))
#else
GR_TYPE
#endif
GraphicsTask::graphics_type( const char *gname )
{
gtype = GR_TYPE_UNKNOWN;
if ( !(graphics_taskin = fopen( gname, "r" )) ) {
throw(PosixError( errno, form("cannot open graphics file %s\n", gname)));
}
get_type();
if (gtype == GR_TYPE_UNKNOWN) {
if ((strstr(gname, ".cgm") != NULL) ||
(strstr(gname, ".CGM") != NULL))
{
gtype = GR_TYPE_CGM;
}
}
fclose(graphics_taskin);
// If the file is not cgm and if the lexer couldn't detect the graphics type,
// see if the graphic is an XWD file.
if (gtype == GR_TYPE_UNKNOWN) {
// Create header container
CARD32 header[sz_XWDheader];
XWDFileHeader *hdrptr;
FILE *fp;
if ( !(fp = fopen( gname, "r" )) ) {
throw(PosixError( errno,
form("cannot reopen graphics file %s\n", gname)));
}
hdrptr = (XWDFileHeader *)(void*)header;
// Initialize the structure
for (CARD32 ndx = 0; ndx < sz_XWDheader; ndx++) {
header[ndx] = (CARD32) 0;
}
if ( fread( &header[0], sizeof(*hdrptr), 1, fp ) == 1 ) {
// Normal fields into host byte-order
hdrptr->file_version = ntohl(hdrptr->file_version);
hdrptr->header_size = ntohl(hdrptr->header_size);
hdrptr->pixmap_width = ntohl(hdrptr->pixmap_width);
hdrptr->pixmap_height = ntohl(hdrptr->pixmap_height);
// Check some of the structure members to confirm the file type.
if ((hdrptr->file_version == XWD_FILE_VERSION) &&
(hdrptr->header_size > 0) &&
(hdrptr->pixmap_width > 0) &&
(hdrptr->pixmap_height > 0)) {
gtype = GR_TYPE_XWD;
}
}
fclose( fp );
}
return ( gtype );
}
//-------------------------------------------------------------------------
GraphicsTask::GraphicsTask( SearchEngine *parent, const Token &t )
{
f_base = t.level();
graphics_data = NULL;
f_parent = parent;
termsbuf = NULL;
f_title = 0;
if ( Dispatch::OutsideIgnoreScope() ) {
graphics_data = new OL_Data ( t, OLAF::OL_Graphic );
addSubTask( graphics_data );
if ( t.LookupAttr( OLAF::OL_Title ) ) {
f_title = new OL_Data(t, OLAF::OL_Title, IGNORE_ON );
if ( !f_title->DataWillBeAvailable() ) {
delete f_title;
f_title = 0;
}
else {
addSubTask(f_title);
}
}
}
}
//-------------------------------------------------------------------------
void
GraphicsTask::markup( const Token &t )
{
if ( f_base > 0 ) {
ComplexTask::markup( t );
if ( t.type() == START && !f_title ) {
if ( t.LookupAttr( OLAF::OL_Title ) ) {
f_title = new OL_Data(t, OLAF::OL_Title, IGNORE_ON );
if ( !f_title->DataWillBeAvailable() ) {
delete f_title;
f_title = 0;
}
else {
addSubTask(f_title);
}
}
}
if ( t.type() == END ) {
if ( Dispatch::OutsideIgnoreScope() ) {
if ( f_base == t.level() ) {
write_record( t );
KILLSUBTASK( graphics_data );
f_base = -1;
}
}
}
}
}
//-------------------------------------------------------------------------
void
GraphicsTask::write_record( const Token &t )
{
/*
* It is up to the client of graphics_data to determine how to
* interpret the content() , which will be treated as file name
*/
SearchPath *spath = Dispatch::GetSearchPath();
const char *file_name = graphics_data->content();
const char *grFileName = spath->get_real_path( file_name );
const char *bounding_box = "0.0.0.0";
GR_TYPE gr_type = GR_TYPE_UNKNOWN;
/*
* assuming that grFileName is actually corresponding to the
* final file where the graphical content is stored
*/
FlexBuffer graphics_buffer;
const char *size_info = NULL;
int graphics_available = 0;
FILE *gp;
if ( grFileName ) {
gp = fopen ( grFileName, "r" );
if ( gp ) {
graphics_available=1;
int c;
while ( ( c=getc(gp) ) != EOF ) {
graphics_buffer.put(c);
}
fclose(gp);
switch ( (gr_type = graphics_type( grFileName )) ) {
case GR_TYPE_UNKNOWN :
{
cerr << "(WARNING) Unsupported graphics type found in "
<< grFileName << endl
<< " It is included in file " << t.file() << endl
<< " at line " << t.line() << endl;
}
break;
case GR_TYPE_POSTSCRIPT :
{
#ifndef DtinfoClient
PostScript *ps_store = new PostScript( grFileName );
bounding_box = ps_store->GetBoundingBox();
if ( ps_store->HasSearchTerms() ) {
termsbuf = ps_store->GetTermsBuffer();
}
delete ps_store;
#else
cerr << "(WARNING) Unsupported PostScript graphic found in "
<< grFileName << endl
<< " It is included in file " << t.file() << endl
<< " at line " << t.line() << endl;
#endif
}
break;
default:
break;
}
size_info = form("%d.%d.%s",
gr_type,
GR_ENCODING_TEXT,
bounding_box );
}
}
else {
cerr << "(WARNING) graphical file = " << file_name << endl
<< " included in file = " << t.file() << endl
<< " at line = " << t.line() << endl
<< " is not found, a zero length graphical data is used\n\n";
}
/* dump the graphics record */
NodeData *nodeData = f_parent->node_data();
const char *gid = nodeData->graphics_id();
BookTask *book = nodeData->node()->book();
const char *bookLocator = book->locator();
DBTable *gtab = book->bookcase()->table(BookCaseDB::Graphics);
gtab->insert( STRING_CODE, bookLocator,
STRING_CODE, gid,
STRING_CODE, "",
STRING_CODE, "v0",
STRING_CODE, graphics_available?size_info : "0.0.0.0.0.0",
-STRING_CODE, graphics_buffer.GetBuffer(),
(size_t)graphics_buffer.GetSize(),
STRING_CODE, f_title?f_title->content():"",
NULL);
/*
if ( compress ) {
gtab->insert(STRING_CODE, gid,
STRING_CODE, "@@ graphcis name",
STRING_CODE, "v0",
STRING_CODE, "@@ type info",
COMPRESSED_STRING_CODE, "@@ CompressedAgent",
-STRING_CODE, graphics_buffer.GetBuffer(),
(size_t)graphics_buffer.GetBSize(),
STRING_CODE, "@@ graphics title" );
}
*/
}