gosu 0.10.9.pre1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/Gosu/Audio.hpp +35 -66
  3. data/Gosu/AutoLink.hpp +14 -16
  4. data/Gosu/Bitmap.hpp +50 -37
  5. data/Gosu/Buttons.hpp +246 -265
  6. data/Gosu/Color.hpp +32 -76
  7. data/Gosu/Directories.hpp +14 -17
  8. data/Gosu/Font.hpp +28 -34
  9. data/Gosu/Fwd.hpp +27 -31
  10. data/Gosu/Gosu.hpp +2 -5
  11. data/Gosu/Graphics.hpp +31 -48
  12. data/Gosu/GraphicsBase.hpp +27 -58
  13. data/Gosu/IO.hpp +44 -56
  14. data/Gosu/Image.hpp +29 -73
  15. data/Gosu/ImageData.hpp +13 -17
  16. data/Gosu/Input.hpp +42 -57
  17. data/Gosu/Inspection.hpp +2 -6
  18. data/Gosu/Math.hpp +32 -38
  19. data/Gosu/Platform.hpp +10 -29
  20. data/Gosu/Text.hpp +30 -39
  21. data/Gosu/TextInput.hpp +29 -36
  22. data/Gosu/Timing.hpp +14 -16
  23. data/Gosu/Utility.hpp +10 -15
  24. data/Gosu/Version.hpp +13 -14
  25. data/Gosu/Window.hpp +53 -68
  26. data/README.md +23 -11
  27. data/ext/gosu/extconf.rb +31 -81
  28. data/lib/gosu/patches.rb +35 -19
  29. data/lib/gosu/run.rb +13 -4
  30. data/rdoc/gosu.rb +24 -20
  31. data/src/ALChannelManagement.hpp +119 -0
  32. data/src/{Audio/Audio.cpp → Audio.cpp} +177 -211
  33. data/src/AudioFile.hpp +57 -0
  34. data/src/AudioToolboxFile.hpp +214 -0
  35. data/src/Bitmap.cpp +159 -0
  36. data/src/BitmapIO.cpp +141 -0
  37. data/src/BlockAllocator.cpp +133 -0
  38. data/src/{Graphics/BlockAllocator.hpp → BlockAllocator.hpp} +34 -35
  39. data/src/ClipRectStack.hpp +87 -0
  40. data/src/{Graphics/Color.cpp → Color.cpp} +30 -28
  41. data/src/DirectoriesApple.cpp +68 -0
  42. data/src/DirectoriesUnix.cpp +20 -18
  43. data/src/DirectoriesWin.cpp +40 -41
  44. data/src/DrawOp.hpp +168 -0
  45. data/src/DrawOpQueue.hpp +190 -0
  46. data/src/FileUnix.cpp +40 -46
  47. data/src/FileWin.cpp +42 -38
  48. data/src/Font.cpp +165 -0
  49. data/src/{Text/FormattedString.hpp → FormattedString.hpp} +114 -114
  50. data/src/GosuAppDelegate.cpp +30 -0
  51. data/src/{UIKit/GosuAppDelegate.h → GosuAppDelegate.h} +0 -0
  52. data/src/{UIKit/GosuGLView.mm → GosuGLView.cpp} +22 -17
  53. data/src/{UIKit/GosuGLView.h → GosuGLView.h} +0 -0
  54. data/src/GosuViewController.cpp +231 -0
  55. data/src/{UIKit/GosuViewController.h → GosuViewController.h} +0 -0
  56. data/src/Graphics.cpp +464 -0
  57. data/src/{Graphics/Common.hpp → GraphicsImpl.hpp} +29 -32
  58. data/src/IO.cpp +17 -16
  59. data/src/Iconv.hpp +13 -22
  60. data/src/Image.cpp +142 -0
  61. data/src/Input.cpp +459 -0
  62. data/src/InputUIKit.cpp +197 -0
  63. data/src/Inspection.cpp +4 -5
  64. data/src/LargeImageData.cpp +151 -0
  65. data/src/LargeImageData.hpp +43 -0
  66. data/src/{Graphics/Macro.cpp → Macro.cpp} +77 -78
  67. data/src/Macro.hpp +30 -0
  68. data/src/Math.cpp +17 -29
  69. data/src/{Audio/OggFile.hpp → OggFile.hpp} +19 -24
  70. data/src/RenderState.hpp +205 -0
  71. data/src/Resolution.cpp +86 -0
  72. data/src/ResolutionApple.cpp +25 -0
  73. data/{ext/gosu/gosu_wrap.cxx → src/RubyGosu.cxx} +2256 -1707
  74. data/{ext/gosu/gosu_wrap.h → src/RubyGosu.h} +9 -9
  75. data/src/{Audio/SndFile.hpp → SndFile.hpp} +54 -43
  76. data/src/TexChunk.cpp +117 -0
  77. data/src/{Graphics/TexChunk.hpp → TexChunk.hpp} +13 -18
  78. data/src/Text.cpp +371 -0
  79. data/src/TextApple.cpp +209 -0
  80. data/src/TextInput.cpp +278 -0
  81. data/src/TextTTFWin.cpp +251 -0
  82. data/src/{Text/TextUnix.cpp → TextUnix.cpp} +96 -92
  83. data/src/TextWin.cpp +194 -0
  84. data/src/{Graphics/Texture.cpp → Texture.cpp} +35 -38
  85. data/src/{Graphics/Texture.hpp → Texture.hpp} +9 -13
  86. data/src/TimingApple.cpp +11 -7
  87. data/src/TimingUnix.cpp +13 -7
  88. data/src/TimingWin.cpp +6 -1
  89. data/src/{Graphics/Transform.cpp → Transform.cpp} +17 -12
  90. data/src/{Graphics/TransformStack.hpp → TransformStack.hpp} +24 -25
  91. data/src/Utility.cpp +29 -70
  92. data/src/UtilityApple.cpp +52 -0
  93. data/src/UtilityWin.cpp +7 -4
  94. data/src/Version.cpp +22 -0
  95. data/src/WinMain.cpp +30 -33
  96. data/src/WinUtility.cpp +24 -22
  97. data/src/WinUtility.hpp +11 -20
  98. data/src/Window.cpp +142 -112
  99. data/src/WindowUIKit.cpp +155 -0
  100. data/src/stb_image.h +384 -173
  101. data/src/stb_vorbis.c +20 -18
  102. metadata +60 -62
  103. data/Gosu/TR1.hpp +0 -56
  104. data/src/AppleUtility.hpp +0 -66
  105. data/src/Audio/ALChannelManagement.hpp +0 -114
  106. data/src/Audio/Audio.mm +0 -1
  107. data/src/Audio/AudioFile.hpp +0 -53
  108. data/src/Audio/AudioToolboxFile.hpp +0 -207
  109. data/src/Bitmap/Bitmap.cpp +0 -183
  110. data/src/Bitmap/BitmapIO.cpp +0 -176
  111. data/src/DirectoriesApple.mm +0 -71
  112. data/src/Graphics/BlockAllocator.cpp +0 -142
  113. data/src/Graphics/ClipRectStack.hpp +0 -93
  114. data/src/Graphics/DrawOp.hpp +0 -175
  115. data/src/Graphics/DrawOpQueue.hpp +0 -188
  116. data/src/Graphics/Graphics.cpp +0 -478
  117. data/src/Graphics/Image.cpp +0 -193
  118. data/src/Graphics/LargeImageData.cpp +0 -133
  119. data/src/Graphics/LargeImageData.hpp +0 -46
  120. data/src/Graphics/Macro.hpp +0 -36
  121. data/src/Graphics/RenderState.hpp +0 -211
  122. data/src/Graphics/Resolution.cpp +0 -91
  123. data/src/Graphics/ResolutionApple.mm +0 -19
  124. data/src/Graphics/TexChunk.cpp +0 -112
  125. data/src/Input/Input.cpp +0 -463
  126. data/src/Input/InputUIKit.mm +0 -190
  127. data/src/Input/TextInput.cpp +0 -261
  128. data/src/Text/Font.cpp +0 -175
  129. data/src/Text/Text.cpp +0 -391
  130. data/src/Text/TextApple.mm +0 -227
  131. data/src/Text/TextTTFWin.cpp +0 -249
  132. data/src/Text/TextWin.cpp +0 -186
  133. data/src/UIKit/GosuAppDelegate.mm +0 -24
  134. data/src/UIKit/GosuViewController.mm +0 -211
  135. data/src/UtilityApple.mm +0 -63
  136. data/src/WindowUIKit.mm +0 -139
