mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-09-21 07:12:10 +00:00
Asymptotic approach to a well-designed graphics loader.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4502 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
c3a3e12319
commit
888532c465
@ -1,3 +1,9 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* Painter.h:
|
||||
* screen.C: changes associated with the name change grfx::GImage ->
|
||||
grfx::Image.
|
||||
|
||||
2002-06-26 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* screen.C: moved the image loading stuff into a new class grfx::Loader.
|
||||
|
@ -21,7 +21,7 @@
|
||||
class LyXFont;
|
||||
|
||||
namespace grfx {
|
||||
class GImage;
|
||||
class Image;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,7 +133,7 @@ public:
|
||||
/// draw an image from the image cache
|
||||
virtual Painter & image(int x, int y,
|
||||
int w, int h,
|
||||
grfx::GImage const & image) = 0;
|
||||
grfx::Image const & image) = 0;
|
||||
|
||||
/// draw a string at position x, y (y is the baseline)
|
||||
virtual Painter & text(int x, int y,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* ControlGraphics.C: changes associated with the name changes
|
||||
grfx::GCache -> grfx::Cache and grfx::GImage -> grfx::Image.
|
||||
|
||||
2002-06-25 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* ControlGraphics.C (readBB): Channges associated with the changed
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "lyxrc.h"
|
||||
|
||||
#include "graphics/GraphicsCache.h"
|
||||
#include "graphics/GraphicsConverter.h"
|
||||
#include "graphics/GraphicsCacheItem.h"
|
||||
#include "graphics/GraphicsImage.h"
|
||||
|
||||
#include "insets/insetgraphics.h"
|
||||
@ -114,12 +114,14 @@ string const ControlGraphics::readBB(string const & file)
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
grfx::GCache & gc = grfx::GCache::get();
|
||||
grfx::ImagePtr const image = gc.image(abs_file);
|
||||
grfx::Cache & gc = grfx::Cache::get();
|
||||
if (gc.inCache(abs_file)) {
|
||||
grfx::Image const * image = gc.item(abs_file)->image();
|
||||
|
||||
if (image.get()) {
|
||||
width = image->getWidth();
|
||||
height = image->getHeight();
|
||||
if (image) {
|
||||
width = image->getWidth();
|
||||
height = image->getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
return ("0 0 " + tostr(width) + ' ' + tostr(height));
|
||||
|
@ -1,3 +1,8 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* QLPainter.[Ch]: changes associated with the name change
|
||||
grfx::GImage -> grfx::Image.
|
||||
|
||||
2002-06-21 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* Menubar_pimpl.C (c-tor): rename MenuBackend const & mb argument to
|
||||
|
@ -186,7 +186,7 @@ Painter & QLPainter::arc(int x, int y,
|
||||
|
||||
Painter & QLPainter::image(int , int ,
|
||||
int , int ,
|
||||
grfx::GImage const & )
|
||||
grfx::Image const & )
|
||||
{
|
||||
#if 0 // FIXME
|
||||
XGCValues val;
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
/// draw an image from the image cache
|
||||
virtual Painter & image(int x, int y,
|
||||
int w, int h,
|
||||
grfx::GImage const & image);
|
||||
grfx::Image const & image);
|
||||
|
||||
/// draw a string at position x, y (y is the baseline)
|
||||
virtual Painter & text(int x, int y,
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
/// This is a singleton class. Get the instance.
|
||||
static SplashScreen const & get();
|
||||
///
|
||||
grfx::GImage const * image() const { return loader_.image(); }
|
||||
grfx::Image const * image() const { return loader_.image(); }
|
||||
///
|
||||
string const & text() const { return text_; }
|
||||
///
|
||||
@ -376,7 +376,7 @@ void LyXScreen::greyOut()
|
||||
|
||||
// Add a splash screen to the centre of the work area
|
||||
SplashScreen const & splash = SplashScreen::get();
|
||||
grfx::GImage const * const splash_image = splash.image();
|
||||
grfx::Image const * const splash_image = splash.image();
|
||||
if (splash_image) {
|
||||
int const w = splash_image->getWidth();
|
||||
int const h = splash_image->getHeight();
|
||||
|
@ -1,3 +1,14 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* XPainter.[Ch]: changes associated with the name change
|
||||
grfx::GImage -> grfx::Image.
|
||||
|
||||
* xformsGImage.[Ch]: deleted.
|
||||
* xformsImage.[Ch]: new files, reflecting changed class name.
|
||||
|
||||
* Makefile.am:
|
||||
* lyx_gui.C: associated changes.
|
||||
|
||||
2002-06-27 Juergen Spitzmueller <j.spitzmueller@gmx.de>
|
||||
|
||||
* FormPreferences.C
|
||||
|
@ -9,11 +9,11 @@ INCLUDES = -I$(top_srcdir)/images -I$(top_srcdir)/src/ \
|
||||
|
||||
SUBDIRS = forms
|
||||
|
||||
EXTRA_DIST = xformsGImage.C xformsGImage.h
|
||||
EXTRA_DIST = xformsImage.C xformsImage.h
|
||||
|
||||
if USE_BASIC_IMAGE_LOADER
|
||||
else
|
||||
XFORMSGIMAGE = xformsGImage.C xformsGImage.h
|
||||
XFORMSIMAGE = xformsImage.C xformsImage.h
|
||||
endif
|
||||
|
||||
# Alphabetical order please. It makes it easier to figure out what's missing.
|
||||
@ -38,7 +38,7 @@ libxforms_la_SOURCES = \
|
||||
xforms_helpers.h \
|
||||
xforms_resize.C \
|
||||
xforms_resize.h \
|
||||
$(XFORMSGIMAGE) xformsBC.C \
|
||||
$(XFORMSIMAGE) xformsBC.C \
|
||||
xformsBC.h \
|
||||
xscreen.C \
|
||||
xscreen.h \
|
||||
|
@ -150,7 +150,7 @@ Painter & XPainter::arc(int x, int y,
|
||||
|
||||
Painter & XPainter::image(int x, int y,
|
||||
int w, int h,
|
||||
grfx::GImage const & image)
|
||||
grfx::Image const & image)
|
||||
{
|
||||
XGCValues val;
|
||||
val.function = GXcopy;
|
||||
|
@ -96,7 +96,7 @@ public:
|
||||
/// draw an image from the image cache
|
||||
virtual Painter & image(int x, int y,
|
||||
int w, int h,
|
||||
grfx::GImage const & image);
|
||||
grfx::Image const & image);
|
||||
|
||||
/// draw a string at position x, y (y is the baseline)
|
||||
virtual Painter & text(int x, int y,
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "ColorHandler.h"
|
||||
#include "xforms_helpers.h"
|
||||
#ifdef USE_XFORMS_IMAGE_LOADER
|
||||
#include "xformsGImage.h"
|
||||
#include "xformsImage.h"
|
||||
#else
|
||||
#include "graphics/GraphicsImageXPM.h"
|
||||
#endif
|
||||
@ -300,11 +300,11 @@ void lyx_gui::init_graphics()
|
||||
|
||||
#ifdef USE_XFORMS_IMAGE_LOADER
|
||||
// connect the image loader based on the xforms library
|
||||
GImage::newImage.connect(boost::bind(&xformsGImage::newImage));
|
||||
GImage::loadableFormats.connect(boost::bind(&xformsGImage::loadableFormats));
|
||||
Image::newImage.connect(boost::bind(&xformsImage::newImage));
|
||||
Image::loadableFormats.connect(boost::bind(&xformsImage::loadableFormats));
|
||||
#else
|
||||
// connect the image loader based on the XPM library
|
||||
GImage::newImage.connect(boost::bind(&GImageXPM::newImage));
|
||||
GImage::loadableFormats.connect(boost::bind(&GImageXPM::loadableFormats));
|
||||
Image::newImage.connect(boost::bind(&ImageXPM::newImage));
|
||||
Image::loadableFormats.connect(boost::bind(&ImageXPM::loadableFormats));
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* \file xformsGImage.C
|
||||
* \file xformsImage.C
|
||||
* Copyright 2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
@ -12,7 +12,7 @@
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include "xformsGImage.h"
|
||||
#include "xformsImage.h"
|
||||
#include "graphics/GraphicsParams.h"
|
||||
#include "LColor.h"
|
||||
#include "converter.h" // formats
|
||||
@ -44,18 +44,18 @@ unsigned int packedcolor(LColor::color c);
|
||||
namespace grfx {
|
||||
|
||||
/// Access to this class is through this static method.
|
||||
ImagePtr xformsGImage::newImage()
|
||||
Image::ImagePtr xformsImage::newImage()
|
||||
{
|
||||
init_graphics();
|
||||
|
||||
ImagePtr ptr;
|
||||
ptr.reset(new xformsGImage);
|
||||
ptr.reset(new xformsImage);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/// Return the list of loadable formats.
|
||||
GImage::FormatList xformsGImage::loadableFormats()
|
||||
Image::FormatList xformsImage::loadableFormats()
|
||||
{
|
||||
static FormatList fmts;
|
||||
if (!fmts.empty())
|
||||
@ -111,15 +111,15 @@ GImage::FormatList xformsGImage::loadableFormats()
|
||||
}
|
||||
|
||||
|
||||
xformsGImage::xformsGImage()
|
||||
xformsImage::xformsImage()
|
||||
: image_(0),
|
||||
pixmap_(0),
|
||||
pixmap_status_(PIXMAP_UNINITIALISED)
|
||||
{}
|
||||
|
||||
|
||||
xformsGImage::xformsGImage(xformsGImage const & other)
|
||||
: GImage(other),
|
||||
xformsImage::xformsImage(xformsImage const & other)
|
||||
: Image(other),
|
||||
image_(0),
|
||||
pixmap_(0),
|
||||
pixmap_status_(PIXMAP_UNINITIALISED)
|
||||
@ -131,7 +131,7 @@ xformsGImage::xformsGImage(xformsGImage const & other)
|
||||
}
|
||||
|
||||
|
||||
xformsGImage::~xformsGImage()
|
||||
xformsImage::~xformsImage()
|
||||
{
|
||||
if (image_)
|
||||
flimage_free(image_);
|
||||
@ -140,13 +140,13 @@ xformsGImage::~xformsGImage()
|
||||
}
|
||||
|
||||
|
||||
GImage * xformsGImage::clone() const
|
||||
Image * xformsImage::clone() const
|
||||
{
|
||||
return new xformsGImage(*this);
|
||||
return new xformsImage(*this);
|
||||
}
|
||||
|
||||
|
||||
unsigned int xformsGImage::getWidth() const
|
||||
unsigned int xformsImage::getWidth() const
|
||||
{
|
||||
if (!image_)
|
||||
return 0;
|
||||
@ -154,7 +154,7 @@ unsigned int xformsGImage::getWidth() const
|
||||
}
|
||||
|
||||
|
||||
unsigned int xformsGImage::getHeight() const
|
||||
unsigned int xformsImage::getHeight() const
|
||||
{
|
||||
if (!image_)
|
||||
return 0;
|
||||
@ -162,7 +162,7 @@ unsigned int xformsGImage::getHeight() const
|
||||
}
|
||||
|
||||
|
||||
Pixmap xformsGImage::getPixmap() const
|
||||
Pixmap xformsImage::getPixmap() const
|
||||
{
|
||||
if (!pixmap_status_ == PIXMAP_SUCCESS)
|
||||
return 0;
|
||||
@ -170,12 +170,12 @@ Pixmap xformsGImage::getPixmap() const
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::load(string const & filename, SignalTypePtr on_finish)
|
||||
void xformsImage::load(string const & filename)
|
||||
{
|
||||
if (image_) {
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "Image is loaded already!" << std::endl;
|
||||
on_finish->operator()(false);
|
||||
finishedLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -183,13 +183,10 @@ void xformsGImage::load(string const & filename, SignalTypePtr on_finish)
|
||||
if (!image_) {
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "Unable to open image" << std::endl;
|
||||
on_finish->operator()(false);
|
||||
finishedLoading(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);
|
||||
|
||||
@ -201,7 +198,7 @@ void xformsGImage::load(string const & filename, SignalTypePtr on_finish)
|
||||
}
|
||||
|
||||
|
||||
bool xformsGImage::setPixmap(GParams const & params)
|
||||
bool xformsImage::setPixmap(Params const & params)
|
||||
{
|
||||
if (!image_ || params.display == NoDisplay)
|
||||
return false;
|
||||
@ -248,7 +245,7 @@ bool xformsGImage::setPixmap(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::clip(GParams const & params)
|
||||
void xformsImage::clip(Params const & params)
|
||||
{
|
||||
if (!image_)
|
||||
return;
|
||||
@ -279,7 +276,7 @@ void xformsGImage::clip(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::rotate(GParams const & params)
|
||||
void xformsImage::rotate(Params const & params)
|
||||
{
|
||||
if (!image_)
|
||||
return ;
|
||||
@ -303,7 +300,7 @@ void xformsGImage::rotate(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::scale(GParams const & params)
|
||||
void xformsImage::scale(Params const & params)
|
||||
{
|
||||
if (!image_)
|
||||
return;
|
||||
@ -322,9 +319,9 @@ void xformsGImage::scale(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::statusCB(string const & status_message)
|
||||
void xformsImage::statusCB(string const & status_message)
|
||||
{
|
||||
if (status_message.empty() || !on_finish_.get())
|
||||
if (status_message.empty())
|
||||
return;
|
||||
|
||||
if (prefixIs(status_message, "Done Reading")) {
|
||||
@ -332,27 +329,21 @@ void xformsGImage::statusCB(string const & status_message)
|
||||
flimage_close(image_);
|
||||
}
|
||||
|
||||
if (on_finish_.get()) {
|
||||
on_finish_->operator()(true);
|
||||
on_finish_.reset();
|
||||
}
|
||||
finishedLoading(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xformsGImage::errorCB(string const & error_message)
|
||||
void xformsImage::errorCB(string const & error_message)
|
||||
{
|
||||
if (error_message.empty() || !on_finish_.get())
|
||||
if (error_message.empty())
|
||||
return;
|
||||
|
||||
if (image_) {
|
||||
flimage_close(image_);
|
||||
}
|
||||
|
||||
if (on_finish_.get()) {
|
||||
on_finish_->operator()(false);
|
||||
on_finish_.reset();
|
||||
}
|
||||
finishedLoading(false);
|
||||
}
|
||||
|
||||
} // namespace grfx
|
||||
@ -373,8 +364,8 @@ int status_report(FL_IMAGE * ob, const char *s)
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "xforms image loader. Status : " << str << std::endl;
|
||||
|
||||
grfx::xformsGImage * ptr =
|
||||
static_cast<grfx::xformsGImage *>(ob->u_vdata);
|
||||
grfx::xformsImage * ptr =
|
||||
static_cast<grfx::xformsImage *>(ob->u_vdata);
|
||||
ptr->statusCB(str);
|
||||
|
||||
return 0;
|
||||
@ -392,8 +383,8 @@ static void error_report(FL_IMAGE * ob, const char *s)
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "xforms image loader. Error : " << str << std::endl;
|
||||
|
||||
grfx::xformsGImage * ptr =
|
||||
static_cast<grfx::xformsGImage *>(ob->u_vdata);
|
||||
grfx::xformsImage * ptr =
|
||||
static_cast<grfx::xformsImage *>(ob->u_vdata);
|
||||
ptr->errorCB(str);
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file xformsGImage.h
|
||||
* \file xformsImage.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
|
||||
/* An instantiation of Image that makes use of the xforms lirary routines
|
||||
* to load and store the image in memory.
|
||||
*/
|
||||
|
||||
#ifndef XFORMS_GRAPHICSIMAGE_H
|
||||
#define XFORMS_GRAPHICSIMAGE_H
|
||||
#ifndef XFORMSIMAGE_H
|
||||
#define XFORMSIMAGE_H
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
@ -25,7 +25,7 @@ typedef flimage_ FL_IMAGE;
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class xformsGImage : public GImage
|
||||
class xformsImage : public Image
|
||||
{
|
||||
public:
|
||||
/// Access to this class is through this static method.
|
||||
@ -35,10 +35,10 @@ public:
|
||||
static FormatList loadableFormats();
|
||||
|
||||
///
|
||||
~xformsGImage();
|
||||
~xformsImage();
|
||||
|
||||
/// Create a copy
|
||||
GImage * clone() const;
|
||||
Image * clone() const;
|
||||
|
||||
///
|
||||
Pixmap getPixmap() const;
|
||||
@ -50,26 +50,26 @@ public:
|
||||
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.
|
||||
* The process is asynchronous, so this method starts the loading.
|
||||
* When finished, the Image::finishedLoading signal is emitted.
|
||||
*/
|
||||
void load(string const & filename, SignalTypePtr);
|
||||
void load(string const & filename);
|
||||
|
||||
/** 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);
|
||||
bool setPixmap(Params const & params);
|
||||
|
||||
/// Clip the image using params.
|
||||
void clip(GParams const & params);
|
||||
void clip(Params const & params);
|
||||
|
||||
/// Rotate the image using params.
|
||||
void rotate(GParams const & params);
|
||||
void rotate(Params const & params);
|
||||
|
||||
/// Scale the image using params.
|
||||
void scale(GParams const & params);
|
||||
void scale(Params const & params);
|
||||
|
||||
/// Internal callbacks.
|
||||
void statusCB(string const &);
|
||||
@ -78,9 +78,9 @@ public:
|
||||
|
||||
private:
|
||||
/// Access to the class is through newImage() and clone.
|
||||
xformsGImage();
|
||||
xformsImage();
|
||||
///
|
||||
xformsGImage(xformsGImage const &);
|
||||
xformsImage(xformsImage const &);
|
||||
|
||||
/// The xforms container.
|
||||
FL_IMAGE * image_;
|
||||
@ -99,11 +99,8 @@ private:
|
||||
};
|
||||
|
||||
PixmapStatus pixmap_status_;
|
||||
|
||||
/// Emit this signal when the loading process is finished.
|
||||
GImage::SignalTypePtr on_finish_;
|
||||
};
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
#endif // XFORMS_GRAPHICSIMAGE_H
|
||||
#endif // XFORMSIMAGE_H
|
@ -1,3 +1,38 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* GraphicsCacheItem.[Ch]: refactor some of the more convoluted logic
|
||||
by moving those SignalPtrs into the grfx::Image and grfx::Converter
|
||||
classes where they really belong.
|
||||
Use the Pimpl idiom to hide the class internals from public view.
|
||||
|
||||
* GraphicsTypes: remove the typedefs, leaving only the enums.
|
||||
|
||||
* GraphicsImage.h: now has a finishedLoading signal, as opposed to being
|
||||
passed a reference to one in the load() method.
|
||||
|
||||
* GraphicsConverter.[Ch]: totally refactored. An instance of
|
||||
grfx::Converter now represents a single conversion process.
|
||||
Thus grfx::CachItem now has a grfx::Converter * that is set when the
|
||||
conversion is initiated and destroyed on completion.
|
||||
|
||||
* GraphicsCache.[Ch]:
|
||||
* GraphicsCacheItem.[Ch]:
|
||||
* GraphicsConverter.[Ch]:
|
||||
* GraphicsLoader.[Ch]: use the Pimpl idiom to hide the class internals
|
||||
from public view.
|
||||
Note that I have done this only after making the above changes,
|
||||
so not only should we have a clean, minimal and well documented
|
||||
interface to these classes in the header files, but the class internals
|
||||
should be much clearer too.
|
||||
|
||||
* Renamed classes
|
||||
grfx::GCache -> grfx::Cache,
|
||||
grfx::GCacheItem -> grfx::CacheItem,
|
||||
grfx::GConverter -> grfx::Converter,
|
||||
grfx::GImage -> grfx::Image,
|
||||
grfx::GImageXPM -> grfx::ImageXPM,
|
||||
grfx::GParams -> grfx::Params.
|
||||
|
||||
2002-06-26 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* GraphicsLoader.[Ch]: use boost::scoped_ptr in preference to
|
||||
|
@ -23,9 +23,22 @@
|
||||
|
||||
#include "frontends/lyx_gui.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace grfx {
|
||||
|
||||
GCache & GCache::get()
|
||||
/** The cache contains one item per file, so use a map to find the
|
||||
* cache item quickly by filename.
|
||||
*/
|
||||
typedef std::map<string, Cache::ItemPtr> CacheType;
|
||||
|
||||
struct Cache::Impl {
|
||||
///
|
||||
CacheType cache;
|
||||
};
|
||||
|
||||
|
||||
Cache & Cache::get()
|
||||
{
|
||||
static bool start = true;
|
||||
if (start) {
|
||||
@ -34,92 +47,76 @@ GCache & GCache::get()
|
||||
}
|
||||
|
||||
// Now return the cache
|
||||
static GCache singleton;
|
||||
static Cache singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
|
||||
GCache::GCache()
|
||||
Cache::Cache()
|
||||
: pimpl_(new Impl())
|
||||
{}
|
||||
|
||||
|
||||
Cache::~Cache()
|
||||
{}
|
||||
|
||||
|
||||
std::vector<string> Cache::loadableFormats() const
|
||||
{
|
||||
cache = new CacheType;
|
||||
return Image::loadableFormats();
|
||||
}
|
||||
|
||||
|
||||
// all elements are destroyed by the shared_ptr's in the map.
|
||||
GCache::~GCache()
|
||||
{
|
||||
delete cache;
|
||||
}
|
||||
|
||||
|
||||
std::vector<string> GCache::loadableFormats() const
|
||||
{
|
||||
return GImage::loadableFormats();
|
||||
}
|
||||
|
||||
|
||||
void GCache::add(string const & file)
|
||||
void Cache::add(string const & file)
|
||||
{
|
||||
if (!AbsolutePath(file)) {
|
||||
lyxerr << "GCacheItem::add(" << file << "):\n"
|
||||
lyxerr << "Cache::add(" << file << "):\n"
|
||||
<< "The file must be have an absolute path."
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Is the file in the cache already?
|
||||
if (inCache(file)) {
|
||||
lyxerr[Debug::GRAPHICS] << "GCache::add(" << file << "):\n"
|
||||
lyxerr[Debug::GRAPHICS] << "Cache::add(" << file << "):\n"
|
||||
<< "The file is already in the cache."
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
(*cache)[file] = GraphicPtr(new GCacheItem(file));
|
||||
pimpl_->cache[file] = ItemPtr(new CacheItem(file));
|
||||
}
|
||||
|
||||
|
||||
void GCache::remove(string const & file)
|
||||
void Cache::remove(string const & file)
|
||||
{
|
||||
CacheType::iterator it = cache->find(file);
|
||||
if (it == cache->end())
|
||||
CacheType::iterator it = pimpl_->cache.find(file);
|
||||
if (it == pimpl_->cache.end())
|
||||
return;
|
||||
|
||||
GraphicPtr item = it->second;
|
||||
|
||||
ItemPtr & item = it->second;
|
||||
|
||||
if (item.use_count() == 1) {
|
||||
// The graphics file is in the cache, but nothing else
|
||||
// references it.
|
||||
cache->erase(it);
|
||||
pimpl_->cache.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GCache::inCache(string const & file) const
|
||||
bool Cache::inCache(string const & file) const
|
||||
{
|
||||
return cache->find(file) != cache->end();
|
||||
return pimpl_->cache.find(file) != pimpl_->cache.end();
|
||||
}
|
||||
|
||||
|
||||
GraphicPtr const GCache::graphic(string const & file) const
|
||||
Cache::ItemPtr const Cache::item(string const & file) const
|
||||
{
|
||||
CacheType::const_iterator it = cache->find(file);
|
||||
if (it == cache->end())
|
||||
return GraphicPtr();
|
||||
CacheType::const_iterator it = pimpl_->cache.find(file);
|
||||
if (it == pimpl_->cache.end())
|
||||
return ItemPtr();
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
ImagePtr const GCache::image(string const & file) const
|
||||
{
|
||||
CacheType::const_iterator it = cache->find(file);
|
||||
if (it == cache->end())
|
||||
return ImagePtr();
|
||||
|
||||
return it->second->image();
|
||||
}
|
||||
|
||||
|
||||
} // namespace grfx
|
||||
|
@ -7,10 +7,10 @@
|
||||
* \author Baruch Even <baruch.even@writeme.com>
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*
|
||||
* grfx::GCache is the manager of the image cache.
|
||||
* It is responsible for creating the grfx::GCacheItem's and maintaining them.
|
||||
* grfx::Cache is the manager of the image cache.
|
||||
* It is responsible for creating the grfx::CacheItem's and maintaining them.
|
||||
*
|
||||
* grfx::GCache is a singleton class. It is possible to have only one
|
||||
* grfx::Cache is a singleton class. It is possible to have only one
|
||||
* instance of it at any moment.
|
||||
*/
|
||||
|
||||
@ -22,18 +22,21 @@
|
||||
#endif
|
||||
|
||||
#include "LString.h"
|
||||
#include "GraphicsTypes.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class GCache : boost::noncopyable {
|
||||
class CacheItem;
|
||||
|
||||
class Cache : boost::noncopyable {
|
||||
public:
|
||||
|
||||
/// This is a singleton class. Get the instance.
|
||||
static GCache & get();
|
||||
static Cache & get();
|
||||
|
||||
/** Which graphics formats can be loaded directly by the image loader.
|
||||
* Other formats can be loaded if a converter to a loadable format
|
||||
@ -44,10 +47,7 @@ public:
|
||||
/// Add a graphics file to the cache.
|
||||
void add(string const & file);
|
||||
|
||||
/** Remove a file from the cache.
|
||||
* Called from the InsetGraphics d-tor.
|
||||
* If we use reference counting, then this may become redundant.
|
||||
*/
|
||||
/// Remove a file from the cache.
|
||||
void remove(string const & file);
|
||||
|
||||
/// Returns \c true if the file is in the cache.
|
||||
@ -63,36 +63,24 @@ public:
|
||||
*
|
||||
* You have been warned!
|
||||
*/
|
||||
GraphicPtr const graphic(string const & file) const;
|
||||
|
||||
/** Get the image associated with file.
|
||||
If the image is not yet loaded, (or is not in the cache!) return
|
||||
an empty container.
|
||||
*/
|
||||
ImagePtr const image(string const & file) const;
|
||||
typedef boost::shared_ptr<CacheItem> ItemPtr;
|
||||
///
|
||||
ItemPtr const item(string const & file) const;
|
||||
|
||||
private:
|
||||
/** Make the c-tor, d-tor private so we can control how many objects
|
||||
* are instantiated.
|
||||
*/
|
||||
GCache();
|
||||
Cache();
|
||||
///
|
||||
~GCache();
|
||||
~Cache();
|
||||
|
||||
/** The cache contains one item per file, so use a map to find the
|
||||
* cache item quickly by filename.
|
||||
* Note that each cache item can have multiple views, potentially one
|
||||
* per inset that references the original file.
|
||||
*/
|
||||
typedef std::map<string, GraphicPtr> CacheType;
|
||||
|
||||
/** Store a pointer to the cache so that we can forward declare
|
||||
* GCacheItem.
|
||||
*/
|
||||
CacheType * cache;
|
||||
/// Use the Pimpl idiom to hide the internals.
|
||||
class Impl;
|
||||
/// The pointer never changes although *pimpl_'s contents may.
|
||||
boost::scoped_ptr<Impl> const pimpl_;
|
||||
};
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
|
||||
#endif // GRAPHICSCACHE_H
|
||||
|
@ -23,46 +23,159 @@
|
||||
#include "support/LAssert.h"
|
||||
#include "support/filetools.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace grfx {
|
||||
|
||||
GCacheItem::GCacheItem(string const & file)
|
||||
: filename_(file), zipped_(false),
|
||||
struct CacheItem::Impl : public boost::signals::trackable {
|
||||
|
||||
///
|
||||
Impl(CacheItem &, string const & file);
|
||||
|
||||
/** Start the image conversion process, checking first that it is
|
||||
* necessary. If it is necessary, then a conversion task is started.
|
||||
* CacheItem asumes that the conversion is asynchronous and so
|
||||
* passes a Signal to the converting routine. When the conversion
|
||||
* is finished, this Signal is emitted, returning the converted
|
||||
* file to this->imageConverted.
|
||||
*
|
||||
* If no file conversion is needed, then convertToDisplayFormat() calls
|
||||
* loadImage() directly.
|
||||
*
|
||||
* convertToDisplayFormat() will set the loading status flag as
|
||||
* approriate through calls to setStatus().
|
||||
*/
|
||||
void convertToDisplayFormat();
|
||||
|
||||
/** Load the image into memory. This is called either from
|
||||
* convertToDisplayFormat() direct or from imageConverted().
|
||||
*/
|
||||
void loadImage();
|
||||
|
||||
/** Get a notification when the image conversion is done.
|
||||
* Connected to a signal on_finish_ which is passed to
|
||||
* Converter::convert.
|
||||
*/
|
||||
void imageConverted(bool);
|
||||
|
||||
/** Get a notification when the image loading is done.
|
||||
* Connected to a signal on_finish_ which is passed to
|
||||
* grfx::Image::loadImage.
|
||||
*/
|
||||
void imageLoaded(bool);
|
||||
|
||||
/** Sets the status of the loading process. Also notifies
|
||||
* listeners that the status has chacnged.
|
||||
*/
|
||||
void setStatus(ImageStatus new_status);
|
||||
|
||||
///
|
||||
CacheItem & parent_;
|
||||
|
||||
/// The filename we refer too.
|
||||
string filename_;
|
||||
/// Is the file compressed?
|
||||
bool zipped_;
|
||||
/// If so, store the uncompressed file in this temporary file.
|
||||
string unzipped_filename_;
|
||||
/// What file are we trying to load?
|
||||
string file_to_load_;
|
||||
/** Should we delete the file after loading? True if the file is
|
||||
* the result of a conversion process.
|
||||
*/
|
||||
bool remove_loaded_file_;
|
||||
|
||||
/// The image and its loading status.
|
||||
boost::shared_ptr<Image> image_;
|
||||
///
|
||||
ImageStatus status_;
|
||||
|
||||
/// The connection to the signal Image::finishedLoading
|
||||
boost::signals::connection cl_;
|
||||
|
||||
/// The connection of the signal ConvProcess::finishedConversion,
|
||||
boost::signals::connection cc_;
|
||||
|
||||
///
|
||||
boost::scoped_ptr<Converter> converter_;
|
||||
};
|
||||
|
||||
|
||||
CacheItem::CacheItem(string const & file)
|
||||
: pimpl_(new Impl(*this, file))
|
||||
{}
|
||||
|
||||
|
||||
CacheItem::~CacheItem()
|
||||
{}
|
||||
|
||||
|
||||
string const & CacheItem::filename() const
|
||||
{
|
||||
return pimpl_->filename_;
|
||||
}
|
||||
|
||||
|
||||
void CacheItem::startLoading()
|
||||
{
|
||||
if (pimpl_->status_ != WaitingToLoad)
|
||||
return;
|
||||
|
||||
pimpl_->convertToDisplayFormat();
|
||||
}
|
||||
|
||||
|
||||
Image const * CacheItem::image() const
|
||||
{
|
||||
return pimpl_->image_.get();
|
||||
}
|
||||
|
||||
|
||||
ImageStatus CacheItem::status() const
|
||||
{
|
||||
return pimpl_->status_;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------
|
||||
// Implementation details follow
|
||||
//------------------------------
|
||||
|
||||
|
||||
CacheItem::Impl::Impl(CacheItem & p, string const & file)
|
||||
: parent_(p), filename_(file), zipped_(false),
|
||||
remove_loaded_file_(false), status_(WaitingToLoad)
|
||||
{}
|
||||
|
||||
|
||||
void GCacheItem::startLoading()
|
||||
{
|
||||
if (status() != WaitingToLoad)
|
||||
return;
|
||||
|
||||
convertToDisplayFormat();
|
||||
}
|
||||
|
||||
|
||||
void GCacheItem::setStatus(ImageStatus new_status)
|
||||
void CacheItem::Impl::setStatus(ImageStatus new_status)
|
||||
{
|
||||
if (status_ == new_status)
|
||||
return;
|
||||
|
||||
status_ = new_status;
|
||||
statusChanged();
|
||||
parent_.statusChanged();
|
||||
}
|
||||
|
||||
|
||||
void GCacheItem::imageConverted(string const & file_to_load)
|
||||
void CacheItem::Impl::imageConverted(bool success)
|
||||
{
|
||||
bool const success =
|
||||
(!file_to_load.empty() && IsFileReadable(file_to_load));
|
||||
|
||||
string const text = success ? "succeeded" : "failed";
|
||||
lyxerr[Debug::GRAPHICS] << "Image conversion " << text << "." << endl;
|
||||
|
||||
file_to_load_ = converter_.get() ?
|
||||
converter_->convertedFile() : string();
|
||||
converter_.reset();
|
||||
cc_.disconnect();
|
||||
|
||||
success = !file_to_load_.empty() && IsFileReadable(file_to_load_);
|
||||
lyxerr[Debug::GRAPHICS] << "Unable to find converted file!" << endl;
|
||||
|
||||
if (!success) {
|
||||
setStatus(ErrorConverting);
|
||||
|
||||
@ -72,34 +185,27 @@ void GCacheItem::imageConverted(string const & file_to_load)
|
||||
return;
|
||||
}
|
||||
|
||||
cc_.disconnect();
|
||||
|
||||
// Do the actual image loading from file to memory.
|
||||
file_to_load_ = file_to_load;
|
||||
|
||||
loadImage();
|
||||
}
|
||||
|
||||
|
||||
// This function gets called from the callback after the image has been
|
||||
// converted successfully.
|
||||
void GCacheItem::loadImage()
|
||||
void CacheItem::Impl::loadImage()
|
||||
{
|
||||
setStatus(Loading);
|
||||
lyxerr[Debug::GRAPHICS] << "Loading image." << endl;
|
||||
|
||||
// Connect a signal to this->imageLoaded and pass this signal to
|
||||
// GImage::loadImage.
|
||||
SignalLoadTypePtr on_finish;
|
||||
on_finish.reset(new SignalLoadType);
|
||||
cl_ = on_finish->connect(boost::bind(&GCacheItem::imageLoaded, this, _1));
|
||||
image_ = Image::newImage();
|
||||
|
||||
image_ = GImage::newImage();
|
||||
image_->load(file_to_load_, on_finish);
|
||||
cl_.disconnect();
|
||||
cl_ = image_->finishedLoading.connect(
|
||||
boost::bind(&Impl::imageLoaded, this, _1));
|
||||
image_->load(file_to_load_);
|
||||
}
|
||||
|
||||
|
||||
void GCacheItem::imageLoaded(bool success)
|
||||
void CacheItem::Impl::imageLoaded(bool success)
|
||||
{
|
||||
string const text = success ? "succeeded" : "failed";
|
||||
lyxerr[Debug::GRAPHICS] << "Image loading " << text << "." << endl;
|
||||
@ -121,19 +227,21 @@ void GCacheItem::imageLoaded(bool success)
|
||||
setStatus(Loaded);
|
||||
}
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
string const findTargetFormat(string const & from)
|
||||
{
|
||||
typedef GImage::FormatList FormatList;
|
||||
FormatList const formats = GImage::loadableFormats();
|
||||
typedef grfx::Image::FormatList FormatList;
|
||||
FormatList const formats = grfx::Image::loadableFormats();
|
||||
|
||||
// There must be a format to load from.
|
||||
lyx::Assert(!formats.empty());
|
||||
|
||||
// First ascertain if we can load directly with no conversion
|
||||
FormatList::const_iterator it1 = formats.begin();
|
||||
FormatList::const_iterator it1 = formats.begin();
|
||||
FormatList::const_iterator end = formats.end();
|
||||
for (; it1 != end; ++it1) {
|
||||
if (from == *it1)
|
||||
@ -141,11 +249,9 @@ string const findTargetFormat(string const & from)
|
||||
}
|
||||
|
||||
// So, we have to convert to a loadable format. Can we?
|
||||
grfx::GConverter const & graphics_converter = grfx::GConverter::get();
|
||||
|
||||
FormatList::const_iterator it2 = formats.begin();
|
||||
FormatList::const_iterator it2 = formats.begin();
|
||||
for (; it2 != end; ++it2) {
|
||||
if (graphics_converter.isReachable(from, *it2))
|
||||
if (grfx::Converter::isReachable(from, *it2))
|
||||
return *it2;
|
||||
}
|
||||
|
||||
@ -157,7 +263,9 @@ string const findTargetFormat(string const & from)
|
||||
} // anon namespace
|
||||
|
||||
|
||||
void GCacheItem::convertToDisplayFormat()
|
||||
namespace grfx {
|
||||
|
||||
void CacheItem::Impl::convertToDisplayFormat()
|
||||
{
|
||||
setStatus(Converting);
|
||||
// Make a local copy in case we unzip it
|
||||
@ -187,7 +295,7 @@ void GCacheItem::convertToDisplayFormat()
|
||||
} else
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "\n\tThe file contains " << from << " format data." << endl;
|
||||
string const to = grfx::findTargetFormat(from);
|
||||
string const to = findTargetFormat(from);
|
||||
|
||||
if (from == to) {
|
||||
// No conversion needed!
|
||||
@ -212,12 +320,10 @@ void GCacheItem::convertToDisplayFormat()
|
||||
// Connect a signal to this->imageConverted and pass this signal to
|
||||
// the graphics converter so that we can load the modified file
|
||||
// on completion of the conversion process.
|
||||
SignalConvertTypePtr on_finish;
|
||||
on_finish.reset(new SignalConvertType);
|
||||
cc_ = on_finish->connect(boost::bind(&GCacheItem::imageConverted, this, _1));
|
||||
|
||||
GConverter & graphics_converter = GConverter::get();
|
||||
graphics_converter.convert(filename, to_file_base, from, to, on_finish);
|
||||
converter_.reset(new Converter(filename, to_file_base, from, to));
|
||||
converter_->finishedConversion.connect(
|
||||
boost::bind(&Impl::imageConverted, this, _1));
|
||||
converter_->startConversion();
|
||||
}
|
||||
|
||||
} // namespace grfx
|
||||
|
@ -7,18 +7,20 @@
|
||||
* \author Baruch Even <baruch.even@writeme.com>
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*
|
||||
* The graphics cache is a container of GCacheItems. Each GCacheItem, defined
|
||||
* here represents a separate image file. The routines here can be used to
|
||||
* load the graphics file into memory at which point (status() == grfx::Loaded).
|
||||
* The user is then free to access image() in order to transform the image
|
||||
* (rotate, scale, clip) and to generate the pixmap.
|
||||
* The graphics cache is a container of grfx::CacheItems.
|
||||
* Each grfx::CacheItem, definedhere represents a separate image file.
|
||||
*
|
||||
* The routines here can be used to load the graphics file into memory at
|
||||
* which point (status() == grfx::Loaded).
|
||||
* The user is then free to access image() in order to copy it and to then
|
||||
* transform the copy (rotate, scale, clip) and to generate the pixmap.
|
||||
*
|
||||
* The graphics cache supports fully asynchronous:
|
||||
* file conversion to a loadable format;
|
||||
* file loading.
|
||||
*
|
||||
* Whether you get that, of course, depends on grfx::GConverter and on the
|
||||
* grfx::GImage-derived image class.
|
||||
* Whether you get that, of course, depends on grfx::Converter and on the
|
||||
* grfx::Image-derived image class.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICSCACHEITEM_H
|
||||
@ -32,124 +34,50 @@
|
||||
#include "LString.h"
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/signals/signal0.hpp>
|
||||
#include <boost/signals/signal1.hpp>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
class InsetGraphics;
|
||||
|
||||
namespace grfx {
|
||||
|
||||
/// A grfx::GCache item holder.
|
||||
class GCacheItem : boost::noncopyable, public boost::signals::trackable {
|
||||
class Image;
|
||||
class Converter;
|
||||
|
||||
/// A grfx::Cache item holder.
|
||||
class CacheItem : boost::noncopyable {
|
||||
public:
|
||||
///
|
||||
GCacheItem(string const & file);
|
||||
CacheItem(string const & file);
|
||||
|
||||
/// Define an empty d-tor out-of-line to keep boost::scoped_ptr happy.
|
||||
~CacheItem();
|
||||
|
||||
///
|
||||
string const & filename() const;
|
||||
|
||||
/// It's in the cache. Now start the loading process.
|
||||
void startLoading();
|
||||
|
||||
/** Get the image associated with filename_.
|
||||
If the image is not yet loaded, return a null pointer.
|
||||
* If the image is not yet loaded, returns 0.
|
||||
* This routine returns a pointer to const; if you want to modify it,
|
||||
* create a copy and modify that.
|
||||
*/
|
||||
ImagePtr const image() const { return image_; }
|
||||
Image const * image() const;
|
||||
|
||||
/// How far have we got in loading the image?
|
||||
ImageStatus status() const { return status_; }
|
||||
ImageStatus status() const;
|
||||
|
||||
/// This signal is emitted when the image loading status changes.
|
||||
boost::signal0<void> statusChanged;
|
||||
|
||||
///
|
||||
string const & filename() const { return filename_; }
|
||||
|
||||
private:
|
||||
/** Start the image conversion process, checking first that it is
|
||||
* necessary. If it is necessary, then a conversion task is started.
|
||||
* GCacheItem asumes that the conversion is asynchronous and so
|
||||
* passes a Signal to the converting routine. When the conversion
|
||||
* is finished, this Signal is emitted, returning the converted
|
||||
* file to this->imageConverted.
|
||||
*
|
||||
* If no file conversion is needed, then convertToDisplayFormat() calls
|
||||
* loadImage() directly.
|
||||
*
|
||||
* convertToDisplayFormat() will set the loading status flag as
|
||||
* approriate through calls to setStatus().
|
||||
*/
|
||||
void convertToDisplayFormat();
|
||||
/// Use the Pimpl idiom to hide the internals.
|
||||
class Impl;
|
||||
|
||||
/** Load the image into memory. This is called either from
|
||||
* convertToDisplayFormat() direct or from imageConverted().
|
||||
*/
|
||||
void loadImage();
|
||||
|
||||
/** Get a notification when the image conversion is done.
|
||||
* Connected to a signal on_finish_ which is passed to
|
||||
* GConverter::convert.
|
||||
*/
|
||||
void imageConverted(string const & file_to_load);
|
||||
|
||||
/** Get a notification when the image loading is done.
|
||||
* Connected to a signal on_finish_ which is passed to
|
||||
* GImage::loadImage.
|
||||
*/
|
||||
void imageLoaded(bool);
|
||||
|
||||
/** Sets the status of the loading process. Also notifies
|
||||
* listeners that the status has chacnged.
|
||||
*/
|
||||
void setStatus(ImageStatus new_status);
|
||||
|
||||
/// The filename we refer too.
|
||||
string filename_;
|
||||
/// Is the file compressed?
|
||||
bool zipped_;
|
||||
/// If so, store the uncompressed file in this temporary file.
|
||||
string unzipped_filename_;
|
||||
/// What file are we trying to load?
|
||||
string file_to_load_;
|
||||
/** Should we delete the file after loading? True if the file is
|
||||
* the result of a conversion process.
|
||||
*/
|
||||
bool remove_loaded_file_;
|
||||
|
||||
/// The image and its loading status.
|
||||
ImagePtr image_;
|
||||
///
|
||||
ImageStatus status_;
|
||||
|
||||
/** A SignalLoadTypePtr is connected to this->imageLoaded and
|
||||
* then passed to ImagePtr::load.
|
||||
* When the image has been loaded, the signal is emitted.
|
||||
*
|
||||
* We pass a shared_ptr because it is eminently possible for the
|
||||
* GCacheItem to be destructed before the loading is complete and
|
||||
* the signal must remain in scope. It doesn't matter if the slot
|
||||
* disappears, SigC takes care of that.
|
||||
*/
|
||||
typedef boost::signal1<void, bool> SignalLoadType;
|
||||
///
|
||||
typedef boost::shared_ptr<SignalLoadType> SignalLoadTypePtr;
|
||||
|
||||
/// The connection of the signal passed to ImagePtr::loadImage.
|
||||
boost::signals::connection cl_;
|
||||
|
||||
/** A SignalConvertTypePtr is connected to this->imageConverted and
|
||||
* then passed to GConverter::convert.
|
||||
* When the image has been converted to a loadable format, the signal
|
||||
* is emitted, returning the name of the loadable file to
|
||||
* imageConverted.
|
||||
*/
|
||||
typedef boost::signal1<void, string const &> SignalConvertType;
|
||||
///
|
||||
typedef boost::shared_ptr<SignalConvertType> SignalConvertTypePtr;
|
||||
|
||||
/// The connection of the signal passed to GConverter::convert.
|
||||
boost::signals::connection cc_;
|
||||
/// The pointer never changes although *pimpl_'s contents may.
|
||||
boost::scoped_ptr<Impl> const pimpl_;
|
||||
};
|
||||
|
||||
} // namespace grfx
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* \file GraphicsConverter.C
|
||||
* Copyright 2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
/**
|
||||
* \file GraphicsConverter.C
|
||||
* Copyright 2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -16,18 +16,198 @@
|
||||
|
||||
#include "converter.h"
|
||||
#include "debug.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#include "support/filetools.h"
|
||||
#include "support/forkedcall.h"
|
||||
#include "support/path.h"
|
||||
#include "support/lyxlib.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
#include "Lsstream.h"
|
||||
#include <fstream>
|
||||
#include <sys/types.h> // needed for pid_t
|
||||
|
||||
using std::endl;
|
||||
|
||||
namespace grfx {
|
||||
|
||||
struct Converter::Impl : public boost::signals::trackable {
|
||||
///
|
||||
Impl(Converter &,
|
||||
string const &, string const &, string const &, string const &);
|
||||
|
||||
///
|
||||
void startConversion();
|
||||
|
||||
/** This method is connected to a signal passed to the forked call
|
||||
* class, passing control back here when the conversion is completed.
|
||||
* Cleans-up the temporary files, emits the finishedConversion
|
||||
* signal and removes the Converter from the list of all processes.
|
||||
*/
|
||||
void converted(string const & cmd, pid_t pid, int retval);
|
||||
|
||||
///
|
||||
string script_command_;
|
||||
///
|
||||
string script_file_;
|
||||
///
|
||||
string to_file_;
|
||||
///
|
||||
Converter & parent_;
|
||||
///
|
||||
bool valid_process_;
|
||||
///
|
||||
bool finished_;
|
||||
};
|
||||
|
||||
|
||||
Converter::Converter(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format)
|
||||
: pimpl_(new Impl(*this,
|
||||
from_file, to_file_base, from_format, to_format))
|
||||
{}
|
||||
|
||||
|
||||
Converter::~Converter()
|
||||
{}
|
||||
|
||||
|
||||
void Converter::startConversion()
|
||||
{
|
||||
pimpl_->startConversion();
|
||||
}
|
||||
|
||||
|
||||
bool Converter::isReachable(string const & from_format_name,
|
||||
string const & to_format_name)
|
||||
{
|
||||
return converters.isReachable(from_format_name, to_format_name);
|
||||
}
|
||||
|
||||
|
||||
string const & Converter::convertedFile() const
|
||||
{
|
||||
static string const empty;
|
||||
return pimpl_->finished_ ? pimpl_->to_file_ : empty;
|
||||
}
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
//------------------------------
|
||||
// Implementation details follow
|
||||
//------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
/** Build the conversion script, returning true if able to build it.
|
||||
* The script is output to the ostringstream 'script'.
|
||||
*/
|
||||
bool build_script(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format,
|
||||
ostringstream & script);
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
namespace grfx {
|
||||
|
||||
Converter::Impl::Impl(Converter & p,
|
||||
string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format)
|
||||
: parent_(p), valid_process_(false), finished_(false)
|
||||
{
|
||||
lyxerr[Debug::GRAPHICS] << "Converter c-tor:\n"
|
||||
<< "\tfrom_file: " << from_file
|
||||
<< "\n\tto_file_base: " << to_file_base
|
||||
<< "\n\tfrom_format: " << from_format
|
||||
<< "\n\tto_format: " << to_format << endl;
|
||||
|
||||
// The conversion commands are stored in a stringstream
|
||||
ostringstream script;
|
||||
script << "#!/bin/sh\n";
|
||||
bool const success = build_script(from_file, to_file_base,
|
||||
from_format, to_format, script);
|
||||
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
lyxerr[Debug::GRAPHICS] << "\tConversion script:"
|
||||
<< "\n--------------------------------------\n"
|
||||
<< script.str().c_str()
|
||||
<< "\n--------------------------------------\n";
|
||||
|
||||
// Output the script to file.
|
||||
static int counter = 0;
|
||||
script_file_ = OnlyPath(to_file_base) + "lyxconvert" +
|
||||
tostr(counter++) + ".sh";
|
||||
|
||||
std::ofstream fs(script_file_.c_str());
|
||||
if (!fs.good())
|
||||
return;
|
||||
|
||||
fs << script.str().c_str();
|
||||
fs.close();
|
||||
|
||||
// The converted image is to be stored in this file
|
||||
to_file_ = ChangeExtension(to_file_base, formats.extension(to_format));
|
||||
|
||||
// The command needed to run the conversion process
|
||||
// We create a dummy command for ease of understanding of the
|
||||
// list of forked processes.
|
||||
// Note that 'sh ' is absolutely essential, or execvp will fail.
|
||||
script_command_ = "sh " + script_file_ + " " +
|
||||
OnlyFilename(from_file) + " " + to_format;
|
||||
|
||||
// All is ready to go
|
||||
valid_process_ = true;
|
||||
}
|
||||
|
||||
|
||||
void Converter::Impl::startConversion()
|
||||
{
|
||||
if (!valid_process_) {
|
||||
converted(string(), 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initiate the conversion
|
||||
Forkedcall::SignalTypePtr convert_ptr;
|
||||
convert_ptr.reset(new Forkedcall::SignalType);
|
||||
|
||||
convert_ptr->connect(
|
||||
boost::bind(&Impl::converted, this, _1, _2, _3));
|
||||
|
||||
Forkedcall call;
|
||||
int retval = call.startscript(script_command_, convert_ptr);
|
||||
if (retval > 0) {
|
||||
// Unable to even start the script, so clean-up the mess!
|
||||
converted(string(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Converter::Impl::converted(string const & /* cmd */,
|
||||
pid_t /* pid */, int retval)
|
||||
{
|
||||
if (finished_)
|
||||
// We're done already!
|
||||
return;
|
||||
|
||||
finished_ = true;
|
||||
// Clean-up behind ourselves
|
||||
lyx::unlink(script_file_);
|
||||
|
||||
if (retval > 0) {
|
||||
lyx::unlink(to_file_);
|
||||
to_file_.erase();
|
||||
parent_.finishedConversion(false);
|
||||
} else {
|
||||
parent_.finishedConversion(true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
namespace {
|
||||
|
||||
@ -51,135 +231,13 @@ string const move_file(string const & from_file, string const & to_file)
|
||||
return command.str().c_str();
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
namespace grfx {
|
||||
|
||||
GConverter & GConverter::get()
|
||||
bool build_script(string const & from_file,
|
||||
string const & to_file_base,
|
||||
string const & from_format,
|
||||
string const & to_format,
|
||||
ostringstream & script)
|
||||
{
|
||||
static GConverter singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
|
||||
bool GConverter::isReachable(string const & from_format_name,
|
||||
string const & to_format_name) const
|
||||
{
|
||||
return converters.isReachable(from_format_name, to_format_name);
|
||||
}
|
||||
|
||||
|
||||
void GConverter::convert(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format,
|
||||
SignalTypePtr on_finish)
|
||||
{
|
||||
lyxerr[Debug::GRAPHICS] << "[GraphicsConverter::convert]\n"
|
||||
<< "\tfrom_file: " << from_file
|
||||
<< "\n\tto_file_base: " << to_file_base
|
||||
<< "\n\tfrom_format: " << from_format
|
||||
<< "\n\tto_format: " << to_format << endl;
|
||||
// The conversion commands are stored in a stringstream
|
||||
ostringstream script;
|
||||
script << "#!/bin/sh\n";
|
||||
string script_command;
|
||||
string script_file;
|
||||
|
||||
bool success = build_script(from_file, to_file_base,
|
||||
from_format, to_format, script);
|
||||
|
||||
if (success) {
|
||||
lyxerr[Debug::GRAPHICS] << "\tConversion script:\n"
|
||||
<< "--------------------------------------\n"
|
||||
<< script.str().c_str()
|
||||
<< "\n--------------------------------------\n";
|
||||
|
||||
// Output the script to file.
|
||||
static int counter = 0;
|
||||
script_file = OnlyPath(to_file_base) + "lyxconvert" +
|
||||
tostr(counter++) + ".sh";
|
||||
|
||||
std::ofstream fs(script_file.c_str());
|
||||
if (!fs.good()) {
|
||||
// Unable to output the conversion script to file.
|
||||
success = false;
|
||||
} else {
|
||||
|
||||
fs << script.str().c_str();
|
||||
fs.close();
|
||||
|
||||
// Create a dummy command for ease of understanding of the
|
||||
// list of forked processes.
|
||||
// Note that 'sh ' is absolutely essential, or execvp will fail.
|
||||
script_command =
|
||||
"sh " + script_file + " " +
|
||||
OnlyFilename(from_file) + " " + to_format;
|
||||
}
|
||||
}
|
||||
|
||||
string const to_file =
|
||||
ChangeExtension(to_file_base, formats.extension(to_format));
|
||||
|
||||
if (!success) {
|
||||
script_file = string();
|
||||
script_command =
|
||||
"convert -depth 8 " +
|
||||
from_format + ':' + from_file + ' ' +
|
||||
to_format + ':' + to_file;
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "\tNo converter defined! I use convert from ImageMagic:\n\t"
|
||||
<< script_command << endl;
|
||||
}
|
||||
|
||||
// Launch the conversion process.
|
||||
ConvProcessPtr shared_ptr;
|
||||
shared_ptr.reset(new ConvProcess(script_file, script_command,
|
||||
to_file, on_finish));
|
||||
all_processes_.push_back(shared_ptr);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
typedef boost::shared_ptr<ConvProcess> ConvProcessPtr;
|
||||
|
||||
class Find_Ptr {
|
||||
public:
|
||||
Find_Ptr(ConvProcess * ptr) : ptr_(ptr) {}
|
||||
|
||||
bool operator()(ConvProcessPtr const & ptr)
|
||||
{
|
||||
return ptr.get() == ptr_;
|
||||
}
|
||||
|
||||
private:
|
||||
ConvProcess * ptr_;
|
||||
};
|
||||
|
||||
} // namespace anon
|
||||
|
||||
|
||||
void GConverter::erase(ConvProcess * process)
|
||||
{
|
||||
std::list<ConvProcessPtr>::iterator begin = all_processes_.begin();
|
||||
std::list<ConvProcessPtr>::iterator end = all_processes_.end();
|
||||
std::list<ConvProcessPtr>::iterator it =
|
||||
std::find_if(begin, end, Find_Ptr(process));
|
||||
|
||||
if (it == end)
|
||||
return;
|
||||
|
||||
all_processes_.erase(it);
|
||||
}
|
||||
|
||||
|
||||
bool GConverter::build_script(string const & from_file,
|
||||
string const & to_file_base,
|
||||
string const & from_format,
|
||||
string const & to_format,
|
||||
ostringstream & script) const
|
||||
{
|
||||
lyxerr[Debug::GRAPHICS] << "[GraphicsConverter::build_script] ... ";
|
||||
lyxerr[Debug::GRAPHICS] << "build_script ... ";
|
||||
typedef Converters::EdgePath EdgePath;
|
||||
|
||||
string const to_file = ChangeExtension(to_file_base,
|
||||
@ -216,7 +274,7 @@ bool GConverter::build_script(string const & from_file,
|
||||
EdgePath::const_iterator it = edgepath.begin();
|
||||
EdgePath::const_iterator end = edgepath.end();
|
||||
for (; it != end; ++it) {
|
||||
Converter const & conv = converters.get(*it);
|
||||
::Converter const & conv = converters.get(*it);
|
||||
|
||||
// Build the conversion command
|
||||
string const infile = outfile;
|
||||
@ -269,44 +327,5 @@ bool GConverter::build_script(string const & from_file,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ConvProcess::ConvProcess(string const & script_file,
|
||||
string const & script_command,
|
||||
string const & to_file, SignalTypePtr on_finish)
|
||||
: script_file_(script_file), to_file_(to_file), on_finish_(on_finish)
|
||||
{
|
||||
Forkedcall::SignalTypePtr convert_ptr;
|
||||
convert_ptr.reset(new Forkedcall::SignalType);
|
||||
|
||||
convert_ptr->connect(boost::bind(&ConvProcess::converted, this, _1, _2, _3));
|
||||
|
||||
Forkedcall call;
|
||||
int retval = call.startscript(script_command, convert_ptr);
|
||||
if (retval > 0) {
|
||||
// Unable to even start the script, so clean-up the mess!
|
||||
converted(string(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConvProcess::converted(string const &/* cmd */,
|
||||
pid_t /* pid */, int retval)
|
||||
{
|
||||
// Clean-up behind ourselves
|
||||
lyx::unlink(script_file_);
|
||||
|
||||
if (retval > 0) {
|
||||
lyx::unlink(to_file_);
|
||||
to_file_.erase();
|
||||
}
|
||||
|
||||
if (on_finish_.get()) {
|
||||
on_finish_->operator()(to_file_);
|
||||
}
|
||||
|
||||
grfx::GConverter::get().erase(this);
|
||||
}
|
||||
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
} // namespace anon
|
||||
|
@ -1,129 +1,72 @@
|
||||
// -*- C++ -*-
|
||||
/*
|
||||
* \file GraphicsConverter.h
|
||||
* Copyright 2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
/**
|
||||
* \file GraphicsConverter.h
|
||||
* Copyright 2002 the LyX Team
|
||||
* Read the file COPYING
|
||||
*
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*
|
||||
* class grfx::GConverter enables graphics files to be converted asynchronously
|
||||
* to a loadable format. It does this by building a shell script of all
|
||||
* the conversion commands needed for the transformation. This script is then
|
||||
* sent to the forked calls controller for non-blocking execution. When it
|
||||
* is finished a signal is emitted, thus informing us to proceed with the
|
||||
* loading of the image.
|
||||
*
|
||||
* Ultimately, this class should be wrapped back into Dekel's converter class.
|
||||
* The controller of a conversion process from file AA of format A to
|
||||
* file BB of format B.
|
||||
* Once finished, the signal finishdConversion is emitted to inform the
|
||||
* instigator where to find file BB.
|
||||
* If the conversion is unsuccessful, then finishedConversion will pass
|
||||
* an empty string.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICSCONVERTER_H
|
||||
#define GRAPHICSCONVERTER_H
|
||||
|
||||
#include "LString.h"
|
||||
#include "Lsstream.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/signals/signal1.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <sys/types.h> // needed for pid_t
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
#include "LString.h"
|
||||
#include <boost/signals/signal1.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class ConvProcess;
|
||||
|
||||
class GConverter : boost::noncopyable {
|
||||
class Converter : boost::noncopyable {
|
||||
public:
|
||||
|
||||
/// This is a singleton class. Get the instance.
|
||||
static GConverter & get();
|
||||
|
||||
/// Can the conversion be performed?
|
||||
bool isReachable(string const & from_format_name,
|
||||
string const & to_format_name) const;
|
||||
static bool isReachable(string const & from_format_name,
|
||||
string const & to_format_name);
|
||||
|
||||
/** Convert the file and at the end return it by emitting this signal
|
||||
* If successful, the returned string will be the name of the
|
||||
* converted file (to_file_base + extension(to_format_name)).
|
||||
* If unsuccessful, the string will be empty.
|
||||
/** One Converter per conversion ensures that finishedConversion
|
||||
* is always connected to the expected slot.
|
||||
*/
|
||||
typedef boost::signal1<void, string const &> SignalType;
|
||||
Converter(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format);
|
||||
|
||||
/// Define an empty d-tor out-of-line to keep boost::scoped_ptr happy.
|
||||
~Converter();
|
||||
|
||||
/// We are explicit about when we begin the conversion process.
|
||||
void startConversion();
|
||||
|
||||
/** At the end of the conversion process inform the outside world
|
||||
* by emitting a signal.
|
||||
*/
|
||||
typedef boost::signal1<void, bool> SignalType;
|
||||
///
|
||||
typedef boost::shared_ptr<SignalType> SignalTypePtr;
|
||||
///
|
||||
void convert(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format,
|
||||
SignalTypePtr on_finish);
|
||||
SignalType finishedConversion;
|
||||
|
||||
/** If the convsion is succesful (finishedConversion returns \c true),
|
||||
* this returns the name of the resulting file.
|
||||
* If conversion fails, however, it returns an empty string.
|
||||
*/
|
||||
string const & convertedFile() const;
|
||||
|
||||
private:
|
||||
/** Make the c-tor private so we can control how many objects
|
||||
* are instantiated.
|
||||
*/
|
||||
GConverter() {}
|
||||
/// Use the Pimpl idiom to hide the internals.
|
||||
class Impl;
|
||||
|
||||
/** Build the conversion script, returning true if able to build it.
|
||||
* The script is output to the ostringstream 'script'.
|
||||
*/
|
||||
bool build_script(string const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format,
|
||||
ostringstream & script) const;
|
||||
|
||||
/** Remove the ConvProcess from the list of all processes.
|
||||
* Called by ConvProcess::converted.
|
||||
*/
|
||||
friend class ConvProcess;
|
||||
///
|
||||
void erase(ConvProcess *);
|
||||
|
||||
/// The list of all conversion processs
|
||||
typedef boost::shared_ptr<ConvProcess> ConvProcessPtr;
|
||||
///
|
||||
std::list<ConvProcessPtr> all_processes_;
|
||||
/// The pointer never changes although *pimpl_'s contents may.
|
||||
boost::scoped_ptr<Impl> const pimpl_;
|
||||
};
|
||||
|
||||
|
||||
/// Each ConvProcess represents a single conversion process.
|
||||
struct ConvProcess : public boost::signals::trackable
|
||||
{
|
||||
///
|
||||
typedef GConverter::SignalTypePtr SignalTypePtr;
|
||||
|
||||
/** Each ConvProcess represents a single conversion process.
|
||||
* It is passed :
|
||||
* 1. The name of the script_file, which it deletes once the
|
||||
* conversion is comlpeted;
|
||||
* 2. The script command itself, which it passes on to the forked
|
||||
* call process;
|
||||
* 3. The name of the output file, which it returns to the calling
|
||||
* process on successfull completion, by emitting
|
||||
* 4. The signal on_finish.
|
||||
*/
|
||||
ConvProcess(string const & script_file, string const & script_command,
|
||||
string const & to_file, SignalTypePtr on_finish);
|
||||
|
||||
/** This method is connected to a signal passed to the forked call
|
||||
* class, passing control back here when the conversion is completed.
|
||||
* Cleans-up the temporary files, emits the on_finish signal and
|
||||
* removes the ConvProcess from the list of all processes.
|
||||
*/
|
||||
void converted(string const & cmd, pid_t pid, int retval);
|
||||
|
||||
///
|
||||
string script_file_;
|
||||
///
|
||||
string to_file_;
|
||||
///
|
||||
SignalTypePtr on_finish_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
#endif // GRAPHICSCONVERTER_H
|
||||
|
@ -18,15 +18,15 @@
|
||||
|
||||
namespace grfx {
|
||||
|
||||
// This will be connected to a function that will return whichever
|
||||
// whichever derived class we desire.
|
||||
boost::signal0<ImagePtr> GImage::newImage;
|
||||
// This is to be connected to a function that will return a new
|
||||
// instance of a viable derived class.
|
||||
boost::signal0<Image::ImagePtr> Image::newImage;
|
||||
|
||||
/// Return the list of loadable formats.
|
||||
boost::signal0<GImage::FormatList> GImage::loadableFormats;
|
||||
boost::signal0<Image::FormatList> Image::loadableFormats;
|
||||
|
||||
std::pair<unsigned int, unsigned int>
|
||||
GImage::getScaledDimensions(GParams const & params) const
|
||||
Image::getScaledDimensions(Params const & params) const
|
||||
{
|
||||
if (params.scale == 0 && params.width == 0 && params.height == 0)
|
||||
// No scaling
|
||||
|
@ -23,14 +23,12 @@
|
||||
#define GRAPHICSIMAGE_H
|
||||
|
||||
#include "LString.h"
|
||||
#include "GraphicsTypes.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <boost/signals/signal0.hpp>
|
||||
#include <boost/signals/signal1.hpp>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/X.h> // for Pixmap :-(
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
@ -41,26 +39,31 @@
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class GParams;
|
||||
class Params;
|
||||
|
||||
class GImage
|
||||
{
|
||||
class Image {
|
||||
public:
|
||||
/// A list of supported formats.
|
||||
typedef std::vector<string> FormatList;
|
||||
/** This will be connected to a function that will return whichever
|
||||
* derived class we desire.
|
||||
/** This is to be connected to a function that will return a new
|
||||
* instance of a viable derived class.
|
||||
*/
|
||||
typedef boost::shared_ptr<Image> ImagePtr;
|
||||
///
|
||||
static boost::signal0<ImagePtr> newImage;
|
||||
|
||||
/// Return the list of loadable formats.
|
||||
typedef std::vector<string> FormatList;
|
||||
///
|
||||
static boost::signal0<FormatList> loadableFormats;
|
||||
|
||||
/// Must define default c-tor explicitly as we define a copy c-tor.
|
||||
Image() {}
|
||||
/// Don't copy the signal finishedLoading
|
||||
Image(Image const &) {}
|
||||
///
|
||||
virtual ~GImage() {}
|
||||
virtual ~Image() {}
|
||||
|
||||
/// Create a copy
|
||||
virtual GImage * clone() const = 0;
|
||||
virtual Image * clone() const = 0;
|
||||
|
||||
///
|
||||
virtual Pixmap getPixmap() const = 0;
|
||||
@ -71,37 +74,41 @@ public:
|
||||
/// Get the image height
|
||||
virtual unsigned int getHeight() const = 0;
|
||||
|
||||
/** At the end of the loading or modification process, return the new
|
||||
* image by emitting this signal */
|
||||
/** At the end of the loading process inform the outside world
|
||||
* by emitting a signal.
|
||||
*/
|
||||
typedef boost::signal1<void, bool> SignalType;
|
||||
///
|
||||
typedef boost::shared_ptr<SignalType> SignalTypePtr;
|
||||
SignalType finishedLoading;
|
||||
|
||||
/// Start loading the image file.
|
||||
virtual void load(string const & filename, SignalTypePtr) = 0;
|
||||
/** Start loading the image file.
|
||||
* The caller should expect this process to be asynchronous and
|
||||
* so should connect to the "finished" signal above.
|
||||
*/
|
||||
virtual void load(string const & filename) = 0;
|
||||
|
||||
/** Generate the pixmap.
|
||||
* Uses the params to decide on color, grayscale etc.
|
||||
* Returns true if the pixmap is created.
|
||||
*/
|
||||
virtual bool setPixmap(GParams const & params) = 0;
|
||||
virtual bool setPixmap(Params const & params) = 0;
|
||||
|
||||
/// Clip the image using params.
|
||||
virtual void clip(GParams const & params) = 0;
|
||||
virtual void clip(Params const & params) = 0;
|
||||
|
||||
/// Rotate the image using params.
|
||||
virtual void rotate(GParams const & params) = 0;
|
||||
virtual void rotate(Params const & params) = 0;
|
||||
|
||||
/// Scale the image using params.
|
||||
virtual void scale(GParams const & params) = 0;
|
||||
virtual void scale(Params const & params) = 0;
|
||||
|
||||
protected:
|
||||
/** Uses the params to ascertain the dimensions of the scaled image.
|
||||
* Returned as make_pair(width, height).
|
||||
* If something geso wrong, returns make_pair(getWidth(), getHeight())
|
||||
* If something goes wrong, returns make_pair(getWidth(), getHeight())
|
||||
*/
|
||||
std::pair<unsigned int, unsigned int>
|
||||
getScaledDimensions(GParams const & params) const;
|
||||
getScaledDimensions(Params const & params) const;
|
||||
};
|
||||
|
||||
} // namespace grfx
|
||||
|
@ -37,16 +37,16 @@ using std::strlen;
|
||||
namespace grfx {
|
||||
|
||||
/// Access to this class is through this static method.
|
||||
ImagePtr GImageXPM::newImage()
|
||||
Image::ImagePtr ImageXPM::newImage()
|
||||
{
|
||||
ImagePtr ptr;
|
||||
ptr.reset(new GImageXPM);
|
||||
ptr.reset(new ImageXPM);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/// Return the list of loadable formats.
|
||||
GImage::FormatList GImageXPM::loadableFormats()
|
||||
Image::FormatList ImageXPM::loadableFormats()
|
||||
{
|
||||
FormatList formats(1);
|
||||
formats[0] = "xpm";
|
||||
@ -54,46 +54,46 @@ GImage::FormatList GImageXPM::loadableFormats()
|
||||
}
|
||||
|
||||
|
||||
GImageXPM::GImageXPM()
|
||||
ImageXPM::ImageXPM()
|
||||
: pixmap_(0),
|
||||
pixmap_status_(PIXMAP_UNINITIALISED)
|
||||
{}
|
||||
|
||||
|
||||
GImageXPM::GImageXPM(GImageXPM const & other)
|
||||
: GImage(other),
|
||||
ImageXPM::ImageXPM(ImageXPM const & other)
|
||||
: Image(other),
|
||||
image_(other.image_),
|
||||
pixmap_(0),
|
||||
pixmap_status_(PIXMAP_UNINITIALISED)
|
||||
{}
|
||||
|
||||
|
||||
GImageXPM::~GImageXPM()
|
||||
ImageXPM::~ImageXPM()
|
||||
{
|
||||
if (pixmap_)
|
||||
XFreePixmap(fl_get_display(), pixmap_);
|
||||
}
|
||||
|
||||
|
||||
GImage * GImageXPM::clone() const
|
||||
Image * ImageXPM::clone() const
|
||||
{
|
||||
return new GImageXPM(*this);
|
||||
return new ImageXPM(*this);
|
||||
}
|
||||
|
||||
|
||||
unsigned int GImageXPM::getWidth() const
|
||||
unsigned int ImageXPM::getWidth() const
|
||||
{
|
||||
return image_.width();
|
||||
}
|
||||
|
||||
|
||||
unsigned int GImageXPM::getHeight() const
|
||||
unsigned int ImageXPM::getHeight() const
|
||||
{
|
||||
return image_.height();
|
||||
}
|
||||
|
||||
|
||||
Pixmap GImageXPM::getPixmap() const
|
||||
Pixmap ImageXPM::getPixmap() const
|
||||
{
|
||||
if (!pixmap_status_ == PIXMAP_SUCCESS)
|
||||
return 0;
|
||||
@ -101,17 +101,17 @@ Pixmap GImageXPM::getPixmap() const
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::load(string const & filename, GImage::SignalTypePtr on_finish)
|
||||
void ImageXPM::load(string const & filename)
|
||||
{
|
||||
if (filename.empty()) {
|
||||
on_finish->operator()(false);
|
||||
finishedLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!image_.empty()) {
|
||||
lyxerr[Debug::GRAPHICS]
|
||||
<< "Image is loaded already!" << std::endl;
|
||||
on_finish->operator()(false);
|
||||
finishedLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -151,11 +151,11 @@ void GImageXPM::load(string const & filename, GImage::SignalTypePtr on_finish)
|
||||
image_.reset(*xpm_image);
|
||||
}
|
||||
|
||||
on_finish->operator()(success == XpmSuccess);
|
||||
finishedLoading(success == XpmSuccess);
|
||||
}
|
||||
|
||||
|
||||
bool GImageXPM::setPixmap(GParams const & params)
|
||||
bool ImageXPM::setPixmap(Params const & params)
|
||||
{
|
||||
if (image_.empty() || params.display == NoDisplay) {
|
||||
return false;
|
||||
@ -235,7 +235,7 @@ bool GImageXPM::setPixmap(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::clip(GParams const & params)
|
||||
void ImageXPM::clip(Params const & params)
|
||||
{
|
||||
if (image_.empty())
|
||||
return;
|
||||
@ -279,7 +279,7 @@ void GImageXPM::clip(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::rotate(GParams const & params)
|
||||
void ImageXPM::rotate(Params const & params)
|
||||
{
|
||||
if (image_.empty())
|
||||
return ;
|
||||
@ -349,7 +349,7 @@ void GImageXPM::rotate(GParams const & params)
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::scale(GParams const & params)
|
||||
void ImageXPM::scale(Params const & params)
|
||||
{
|
||||
if (image_.empty())
|
||||
return;
|
||||
@ -419,19 +419,19 @@ void mapcolor(char const * c_color, char ** g_color_ptr, char ** m_color_ptr);
|
||||
|
||||
namespace grfx {
|
||||
|
||||
GImageXPM::Data::Data()
|
||||
ImageXPM::Data::Data()
|
||||
: width_(0), height_(0), cpp_(0), ncolors_(0)
|
||||
{}
|
||||
|
||||
|
||||
GImageXPM::Data::~Data()
|
||||
ImageXPM::Data::~Data()
|
||||
{
|
||||
if (colorTable_.unique())
|
||||
free_color_table(colorTable_.get(), ncolors_);
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::Data::reset(XpmImage & image)
|
||||
void ImageXPM::Data::reset(XpmImage & image)
|
||||
{
|
||||
width_ = image.width;
|
||||
height_ = image.height;
|
||||
@ -511,7 +511,7 @@ void GImageXPM::Data::reset(XpmImage & image)
|
||||
}
|
||||
|
||||
|
||||
XpmImage GImageXPM::Data::get() const
|
||||
XpmImage ImageXPM::Data::get() const
|
||||
{
|
||||
XpmImage image;
|
||||
image.width = width_;
|
||||
@ -524,7 +524,7 @@ XpmImage GImageXPM::Data::get() const
|
||||
}
|
||||
|
||||
|
||||
void GImageXPM::Data::resetData(int w, int h, unsigned int * d)
|
||||
void ImageXPM::Data::resetData(int w, int h, unsigned int * d)
|
||||
{
|
||||
width_ = w;
|
||||
height_ = h;
|
||||
@ -532,7 +532,7 @@ void GImageXPM::Data::resetData(int w, int h, unsigned int * d)
|
||||
}
|
||||
|
||||
|
||||
unsigned int * GImageXPM::Data::initialisedData(int w, int h) const
|
||||
unsigned int * ImageXPM::Data::initialisedData(int w, int h) const
|
||||
{
|
||||
size_t const data_size = w * h;
|
||||
|
||||
@ -546,7 +546,7 @@ unsigned int * GImageXPM::Data::initialisedData(int w, int h) const
|
||||
}
|
||||
|
||||
|
||||
unsigned int GImageXPM::Data::color_none_id() const
|
||||
unsigned int ImageXPM::Data::color_none_id() const
|
||||
{
|
||||
XpmColor * table = colorTable_.get();
|
||||
for (size_t i = 0; i < ncolors_; ++i) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
* \author Baruch Even <baruch.even@writeme.com>
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*
|
||||
* An instantiation of GImage that makes use of libXPM to load and store
|
||||
* An instantiation of Image that makes use of libXPM to load and store
|
||||
* the image in memory.
|
||||
*/
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class GImageXPM : public GImage
|
||||
class ImageXPM : public Image
|
||||
{
|
||||
public:
|
||||
/// Access to this class is through this static method.
|
||||
@ -34,10 +34,10 @@ public:
|
||||
static FormatList loadableFormats();
|
||||
|
||||
///
|
||||
~GImageXPM();
|
||||
~ImageXPM();
|
||||
|
||||
/// Create a copy
|
||||
GImage * clone() const;
|
||||
Image * clone() const;
|
||||
|
||||
///
|
||||
Pixmap getPixmap() const;
|
||||
@ -49,31 +49,31 @@ public:
|
||||
unsigned int getHeight() const;
|
||||
|
||||
/** Load the image file into memory.
|
||||
* In this case (GImageXPM), the process is blocking.
|
||||
* In this case (ImageXPM), the process is blocking.
|
||||
*/
|
||||
void load(string const & filename, SignalTypePtr);
|
||||
void load(string const & filename);
|
||||
|
||||
/** 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);
|
||||
bool setPixmap(Params const & params);
|
||||
|
||||
/// Clip the image using params.
|
||||
void clip(GParams const & params);
|
||||
void clip(Params const & params);
|
||||
|
||||
/// Rotate the image using params.
|
||||
void rotate(GParams const & params);
|
||||
void rotate(Params const & params);
|
||||
|
||||
/// Scale the image using params.
|
||||
void scale(GParams const & params);
|
||||
void scale(Params const & params);
|
||||
|
||||
private:
|
||||
/// Access to the class is through newImage() and clone.
|
||||
GImageXPM();
|
||||
ImageXPM();
|
||||
///
|
||||
GImageXPM(GImageXPM const &);
|
||||
ImageXPM(ImageXPM const &);
|
||||
|
||||
/** Contains the data read from file.
|
||||
* This class is a wrapper for a XpmImage struct, but all views
|
||||
|
@ -19,103 +19,111 @@
|
||||
#include "GraphicsParams.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/signals/trackable.hpp>
|
||||
|
||||
namespace grfx {
|
||||
|
||||
struct Loader::Impl {
|
||||
struct Loader::Impl : boost::signals::trackable {
|
||||
///
|
||||
Impl(Loader &, GParams const &);
|
||||
Impl(Loader &, Params const &);
|
||||
///
|
||||
~Impl();
|
||||
///
|
||||
void setFile(string const & file);
|
||||
void resetFile(string const &);
|
||||
///
|
||||
void unsetOldFile();
|
||||
void resetParams(Params const &);
|
||||
///
|
||||
void createPixmap();
|
||||
///
|
||||
void statusChanged();
|
||||
|
||||
///
|
||||
Loader & parent_;
|
||||
/// The loading status of the image.
|
||||
ImageStatus status_;
|
||||
/** Must store a copy of the cached item to ensure that it is not
|
||||
* erased unexpectedly by the cache itself.
|
||||
*/
|
||||
GraphicPtr graphic_;
|
||||
///
|
||||
GParams params_;
|
||||
Cache::ItemPtr cached_item_;
|
||||
/// We modify a local copy of the image once it is loaded.
|
||||
ImagePtr image_;
|
||||
Image::ImagePtr image_;
|
||||
|
||||
private:
|
||||
///
|
||||
void statusChanged();
|
||||
|
||||
///
|
||||
Params params_;
|
||||
///
|
||||
Loader & parent_;
|
||||
};
|
||||
|
||||
|
||||
Loader::Impl::Impl(Loader & parent, GParams const & params)
|
||||
: parent_(parent), status_(WaitingToLoad), params_(params)
|
||||
Loader::Impl::Impl(Loader & parent, Params const & params)
|
||||
: status_(WaitingToLoad), params_(params), parent_(parent)
|
||||
{}
|
||||
|
||||
|
||||
Loader::Impl::~Impl()
|
||||
{
|
||||
unsetOldFile();
|
||||
resetFile(string());
|
||||
}
|
||||
|
||||
|
||||
void Loader::Impl::setFile(string const & file)
|
||||
void Loader::Impl::resetFile(string const & file)
|
||||
{
|
||||
if (file.empty())
|
||||
string const old_file = cached_item_.get() ?
|
||||
cached_item_->filename() : string();
|
||||
|
||||
if (file == old_file)
|
||||
return;
|
||||
|
||||
GCache & gc = GCache::get();
|
||||
if (!old_file.empty()) {
|
||||
cached_item_.reset();
|
||||
Cache::get().remove(old_file);
|
||||
}
|
||||
|
||||
status_ = cached_item_.get() ? cached_item_->status() : WaitingToLoad;
|
||||
image_.reset();
|
||||
|
||||
if (cached_item_.get() || file.empty())
|
||||
return;
|
||||
|
||||
Cache & gc = Cache::get();
|
||||
if (!gc.inCache(file))
|
||||
gc.add(file);
|
||||
|
||||
// We /must/ make a local copy of this.
|
||||
graphic_ = gc.graphic(file);
|
||||
status_ = graphic_->status();
|
||||
cached_item_ = gc.item(file);
|
||||
status_ = cached_item_->status();
|
||||
|
||||
if (status_ == Loaded) {
|
||||
createPixmap();
|
||||
}
|
||||
|
||||
// It's easiest to do this without checking
|
||||
parent_.statusChanged();
|
||||
cached_item_->statusChanged.connect(
|
||||
boost::bind(&Impl::statusChanged, this));
|
||||
}
|
||||
|
||||
|
||||
void Loader::Impl::unsetOldFile()
|
||||
void Loader::Impl::resetParams(Params const & params)
|
||||
{
|
||||
if (!graphic_.get())
|
||||
if (params == params_)
|
||||
return;
|
||||
|
||||
string const old_file = graphic_->filename();
|
||||
graphic_.reset();
|
||||
GCache::get().remove(old_file);
|
||||
|
||||
status_ = WaitingToLoad;
|
||||
params_ = GParams();
|
||||
params_ = params;
|
||||
status_ = cached_item_.get() ? cached_item_->status() : WaitingToLoad;
|
||||
image_.reset();
|
||||
}
|
||||
|
||||
|
||||
void Loader::Impl::statusChanged()
|
||||
{
|
||||
status_ = graphic_->status();
|
||||
if (status_ == Loaded)
|
||||
createPixmap();
|
||||
|
||||
status_ = cached_item_.get() ? cached_item_->status() : WaitingToLoad;
|
||||
createPixmap();
|
||||
parent_.statusChanged();
|
||||
}
|
||||
|
||||
|
||||
void Loader::Impl::createPixmap()
|
||||
{
|
||||
if (!graphic_.get() || image_.get() ||
|
||||
if (!cached_item_.get() || image_.get() ||
|
||||
params_.display == NoDisplay || status_ != Loaded)
|
||||
return;
|
||||
|
||||
image_.reset(graphic_->image()->clone());
|
||||
image_.reset(cached_item_->image()->clone());
|
||||
|
||||
// These do nothing if there's nothing to do
|
||||
image_->clip(params_);
|
||||
@ -134,22 +142,21 @@ void Loader::Impl::createPixmap()
|
||||
|
||||
|
||||
Loader::Loader()
|
||||
: pimpl_(new Impl(*this, GParams()))
|
||||
: pimpl_(new Impl(*this, Params()))
|
||||
{}
|
||||
|
||||
|
||||
Loader::Loader(string const & file, DisplayType type)
|
||||
: pimpl_(new Impl(*this, GParams()))
|
||||
: pimpl_(new Impl(*this, Params()))
|
||||
{
|
||||
pimpl_->params_.display = type;
|
||||
pimpl_->setFile(file);
|
||||
reset(file, type);
|
||||
}
|
||||
|
||||
|
||||
Loader::Loader(string const & file, GParams const & params)
|
||||
Loader::Loader(string const & file, Params const & params)
|
||||
: pimpl_(new Impl(*this, params))
|
||||
{
|
||||
pimpl_->setFile(file);
|
||||
reset(file, params);
|
||||
}
|
||||
|
||||
|
||||
@ -159,48 +166,43 @@ Loader::~Loader()
|
||||
|
||||
void Loader::reset(string const & file, DisplayType type)
|
||||
{
|
||||
pimpl_->unsetOldFile();
|
||||
Params params;
|
||||
params.display = type;
|
||||
pimpl_->resetParams(params);
|
||||
|
||||
pimpl_->params_ = GParams();
|
||||
pimpl_->params_.display = type;
|
||||
pimpl_->setFile(file);
|
||||
pimpl_->resetFile(file);
|
||||
pimpl_->createPixmap();
|
||||
}
|
||||
|
||||
|
||||
void Loader::reset(string const & file, GParams const & params)
|
||||
void Loader::reset(string const & file, Params const & params)
|
||||
{
|
||||
pimpl_->unsetOldFile();
|
||||
|
||||
pimpl_->params_ = params;
|
||||
pimpl_->setFile(file);
|
||||
pimpl_->resetParams(params);
|
||||
pimpl_->resetFile(file);
|
||||
pimpl_->createPixmap();
|
||||
}
|
||||
|
||||
|
||||
void Loader::reset(GParams const & params)
|
||||
void Loader::reset(Params const & params)
|
||||
{
|
||||
pimpl_->params_ = params;
|
||||
|
||||
if (pimpl_->status_ == Loaded)
|
||||
pimpl_->createPixmap();
|
||||
pimpl_->resetParams(params);
|
||||
pimpl_->createPixmap();
|
||||
}
|
||||
|
||||
|
||||
void Loader::startLoading()
|
||||
{
|
||||
if (pimpl_->status_ != WaitingToLoad || !pimpl_->graphic_.get())
|
||||
if (pimpl_->status_ != WaitingToLoad || !pimpl_->cached_item_.get())
|
||||
return;
|
||||
|
||||
pimpl_->graphic_->statusChanged.connect(
|
||||
boost::bind(&Loader::Impl::statusChanged,
|
||||
pimpl_.get()));
|
||||
pimpl_->graphic_->startLoading();
|
||||
pimpl_->cached_item_->startLoading();
|
||||
}
|
||||
|
||||
|
||||
string const & Loader::filename() const
|
||||
{
|
||||
static string const empty;
|
||||
return pimpl_->graphic_.get() ? pimpl_->graphic_->filename() : empty;
|
||||
return pimpl_->cached_item_.get() ?
|
||||
pimpl_->cached_item_->filename() : empty;
|
||||
}
|
||||
|
||||
|
||||
@ -210,7 +212,7 @@ ImageStatus Loader::status() const
|
||||
}
|
||||
|
||||
|
||||
GImage const * Loader::image() const
|
||||
Image const * Loader::image() const
|
||||
{
|
||||
return pimpl_->image_.get();
|
||||
}
|
||||
|
@ -6,7 +6,8 @@
|
||||
*
|
||||
* \author Angus Leeming <leeming@lyx.org>
|
||||
*
|
||||
* The public view of the graphics cache.
|
||||
* The public face of the graphics cache.
|
||||
*
|
||||
* * The user supplies an image file and the display parameters.
|
||||
* * He can change the file or the display parameters through a reset() method.
|
||||
* * He must start the loading process explicitly with startLoading().
|
||||
@ -32,11 +33,9 @@
|
||||
|
||||
namespace grfx {
|
||||
|
||||
class GParams;
|
||||
class Image;
|
||||
class Params;
|
||||
|
||||
/** One image, one instance of grfx::Loader, although the image can be
|
||||
* changed.
|
||||
*/
|
||||
class Loader {
|
||||
public:
|
||||
/// Must use the reset methods to make this instance usable.
|
||||
@ -44,7 +43,7 @@ public:
|
||||
/// The image is not transformed, just displayed as-is.
|
||||
Loader(string const & file_with_path, DisplayType = ColorDisplay);
|
||||
/// The image is transformed before display.
|
||||
Loader(string const & file_with_path, GParams const &);
|
||||
Loader(string const & file_with_path, Params const &);
|
||||
|
||||
/// Define an empty d-tor out-of-line to keep boost::scoped_ptr happy.
|
||||
~Loader();
|
||||
@ -52,9 +51,9 @@ public:
|
||||
/// The file can be changed, or the display params, or both.
|
||||
void reset(string const & file_with_path, DisplayType = ColorDisplay);
|
||||
///
|
||||
void reset(string const & file_with_path, GParams const &);
|
||||
void reset(string const & file_with_path, Params const &);
|
||||
///
|
||||
void reset(GParams const &);
|
||||
void reset(Params const &);
|
||||
|
||||
/// Returns the absolute path of the loaded (loading?) file.
|
||||
string const & filename() const;
|
||||
@ -73,7 +72,7 @@ public:
|
||||
/** The loaded image with Pixmap set.
|
||||
* If the Pixmap is not yet set (see status() for why...), returns 0.
|
||||
*/
|
||||
GImage const * image() const;
|
||||
Image const * image() const;
|
||||
|
||||
private:
|
||||
/// Use the Pimpl idiom to hide the internals.
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
namespace grfx {
|
||||
|
||||
GParams::GParams()
|
||||
Params::Params()
|
||||
: display(ColorDisplay),
|
||||
width(0),
|
||||
height(0),
|
||||
@ -28,7 +28,7 @@ GParams::GParams()
|
||||
{}
|
||||
|
||||
|
||||
bool operator==(GParams const & a, GParams const & b)
|
||||
bool operator==(Params const & a, Params const & b)
|
||||
{
|
||||
return (a.filename == b.filename &&
|
||||
a.display == b.display &&
|
||||
@ -40,7 +40,7 @@ bool operator==(GParams const & a, GParams const & b)
|
||||
}
|
||||
|
||||
|
||||
bool operator!=(GParams const & a, GParams const & b)
|
||||
bool operator!=(Params const & a, Params const & b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
@ -43,9 +43,9 @@ struct BoundingBox {
|
||||
bool operator==(BoundingBox const &, BoundingBox const &);
|
||||
bool operator!=(BoundingBox const &, BoundingBox const &);
|
||||
|
||||
struct GParams
|
||||
struct Params
|
||||
{
|
||||
GParams();
|
||||
Params();
|
||||
|
||||
DisplayType display;
|
||||
|
||||
@ -69,8 +69,8 @@ struct GParams
|
||||
int angle;
|
||||
};
|
||||
|
||||
bool operator==(GParams const &, GParams const &);
|
||||
bool operator!=(GParams const &, GParams const &);
|
||||
bool operator==(Params const &, Params const &);
|
||||
bool operator!=(Params const &, Params const &);
|
||||
|
||||
} // namespace grfx
|
||||
|
||||
|
@ -7,30 +7,18 @@
|
||||
* \author Angus Leeming <a.leeming@ic.ac.uk>
|
||||
*
|
||||
* All that header files outside the graphics subdirectory should need to
|
||||
* access. That just leaves insetgraphics.C to access GraphicsCache.h.
|
||||
* It also makes life easier for files inside the graphics subdirectory!
|
||||
* access.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICSTYPES_H
|
||||
#define GRAPHICSTYPES_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
namespace grfx {
|
||||
|
||||
///
|
||||
class GImage;
|
||||
///
|
||||
typedef boost::shared_ptr<GImage> ImagePtr;
|
||||
///
|
||||
class GCacheItem;
|
||||
/// The cache contains data of this type.
|
||||
typedef boost::shared_ptr<GCacheItem> GraphicPtr;
|
||||
|
||||
/// The status of the loading process
|
||||
enum ImageStatus {
|
||||
/** The data is in the cache, but no request to display it
|
||||
|
@ -1,3 +1,10 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* insetgraphicsParams.[Ch]: forward declare grfx::Params.
|
||||
rename asGParams -> as_grfxParams.
|
||||
|
||||
* insetgraphics.C: reflect above change.
|
||||
|
||||
2002-06-26 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* insetgraphics.h: use boost::scoped_ptr in preference to
|
||||
|
@ -80,6 +80,7 @@ TODO Before initial production release:
|
||||
|
||||
#include "graphics/GraphicsLoader.h"
|
||||
#include "graphics/GraphicsImage.h"
|
||||
#include "graphics/GraphicsParams.h"
|
||||
|
||||
#include "frontends/LyXView.h"
|
||||
#include "lyxtext.h"
|
||||
@ -181,7 +182,7 @@ void InsetGraphics::Cache::update(string const & file_with_path)
|
||||
lyx::Assert(!file_with_path.empty());
|
||||
|
||||
string const path = OnlyPath(file_with_path);
|
||||
loader.reset(file_with_path, parent_.params().asGParams(path));
|
||||
loader.reset(file_with_path, parent_.params().as_grfxParams(path));
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "insetgraphicsParams.h"
|
||||
|
||||
#include "graphics/GraphicsParams.h"
|
||||
|
||||
#include "support/translator.h"
|
||||
#include "support/filetools.h"
|
||||
#include "support/lyxlib.h"
|
||||
@ -307,9 +309,9 @@ bool InsetGraphicsParams::Read(LyXLex & lex, string const & token)
|
||||
}
|
||||
|
||||
|
||||
grfx::GParams InsetGraphicsParams::asGParams(string const & filepath) const
|
||||
grfx::Params InsetGraphicsParams::as_grfxParams(string const & filepath) const
|
||||
{
|
||||
grfx::GParams pars;
|
||||
grfx::Params pars;
|
||||
pars.width = 0;
|
||||
pars.height = 0;
|
||||
pars.scale = 0;
|
||||
|
@ -22,8 +22,9 @@
|
||||
#include "buffer.h"
|
||||
#include "lyxlex.h"
|
||||
|
||||
#include "graphics/GraphicsParams.h"
|
||||
|
||||
namespace grfx {
|
||||
class Params;
|
||||
}
|
||||
|
||||
/// This struct holds all the parameters needed by insetGraphics.
|
||||
struct InsetGraphicsParams
|
||||
@ -98,7 +99,7 @@ struct InsetGraphicsParams
|
||||
// Only a subset of InsetGraphicsParams is needed for display purposes.
|
||||
// This function also interrogates lyxrc to ascertain whether
|
||||
// to display or not.
|
||||
grfx::GParams asGParams(string const & filepath) const;
|
||||
grfx::Params as_grfxParams(string const & filepath) const;
|
||||
|
||||
private:
|
||||
/// Initialize the object to a default status.
|
||||
|
@ -1,3 +1,6 @@
|
||||
2002-06-28 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* preview.h (preview): don't pass grfx::GraphicPtr & anymore.
|
||||
|
||||
2002-06-24 André Pönitz <poenitz@gmx.net>
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
#define PREVIEW_H
|
||||
|
||||
#include "LString.h"
|
||||
#include "graphics/GraphicsTypes.h"
|
||||
|
||||
bool preview(string const & str, grfx::GraphicPtr & graphic);
|
||||
bool preview(string const & str);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user