dont have any languages yet
[dana/openbox.git] / otk / texture.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 #  include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 extern "C" {
8 #include <stdio.h>
9 #ifdef HAVE_CTYPE_H
10 #include <ctype.h>
11 #endif
12 }
13
14 #include <assert.h>
15
16 #include "texture.hh"
17 #include "basedisplay.hh"
18 #include "image.hh"
19 #include "screen.hh"
20 #include "blackbox.hh"
21
22 using std::string;
23
24
25 BTexture::BTexture(const BaseDisplay * const _display,
26                    unsigned int _screen, BImageControl* _ctrl)
27   : c(_display, _screen), ct(_display, _screen),
28     lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0),
29     dpy(_display), ctrl(_ctrl), scrn(_screen) { }
30
31
32 BTexture::BTexture(const string &d, const BaseDisplay * const _display,
33                    unsigned int _screen, BImageControl* _ctrl)
34   : c(_display, _screen), ct(_display, _screen),
35     lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0),
36     dpy(_display), ctrl(_ctrl), scrn(_screen) {
37   setDescription(d);
38 }
39
40
41 void BTexture::setColor(const BColor &cc) {
42   c = cc;
43   c.setDisplay(display(), screen());
44
45   unsigned char r, g, b, rr, gg, bb;
46
47   // calculate the light color
48   r = c.red();
49   g = c.green();
50   b = c.blue();
51   rr = r + (r >> 1);
52   gg = g + (g >> 1);
53   bb = b + (b >> 1);
54   if (rr < r) rr = ~0;
55   if (gg < g) gg = ~0;
56   if (bb < b) bb = ~0;
57   lc = BColor(rr, gg, bb, display(), screen());
58
59   // calculate the shadow color
60   r = c.red();
61   g = c.green();
62   b = c.blue();
63   rr = (r >> 2) + (r >> 1);
64   gg = (g >> 2) + (g >> 1);
65   bb = (b >> 2) + (b >> 1);
66   if (rr > r) rr = 0;
67   if (gg > g) gg = 0;
68   if (bb > b) bb = 0;
69   sc = BColor(rr, gg, bb, display(), screen());
70 }
71
72
73 void BTexture::setDescription(const string &d) {
74   descr.erase();
75   descr.reserve(d.length());
76
77   string::const_iterator it = d.begin(), end = d.end();
78   for (; it != end; ++it)
79     descr += tolower(*it);
80
81   if (descr.find("parentrelative") != string::npos) {
82     setTexture(BTexture::Parent_Relative);
83   } else {
84     setTexture(0);
85
86     if (descr.find("gradient") != string::npos) {
87       addTexture(BTexture::Gradient);
88       if (descr.find("crossdiagonal") != string::npos)
89         addTexture(BTexture::CrossDiagonal);
90       else if (descr.find("rectangle") != string::npos)
91         addTexture(BTexture::Rectangle);
92       else if (descr.find("pyramid") != string::npos)
93         addTexture(BTexture::Pyramid);
94       else if (descr.find("pipecross") != string::npos)
95         addTexture(BTexture::PipeCross);
96       else if (descr.find("elliptic") != string::npos)
97         addTexture(BTexture::Elliptic);
98       else if (descr.find("horizontal") != string::npos)
99         addTexture(BTexture::Horizontal);
100       else if (descr.find("vertical") != string::npos)
101         addTexture(BTexture::Vertical);
102       else
103         addTexture(BTexture::Diagonal);
104     } else {
105       addTexture(BTexture::Solid);
106     }
107
108     if (descr.find("sunken") != string::npos)
109       addTexture(BTexture::Sunken);
110     else if (descr.find("flat") != string::npos)
111       addTexture(BTexture::Flat);
112     else
113       addTexture(BTexture::Raised);
114
115     if (texture() & BTexture::Flat) {
116       if (descr.find("border") != string::npos)
117         addTexture(BTexture::Border);
118     } else {
119       if (descr.find("bevel2") != string::npos)
120         addTexture(BTexture::Bevel2);
121       else
122         addTexture(BTexture::Bevel1);
123     }
124
125     if (descr.find("interlaced") != string::npos)
126       addTexture(BTexture::Interlaced);
127   }
128 }
129
130 void BTexture::setDisplay(const BaseDisplay * const _display,
131                           const unsigned int _screen) {
132   if (_display == display() && _screen == screen()) {
133     // nothing to do
134     return;
135   }
136
137   dpy = _display;
138   scrn = _screen;
139   c.setDisplay(_display, _screen);
140   ct.setDisplay(_display, _screen);
141   lc.setDisplay(_display, _screen);
142   sc.setDisplay(_display, _screen);
143   bc.setDisplay(_display, _screen);
144 }
145
146
147 BTexture& BTexture::operator=(const BTexture &tt) {
148   c  = tt.c;
149   ct = tt.ct;
150   lc = tt.lc;
151   sc = tt.sc;
152   bc = tt.bc;
153   descr = tt.descr;
154   t  = tt.t;
155   dpy = tt.dpy;
156   scrn = tt.scrn;
157   ctrl = tt.ctrl;
158
159   return *this;
160 }
161
162
163 Pixmap BTexture::render(const unsigned int width, const unsigned int height,
164                         const Pixmap old) {
165   assert(display() != 0);
166   assert(texture() != BTexture::NoTexture);
167
168   if (texture() == (BTexture::Flat | BTexture::Solid))
169     return None;
170   if (texture() == BTexture::Parent_Relative)
171     return ParentRelative;
172
173   if (screen() == ~(0u))
174     scrn = DefaultScreen(display()->getXDisplay());
175
176   assert(ctrl != 0);
177   Pixmap ret = ctrl->renderImage(width, height, *this);
178
179   if (old)
180     ctrl->removeImage(old);
181
182   return ret;
183 }