From 9ab27bcd7e601aedc6253808007105f4e4545661 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrgen=20Vigna?= Date: Tue, 8 Aug 2000 09:18:39 +0000 Subject: [PATCH] Baruch's graphic-inset patch. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@957 a592a061-630c-0410-9148-cb99ea01b6c8 --- ChangeLog | 33 +++++++ src/buffer.C | 2 +- src/frontends/xforms/FormGraphics.C | 2 + src/frontends/xforms/FormGraphics.h | 3 +- src/frontends/xforms/form_graphics.C | 2 +- src/graphics/GraphicsCache.C | 25 +++++- src/graphics/GraphicsCache.h | 5 ++ src/graphics/GraphicsCacheItem.C | 128 +++++++++++++++++++++++++++ src/graphics/GraphicsCacheItem.h | 91 ++++++++++++++++++- src/graphics/Makefile.am | 4 + src/insets/figinset.C | 2 + src/insets/insetgraphics.C | 81 ++++++++++++----- src/insets/insetgraphics.h | 16 +++- src/insets/insetgraphicsParams.C | 10 +-- src/insets/insetgraphicsParams.h | 1 + src/lyxfunc.C | 5 +- src/support/translator.h | 7 +- 17 files changed, 369 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52bacc1e78..8b9d4a4f10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2000-08-07 Baruch Even + + * src/graphics/Renderer.h: + * src/graphics/Renderer.C: Added base class for rendering of different + image formats into Pixmaps. + + * src/graphics/XPM_Renderer.h: + * src/graphics/XPM_Renderer.C: Taken from GraphicsCacheItem and placed + in a different class. + + * src/graphics/GraphicsCacheItem.C: factored out the rendering in order to + easily add support for other formats. + + * src/insets/figinset.C: plugged a leak of an X resource. + 2000-08-07 Lars Gullik Bjønnes * src/CutAndPaste.[Ch]: make all metods static. @@ -50,6 +65,24 @@ * src/tabular.C (UseParbox): new function +2000-08-06 Baruch Even + + * src/graphics/GraphicsCache.h: + * src/graphics/GraphicsCache.C: + * src/graphics/GraphicsCacheItem.h: + * src/graphics/GraphicsCacheItem.C: Made them to actually do something + usefull. + + * src/insets/insetgraphics.h: + * src/insets/insetgraphics.C: Added the use of the GraphicsCache and the + drawing of the inline image. + + * src/buffer.C: Fixed a bug where a loaded InsetGraphics would be loaded + into the wrong position. + + * src/lyxfunc.C: When adding an InsetGraphics the edit dialog is now + launched. + 2000-08-05 Lars Gullik Bjønnes * src/support/translator.h: move all typedefs to public section diff --git a/src/buffer.C b/src/buffer.C index 613f0d8b1f..7e5395cabc 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -1039,8 +1039,8 @@ void Buffer::readInset(LyXLex & lex, LyXParagraph *& par, } else if (tmptok == "GRAPHICS") { Inset * inset = new InsetGraphics; inset->Read(this, lex); - ++pos; par->InsertInset(pos, inset, font); + ++pos; } else if (tmptok == "LatexCommand") { InsetCommandParams inscmd; inscmd.Read(lex); diff --git a/src/frontends/xforms/FormGraphics.C b/src/frontends/xforms/FormGraphics.C index 2abeba92ac..65582dbadf 100644 --- a/src/frontends/xforms/FormGraphics.C +++ b/src/frontends/xforms/FormGraphics.C @@ -14,6 +14,7 @@ #endif #include + #include "lyx_gui_misc.h" #include "gettext.h" #include FORMS_H_LOCATION @@ -517,3 +518,4 @@ void FormGraphics::InputCB(FL_OBJECT * ob, long) FormGraphics * pre = static_cast(ob->form->u_vdata); pre->input(); } + diff --git a/src/frontends/xforms/FormGraphics.h b/src/frontends/xforms/FormGraphics.h index 6375e4c69f..4cba3e2ba6 100644 --- a/src/frontends/xforms/FormGraphics.h +++ b/src/frontends/xforms/FormGraphics.h @@ -19,6 +19,7 @@ #define FORMGRAPHICS_H #include + #include "LString.h" #include "frontends/DialogBase.h" //#include "form_graphics.h" @@ -154,5 +155,3 @@ private: }; #endif - - diff --git a/src/frontends/xforms/form_graphics.C b/src/frontends/xforms/form_graphics.C index 293e2963c2..96289ef7be 100644 --- a/src/frontends/xforms/form_graphics.C +++ b/src/frontends/xforms/form_graphics.C @@ -1,5 +1,6 @@ // File modified by fdfix.sh for use by lyx (with xforms >= 0.88) and gettext #include + #include "lyx_gui_misc.h" #include "gettext.h" @@ -102,4 +103,3 @@ FD_form_graphics * FormGraphics::build_graphics() return fdui; } /*---------------------------------------*/ - diff --git a/src/graphics/GraphicsCache.C b/src/graphics/GraphicsCache.C index 1721b0c6f3..2c1d0915d6 100644 --- a/src/graphics/GraphicsCache.C +++ b/src/graphics/GraphicsCache.C @@ -17,6 +17,7 @@ #include "GraphicsCache.h" +#include "support/LAssert.h" GraphicsCache * GraphicsCache::singleton = 0; @@ -26,6 +27,7 @@ GraphicsCache::getInstance() { if (! singleton) { singleton = new GraphicsCache; + Assert(singleton != 0); } return singleton; @@ -34,7 +36,13 @@ GraphicsCache::getInstance() GraphicsCache::~GraphicsCache() { - delete singleton; + // Free the map. + //std::foreach(map.begin(), map.end(), ...); + // This is not really needed, it will only happen on program close and in + // any case the OS will release those resources (not doing it may have + // a good effect on closing time). + + delete singleton; } @@ -46,8 +54,19 @@ GraphicsCache::addFile(string const & filename) if (it != cache.end()) { return (*it).second; } - // INCOMPLETE! - return 0; + + GraphicsCacheItem * cacheItem = new GraphicsCacheItem(); + if (cacheItem == 0) { + return 0; + } + + bool result = cacheItem->setFilename(filename); + if (!result) + return 0; + + cache[filename] = cacheItem; + + return cacheItem; } diff --git a/src/graphics/GraphicsCache.h b/src/graphics/GraphicsCache.h index eba3413b19..5c887fbccb 100644 --- a/src/graphics/GraphicsCache.h +++ b/src/graphics/GraphicsCache.h @@ -52,5 +52,10 @@ private: typedef std::map CacheType; /// CacheType cache; + + // We need this so that an Item can tell the cache that it should be + // deleted. (to call removeFile). + // It also helps removing a warning gcc emits. + friend GraphicsCacheItem; }; #endif diff --git a/src/graphics/GraphicsCacheItem.C b/src/graphics/GraphicsCacheItem.C index c2704e62cb..3efca95af8 100644 --- a/src/graphics/GraphicsCacheItem.C +++ b/src/graphics/GraphicsCacheItem.C @@ -17,3 +17,131 @@ #include "GraphicsCacheItem.h" +#include "graphics/XPM_Renderer.h" +#include "support/filetools.h" +#include "debug.h" +#include "support/LAssert.h" +#include // unlink + +#include + +#include FORMS_H_LOCATION + +using std::endl; + +GraphicsCacheItem::GraphicsCacheItem() + : height_(-1), width_(-1), imageStatus_(Loading), + pixmap_(0), renderer(0) +{} + +GraphicsCacheItem::~GraphicsCacheItem() +{ + if (imageStatus_ == Loaded) { + XFreePixmap(fl_display, pixmap_); + } + + delete renderer; +} + +bool +GraphicsCacheItem::setFilename(string const & filename) +{ + imageStatus_ = Loading; + + renderer = new XPM_Renderer(); + if (renderXPM(filename)) + return true; + + return false; +} + +/*** Callback method ***/ + +typedef map CallbackMap; +static CallbackMap callbackMap; + +void +callback(string cmd, int retval) +{ + lyxerr << "callback, cmd="< imageDone; private: - /// - GraphicsCacheItem() {} + /// Private c-tor so that only GraphicsCache can create an instance. + GraphicsCacheItem(); + + /// Set the filename this item will be pointing too. + bool setFilename(string const & filename); + + /// Create an XPM file version of the image. + bool renderXPM(string const & filename); + + /// Load the image from XPM to memory Pixmap + void loadXPMImage(); + /// friend class GraphicsCache; + + /// The file name of the XPM file. + string xpmfile; + /// The image height + int height_; + /// The image width + int width_; + /// Is the pixmap loaded? + ImageStatus imageStatus_; + /// The image pixmap + Pixmap pixmap_; + /// The rendering object. + Renderer * renderer; + + /// The system caller, runs the convertor. + Systemcalls syscall; }; #endif diff --git a/src/graphics/Makefile.am b/src/graphics/Makefile.am index b54aa9d4b1..375172133b 100644 --- a/src/graphics/Makefile.am +++ b/src/graphics/Makefile.am @@ -7,6 +7,10 @@ ETAGS_ARGS = --lang=c++ INCLUDES = -I${srcdir}/../ $(SIGC_CFLAGS) libgraphics_la_SOURCES = \ + Renderer.h \ + Renderer.C \ + XPM_Renderer.h \ + XPM_Renderer.C \ GraphicsCache.h \ GraphicsCache.C \ GraphicsCacheItem.h \ diff --git a/src/insets/figinset.C b/src/insets/figinset.C index f4a836b6ad..8b6d750126 100644 --- a/src/insets/figinset.C +++ b/src/insets/figinset.C @@ -592,6 +592,8 @@ void runqueue() prop[i]); if (strcmp(p, "GHOSTVIEW") == 0) { err = false; + // We free it when we leave so we don't leak. + XFree(p); break; } XFree(p); diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 9955ca95e8..d745a133b6 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -42,11 +42,14 @@ Current PROBLEMS: we need to give latex quite a few translation commands and from the graphicx package docs it appears that it takes quite a bit of memory on the side of TeXing. - + + * How do we handle the inline viewing? we may need to show the same image + in several formats (color, monochrome, grayscale) or even in different + sizes, not to mention rotations! + TODO Basics: - * Add support for more features so that it will be useable as a drop in - replacement to insetfig. + * Add support for more features so that it will be better than insetfig. * Keep aspect ratio radio button * Create the GraphicsCache and FormatTranslator @@ -80,6 +83,9 @@ TODO Extended features: * If the dialog had no real change from previous time, do not mark document as changed. * Keep a tab on the image file, if it changes, update the lyx view. + * The image choosing dialog could show thumbnails of the image formats + it knows of, thus selection based on the image instead of based on + filename. */ /* NOTES: @@ -145,6 +151,7 @@ TODO Extended features: * This means to add the image inside the LyX file, usefull when * transferring the file around. */ + #ifdef __GNUG__ #pragma implementation @@ -178,8 +185,9 @@ using std::endl; InsetGraphics::InsetGraphics() #ifdef IG_OLDPARAMS : use_bb(false), hiresbb(false), angle(0.0), origin(DEFAULT) - ,keepaspectratio(false), scale(0.0), clip(false), draft(false) + ,keepaspectratio(false), scale(0.0), clip(false), draft(false) #endif + : cachehandle(0), bv_(0) {} InsetGraphics::~InsetGraphics() @@ -190,27 +198,28 @@ InsetGraphics::~InsetGraphics() int InsetGraphics::ascent(BufferView *, LyXFont const &) const { - - return 25; + if (cachehandle && + cachehandle->getImageStatus() == GraphicsCacheItem::Loaded) + return cachehandle->getHeight(); + else + return 50; } int InsetGraphics::descent(BufferView *, LyXFont const &) const { // this is not true if viewport is used and clip is not. - return 25; + return 0; } int InsetGraphics::width(BufferView *, LyXFont const &) const { - // Need to replace this with data coming from GraphicsCache -#ifdef IG_OLDPARAMS - if (bb.isSet()) { - return bb.urx - bb.llx + 2; - } -#endif - return 50; + if (cachehandle && + cachehandle->getImageStatus() == GraphicsCacheItem::Loaded) + return cachehandle->getWidth(); + else + return 50; } @@ -219,16 +228,30 @@ void InsetGraphics::draw(BufferView * bv, LyXFont const & font, { Painter & paint = bv->painter(); + // This will draw the graphics. As for now we only draw a // placeholder rectangele. - paint.rectangle(int(x)+2, baseline - ascent(bv, font), + if (cachehandle && + cachehandle->getImageStatus() == GraphicsCacheItem::Loaded) { + + paint.pixmap(int(x)+2, baseline - ascent(bv, font), + width(bv, font) - 4, + ascent(bv,font) + descent(bv,font), + cachehandle->getImage()); + } else { + paint.rectangle(int(x)+2, baseline - ascent(bv, font), width(bv, font) - 4, ascent(bv, font) + descent(bv, font)); + + } + + x += width(bv, font); } void InsetGraphics::Edit(BufferView *bv, int, int, unsigned int) { + bv_ = bv; bv->owner()->getDialogs() -> showGraphics(this); } @@ -241,7 +264,7 @@ Inset::EDITABLE InsetGraphics::Editable() const void InsetGraphics::Write(Buffer const * buf, ostream & os) const { - os << "Graphics FormatVersion 1" << endl; + os << "GRAPHICS FormatVersion 1" << endl; params.Write(buf, os); } @@ -606,16 +629,30 @@ void InsetGraphics::Validate(LaTeXFeatures & features) const void InsetGraphics::updateInset() { // If file changed... - //graphicscache.addFile(params.filename); - //bb = graphicscache.getBB(params.filename); - //pixmap = graphicscache.getPixmap(params.filename); + + GraphicsCache * gc = GraphicsCache::getInstance(); + GraphicsCacheItem * temp = 0; + + if (!params.filename.empty()) { + temp = gc->addFile(params.filename); + if (temp) + temp->imageDone.connect(slot(this, &InsetGraphics::imageDone)); + } + + delete cachehandle; + cachehandle = temp; + +} + +void InsetGraphics::imageDone() +{ + if (bv_) + bv_->updateInset(this, false); } bool InsetGraphics::setParams(InsetGraphicsParams const & params) { - // TODO: Make it return true only when the data has been changed. - // for this to work we still need to implement operator == in - // InsetGraphicsParams + // If nothing is changed, just return and say so. if (this->params == params) return false; diff --git a/src/insets/insetgraphics.h b/src/insets/insetgraphics.h index 4452599a8c..9a28714bfb 100644 --- a/src/insets/insetgraphics.h +++ b/src/insets/insetgraphics.h @@ -12,10 +12,13 @@ #ifndef INSET_GRAPHICS_H #define INSET_GRAPHICS_H + #ifdef __GNUG__ #pragma interface #endif +#include + #include "insets/lyxinset.h" #include "insets/insetgraphicsParams.h" @@ -25,13 +28,19 @@ #include "sigc++/signal_system.h" #ifdef SIGC_CXX_NAMESPACES using SigC::Signal0; +using SigC::slot; +using SigC::Object; #endif class Dialogs; class GraphicsCacheItem; /// -class InsetGraphics : public Inset { +#ifdef SIGC_CXX_NAMESPACES +class InsetGraphics : public Inset, public SigC::Object { +#else +class InsetGraphics : public Inset, public Object { +#endif public: /// InsetGraphics(); @@ -94,9 +103,14 @@ private: /// Update the inset after parameter change. void updateInset(); + /// Get notified when the inline image processing has finished. + void imageDone(); + /// The graphics cache handle. GraphicsCacheItem * cachehandle; + /// Holds the buffer view that we are associated with. + BufferView * bv_; InsetGraphicsParams params; diff --git a/src/insets/insetgraphicsParams.C b/src/insets/insetgraphicsParams.C index 0896fac9cf..b5d300bc9a 100644 --- a/src/insets/insetgraphicsParams.C +++ b/src/insets/insetgraphicsParams.C @@ -9,19 +9,19 @@ * This file Copyright 2000 Baruch Even * ================================================= */ + #ifdef __GNUG__ #pragma implementation #endif #include + #include "insetgraphicsParams.h" #include "support/translator.h" #include "support/filetools.h" -#ifdef ENABLE_ASSERTIONS #include "support/LAssert.h" -#endif using std::endl; @@ -120,9 +120,7 @@ void InsetGraphicsParams::init() rotateOrigin = DEFAULT; rotateAngle = 0; -#ifdef ENABLE_ASSERTION testInvariant(); -#endif } void InsetGraphicsParams::copy(InsetGraphicsParams const & igp) @@ -140,14 +138,11 @@ void InsetGraphicsParams::copy(InsetGraphicsParams const & igp) rotateOrigin = igp.rotateOrigin; rotateAngle = igp.rotateAngle; -#ifdef ENABLE_ASSERTIONS testInvariant(); -#endif } void InsetGraphicsParams::testInvariant() const { -#ifdef ENABLE_ASSERTIONS // Filename might be empty (when the dialog is first created). // Assert(!filename.empty()); @@ -180,7 +175,6 @@ void InsetGraphicsParams::testInvariant() const Assert(rotateAngle < 360); Assert(rotateAngle > -360); -#endif } bool operator==(InsetGraphicsParams const & left, diff --git a/src/insets/insetgraphicsParams.h b/src/insets/insetgraphicsParams.h index 027b385ae4..2611672099 100644 --- a/src/insets/insetgraphicsParams.h +++ b/src/insets/insetgraphicsParams.h @@ -17,6 +17,7 @@ #endif #include + #include "LString.h" #include "buffer.h" diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 955b64ffc0..56bc0d84ba 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -946,8 +946,9 @@ string LyXFunc::Dispatch(int ac, if (!owner->view()->insertInset(new_inset)) { delete new_inset; } else { - // this is need because you don't use a inset->Edit() - owner->view()->updateInset(new_inset, true); + // this is need because you don't use a inset->Edit() + owner->view()->updateInset(new_inset, true); + new_inset->Edit(owner->view(), 0, 0, 0); } break; } diff --git a/src/support/translator.h b/src/support/translator.h index d150c17900..9e9fb15449 100644 --- a/src/support/translator.h +++ b/src/support/translator.h @@ -12,12 +12,13 @@ #ifndef TRANSLATOR_H #define TRANSLATOR_H - #include #include #include #include +#include "support/LAssert.h" + // Functors used in the template. template class equal_1st_in_pair { @@ -72,9 +73,7 @@ public: /// Find the mapping for the first argument T2 const & find(T1 const & first) const { -#ifdef ENABLE_ASSERTIONS Assert( ! map.empty()); -#endif // For explanation see the next find() function. Map::const_iterator it = @@ -91,9 +90,7 @@ public: /// Find the mapping for the second argument T1 const & find(T2 const & second) const { -#ifdef ENABLE_ASSERTIONS Assert( ! map.empty()); -#endif // The idea is as follows: // find_if() will try to compare the data in the vector with the value. -- 2.39.2