On Wednesday 27 February 2002 12:55 pm, Edwin Leuven wrote:
> > What I find interesting is
> > 2 I've been requesting testers for days. I have to put this thing in cvs
> > and inflict pain to make progress :-(
> 
> The only way to progress. Let's delete the xforms code...I'll bet 
> we'll have a nice qt2 frontend in no time. If only I had free cvs access....
> 
> Ed.

;-)

There is no xforms code in the graphics directory. There is an image loader 
that uses libXPM to do the hard work. There is also an abstract base class in 
GraphicsImage.h that could be used to create an image loader using the qt2 
libraries.

Just change GraphicsCache.C and away you go! I append 
xformsGraphicsImage.[Ch] so you can get the general idea. Note that this 
doesn't actually work, unless you have xforms 0.89.x (where x is currently 
unknown but is > 0!) but that's not the point!

Angus


// I think that graphicsInit should become a new Dialogs::graphicsInit 
// static method.
// These #includes would then be moved to Dialogs.C.
// Angus 25 Feb 2002
#include "GraphicsImageXPM.h"
//#include "xformsGraphicsImage.h"

namespace {

void graphicsInit() 
{
        using namespace grfx;
        using SigC::slot;
    
        // connect the image loader based on the XPM library
        GImage::newImage.connect(slot(&GImageXPM::newImage));
        GImage::loadableFormats.connect(slot(&GImageXPM::loadableFormats));
        // connect the image loader based on the xforms library
//      GImage::newImage.connect(slot(&xformsGImage::newImage));
//      GImage::loadableFormats.connect(slot(&xformsGImage::loadableFormats));
}
    
} // namespace anon
/*
 * \file xformsGraphicsImage.C
 * Copyright 2002 the LyX Team
 * Read the file COPYING
 *
 * \author Angus Leeming <[EMAIL PROTECTED]>
 */

#include <config.h>

#ifdef __GNUG__
#pragma implementation
#endif

#include "xformsGraphicsImage.h"
#include "GraphicsParams.h"
#include "ColorHandler.h"
#include "debug.h"
#include "support/lstrings.h"
#include "support/LAssert.h"
#include "Lsstream.h"

// Duplicate old_image
// Doesn't appear in older versions of forms.h
// FL_IMAGE *flimage_dup(FL_IMAGE *old_image);

