gosu 0.7.20 → 0.7.21
Sign up to get free protection for your applications and to get access to all the features.
- data/Gosu/Audio.hpp +1 -0
- data/Gosu/Color.hpp +5 -0
- data/Gosu/Font.hpp +5 -0
- data/Gosu/Graphics.hpp +12 -0
- data/Gosu/GraphicsBase.hpp +4 -3
- data/Gosu/ImageData.hpp +1 -0
- data/Gosu/Input.hpp +1 -0
- data/Gosu/Platform.hpp +8 -0
- data/Gosu/Text.hpp +17 -7
- data/Gosu/Version.hpp +2 -2
- data/Gosu/Window.hpp +4 -4
- data/GosuImpl/Audio/AudioSDL.cpp +4 -0
- data/GosuImpl/Graphics/BitmapPNG.cpp +7 -6
- data/GosuImpl/Graphics/Common.hpp +28 -0
- data/GosuImpl/Graphics/DrawOp.hpp +31 -6
- data/GosuImpl/Graphics/Font.cpp +63 -34
- data/GosuImpl/Graphics/FormattedString.hpp +248 -0
- data/GosuImpl/Graphics/Graphics.cpp +39 -7
- data/GosuImpl/Graphics/LargeImageData.cpp +10 -0
- data/GosuImpl/Graphics/LargeImageData.hpp +2 -0
- data/GosuImpl/Graphics/Macro.hpp +5 -0
- data/GosuImpl/Graphics/TexChunk.cpp +10 -5
- data/GosuImpl/Graphics/TexChunk.hpp +4 -2
- data/GosuImpl/Graphics/Text.cpp +118 -57
- data/GosuImpl/Graphics/TextTouch.mm +49 -17
- data/GosuImpl/Graphics/TextUnix.cpp +1 -2
- data/GosuImpl/Graphics/TextWin.cpp +2 -3
- data/GosuImpl/Graphics/Texture.cpp +33 -2
- data/GosuImpl/Graphics/Texture.hpp +3 -1
- data/GosuImpl/Graphics/Transform.cpp +59 -0
- data/GosuImpl/RubyGosu.swg +46 -4
- data/GosuImpl/RubyGosu_wrap.cxx +822 -157
- data/GosuImpl/Utility.cpp +1 -0
- data/GosuImpl/WindowWin.cpp +8 -8
- data/examples/CptnRuby.rb +27 -28
- data/lib/gosu.rb +1 -1
- data/linux/extconf.rb +2 -2
- metadata +21 -6
- data/GosuImpl/RubyGosu_wrap.cxx.rej +0 -187
@@ -0,0 +1,248 @@
|
|
1
|
+
#ifndef GOSUIMPL_GRAPHICS_TEXTFORMATTING
|
2
|
+
#define GOSUIMPL_GRAPHICS_TEXTFORMATTING
|
3
|
+
|
4
|
+
#include <Gosu/Color.hpp>
|
5
|
+
#include <Gosu/Utility.hpp>
|
6
|
+
#include <boost/cstdint.hpp>
|
7
|
+
#include <boost/foreach.hpp>
|
8
|
+
#include <stdexcept>
|
9
|
+
#include <vector>
|
10
|
+
#include <cwchar>
|
11
|
+
|
12
|
+
namespace Gosu
|
13
|
+
{
|
14
|
+
class FormattedString
|
15
|
+
{
|
16
|
+
struct FormattedChar
|
17
|
+
{
|
18
|
+
wchar_t wc;
|
19
|
+
Gosu::Color color;
|
20
|
+
unsigned flags;
|
21
|
+
std::wstring entity;
|
22
|
+
|
23
|
+
bool sameStyleAs(const FormattedChar& other) const
|
24
|
+
{
|
25
|
+
return wc && other.wc && color == other.color && flags == other.flags;
|
26
|
+
}
|
27
|
+
};
|
28
|
+
std::vector<FormattedChar> chars;
|
29
|
+
|
30
|
+
static unsigned flags(int b, int u, int i)
|
31
|
+
{
|
32
|
+
unsigned flags = 0;
|
33
|
+
if (b > 0) flags |= ffBold;
|
34
|
+
if (u > 0) flags |= ffUnderline;
|
35
|
+
if (i > 0) flags |= ffItalic;
|
36
|
+
return flags;
|
37
|
+
}
|
38
|
+
|
39
|
+
public:
|
40
|
+
FormattedString()
|
41
|
+
{
|
42
|
+
}
|
43
|
+
|
44
|
+
explicit FormattedString(const std::wstring& html, unsigned baseFlags)
|
45
|
+
{
|
46
|
+
unsigned pos = 0;
|
47
|
+
int b = (baseFlags & ffBold) ? 1 : 0,
|
48
|
+
u = (baseFlags & ffUnderline) ? 1 : 0,
|
49
|
+
i = (baseFlags & ffItalic) ? 1 : 0;
|
50
|
+
std::vector<Gosu::Color> c;
|
51
|
+
c.push_back(0xffffffff);
|
52
|
+
while (pos < html.length())
|
53
|
+
{
|
54
|
+
// TODO: range checking for the color ops so .at() doesn't crash valid strings
|
55
|
+
|
56
|
+
if (html.substr(pos, 3) == L"<b>")
|
57
|
+
{
|
58
|
+
b += 1;
|
59
|
+
pos += 3;
|
60
|
+
continue;
|
61
|
+
}
|
62
|
+
if (html.substr(pos, 4) == L"</b>")
|
63
|
+
{
|
64
|
+
b -= 1;
|
65
|
+
pos += 4;
|
66
|
+
continue;
|
67
|
+
}
|
68
|
+
if (html.substr(pos, 3) == L"<u>")
|
69
|
+
{
|
70
|
+
u += 1;
|
71
|
+
pos += 3;
|
72
|
+
continue;
|
73
|
+
}
|
74
|
+
if (html.substr(pos, 4) == L"</u>")
|
75
|
+
{
|
76
|
+
u -= 1;
|
77
|
+
pos += 4;
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
if (html.substr(pos, 3) == L"<i>")
|
81
|
+
{
|
82
|
+
i += 1;
|
83
|
+
pos += 3;
|
84
|
+
continue;
|
85
|
+
}
|
86
|
+
if (html.substr(pos, 4) == L"</i>")
|
87
|
+
{
|
88
|
+
i -= 1;
|
89
|
+
pos += 4;
|
90
|
+
continue;
|
91
|
+
}
|
92
|
+
if (html.substr(pos, 3) == L"<c=" &&
|
93
|
+
html.at(pos + 9) == L'>')
|
94
|
+
{
|
95
|
+
using namespace std;
|
96
|
+
boost::uint32_t rgb =
|
97
|
+
std::wcstoul(html.c_str() + pos + 3, 0, 16);
|
98
|
+
c.push_back(0xff000000 | rgb);
|
99
|
+
pos += 10;
|
100
|
+
continue;
|
101
|
+
}
|
102
|
+
if (html.substr(pos, 3) == L"<c=" &&
|
103
|
+
html.at(pos + 11) == L'>')
|
104
|
+
{
|
105
|
+
using namespace std;
|
106
|
+
boost::uint32_t argb =
|
107
|
+
std::wcstoul(html.c_str() + pos + 3, 0, 16);
|
108
|
+
c.push_back(argb);
|
109
|
+
pos += 12;
|
110
|
+
continue;
|
111
|
+
}
|
112
|
+
if (html.substr(pos, 4) == L"</c>")
|
113
|
+
{
|
114
|
+
c.pop_back();
|
115
|
+
pos += 4;
|
116
|
+
continue;
|
117
|
+
}
|
118
|
+
if (html.substr(pos, 4) == L"<")
|
119
|
+
{
|
120
|
+
FormattedChar fc = { L'<', c.back(), flags(b,u,i) };
|
121
|
+
chars.push_back(fc);
|
122
|
+
pos += 4;
|
123
|
+
continue;
|
124
|
+
}
|
125
|
+
if (html.substr(pos, 4) == L">")
|
126
|
+
{
|
127
|
+
FormattedChar fc = { L'>', c.back(), flags(b,u,i) };
|
128
|
+
chars.push_back(fc);
|
129
|
+
pos += 4;
|
130
|
+
continue;
|
131
|
+
}
|
132
|
+
if (html.substr(pos, 5) == L"&")
|
133
|
+
{
|
134
|
+
FormattedChar fc = { L'&', c.back(), flags(b,u,i) };
|
135
|
+
chars.push_back(fc);
|
136
|
+
pos += 5;
|
137
|
+
continue;
|
138
|
+
}
|
139
|
+
if (html[pos] == L'&' && pos < html.length() - 1)
|
140
|
+
{
|
141
|
+
int endOfEntity = pos + 1;
|
142
|
+
while (html[endOfEntity] != L';')
|
143
|
+
{
|
144
|
+
using namespace std; // never know where the wchar_t stuff is ...
|
145
|
+
if (!iswalnum(static_cast<wint_t>(html[endOfEntity])))
|
146
|
+
goto normalCharacter;
|
147
|
+
endOfEntity += 1;
|
148
|
+
if (endOfEntity >= html.size())
|
149
|
+
goto normalCharacter;
|
150
|
+
}
|
151
|
+
FormattedChar fc = { 0, c.back(), 0, std::wstring(html.begin() + pos + 1, html.begin() + endOfEntity) };
|
152
|
+
chars.push_back(fc);
|
153
|
+
pos = endOfEntity + 1;
|
154
|
+
continue;
|
155
|
+
}
|
156
|
+
|
157
|
+
normalCharacter:
|
158
|
+
FormattedChar fc = { html[pos], c.back(), flags(b,u,i) };
|
159
|
+
chars.push_back(fc);
|
160
|
+
pos += 1;
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
std::wstring unformat() const
|
165
|
+
{
|
166
|
+
std::wstring result(length(), L' ');
|
167
|
+
for (int i = 0; i < chars.size(); ++i)
|
168
|
+
result[i] = chars[i].wc;
|
169
|
+
return result;
|
170
|
+
}
|
171
|
+
|
172
|
+
const wchar_t* entityAt(unsigned index) const
|
173
|
+
{
|
174
|
+
if (chars[index].wc != 0 || chars[index].entity.empty())
|
175
|
+
return 0;
|
176
|
+
return chars[index].entity.c_str();
|
177
|
+
}
|
178
|
+
|
179
|
+
wchar_t charAt(unsigned index) const
|
180
|
+
{
|
181
|
+
return chars[index].wc;
|
182
|
+
}
|
183
|
+
|
184
|
+
unsigned flagsAt(unsigned index) const
|
185
|
+
{
|
186
|
+
return chars[index].flags;
|
187
|
+
}
|
188
|
+
|
189
|
+
Gosu::Color colorAt(unsigned index) const
|
190
|
+
{
|
191
|
+
return chars[index].color;
|
192
|
+
}
|
193
|
+
|
194
|
+
unsigned length() const
|
195
|
+
{
|
196
|
+
return chars.size();
|
197
|
+
}
|
198
|
+
|
199
|
+
FormattedString range(unsigned begin, unsigned end) const
|
200
|
+
{
|
201
|
+
FormattedString result;
|
202
|
+
result.chars.assign(chars.begin() + begin, chars.begin() + end);
|
203
|
+
return result;
|
204
|
+
}
|
205
|
+
|
206
|
+
std::vector<FormattedString> splitLines() const
|
207
|
+
{
|
208
|
+
std::vector<FormattedString> result;
|
209
|
+
unsigned begin = 0;
|
210
|
+
for (unsigned cur = 0; cur < length(); ++cur)
|
211
|
+
{
|
212
|
+
if (charAt(cur) == L'\n')
|
213
|
+
{
|
214
|
+
FormattedString line;
|
215
|
+
line.chars.assign(chars.begin() + begin, chars.begin() + cur);
|
216
|
+
result.push_back(line);
|
217
|
+
begin = cur + 1;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
FormattedString line;
|
221
|
+
line.chars.assign(chars.begin() + begin, chars.end());
|
222
|
+
result.push_back(line);
|
223
|
+
return result;
|
224
|
+
}
|
225
|
+
|
226
|
+
std::vector<FormattedString> splitParts() const
|
227
|
+
{
|
228
|
+
std::vector<FormattedString> result;
|
229
|
+
unsigned begin = 0;
|
230
|
+
for (unsigned cur = 1; cur < length(); ++cur)
|
231
|
+
{
|
232
|
+
if (!chars[begin].sameStyleAs(chars[cur]))
|
233
|
+
{
|
234
|
+
FormattedString line;
|
235
|
+
line.chars.assign(chars.begin() + begin, chars.begin() + cur);
|
236
|
+
result.push_back(line);
|
237
|
+
begin = cur;
|
238
|
+
}
|
239
|
+
}
|
240
|
+
FormattedString line;
|
241
|
+
line.chars.assign(chars.begin() + begin, chars.end());
|
242
|
+
result.push_back(line);
|
243
|
+
return result;
|
244
|
+
}
|
245
|
+
};
|
246
|
+
}
|
247
|
+
|
248
|
+
#endif
|
@@ -6,6 +6,8 @@
|
|
6
6
|
#include <GosuImpl/Graphics/LargeImageData.hpp>
|
7
7
|
#include <GosuImpl/Graphics/Macro.hpp>
|
8
8
|
#include <Gosu/Bitmap.hpp>
|
9
|
+
#include <Gosu/Image.hpp>
|
10
|
+
#include <boost/foreach.hpp>
|
9
11
|
#if 0
|
10
12
|
#include <boost/thread.hpp>
|
11
13
|
#endif
|
@@ -22,10 +24,20 @@ struct Gosu::Graphics::Impl
|
|
22
24
|
DrawOpQueueStack queues;
|
23
25
|
typedef std::vector<boost::shared_ptr<Texture> > Textures;
|
24
26
|
Textures textures;
|
27
|
+
Transforms currentTransforms;
|
28
|
+
Transforms absoluteTransforms;
|
25
29
|
|
26
30
|
#if 0
|
27
31
|
boost::mutex texMutex;
|
28
32
|
#endif
|
33
|
+
|
34
|
+
void calculateAbsoluteTransform()
|
35
|
+
{
|
36
|
+
Transform result = scale(1);
|
37
|
+
BOOST_FOREACH (const Transform& tf, currentTransforms)
|
38
|
+
result = multiply(result, tf);
|
39
|
+
absoluteTransforms.push_back(result);
|
40
|
+
}
|
29
41
|
};
|
30
42
|
|
31
43
|
Gosu::Graphics::Graphics(unsigned physWidth, unsigned physHeight, bool fullscreen)
|
@@ -57,6 +69,9 @@ Gosu::Graphics::Graphics(unsigned physWidth, unsigned physHeight, bool fullscree
|
|
57
69
|
|
58
70
|
// Create default draw-op queue.
|
59
71
|
pimpl->queues.resize(1);
|
72
|
+
|
73
|
+
// Push one identity matrix as the default transform.
|
74
|
+
pimpl->absoluteTransforms.push_back(scale(1));
|
60
75
|
}
|
61
76
|
|
62
77
|
Gosu::Graphics::~Graphics()
|
@@ -107,7 +122,12 @@ void Gosu::Graphics::setResolution(unsigned virtualWidth, unsigned virtualHeight
|
|
107
122
|
bool Gosu::Graphics::begin(Gosu::Color clearWithColor)
|
108
123
|
{
|
109
124
|
// If there is a recording in process, stop it.
|
125
|
+
// TODO: Raise exception?
|
110
126
|
pimpl->queues.resize(1);
|
127
|
+
|
128
|
+
// If there are transformations in progress, clear them.
|
129
|
+
pimpl->currentTransforms.resize(0);
|
130
|
+
pimpl->absoluteTransforms.resize(1);
|
111
131
|
|
112
132
|
// Flush leftover clippings
|
113
133
|
endClipping();
|
@@ -229,11 +249,23 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::endRecording()
|
|
229
249
|
return result;
|
230
250
|
}
|
231
251
|
|
252
|
+
void Gosu::Graphics::pushTransform(const Gosu::Transform& transform)
|
253
|
+
{
|
254
|
+
pimpl->currentTransforms.push_back(transform);
|
255
|
+
pimpl->calculateAbsoluteTransform();
|
256
|
+
}
|
257
|
+
|
258
|
+
void Gosu::Graphics::popTransform()
|
259
|
+
{
|
260
|
+
pimpl->currentTransforms.pop_back();
|
261
|
+
pimpl->calculateAbsoluteTransform();
|
262
|
+
}
|
263
|
+
|
232
264
|
void Gosu::Graphics::drawLine(double x1, double y1, Color c1,
|
233
265
|
double x2, double y2, Color c2,
|
234
266
|
ZPos z, AlphaMode mode)
|
235
267
|
{
|
236
|
-
DrawOp op;
|
268
|
+
DrawOp op(pimpl->absoluteTransforms.back());
|
237
269
|
|
238
270
|
x1 *= factorX();
|
239
271
|
y1 *= factorY();
|
@@ -253,7 +285,7 @@ void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
|
|
253
285
|
double x3, double y3, Color c3,
|
254
286
|
ZPos z, AlphaMode mode)
|
255
287
|
{
|
256
|
-
DrawOp op;
|
288
|
+
DrawOp op(pimpl->absoluteTransforms.back());
|
257
289
|
|
258
290
|
x1 *= factorX();
|
259
291
|
y1 *= factorY();
|
@@ -283,7 +315,7 @@ void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
|
|
283
315
|
{
|
284
316
|
reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
285
317
|
|
286
|
-
DrawOp op;
|
318
|
+
DrawOp op(pimpl->absoluteTransforms.back());
|
287
319
|
|
288
320
|
x1 *= factorX();
|
289
321
|
y1 *= factorY();
|
@@ -332,7 +364,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
332
364
|
if (srcX == 0 && srcWidth == src.width() &&
|
333
365
|
srcY == 0 && srcHeight == src.height())
|
334
366
|
{
|
335
|
-
data = texture->tryAlloc(*this, pimpl->queues, texture,
|
367
|
+
data = texture->tryAlloc(*this, pimpl->absoluteTransforms, pimpl->queues, texture,
|
336
368
|
src, 0, 0, src.width(), src.height(), 0);
|
337
369
|
}
|
338
370
|
else
|
@@ -340,7 +372,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
340
372
|
Bitmap trimmedSrc;
|
341
373
|
trimmedSrc.resize(srcWidth, srcHeight);
|
342
374
|
trimmedSrc.insert(src, 0, 0, srcX, srcY, srcWidth, srcHeight);
|
343
|
-
data = texture->tryAlloc(*this, pimpl->queues, texture,
|
375
|
+
data = texture->tryAlloc(*this, pimpl->absoluteTransforms, pimpl->queues, texture,
|
344
376
|
trimmedSrc, 0, 0, trimmedSrc.width(), trimmedSrc.height(), 0);
|
345
377
|
}
|
346
378
|
|
@@ -373,7 +405,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
373
405
|
boost::shared_ptr<Texture> texture(*i);
|
374
406
|
|
375
407
|
std::auto_ptr<ImageData> data;
|
376
|
-
data = texture->tryAlloc(*this, pimpl->queues, texture, bmp, 0, 0, bmp.width(), bmp.height(), 1);
|
408
|
+
data = texture->tryAlloc(*this, pimpl->absoluteTransforms, pimpl->queues, texture, bmp, 0, 0, bmp.width(), bmp.height(), 1);
|
377
409
|
if (data.get())
|
378
410
|
return data;
|
379
411
|
}
|
@@ -385,7 +417,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
385
417
|
pimpl->textures.push_back(texture);
|
386
418
|
|
387
419
|
std::auto_ptr<ImageData> data;
|
388
|
-
data = texture->tryAlloc(*this, pimpl->queues, texture, bmp, 0, 0, bmp.width(), bmp.height(), 1);
|
420
|
+
data = texture->tryAlloc(*this, pimpl->absoluteTransforms, pimpl->queues, texture, bmp, 0, 0, bmp.width(), bmp.height(), 1);
|
389
421
|
if (!data.get())
|
390
422
|
throw std::logic_error("Internal texture block allocation error");
|
391
423
|
|
@@ -116,3 +116,13 @@ void Gosu::LargeImageData::draw(double x1, double y1, Color c1,
|
|
116
116
|
absXBL, absYBL, absCBL, absXBR, absYBR, absCBR, z, mode);
|
117
117
|
}
|
118
118
|
}
|
119
|
+
|
120
|
+
Gosu::Bitmap Gosu::LargeImageData::toBitmap() const
|
121
|
+
{
|
122
|
+
Bitmap bitmap;
|
123
|
+
bitmap.resize(width(), height());
|
124
|
+
for (int x = 0; x < partsX; ++x)
|
125
|
+
for (int y = 0; y < partsY; ++y)
|
126
|
+
bitmap.insert(parts[y * partsX + x]->toBitmap(), x * partWidth, y * partHeight);
|
127
|
+
return bitmap;
|
128
|
+
}
|
data/GosuImpl/Graphics/Macro.hpp
CHANGED
@@ -4,10 +4,10 @@
|
|
4
4
|
#include <Gosu/Bitmap.hpp>
|
5
5
|
#include <Gosu/Graphics.hpp>
|
6
6
|
|
7
|
-
Gosu::TexChunk::TexChunk(Graphics& graphics, DrawOpQueueStack& queues,
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
Gosu::TexChunk::TexChunk(Graphics& graphics, Transforms& transforms, DrawOpQueueStack& queues,
|
8
|
+
boost::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding)
|
9
|
+
: graphics(&graphics), transforms(&transforms), queues(&queues),
|
10
|
+
texture(texture), x(x), y(y), w(w), h(h), padding(padding)
|
11
11
|
{
|
12
12
|
}
|
13
13
|
|
@@ -45,7 +45,7 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1,
|
|
45
45
|
double x4, double y4, Color c4,
|
46
46
|
ZPos z, AlphaMode mode) const
|
47
47
|
{
|
48
|
-
DrawOp newDrawOp;
|
48
|
+
DrawOp newDrawOp(transforms->back());
|
49
49
|
|
50
50
|
reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
51
51
|
|
@@ -82,3 +82,8 @@ boost::optional<Gosu::GLTexInfo> Gosu::TexChunk::glTexInfo() const
|
|
82
82
|
getCoords(info.left, info.top, info.right, info.bottom);
|
83
83
|
return info;
|
84
84
|
}
|
85
|
+
|
86
|
+
Gosu::Bitmap Gosu::TexChunk::toBitmap() const
|
87
|
+
{
|
88
|
+
return texture->toBitmap(x, y, w, h);
|
89
|
+
}
|
@@ -12,13 +12,14 @@
|
|
12
12
|
class Gosu::TexChunk : public Gosu::ImageData
|
13
13
|
{
|
14
14
|
Graphics* graphics;
|
15
|
+
Transforms* transforms;
|
15
16
|
DrawOpQueueStack* queues;
|
16
17
|
boost::shared_ptr<Texture> texture;
|
17
18
|
int x, y, w, h, padding;
|
18
19
|
|
19
20
|
public:
|
20
|
-
TexChunk(Graphics& graphics,
|
21
|
-
int x, int y, int w, int h, int padding);
|
21
|
+
TexChunk(Graphics& graphics, Transforms& transforms, DrawOpQueueStack& queues,
|
22
|
+
boost::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding);
|
22
23
|
~TexChunk();
|
23
24
|
|
24
25
|
unsigned int width() const;
|
@@ -34,6 +35,7 @@ public:
|
|
34
35
|
ZPos z, AlphaMode mode) const;
|
35
36
|
|
36
37
|
boost::optional<GLTexInfo> glTexInfo() const;
|
38
|
+
Gosu::Bitmap toBitmap() const;
|
37
39
|
};
|
38
40
|
|
39
41
|
#endif
|