Add an image loader using the xforms library routines and compile it if

your version of the xforms library is good enough.
The qt2 stuff is only partially tested (link problems elsewhere) and
the gnome stuff is not tested at all.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3676 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2002-03-06 12:07:23 +00:00
parent e154cde323
commit 4c263b730e
17 changed files with 673 additions and 11 deletions

View File

@ -1,3 +1,8 @@
2002-03-05 Angus Leeming <a.leeming@ic.ac.uk>
* configure.in: compile the xforms image loader if your version of the
xforms libraries is up to the task, else use the basic alternative.
2002-03-04 Lars Gullik Bjønnes <larsbj@birdstep.com>
* configure.in: help qt2 along a bit

View File

@ -1,3 +1,8 @@
2002-03-06 Angus Leeming <a.leeming@ic.ac.uk>
* lyxinclude.m4 (LYX_USE_XFORMS_IMAGE_LOADER): test whether the
xforms libraries can be used to load images into LyX.
2002-02-28 Jean-Marc Lasgouttes <lasgouttes@freesurf.fr>
* lyxinclude.m4 (LYX_PROG_CXX): use -dumpversion instead of

View File

@ -980,3 +980,19 @@ AM_PROG_LIBTOOL dnl for libraries
CC=$ac_save_cc
CFLAGS="$ac_save_cflags"
])
### Check whether the xforms library has a viable image loader
AC_DEFUN(LYX_USE_XFORMS_IMAGE_LOADER,
[
TEMP_LDFLAGS=$LDFLAGS
LDFLAGS=$XFORMS_LIB $LDFLAGS
lyx_use_xforms_image_loader=no
AC_CHECK_FUNCS(flimage_dup,[
AC_CHECK_FUNCS(flimage_to_pixmap,[
lyx_use_xforms_image_loader=yes
AC_CHECK_FUNCS(flimage_enable_ps)])])
LDFLAGS=$TEMP_LDFLAGS
])

View File

@ -251,6 +251,16 @@ LYX_ERROR(dnl
the development tools.])
fi
### Check whether the xforms library has a viable image loader
### For now, run this test always so config.h is unchanged by a change in
### frontend
LYX_USE_XFORMS_IMAGE_LOADER
### If the gui cannot load images itself, then we default to the
### very simple one in graphics/GraphicsImageXPM.[Ch]
AM_CONDITIONAL(USE_BASIC_IMAGE_LOADER,
test x$lyx_use_xforms_image_loader = xno)
### Setup GNU gettext
dnl GNU gettext is written in C
AC_LANG_C

View File

@ -1,3 +1,10 @@
2002-03-05 Angus Leeming <a.leeming@ic.ac.uk>
* GUIRunTime.C (initialiseGraphics): use the xforms image loader if
your version of the xforms libraries is up to the task.
* Makefile.am: link in the xforms image loader if so configured.
2002-03-04 Angus Leeming <a.leeming@ic.ac.uk>
* Dialogs.C (redrawGUI): removed to frontends/Dialogs.C

View File

