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