@@ -1,175 +0,0 @@
1
- #include <Gosu/Font.hpp>
2
- #include <Gosu/Graphics.hpp>
3
- #include <Gosu/Image.hpp>
4
- #include <Gosu/Math.hpp>
5
- #include <Gosu/Text.hpp>
6
- #include <Gosu/TR1.hpp>
7
- #include "../Graphics/Common.hpp"
8
- #include "FormattedString.hpp"
9
- #include <cassert>
10
- #include <map>
11
- using namespace std;
12
-
13
- struct Gosu::Font::Impl
14
- {
15
- wstring name;
16
- unsigned height, flags;
17
-
18
- // Unicode planes of 2^16 characters each. On Windows, where wchar_t is only 16 bits wide, only
19
- // the first plane will ever be touched.
20
- struct CharInfo
21
- {
22
- GOSU_UNIQUE_PTR<Image> image;
23
- double factor;
24
- };
25
- typedef tr1::array<CharInfo, 65536> Plane;
26
- GOSU_UNIQUE_PTR<Plane> planes[16][ffCombinations];
27
-
28
- map<wstring, tr1::shared_ptr<Image> > entityCache;
29
-
30
- CharInfo& charInfo(wchar_t wc, unsigned flags)
31
- {
32
- size_t planeIndex = wc / 65536;
33
- size_t charIndex = wc % 65536;
34
-
35
- if (planeIndex >= 16)
36
- throw invalid_argument("Unicode plane out of reach");
37
- if (flags >= ffCombinations)
38
- throw invalid_argument("Font flags out of range");
39
-
40
- if (!planes[planeIndex][flags].get())
41
- planes[planeIndex][flags].reset(new Plane);
42
- return (*planes[planeIndex][flags])[charIndex];
43
- }
44
-
45
- const Image& imageAt(const FormattedString& fs, unsigned i)
46
- {
47
- if (fs.entityAt(i))
48
- {
49
- tr1::shared_ptr<Image>& ptr = entityCache[fs.entityAt(i)];
50
- if (!ptr)
51
- ptr.reset(new Image(entityBitmap(fs.entityAt(i)), ifSmooth));
52
- return *ptr;
53
- }
54
-
55
- wchar_t wc = fs.charAt(i);
56
- unsigned flags = fs.flagsAt(i);
57
- CharInfo& info = charInfo(wc, flags);
58
-
59
- if (info.image.get())
60
- return *info.image;
61
-
62
- wstring charString(1, wc);
63
- // TODO: Would be nice to have.
64
- // if (isFormattingChar(wc))
65
- // charString.clear();
66
- unsigned charWidth = Gosu::textWidth(charString, name, height, flags);
67
-
68
- Bitmap bitmap(charWidth, height, 0x00ffffff);
69
- drawText(bitmap, charString, 0, 0, Color::WHITE, name, height, flags);
70
- info.image.reset(new Image(bitmap));
71
- info.factor = 0.5;
72
- return *info.image;
73
- }
74
-
75
- double factorAt(const FormattedString& fs, unsigned index)
76
- {
77
- if (fs.entityAt(index))
78
- return 1;
79
- return charInfo(fs.charAt(index), fs.flagsAt(index)).factor;
80
- }
81
- };
82
-
83
- Gosu::Font::Font(unsigned fontHeight, const wstring& fontName, unsigned fontFlags)
84
- : pimpl(new Impl)
85
- {
86
- pimpl->name = fontName;
87
- pimpl->height = fontHeight * 2;
88
- pimpl->flags = fontFlags;
89
- }
90
-
91
- wstring Gosu::Font::name() const
92
- {
93
- return pimpl->name;
94
- }
95
-
96
- unsigned Gosu::Font::height() const
97
- {
98
- return pimpl->height / 2;
99
- }
100
-
101
- unsigned Gosu::Font::flags() const
102
- {
103
- return pimpl->flags;
104
- }
105
-
106
- double Gosu::Font::textWidth(const wstring& text, double factorX) const
107
- {
108
- FormattedString fs(text.c_str(), flags());
109
- double result = 0;
110
- for (unsigned i = 0; i < fs.length(); ++i)
111
- {
112
- const Image& image = pimpl->imageAt(fs, i);
113
- double factor = pimpl->factorAt(fs, i);
114
- result += image.width() * factor;
115
- }
116
- return result * factorX;
117
- }
118
-
119
- void Gosu::Font::draw(const wstring& text, double x, double y, ZPos z,
120
- double factorX, double factorY, Color c, AlphaMode mode) const
121
- {
122
- FormattedString fs(text.c_str(), flags());
123
-
124
- for (unsigned i = 0; i < fs.length(); ++i)
125
- {
126
- const Image& image = pimpl->imageAt(fs, i);
127
- double factor = pimpl->factorAt(fs, i);
128
- Gosu::Color color = fs.entityAt(i)
129
- ? Gosu::Color(fs.colorAt(i).alpha() * c.alpha() / 255, 255, 255, 255)
130
- : Gosu::multiply(fs.colorAt(i), c);
131
- image.draw(x, y, z, factorX * factor, factorY * factor, color, mode);
132
- x += image.width() * factorX * factor;
133
- }
134
- }
135
-
136
- void Gosu::Font::drawRel(const wstring& text, double x, double y, ZPos z,
137
- double relX, double relY, double factorX, double factorY, Color c,
138
- AlphaMode mode) const
139
- {
140
- x -= textWidth(text) * factorX * relX;
141
- y -= height() * factorY * relY;
142
-
143
- draw(text, x, y, z, factorX, factorY, c, mode);
144
- }
145
-
146
- void Gosu::Font::setImage(wchar_t wc, const Image& image)
147
- {
148
- for (unsigned flags = 0; flags < ffCombinations; ++flags)
149
- setImage(wc, flags, image);
150
- }
151
-
152
- void Gosu::Font::setImage(wchar_t wc, unsigned fontFlags, const Image& image)
153
- {
154
- Impl::CharInfo& ci = pimpl->charInfo(wc, fontFlags);
155
- if (ci.image.get())
156
- throw logic_error("Cannot set image for the same Font character twice or after it has been drawn");
157
- ci.image.reset(new Gosu::Image(image));
158
- ci.factor = 1.0;
159
- }
160
-
161
- void Gosu::Font::drawRot(const wstring& text, double x, double y, ZPos z, double angle,
162
- double factorX, double factorY, Color c, AlphaMode mode) const
163
- {
164
- Gosu::Graphics::pushTransform(rotate(angle, x, y));
165
- draw(text, x, y, z, factorX, factorY, c, mode);
166
- Gosu::Graphics::popTransform();
167
- }
168
-
169
- // Deprecated constructors
170
-
171
- Gosu::Font::Font(Graphics& graphics, const wstring& fontName, unsigned fontHeight,
172
- unsigned fontFlags)
173
- {
174
- Font(fontHeight, fontName, fontFlags).pimpl.swap(pimpl);
175
- }
@@ -1,391 +0,0 @@
1
- #include <Gosu/Text.hpp>
2
- #include <Gosu/Bitmap.hpp>
3
- #include <Gosu/Graphics.hpp>
4
- #include <Gosu/Image.hpp>
5
- #include <Gosu/Math.hpp>
6
- #include <Gosu/TR1.hpp>
7
- #include <Gosu/Utility.hpp>
8
- #include "../Graphics/Common.hpp"
9
- #include "FormattedString.hpp"
10
- #include <cassert>
11
- #include <cmath>
12
- #include <algorithm>
13
- #include <map>
14
- #include <vector>
15
- using namespace std;
16
-
17
- namespace Gosu
18
- {
19
- namespace
20
- {
21
- // Just a very simple heuristic that should make Chinese and Japanese text working in most
22
- // of the cases.
23
- bool isBreakingAsianGlyph(wchar_t ch)
24
- {
25
- if (ch >= 0x3040 && ch <= 0x3096)
26
- return true; // Hiragana
27
-
28
- if (ch >= 0x30a0 && ch <= 0x30fa)
29
- return true; // Katakana
30
-
31
- if (ch >= 0x4e00 && ch <= 0x9fff)
32
- return true; // CJK Unified Ideographs
33
-
34
- if (ch >= 0x3400 && ch <= 0x4db5)
35
- return true; // CJK Unified Ideographs Extension A
36
-
37
- return false;
38
- }
39
-
40
- struct WordInfo
41
- {
42
- FormattedString text;
43
- unsigned width;
44
- unsigned spaceWidth;
45
- };
46
- typedef vector<WordInfo> Words;
47
-
48
- // Local helper class which manages building the bitmap from the
49
- // collected words.
50
- class TextBlockBuilder
51
- {
52
- Bitmap bmp;
53
- unsigned usedLines, allocatedLines;
54
-
55
- wstring fontName;
56
- unsigned fontHeight;
57
- int lineSpacing;
58
- TextAlign align;
59
-
60
- unsigned spaceWidth_;
61
-
62
- void allocNextLine()
63
- {
64
- ++usedLines;
65
- if (usedLines == allocatedLines)
66
- {
67
- allocatedLines += 10;
68
- bmp.resize(bmp.width(),
69
- fontHeight * allocatedLines + lineSpacing * (allocatedLines - 1),
70
- 0x00ffffff);
71
- }
72
- }
73
-
74
- public:
75
- TextBlockBuilder(const wstring& fontName, unsigned fontHeight,
76
- int lineSpacing, unsigned width, TextAlign align)
77
- {
78
- usedLines = 0;
79
- allocatedLines = 10;
80
-
81
- bmp.resize(width, (lineSpacing + fontHeight) * allocatedLines, 0x00ffffff);
82
-
83
- this->fontName = fontName;
84
- this->fontHeight = fontHeight;
85
- this->lineSpacing = lineSpacing;
86
- this->align = align;
87
-
88
- spaceWidth_ = textWidth(FormattedString(L" ", 0));
89
- }
90
-
91
- unsigned width() const
92
- {
93
- return bmp.width();
94
- }
95
-
96
- unsigned textWidth(const FormattedString& text) const
97
- {
98
- if (text.length() == 0)
99
- return 0;
100
-
101
- if (text.entityAt(0))
102
- return entityBitmap(text.entityAt(0)).width();
103
-
104
- vector<FormattedString> parts = text.splitParts();
105
- unsigned result = 0;
106
- for (unsigned i = 0; i < parts.size(); ++i)
107
- result += Gosu::textWidth(parts[i].unformat(), fontName, fontHeight, parts[i].flagsAt(0));
108
- return result;
109
- }
110
-
111
- void addLine(Words::const_iterator begin, Words::const_iterator end,
112
- unsigned wordsWidth, bool overrideAlign)
113
- {
114
- allocNextLine();
115
-
116
- unsigned words = end - begin;
117
-
118
- unsigned totalSpacing = 0;
119
- if (begin < end)
120
- for (Words::const_iterator i = begin; i != end - 1; ++i)
121
- totalSpacing += i->spaceWidth;
122
-
123
- // Where does the line start? (y)
124
- unsigned top = (usedLines - 1) * (fontHeight + lineSpacing);
125
-
126
- // Where does the line start? (x)
127
- double pos;
128
- switch (align)
129
- {
130
- // Start so that the text touches the right border.
131
- case taRight:
132
- pos = bmp.width() - wordsWidth - totalSpacing;
133
- break;
134
-
135
- // Start so that the text is centered.
136
- case taCenter:
137
- pos = bmp.width() - wordsWidth - totalSpacing;
138
- pos /= 2;
139
- break;
140
-
141
- // Just start at the left border.
142
- default:
143
- pos = 0;
144
- }
145
-
146
- for (Words::const_iterator cur = begin; cur != end; ++cur)
147
- {
148
- vector<FormattedString> parts = cur->text.splitParts();
149
- int x = 0;
150
- for (int i = 0; i < parts.size(); ++i)
151
- {
152
- FormattedString& part = parts[i];
153
-
154
- if (part.entityAt(0))
155
- {
156
- Gosu::Bitmap entity = entityBitmap(part.entityAt(0));
157
- multiplyBitmapAlpha(entity, part.colorAt(0).alpha());
158
- bmp.insert(entity, trunc(pos) + x, trunc(top));
159
- x += entity.width();
160
- continue;
161
- }
162
-
163
- wstring unformattedPart = part.unformat();
164
- drawText(bmp, unformattedPart, trunc(pos) + x, trunc(top),
165
- part.colorAt(0), fontName, fontHeight, part.flagsAt(0));
166
- x += Gosu::textWidth(unformattedPart, fontName, fontHeight,
167
- part.flagsAt(0));
168
- }
169
-
170
- if (align == taJustify && !overrideAlign)
171
- pos += cur->width + 1.0 * (width() - wordsWidth) / (words - 1);
172
- else
173
- pos += cur->width + cur->spaceWidth;
174
- }
175
- }
176
-
177
- void addEmptyLine()
178
- {
179
- allocNextLine();
180
- }
181
-
182
- Bitmap result() const
183
- {
184
- Bitmap result = bmp;
185
- result.resize(result.width(),
186
- fontHeight * usedLines + lineSpacing * (usedLines - 1), 0x00ffffff);
187
- return result;
188
- }
189
-
190
- unsigned spaceWidth() const
191
- {
192
- return spaceWidth_;
193
- }
194
- };
195
-
196
- void processWords(TextBlockBuilder& builder, const Words& words)
197
- {
198
- if (words.empty())
199
- return builder.addEmptyLine();
200
-
201
- // Index into words to the first word in the current line.
202
- Words::const_iterator lineBegin = words.begin();
203
-
204
- // Used width, in pixels, of the words [lineBegin..w[.
205
- unsigned wordsWidth = 0;
206
-
207
- // Used width of the spaces between (w-lineBegin) words.
208
- unsigned spacesWidth = 0;
209
-
210
- for (Words::const_iterator w = words.begin(); w != words.end(); ++w)
211
- {
212
- unsigned newWordsWidth = wordsWidth + w->width;
213
-
214
- if (newWordsWidth + spacesWidth <= builder.width())
215
- {
216
- // There's enough space for the words [lineBegin..w] plus
217
- // the spaces between them: Proceed with the next word.
218
- wordsWidth = newWordsWidth;
219
- spacesWidth += w->spaceWidth;
220
- }
221
- else
222
- {
223
- // No, this word wouldn't fit into the current line: Draw
224
- // the current line, then start a new line with the current
225
- // word.
226
- builder.addLine(lineBegin, w, wordsWidth, false);
227
-
228
- lineBegin = w;
229
- wordsWidth = w->width;
230
- spacesWidth = w->spaceWidth;
231
- }
232
- }
233
-
234
- // Draw the last line as well.
235
- if (words.empty() || lineBegin != words.end())
236
- builder.addLine(lineBegin, words.end(), wordsWidth, true);
237
- }
238
-
239
- void processParagraph(TextBlockBuilder& builder, const FormattedString& paragraph)
240
- {
241
- Words collectedWords;
242
-
243
- unsigned beginOfWord = 0;
244
-
245
- for (unsigned cur = 0; cur < paragraph.length(); ++cur)
246
- {
247
- WordInfo newWord;
248
-
249
- if (paragraph.charAt(cur) == L' ')
250
- {
251
- // Whitespace:
252
- // Add last word to list if existent
253
- if (beginOfWord != cur)
254
- {
255
- newWord.text = paragraph.range(beginOfWord, cur);
256
- newWord.width = builder.textWidth(newWord.text);
257
- newWord.spaceWidth = builder.spaceWidth();
258
- collectedWords.push_back(newWord);
259
- }
260
- beginOfWord = cur + 1;
261
- }
262
- else if (isBreakingAsianGlyph(paragraph.charAt(cur)))
263
- {
264
- // Asian glyph (treat as single word):
265
- // Add last word to list if existent
266
- if (beginOfWord != cur)
267
- {
268
- newWord.text = paragraph.range(beginOfWord, cur);
269
- newWord.width = builder.textWidth(newWord.text);
270
- newWord.spaceWidth = 0;
271
- collectedWords.push_back(newWord);
272
- }
273
- // Add glyph as a single "word"
274
- newWord.text = paragraph.range(cur, cur + 1);
275
- newWord.width = builder.textWidth(newWord.text);
276
- newWord.spaceWidth = 0;
277
- collectedWords.push_back(newWord);
278
- beginOfWord = cur + 1;
279
- }
280
- }
281
- if (beginOfWord < paragraph.length())
282
- {
283
- WordInfo lastWord;
284
- lastWord.text = paragraph.range(beginOfWord, paragraph.length());
285
- lastWord.width = builder.textWidth(lastWord.text);
286
- lastWord.spaceWidth = 0;
287
- collectedWords.push_back(lastWord);
288
- }
289
-
290
- processWords(builder, collectedWords);
291
- }
292
-
293
- void processText(TextBlockBuilder& builder, const FormattedString& text)
294
- {
295
- vector<FormattedString> paragraphs = text.splitLines();
296
- for (int i = 0; i < paragraphs.size(); ++i)
297
- processParagraph(builder, paragraphs[i]);
298
- }
299
- }
300
- }
301
-
302
- Gosu::Bitmap Gosu::createText(const wstring& text,
303
- const wstring& fontName, unsigned fontHeight, int lineSpacing,
304
- unsigned width, TextAlign align, unsigned fontFlags)
305
- {
306
- if (lineSpacing <= -static_cast<int>(fontHeight))
307
- throw logic_error("negative line spacing of more than line height impossible");
308
-
309
- FormattedString fs(text.c_str(), fontFlags);
310
- if (fs.length() == 0)
311
- return Bitmap(width, fontHeight);
312
-
313
- // Set up the builder object which will manage all the drawing and
314
- // conversions for us.
315
- TextBlockBuilder builder(fontName, fontHeight, lineSpacing, width, align);
316
-
317
- // Let the process* functions draw everything.
318
- processText(builder, fs);
319
-
320
- // Done!
321
- return builder.result();
322
- }
323
-
324
- // Very easy special case.
325
- Gosu::Bitmap Gosu::createText(const wstring& text,
326
- const wstring& fontName, unsigned fontHeight, unsigned fontFlags)
327
- {
328
- FormattedString fs(text.c_str(), fontFlags);
329
- if (fs.length() == 0)
330
- return Bitmap(1, fontHeight);
331
-
332
- vector<FormattedString> lines = fs.splitLines();
333
-
334
- Bitmap bmp(1, lines.size() * fontHeight);
335
-
336
- for (int i = 0; i < lines.size(); ++i)
337
- {
338
- if (lines[i].length() == 0)
339
- continue;
340
-
341
- unsigned x = 0;
342
- vector<FormattedString> parts = lines[i].splitParts();
343
- for (int p = 0; p < parts.size(); ++p)
344
- {
345
- const FormattedString& part = parts[p];
346
- if (part.length() == 1 && part.entityAt(0))
347
- {
348
- Gosu::Bitmap entity = entityBitmap(part.entityAt(0));
349
- multiplyBitmapAlpha(entity, part.colorAt(0).alpha());
350
- bmp.resize(max(bmp.width(), x + entity.width()), bmp.height(), 0x00ffffff);
351
- bmp.insert(entity, x, i * fontHeight);
352
- x += entity.width();
353
- continue;
354
- }
355
-
356
- assert(part.length() > 0);
357
- wstring unformattedText = part.unformat();
358
- unsigned partWidth =
359
- textWidth(unformattedText, fontName, fontHeight, part.flagsAt(0));
360
- bmp.resize(max(bmp.width(), x + partWidth), bmp.height(), 0x00ffffff);
361
- drawText(bmp, unformattedText, x, i * fontHeight, part.colorAt(0),
362
- fontName, fontHeight, part.flagsAt(0));
363
- x += partWidth;
364
- }
365
- }
366
-
367
- return bmp;
368
- }
369
-
370
- namespace
371
- {
372
- map<wstring, tr1::shared_ptr<Gosu::Bitmap> > entities;
373
- }
374
-
375
- void Gosu::registerEntity(const wstring& name, const Gosu::Bitmap& replacement)
376
- {
377
- entities[name].reset(new Bitmap(replacement));
378
- }
379
-
380
- bool Gosu::isEntity(const wstring& name)
381
- {
382
- return entities[name].get();
383
- }
384
-
385
- const Gosu::Bitmap& Gosu::entityBitmap(const wstring& name)
386
- {
387
- tr1::shared_ptr<Gosu::Bitmap>& ptr = entities[name];
388
- if (!ptr)
389
- throw runtime_error("Unknown entity: " + Gosu::wstringToUTF8(name));
390
- return *ptr;
391
- }