@ -1,3 +1,4 @@
/* This file is part of
* ======================================================
*
@ -21,7 +22,13 @@
#include <gnome--/main.h>
#include <glade/glade.h>
// For now we use the xforms image loader if we can.
// In the future, this will be replaced by a gnome equivalent.
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
#include "xforms/xformsGImage.h"
#else
#include "graphics/GraphicsImageXPM.h"
#endif
using std::endl;
@ -130,16 +137,22 @@ LyXView * GUIRunTime::createMainView(int w, int h)
}
// Called bu the graphics cache to connect the approriate frontend
// Called by the graphics cache to connect the appropriate frontend
// image loading routines to the LyX kernel.
void GUIRunTime::initialiseGraphics()
{
using namespace grfx;
using SigC::slot;
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
// connect the image loader based on the xforms library
GImage::newImage.connect(slot(&xformsGImage::newImage));
GImage::loadableFormats.connect(slot(&xformsGImage::loadableFormats));
#else
// connect the image loader based on the XPM library
GImage::newImage.connect(slot(&GImageXPM::newImage));
GImage::loadableFormats.connect(slot(&GImageXPM::loadableFormats));
#endif
}

View File

@ -15,6 +15,11 @@ INCLUDES = ${FRONTEND_INCLUDES} -I${top_srcdir}/src/ \
#libgnome_la_LIBADD = \
# @FRONTEND_LDFLAGS@ @FRONTEND_LIBS@
if USE_BASIC_IMAGE_LOADER
else
XFORMSGIMAGE = ../xforms/xformsGImage.lo
endif
xforms_objects = \
../xforms/xforms_helpers.lo \
../xforms/Toolbar_pimpl.lo \
@ -28,7 +33,7 @@ xforms_objects = \
../xforms/FormMathsSpace.lo \
../xforms/DropDown.lo \
../xforms/Alert_pimpl.lo \
../xforms/Menubar_pimpl.lo
$(XFORMSGIMAGE) ../xforms/Menubar_pimpl.lo
libgnome.la: xforms.lo $(libgnome_la_OBJECTS) $(libgnome_la_DEPENDENCIES)

View File

@ -1,3 +1,10 @@
2002-03-05 Angus Leeming <a.leeming@ic.ac.uk>
* GUIRunTime.C (initialiseGraphics): use the xforms image loader if
your version of the xforms libraries is up to the task.
* xforms/Makefile.am: link in the xforms image loader if so configured.
2002-03-04 Angus Leeming <a.leeming@ic.ac.uk>
* Dialogs.C (redrawGUI): removed to frontends/Dialogs.C

View File

@ -19,10 +19,17 @@
#include "XFormsView.h"
#include "GUIRunTime.h"
#include "debug.h"
#include "graphics/GraphicsImageXPM.h"
#include FORMS_H_LOCATION
// For now we use the xforms image loader if we can.
// In the future, this will be replaced by a Qt equivalent.
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
#include "xforms/xformsGImage.h"
#else
#include "graphics/GraphicsImageXPM.h"
#endif
using std::endl;
// For now we need this here as long as we use xforms components!
@ -91,16 +98,22 @@ LyXView * GUIRunTime::createMainView(int w, int h)
}
// Called bu the graphics cache to connect the approriate frontend
// Called by the graphics cache to connect the appropriate frontend
// image loading routines to the LyX kernel.
void GUIRunTime::initialiseGraphics()
{
using namespace grfx;
using SigC::slot;
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
// connect the image loader based on the xforms library
GImage::newImage.connect(slot(&xformsGImage::newImage));
GImage::loadableFormats.connect(slot(&xformsGImage::loadableFormats));
#else
// connect the image loader based on the XPM library
GImage::newImage.connect(slot(&GImageXPM::newImage));
GImage::loadableFormats.connect(slot(&GImageXPM::loadableFormats));
#endif
}

View File

@ -12,6 +12,13 @@ INCLUDES = -I${top_srcdir}/src/ -I${top_srcdir}/src/frontends/ \
LIBS=
ETAGS_ARGS = --lang=c++
EXTRA_DIST = xformsGImage.C xformsGImage.h
if USE_BASIC_IMAGE_LOADER
else
XFORMSGIMAGE = xformsGImage.C xformsGImage.h
endif
libqt2xforms_la_SOURCES = \
bmtable.h \
bmtable.c \
@ -81,14 +88,14 @@ libqt2xforms_la_SOURCES = \
form_maths_style.C \
input_validators.h \
input_validators.C \
xformsBC.h \
$(XFORMSGIMAGE) xformsBC.h \
xformsBC.C \
xforms_helpers.h \
xforms_helpers.C
libqt2xforms.la: link_files $(XFORMS_SOURCES)
libqt2xforms.la: link_files $(libqt2xforms_la_SOURCES)
link_files:
for i in $(XFORMS_SOURCES); do \
for i in $(libqt2xforms_la_SOURCES); do \
ln -sf "${top_srcdir}/src/frontends/xforms/$$i" . ; \
done

View File

@ -1,3 +1,13 @@
2002-03-05 Angus Leeming <a.leeming@ic.ac.uk>
* xformsGImage.[Ch]: new files. An image loader based on xforms library
routines.
* GUIRunTime.C (initialiseGraphics): use the xforms image loader if
your version of the xforms libraries is up to the task.
* Makefile.am: compile the xforms image loader if so configured.
2002-03-04 Angus Leeming <a.leeming@ic.ac.uk>
* Dialogs.C (redrawGUI): removed to frontends/Dialogs.C

View File

@ -18,7 +18,12 @@
#include "GUIRunTime.h"
#include "XFormsView.h"
#include "debug.h"
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
#include "xformsGImage.h"
#else
#include "graphics/GraphicsImageXPM.h"
#endif
// I keep these here so that it will be processed as early in
// the compilation process as possible.
@ -134,9 +139,15 @@ void GUIRunTime::initialiseGraphics()
using namespace grfx;
using SigC::slot;
#if defined(HAVE_FLIMAGE_DUP) && defined(HAVE_FLIMAGE_TO_PIXMAP)
// connect the image loader based on the xforms library
GImage::newImage.connect(slot(&xformsGImage::newImage));
GImage::loadableFormats.connect(slot(&xformsGImage::loadableFormats));
#else
// connect the image loader based on the XPM library
GImage::newImage.connect(slot(&GImageXPM::newImage));
GImage::loadableFormats.connect(slot(&GImageXPM::loadableFormats));
#endif
}

View File

@ -10,6 +10,14 @@ INCLUDES = -I${top_srcdir}/images -I${top_srcdir}/src/ \
LIBS=
LYXDATADIRS = forms
ETAGS_ARGS = --lang=c++
EXTRA_DIST = xformsGImage.C xformsGImage.h
if USE_BASIC_IMAGE_LOADER
else
XFORMSGIMAGE = xformsGImage.C xformsGImage.h
endif
# Alphabetical order please. It makes it easier to figure out what's missing.
libxforms_la_SOURCES = \
Alert_pimpl.C \
@ -198,7 +206,7 @@ libxforms_la_SOURCES = \
Tooltips.h \
xforms_helpers.C \
xforms_helpers.h \
xformsBC.C \
$(XFORMSGIMAGE) xformsBC.C \
xformsBC.h
# These still have to be added. Sooner or later. ARRae-20000411

View File

@ -0,0 +1,429 @@
/*
* \file xformsGImage.C
* Copyright 2002 the LyX Team
* Read the file COPYING
*
* \author Angus Leeming <a.leeming@ic.ac.uk>
*/
#include <config.h>
#ifdef __GNUG__
#pragma implementation
#endif
#include "xformsGImage.h"
#include "graphics/GraphicsParams.h"
#include "LColor.h"
#include "converter.h" // formats
#include "debug.h"
#include "frontends/GUIRunTime.h" // x11Display, x11Screen
#include "support/LAssert.h"
#include "support/lyxfunctional.h" // compare_memfun
using std::find_if;
namespace {
void init_graphics();
unsigned int packedcolor(LColor::color c);
} // namespace anon
namespace grfx {
/// Access to this class is through this static method.
ImagePtr xformsGImage::newImage()
{
init_graphics();
ImagePtr ptr;
ptr.reset(new xformsGImage());
return ptr;
}
/// Return the list of loadable formats.
GImage::FormatList xformsGImage::loadableFormats()
{
static FormatList fmts;
if (!fmts.empty())
return fmts;
init_graphics();
// The formats recognised by LyX
Formats::const_iterator begin = formats.begin();
Formats::const_iterator end = formats.end();
lyxerr[Debug::GRAPHICS]
<< "\nThe image loader can load the following directly:\n";
// Don't forget the Fortran numbering used by xforms!
int const nformats = flimage_get_number_of_formats();
for (int i = 1; i <= nformats; ++i) {
FLIMAGE_FORMAT_INFO const * info = flimage_get_format_info(i);
string const formal_name =
info->formal_name ? info->formal_name : string();
string ext =
info->extension ? info->extension : string();
if (ext.empty() || ext == "gz")
continue;
if (ext == "rgb") ext = "sgi";
lyxerr[Debug::GRAPHICS]
<< formal_name << ", extension \"" << ext << "\"\n";
Formats::const_iterator it =
find_if(begin, end,
lyx::compare_memfun(&Format::extension, ext));
if (it != end)
fmts.push_back(it->name());
}
lyxerr[Debug::GRAPHICS]
<< "\nOf these, LyX recognises the following formats:\n";
FormatList::const_iterator fbegin = fmts.begin();
FormatList::const_iterator fend = fmts.end();
for (FormatList::const_iterator fit = fbegin; fit != fend; ++fit) {
if (fit != fbegin)
lyxerr[Debug::GRAPHICS] << ", ";
lyxerr[Debug::GRAPHICS] << *fit;
}
lyxerr[Debug::GRAPHICS] << '\n' << std::endl;
return fmts;
}
xformsGImage::xformsGImage()
: image_(0),
pixmap_(0),
pixmap_status_(PIXMAP_UNINITIALISED)
{}
xformsGImage::xformsGImage(xformsGImage const & other)
: GImage(other),
image_(0),
pixmap_(0),
pixmap_status_(PIXMAP_UNINITIALISED)
{
if (other.image_) {
image_ = flimage_dup(other.image_);
image_->u_vdata = this;
}
}
xformsGImage::~xformsGImage()
{
if (image_)
flimage_free(image_);
if (pixmap_)
XFreePixmap(GUIRunTime::x11Display(), pixmap_);
}
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 (!pixmap_status_ == PIXMAP_SUCCESS)
return 0;
return pixmap_;
}
void xformsGImage::load(string const & filename, 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;
// Set this now and we won't need to bother again.
image_->fill_color = packedcolor(LColor::graphicsbg);
// Used by the callback routines to return to this
image_->u_vdata = this;
// Begin the reading process.
flimage_read(image_);
}
bool xformsGImage::setPixmap(GParams const & params)
{
if (!image_ || params.display == GParams::NONE)
return false;
Display * display = GUIRunTime::x11Display();
if (pixmap_ && pixmap_status_ == PIXMAP_SUCCESS)
XFreePixmap(display, pixmap_);
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;
}
if (color_key != FL_IMAGE_RGB) {
flimage_convert(image_, color_key, 0);
}
unsigned int fill = packedcolor(LColor::graphicsbg);
if (fill != image_->fill_color) {
// the background color has changed.
// Note that in grayscale/monochrome images the background is
// grayed also, so this call will have no visible effect. Sorry!
flimage_replace_pixel(image_, image_->fill_color, fill);
image_->fill_color = fill;
}
image_->xdisplay = display;
Screen * screen = ScreenOfDisplay(display, GUIRunTime::x11Screen());
pixmap_ = flimage_to_pixmap(image_, XRootWindowOfScreen(screen));
pixmap_status_ = pixmap_ ? PIXMAP_SUCCESS : PIXMAP_FAILED;
return pixmap_status_ == PIXMAP_SUCCESS;
}
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;
int const xoffset_l = params.bb.xl;
int const xoffset_r = image_->w - params.bb.xr;
int const yoffset_t = image_->h - params.bb.yt;
int const yoffset_b = params.bb.yb;
flimage_crop(image_, xoffset_l, yoffset_t, xoffset_r, yoffset_b);
}
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 grfx
namespace {
extern "C" {
int status_report(FL_IMAGE * ob, const char *s)
{
lyx::Assert(ob && ob->u_vdata);
string const str = s ? strip(s) : string();
if (str.empty())
return 0;
lyxerr[Debug::GRAPHICS]
<< "xforms image loader. Status : " << str << std::endl;
grfx::xformsGImage * ptr =
static_cast<grfx::xformsGImage *>(ob->u_vdata);
ptr->statusCB(str);
return 0;
}
static void error_report(FL_IMAGE * ob, const char *s)
{
lyx::Assert(ob && ob->u_vdata);
string const str = s ? strip(s) : string();
if (str.empty())
return;
lyxerr[Debug::GRAPHICS]
<< "xforms image loader. Error : " << str << std::endl;
grfx::xformsGImage * ptr =
static_cast<grfx::xformsGImage *>(ob->u_vdata);
ptr->errorCB(str);
}
} // extern "C"
void init_graphics()
{
// Paranoia check
static bool initialised = false;
if (initialised)
return;
initialised = true;
flimage_enable_bmp();
flimage_enable_fits();
flimage_enable_gif();
flimage_enable_jpeg();
// xforms itself uses pngtopnm to convert to a loadable format.
// We prefer to use our own conversion mechanism, therefore.
// flimage_enable_png();
flimage_enable_pnm();
#ifdef HAVE_FLIMAGE_ENABLE_PS
// xforms recognises PS but not EPS
flimage_enable_ps();
#endif
flimage_enable_sgi();
flimage_enable_tiff();
flimage_enable_xbm();
flimage_enable_xwd();
flimage_enable_xpm();
FLIMAGE_SETUP setup;
setup.visual_cue = status_report;
setup.error_message = error_report;
flimage_setup(&setup);
}
unsigned int packedcolor(LColor::color c)
{
string const x11color = lcolor.getX11Name(c);
Display * display = GUIRunTime::x11Display();
Colormap cmap = GUIRunTime::x11Colormap();
XColor xcol;
XColor ccol;
if (XLookupColor(display, cmap, x11color.c_str(), &xcol, &ccol) == 0)
// Unable to parse x11color.
return FL_PACK(255,255,255);
// Note that X stores the RGB values in the range 0 - 65535
// whilst we require them in the range 0 - 255.
unsigned int const r = xcol.red / 256;
unsigned int const g = xcol.green / 256;
unsigned int const b = xcol.blue / 256;
return FL_PACK(r, g, b);
}
} // namespace anon