namespace grfx {

namespace {

bool init_graphics_ = false;
	
void init_graphics();
 
} // namespace anon

/// Access to this class is through this static method.
ImagePtr xformsGImage::newImage()
{
	if (!init_graphics_)
		init_graphics();

	ImagePtr ptr;
	ptr.reset(new xformsGImage());
	return ptr;
}
	

/// Return the list of loadable formats.
GImage::FormatList xformsGImage::loadableFormats()
{
	if (!init_graphics_)
		init_graphics();

	int const nformats = flimage_get_number_of_formats();
	
	FormatList formats(nformats);
	for (int i = 0; i < nformats; ++i) {	
		// don't forget the Fortran numbering used by xforms!
		formats[i] = flimage_get_format_info(i+1)->extension;
	}
	return formats;
}
 

xformsGImage::xformsGImage()
	: image_(0)
{}


xformsGImage::xformsGImage(xformsGImage const & other)
	: GImage(other),
	  image_(0)
{
	// Create a copy of the image_. It is this that will
	// be modified, not the original image.
	// Note that only recent versions of xforms 0.89 have
	// flimage_dup
	if (other.image_)
		image_ = flimage_dup(other.image_);
}


xformsGImage::~xformsGImage()
{
	if (image_)
		flimage_free(image_);
}


GImage * xformsGImage::clone() const
{
	return new xformsGImage(*this);
}


unsigned int xformsGImage::getWidth() const
{
	if (!image_)
		return 0;
	return image_->w;
}


unsigned int xformsGImage::getHeight() const
{
	if (!image_)
		return 0;
	return image_->h;
}


Pixmap xformsGImage::getPixmap() const
{
	if (!image_)
		return 0;

	return image_->pixmap;
}


void xformsGImage::load(string const & filename, GImage::SignalTypePtr on_finish)
{
	if (image_) {
		lyxerr[Debug::GRAPHICS]
			<< "Image is loaded already!" << std::endl;
		on_finish->emit(false);
		return;
	}

	image_ = flimage_open(filename.c_str());
	if (!image_) {
		lyxerr[Debug::GRAPHICS]
			<< "Unable to open image" << std::endl;
		on_finish->emit(false);
		return;
	}

	// Store the Signal that will be emitted once the image is loaded.
	on_finish_ = on_finish;

	image_->u_vdata = this;
	flimage_read(image_);
}


bool xformsGImage::setPixmap(GParams const & params)
{
	if (!image_ || params.display == GParams::NONE) {
		return false;
	}

	int color_key;
	switch (params.display) {
	case GParams::MONOCHROME:
		color_key = FL_IMAGE_MONO;
		break;
	case GParams::GRAYSCALE:
		color_key = FL_IMAGE_GRAY;
		break;
	case GParams::COLOR:
	default: // NONE cannot happen!
		color_key = FL_IMAGE_RGB;
		break;
	}

	//image->fill_color = FL_PACK(255,255,0);
	image_->fill_color =
		int(lyxColorHandler->colorPixel(LColor::graphicsbg));

	flimage_convert(image_, color_key, 0);
	return true;
}


void xformsGImage::clip(GParams const & params)
{
	if (!image_)
		return;

	if (params.bb.empty())
		// No clipping is necessary.
		return;
		
	int const new_width  = params.bb.xr - params.bb.xl;
	int const new_height = params.bb.yt - params.bb.yb;

	if (new_width  > image_->w || new_height > image_->h)
		// Bounds are invalid.
		return;

	if (new_width  == image_->w && new_height == image_->h)
		// Bounds are unchanged.
		return;

	flimage_crop(image_,
		     params.bb.xl, params.bb.yt, params.bb.xr, params.bb.yb);
}


void xformsGImage::rotate(GParams const & params)
{
	if (!image_)
		return ;

	if (!params.angle)
		// No rotation is necessary.
		return;

	// The angle passed to flimage_rotate is the angle in one-tenth of a
	// degree units.
	flimage_rotate(image_, params.angle * 10, FLIMAGE_SUBPIXEL);
}


void xformsGImage::scale(GParams const & params)
{
	if (!image_)
		return;

	// boost::tie produces horrible compilation errors on my machine
	// Angus 25 Feb 2002
	std::pair<unsigned int, unsigned int> d = getScaledDimensions(params);
	unsigned int const width  = d.first;
	unsigned int const height = d.second;
	if (width == getWidth() && height == getHeight())
		// No scaling needed
		return;

	flimage_scale(image_, width, height, FLIMAGE_SUBPIXEL);
}


void xformsGImage::statusCB(string const & status_message)
{
	if (status_message.empty() || !on_finish_.get())
		return;

	if (prefixIs(status_message, "Done Reading")) {
		on_finish_->emit(true);
		on_finish_.reset();
	}
}

void xformsGImage::errorCB(string const & error_message)
{
	if (error_message.empty() || !on_finish_.get())
		return;

	on_finish_->emit(false);
	on_finish_.reset();
}

namespace {

extern "C" {
	
int status_report(FL_IMAGE * ob, const char *s)
{
	lyx::Assert(ob && ob->u_vdata);

	if (s) {
		lyxerr[Debug::GRAPHICS]
			<< "xforms image loader. Status : " << s << std::endl;
	}

	grfx::xformsGImage * ptr =
		static_cast<grfx::xformsGImage *>(ob->u_vdata);
	ptr->statusCB(s);
	
	return 0;
}


static void error_report(FL_IMAGE * ob, const char *s)
{
	lyx::Assert(ob && ob->u_vdata);

	if (s) {
		lyxerr[Debug::GRAPHICS]
			<< "xforms image loader. Error : " << s << std::endl;
	}

	grfx::xformsGImage * ptr =
		static_cast<grfx::xformsGImage *>(ob->u_vdata);
	ptr->errorCB(s);
}

} // extern "C"
	

void init_graphics()
{
	init_graphics_ = true;

	FLIMAGE_SETUP setup;
	setup.visual_cue    = status_report;
	setup.error_message = error_report;
	flimage_setup(&setup);

//  	flimage_enable_bmp();
//  	flimage_enable_fits();
//  	flimage_enable_gif();
//  #ifndef NO_JPEG
//  	flimage_enable_jpeg();
//  #endif
//  	flimage_enable_png();
//  	flimage_enable_pnm();
//  	flimage_enable_sgi();
//  	flimage_enable_tiff();
//  	flimage_enable_xbm();
	flimage_enable_xpm();
//  	flimage_enable_xwd();
}
	
} // namespace anon

} // namespace grfx
// -*- C++ -*-
/**
 *  \file xformsGraphicsImage.h
 *  Copyright 2002 the LyX Team
 *  Read the file COPYING
 *
 *  \author Angus Leeming <[EMAIL PROTECTED]>
 *
 *  An instantiation of GImage that makes use of the xforms lirary routines
 *  to load and store the image in memory.
 */

#ifndef XFORMS_GRAPHICSIMAGE_H
#define XFORMS_GRAPHICSIMAGE_H

#include "GraphicsImage.h"
#include FORMS_H_LOCATION

#ifdef __GNUG__
#pragma interface
#endif

namespace grfx {

class xformsGImage : public GImage
{
public:
	/// Access to this class is through this static method.
	static ImagePtr newImage();

	/// Return the list of loadable formats.
	static FormatList loadableFormats();

	///
	~xformsGImage();

	/// Create a copy
	GImage * clone() const;

	///
	Pixmap getPixmap() const;

	/// Get the image width
	unsigned int getWidth() const;
	
	/// Get the image height
	unsigned int getHeight() const;

	/** Load the image file into memory.
	 *  In this case (GImageXPM), the process is blocking.
	 */
	void load(string const & filename, SignalTypePtr);

	/** Generate the pixmap, based on the current state of the
	 *  xpm_image_ (clipped, rotated, scaled etc).
	 *  Uses the params to decide on color, grayscale etc.
	 *  Returns true if the pixmap is created.
	 */
	bool setPixmap(GParams const & params);

	/// Clip the image using params.
	void clip(GParams const & params);
	
	/// Rotate the image using params.
	void rotate(GParams const & params);
	
	/// Scale the image using params.
	void scale(GParams const & params);

	///
	void statusCB(string const &);
	///
	void errorCB(string const &);

private:
	/// Access to the class is through newImage() and clone.
	xformsGImage();
	///
	xformsGImage(xformsGImage const &);

	/// The xforms container.
	FL_IMAGE * image_;

	/// Emit this signal when the loading process is finished.
	GImage::SignalTypePtr on_finish_;
};

} // namespace grfx

#endif // XFORMS_GRAPHICSIMAGE_H

Reply via email to