aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbPixmap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/FbPixmap.cc')
-rw-r--r--src/FbTk/FbPixmap.cc291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc
new file mode 100644
index 0000000..bbc8fcb
--- /dev/null
+++ b/src/FbTk/FbPixmap.cc
@@ -0,0 +1,291 @@
1// FbPixmap.cc for FbTk - Fluxbox ToolKit
2// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: FbPixmap.cc,v 1.10 2004/01/11 12:48:46 fluxgen Exp $
23
24#include "FbPixmap.hh"
25#include "App.hh"
26#include "GContext.hh"
27
28#include <X11/Xutil.h>
29#include <iostream>
30using namespace std;
31
32namespace FbTk {
33
34FbPixmap::FbPixmap():m_pm(0),
35 m_width(0), m_height(0),
36 m_depth(0) { }
37
38FbPixmap::FbPixmap(const FbPixmap &the_copy):m_pm(0),
39 m_width(0), m_height(0),
40 m_depth(0) {
41 copy(the_copy);
42}
43
44FbPixmap::FbPixmap(Pixmap pm):m_pm(0),
45 m_width(0), m_height(0),
46 m_depth(0) {
47 if (pm == 0)
48 return;
49 // assign X pixmap to this
50 (*this) = pm;
51}
52
53FbPixmap::FbPixmap(const FbDrawable &src,
54 unsigned int width, unsigned int height,
55 int depth):m_pm(0),
56 m_width(0), m_height(0),
57 m_depth(0) {
58
59 create(src.drawable(), width, height, depth);
60}
61
62FbPixmap::FbPixmap(Drawable src,
63 unsigned int width, unsigned int height,
64 int depth):m_pm(0),
65 m_width(0), m_height(0),
66 m_depth(0) {
67
68 create(src, width, height, depth);
69}
70
71FbPixmap::~FbPixmap() {
72 free();
73}
74
75FbPixmap &FbPixmap::operator = (const FbPixmap &the_copy) {
76 copy(the_copy);
77 return *this;
78}
79
80FbPixmap &FbPixmap::operator = (Pixmap pm) {
81 // free pixmap before we set new
82 free();
83
84 if (pm == 0)
85 return *this;
86
87 // get width, height and depth for the pixmap
88 Window root;
89 int x, y;
90 unsigned int border_width, bpp;
91 XGetGeometry(FbTk::App::instance()->display(),
92 pm,
93 &root,
94 &x, &y,
95 &m_width, &m_height,
96 &border_width,
97 &bpp);
98
99 m_depth = bpp;
100
101 m_pm = pm;
102
103 return *this;
104}
105
106void FbPixmap::copy(const FbPixmap &the_copy) {
107
108 bool create_new = false;
109
110 if (the_copy.width() != width() ||
111 the_copy.height() != height() ||
112 the_copy.depth() != depth() ||
113 drawable() == 0)
114 create_new = true;
115
116 if (create_new)
117 free();
118
119 if (the_copy.drawable() != 0) {
120 if (create_new) {
121 create(the_copy.drawable(),
122 the_copy.width(), the_copy.height(),
123 the_copy.depth());
124 }
125
126 if (drawable()) {
127 GContext gc(drawable());
128
129 copyArea(the_copy.drawable(),
130 gc.gc(),
131 0, 0,
132 0, 0,
133 width(), height());
134 }
135 }
136}
137
138void FbPixmap::copy(Pixmap pm) {
139 free();
140 if (pm == 0)
141 return;
142
143 // get width, height and depth for the pixmap
144 Window root;
145 int x, y;
146 unsigned int border_width, bpp;
147 unsigned int new_width, new_height;
148
149 XGetGeometry(FbTk::App::instance()->display(),
150 pm,
151 &root,
152 &x, &y,
153 &new_width, &new_height,
154 &border_width,
155 &bpp);
156 // create new pixmap and copy area
157 create(root, new_width, new_height, bpp);
158
159 Display *disp = FbTk::App::instance()->display();
160
161 GC gc = XCreateGC(disp, drawable(), 0, 0);
162
163 XCopyArea(disp, pm, drawable(), gc,
164 0, 0,
165 width(), height(),
166 0, 0);
167
168 XFreeGC(disp, gc);
169}
170
171void FbPixmap::rotate() {
172
173 Display *dpy = FbTk::App::instance()->display();
174
175 // make an image copy
176 XImage *src_image = XGetImage(dpy, drawable(),
177 0, 0, // pos
178 width(), height(), // size
179 ~0, // plane mask
180 ZPixmap); // format
181 // reverse height/width for new pixmap
182 FbPixmap new_pm(drawable(), height(), width(), depth());
183
184 GContext gc(drawable());
185
186 // copy new area
187 for (int y = 0; y < static_cast<signed>(height()); ++y) {
188 for (int x = 0; x < static_cast<signed>(width()); ++x) {
189 gc.setForeground(XGetPixel(src_image, x, y));
190 // revers coordinates
191 XDrawPoint(dpy, new_pm.drawable(), gc.gc(), y, x);
192 }
193 }
194
195 XDestroyImage(src_image);
196 // free old pixmap and set new from new_pm
197 free();
198
199 m_width = new_pm.width();
200 m_height = new_pm.height();
201 m_depth = new_pm.depth();
202 m_pm = new_pm.release();
203}
204
205void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) {
206 if (drawable() == 0 ||
207 (dest_width == width() && dest_height == height()))
208 return;
209
210 Display *dpy = FbTk::App::instance()->display();
211
212 XImage *src_image = XGetImage(dpy, drawable(),
213 0, 0, // pos
214 width(), height(), // size
215 ~0, // plane mask
216 ZPixmap); // format
217 if (src_image == 0)
218 return;
219
220 // create new pixmap with dest size
221 FbPixmap new_pm(drawable(), dest_width, dest_height, depth());
222
223 GContext gc(drawable());
224 // calc zoom
225 float zoom_x = static_cast<float>(width())/static_cast<float>(dest_width);
226 float zoom_y = static_cast<float>(height())/static_cast<float>(dest_height);
227
228 // start scaling
229 float src_x = 0, src_y = 0;
230 for (int tx=0; tx < static_cast<signed>(dest_width); ++tx, src_x += zoom_x) {
231 src_y = 0;
232 for (int ty=0; ty < static_cast<signed>(dest_height); ++ty, src_y += zoom_y) {
233 gc.setForeground(XGetPixel(src_image,
234 static_cast<int>(src_x),
235 static_cast<int>(src_y)));
236 XDrawPoint(dpy, new_pm.drawable(), gc.gc(), tx, ty);
237 }
238 }
239
240 XDestroyImage(src_image);
241
242 // free old pixmap and set new from new_pm
243 free();
244
245 m_width = new_pm.width();
246 m_height = new_pm.height();
247 m_depth = new_pm.depth();
248 m_pm = new_pm.release();
249}
250
251void FbPixmap::resize(unsigned int width, unsigned int height) {
252 FbPixmap pm(drawable(), width, height, depth());
253 *this = pm.release();
254}
255
256Pixmap FbPixmap::release() {
257 Pixmap ret = m_pm;
258 m_pm = 0;
259 m_width = 0;
260 m_height = 0;
261 m_depth = 0;
262 return ret;
263}
264
265void FbPixmap::free() {
266 if (m_pm != 0) {
267 XFreePixmap(FbTk::App::instance()->display(), m_pm);
268 m_pm = 0;
269 }
270 m_width = 0;
271 m_height = 0;
272 m_depth = 0;
273}
274
275void FbPixmap::create(Drawable src,
276 unsigned int width, unsigned int height,
277 int depth) {
278 if (src == 0)
279 return;
280
281 m_pm = XCreatePixmap(FbTk::App::instance()->display(),
282 src, width, height, depth);
283 if (m_pm == 0)
284 return;
285
286 m_width = width;
287 m_height = height;
288 m_depth = depth;
289}
290
291}; // end namespace FbTk