View File

@ -0,0 +1,106 @@
// -*- C++ -*-
/**
* \file xformsGImage.h
* Copyright 2002 the LyX Team
* Read the file COPYING
*
* \author Angus Leeming <a.leeming@ic.ac.uk>
*
* 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
#ifdef __GNUG__
#pragma interface
#endif
#include "graphics/GraphicsImage.h"
#include FORMS_H_LOCATION
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.
* The process is asynchronous, so this method starts the loading
* and saves the signal. It is emitted once loading is finished.
*/
void load(string const & filename, SignalTypePtr);
/** Generate the pixmap, based on the current state of
* 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);
/// Internal callbacks.
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_;
/// The pixmap itself.
Pixmap pixmap_;
/// Is the pixmap initialized?
enum PixmapStatus {
///
PIXMAP_UNINITIALISED,
///
PIXMAP_FAILED,
///
PIXMAP_SUCCESS
};
PixmapStatus pixmap_status_;
/// Emit this signal when the loading process is finished.
GImage::SignalTypePtr on_finish_;
};
} // namespace grfx
#endif // XFORMS_GRAPHICSIMAGE_H

View File

@ -1,3 +1,9 @@
2002-03-05 Angus Leeming <a.leeming@ic.ac.uk>
* Makefile.am: if there is no image loading class leveraging the power
of the appropriate gui library, then compile the basic alternative
found in GraphicsImageXPM.[Ch].
2002-03-04 Angus Leeming <a.leeming@ic.ac.uk>
* GraphicsCache.C: change associated with move of initialiseGraphics

View File

@ -7,6 +7,12 @@ ETAGS_ARGS = --lang=c++
BOOST_INCLUDES = -I$(top_srcdir)/boost
INCLUDES = -I${srcdir}/../ $(SIGC_CFLAGS) $(BOOST_INCLUDES)
EXTRA_DIST = GraphicsImageXPM.C GraphicsImageXPM.h
if USE_BASIC_IMAGE_LOADER
GRAPHICSIMAGEXPM = GraphicsImageXPM.C GraphicsImageXPM.h
endif
libgraphics_la_SOURCES = \
GraphicsCache.h \
GraphicsCache.C \
@ -16,9 +22,7 @@ libgraphics_la_SOURCES = \
GraphicsConverter.C \
GraphicsImage.h \
GraphicsImage.C \
GraphicsImageXPM.h \
GraphicsImageXPM.C \
GraphicsParams.C \
$(GRAPHICSIMAGEXPM) GraphicsParams.C \
GraphicsParams.h \
GraphicsTypes.h