]> git.lyx.org Git - lyx.git/blob - src/graphics/GraphicsCacheItem_pimpl.C
Baruch's patch + some fixes to it.
[lyx.git] / src / graphics / GraphicsCacheItem_pimpl.C
1 // -*- C++ -*-
2 /* This file is part of
3  * =================================================
4  * 
5  *          LyX, The Document Processor
6  *          Copyright 1995 Matthias Ettrich.
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  *          This file Copyright 2000 Baruch Even
10  * ================================================= */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "GraphicsCacheItem.h"
19 #include "GraphicsCacheItem_pimpl.h"
20
21 #include "graphics/XPM_Renderer.h"
22 #include "graphics/EPS_Renderer.h"
23 #include "support/filetools.h"
24 #include "debug.h"
25 #include "support/LAssert.h"
26 #include <unistd.h> // unlink
27
28 #include <map>
29
30 #include FORMS_H_LOCATION
31
32 using std::endl;
33 using std::map;
34
35
36 GraphicsCacheItem_pimpl::GraphicsCacheItem_pimpl()
37         : height_(-1), width_(-1), imageStatus_(GraphicsCacheItem::Loading),
38           pixmap_(0), renderer(0), refCount(0)
39 {}
40
41 GraphicsCacheItem_pimpl::~GraphicsCacheItem_pimpl()
42 {
43         if (imageStatus_ == GraphicsCacheItem::Loaded) {
44                 XFreePixmap(fl_display, pixmap_);
45         }
46
47         delete renderer;
48 }
49
50 bool
51 GraphicsCacheItem_pimpl::setFilename(string const & filename)
52 {
53         imageStatus_ = GraphicsCacheItem::Loading;
54
55         renderer = new XPM_Renderer();
56         if (renderXPM(filename))
57                 return true;
58         
59         return false;
60 }
61
62 /*** Callback method ***/
63
64 typedef map<string, GraphicsCacheItem_pimpl*> CallbackMap;
65 static CallbackMap callbackMap;
66
67 void
68 callback(string cmd, int retval)
69 {
70         lyxerr << "callback, cmd="<<cmd<<", retval="<<retval<<endl;
71
72         GraphicsCacheItem_pimpl * item = callbackMap[cmd];
73         callbackMap.erase(cmd);
74         
75         item->imageConverted(retval);
76 }
77
78 void
79 GraphicsCacheItem_pimpl::imageConverted(int retval)
80 {
81         lyxerr << "imageConverted, retval="<<retval<<endl;
82
83         if (retval) {
84                 imageStatus_ = GraphicsCacheItem::ErrorConverting;
85                 return;
86         }
87
88         // Do the actual image loading from XPM to memory.
89         loadXPMImage(); 
90 }
91
92 /**********************/
93
94 bool
95 GraphicsCacheItem_pimpl::renderXPM(string const & filename)
96 {
97         // Create the command to do the conversion, this depends on ImageMagicks
98         // convert program.
99         string command = "convert ";
100         command += filename;
101         command += " XPM:";
102
103         // Take only the filename part of the file, without path or extension.
104         string temp = OnlyFilename(filename);
105         temp = ChangeExtension(filename , string());
106         
107         // Add some stuff to have it a unique temp file.
108         xpmfile = TmpFileName(string(), temp);
109         xpmfile = ChangeExtension(xpmfile, ".xpm");     
110         
111         command += xpmfile;
112
113         // Set the callback mapping to point to us.
114         callbackMap[command] = this;
115
116         // Run the convertor.
117         // There is a problem with running it asyncronously, it doesn't return
118         // to call the callback, so until the Systemcalls mechanism is fixed
119         // I use the syncronous method.
120         lyxerr << "Launching convert to xpm, command="<<command<<endl;
121 //      syscall.startscript(Systemcalls::DontWait, command, &callback);
122         syscall.startscript(Systemcalls::Wait, command, &callback);
123
124         return true;
125 }
126
127 // This function gets called from the callback after the image has been
128 // converted successfully.
129 void
130 GraphicsCacheItem_pimpl::loadXPMImage()
131 {
132         if (! renderer->setFilename(xpmfile)) {
133                 return;
134         }
135
136         if (renderer->renderImage()) {
137                 pixmap_ = renderer->getPixmap();
138                 width_ = renderer->getWidth();
139                 height_ = renderer->getHeight();
140                 imageStatus_ = GraphicsCacheItem::Loaded;
141         } else {
142                 imageStatus_ = GraphicsCacheItem::ErrorReading;
143         }
144
145         // remove the xpm file now.
146         ::unlink(xpmfile.c_str());
147         // and remove the reference to the filename.
148         xpmfile = string();
149 }