gosu 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/Gosu/Bitmap.hpp +3 -3
  3. data/Gosu/Directories.hpp +6 -3
  4. data/Gosu/Gosu.hpp +0 -1
  5. data/Gosu/GraphicsBase.hpp +12 -8
  6. data/Gosu/Input.hpp +5 -16
  7. data/Gosu/Platform.hpp +1 -0
  8. data/Gosu/Version.hpp +3 -5
  9. data/Gosu/Window.hpp +7 -8
  10. data/README.txt +3 -3
  11. data/ext/gosu/extconf.rb +17 -16
  12. data/ext/gosu/gosu_wrap.cxx +59 -58
  13. data/ext/gosu/gosu_wrap.h +1 -1
  14. data/rdoc/gosu.rb +285 -283
  15. data/src/{MacUtility.hpp → AppleUtility.hpp} +24 -42
  16. data/src/Audio/ALChannelManagement.hpp +1 -1
  17. data/src/Audio/{AudioOpenAL.cpp → Audio.cpp} +6 -7
  18. data/src/Audio/Audio.mm +1 -0
  19. data/src/Audio/AudioFile.hpp +2 -2
  20. data/src/Audio/AudioToolboxFile.hpp +5 -20
  21. data/src/Audio/OggFile.hpp +44 -56
  22. data/src/Audio/SndFile.hpp +2 -2
  23. data/src/Bitmap/Bitmap.cpp +98 -2
  24. data/src/Bitmap/BitmapIO.cpp +156 -0
  25. data/src/DirectoriesApple.mm +76 -0
  26. data/src/DirectoriesUnix.cpp +5 -12
  27. data/src/DirectoriesWin.cpp +5 -0
  28. data/src/Graphics/BlockAllocator.hpp +2 -2
  29. data/src/Graphics/ClipRectStack.hpp +2 -2
  30. data/src/Graphics/Common.hpp +2 -2
  31. data/src/Graphics/DrawOp.hpp +2 -2
  32. data/src/Graphics/DrawOpQueue.hpp +2 -2
  33. data/src/Graphics/Graphics.cpp +7 -2
  34. data/src/Graphics/LargeImageData.cpp +6 -6
  35. data/src/Graphics/LargeImageData.hpp +3 -3
  36. data/src/Graphics/Macro.hpp +2 -2
  37. data/src/Graphics/RenderState.hpp +2 -2
  38. data/src/Graphics/Resolution.cpp +1 -1
  39. data/src/Graphics/TexChunk.hpp +2 -2
  40. data/src/Graphics/Texture.cpp +21 -16
  41. data/src/Graphics/Texture.hpp +7 -5
  42. data/src/Graphics/TransformStack.hpp +2 -2
  43. data/src/Iconv.hpp +2 -2
  44. data/src/Input/Input.cpp +3 -1
  45. data/src/Input/{InputTouch.mm → InputUIKit.mm} +32 -26
  46. data/src/Input/TextInput.cpp +1 -1
  47. data/src/Text/FormattedString.hpp +2 -2
  48. data/src/Text/TextApple.mm +8 -8
  49. data/src/Text/TextMac.cpp +1 -1
  50. data/src/Text/TextUnix.cpp +1 -1
  51. data/src/UIKit/GosuAppDelegate.h +8 -0
  52. data/src/UIKit/GosuAppDelegate.mm +24 -0
  53. data/src/UIKit/GosuGLView.h +8 -0
  54. data/src/UIKit/GosuGLView.mm +130 -0
  55. data/src/UIKit/GosuViewController.h +13 -0
  56. data/src/UIKit/GosuViewController.mm +214 -0
  57. data/src/UtilityApple.mm +5 -18
  58. data/src/Window.cpp +1 -3
  59. data/src/WindowUIKit.mm +124 -0
  60. data/src/stb_image.h +6437 -0
  61. data/src/stb_image_write.h +730 -0
  62. data/src/stb_vorbis.c +5459 -0
  63. metadata +18 -26
  64. data/Gosu/Sockets.hpp +0 -156
  65. data/src/Audio/AudioOpenAL.mm +0 -1
  66. data/src/Bitmap/BitmapApple.mm +0 -226
  67. data/src/Bitmap/BitmapBMP.cpp +0 -79
  68. data/src/Bitmap/BitmapColorKey.cpp +0 -50
  69. data/src/Bitmap/BitmapFreeImage.cpp +0 -174
  70. data/src/Bitmap/BitmapGDIplus.cpp +0 -212
  71. data/src/Bitmap/BitmapUtils.cpp +0 -76
  72. data/src/DirectoriesMac.mm +0 -38
  73. data/src/DirectoriesTouch.mm +0 -38
  74. data/src/GosuView.hpp +0 -15
  75. data/src/GosuView.mm +0 -208
  76. data/src/Input/AccelerometerReader.hpp +0 -10
  77. data/src/Input/AccelerometerReader.mm +0 -31
  78. data/src/Sockets/CommSocket.cpp +0 -305
  79. data/src/Sockets/ListenerSocket.cpp +0 -59
  80. data/src/Sockets/MessageSocket.cpp +0 -128
  81. data/src/Sockets/Socket.cpp +0 -145
  82. data/src/Sockets/Socket.hpp +0 -66
  83. data/src/WindowTouch.mm +0 -243
  84. data/src/X11vroot.h +0 -118
@@ -1,79 +0,0 @@
1
- #include <Gosu/Platform.hpp>
2
-
3
- // All other platforms use OS libraries instead.
4
- #ifdef GOSU_IS_IPHONE
5
- #include <Gosu/Bitmap.hpp>
6
- #include <Gosu/IO.hpp>
7
- #include <Gosu/TR1.hpp>
8
-
9
- namespace
10
- {
11
- template<unsigned bits> struct UintSelector;
12
- template<> struct UintSelector<8> { typedef std::tr1::uint8_t Type; };
13
- template<> struct UintSelector<16> { typedef std::tr1::uint16_t Type; };
14
- template<> struct UintSelector<32> { typedef std::tr1::uint32_t Type; };
15
-
16
- template<unsigned bits, typename T>
17
- void writeVal(Gosu::Writer& writer, T value)
18
- {
19
- typename UintSelector<bits>::Type val = value;
20
- writer.writePod(val, Gosu::boLittle);
21
- }
22
- }
23
-
24
- Gosu::Writer Gosu::saveToBMP(const Bitmap& bmp, Writer writer)
25
- {
26
- // rowSize is the width ceiled to the next multiple of four.
27
- unsigned rowSize = bmp.width() * 3;
28
- rowSize = int((float(rowSize) - 1.0)/4.0 + 1.0) * 4;
29
-
30
- // File header
31
- // Type
32
- writeVal<8>(writer, 'B');
33
- writeVal<8>(writer, 'M');
34
- // Size
35
- writeVal<32>(writer, 14 + 40 + rowSize * bmp.height());
36
- // Reserved
37
- writeVal<16>(writer, 0);
38
- writeVal<16>(writer, 0);
39
- // Offset to data
40
- writeVal<32>(writer, 14 + 40);
41
-
42
- // Info header
43
- // Size
44
- writeVal<32>(writer, 40);
45
- // Width, height
46
- writeVal<32>(writer, bmp.width());
47
- writeVal<32>(writer, bmp.height());
48
- // Planes
49
- writeVal<16>(writer, 1);
50
- // Bit count
51
- writeVal<16>(writer, 24);
52
- // Compression
53
- writeVal<32>(writer, 0);
54
- // Image size
55
- writeVal<32>(writer, rowSize * bmp.height());
56
- // xPelsPerMeter/yPelsPerMeter
57
- writeVal<32>(writer, 0);
58
- writeVal<32>(writer, 0);
59
- // Used and important colors
60
- writeVal<32>(writer, 0);
61
- writeVal<32>(writer, 0);
62
-
63
- for (int y = bmp.height() - 1; y >= 0; y--)
64
- {
65
- for (unsigned x = 0; x < bmp.width(); x++)
66
- {
67
- // BGR order
68
- writeVal<8>(writer, bmp.getPixel(x, y).blue());
69
- writeVal<8>(writer, bmp.getPixel(x, y).green());
70
- writeVal<8>(writer, bmp.getPixel(x, y).red());
71
- }
72
- int offset = rowSize - bmp.width() * 3;
73
- for(int i = 0; i < offset; ++i)
74
- writeVal<8>(writer, 0);
75
- }
76
- return writer;
77
- }
78
-
79
- #endif
@@ -1,50 +0,0 @@
1
- #include <Gosu/Bitmap.hpp>
2
- #include <vector>
3
-
4
- void Gosu::applyColorKey(Bitmap& bitmap, Color key)
5
- {
6
- std::vector<Color> surroundingColors;
7
- surroundingColors.reserve(4);
8
-
9
- for (unsigned y = 0; y < bitmap.height(); ++y)
10
- for (unsigned x = 0; x < bitmap.width(); ++x)
11
- if (bitmap.getPixel(x, y) == key)
12
- {
13
- surroundingColors.clear();
14
- if (x > 0 && bitmap.getPixel(x - 1, y) != key)
15
- surroundingColors.push_back(bitmap.getPixel(x - 1, y));
16
- if (x < bitmap.width() - 1 && bitmap.getPixel(x + 1, y) != key)
17
- surroundingColors.push_back(bitmap.getPixel(x + 1, y));
18
- if (y > 0 && bitmap.getPixel(x, y - 1) != key)
19
- surroundingColors.push_back(bitmap.getPixel(x, y - 1));
20
- if (y < bitmap.height() - 1 && bitmap.getPixel(x, y + 1) != key)
21
- surroundingColors.push_back(bitmap.getPixel(x, y + 1));
22
-
23
- if (surroundingColors.empty())
24
- {
25
- bitmap.setPixel(x, y, Color::NONE);
26
- continue;
27
- }
28
-
29
- unsigned red = 0, green = 0, blue = 0;
30
- for (unsigned i = 0; i < surroundingColors.size(); ++i)
31
- {
32
- red += surroundingColors[i].red();
33
- green += surroundingColors[i].green();
34
- blue += surroundingColors[i].blue();
35
- }
36
- bitmap.setPixel(x, y, Color(0, red / surroundingColors.size(),
37
- green / surroundingColors.size(), blue / surroundingColors.size()));
38
- }
39
- }
40
-
41
- void Gosu::unapplyColorKey(Bitmap& bitmap, Color color)
42
- {
43
- Color* p = bitmap.data();
44
- for (int i = bitmap.width() * bitmap.height(); i > 0; --i, ++p)
45
- if (p->alpha() == 0)
46
- *p = color;
47
- else
48
- p->setAlpha(255);
49
- }
50
-
@@ -1,174 +0,0 @@
1
- #include <Gosu/Bitmap.hpp>
2
- #include <Gosu/IO.hpp>
3
- #include <Gosu/Platform.hpp>
4
- #include <Gosu/TR1.hpp>
5
- #include <Gosu/Utility.hpp>
6
- #include <stdexcept>
7
- #include <vector>
8
- #include <FreeImage.h>
9
-
10
- // Compatibility with FreeImage <3.1.3. Subtly changes Gosu's behavior though.
11
- #ifndef JPEG_EXIFROTATE
12
- #define JPEG_EXIFROTATE 0
13
- #endif
14
-
15
- // With MSVC, add a suffix so FreeImage can be linked as a fallback for GDI+.
16
- // With MinGW, Gosu uses FreeImage all the time, so no suffix is needed.
17
- #ifdef _MSC_VER
18
- #define FI(x) x##_FreeImage
19
- #else
20
- #define FI(x) x
21
- #endif
22
-
23
- namespace
24
- {
25
- const int GOSU_FIFLAGS = (JPEG_EXIFROTATE | ICO_MAKEALPHA | PNG_IGNOREGAMMA);
26
-
27
- void reshuffleBitmap(Gosu::Bitmap& bitmap)
28
- {
29
- // Since FreeImage gracefully ignores the MASK parameters above, we
30
- // manually exchange the R and B channels.
31
- std::tr1::uint32_t* p = reinterpret_cast<std::tr1::uint32_t*>(bitmap.data());
32
- for (int i = bitmap.width() * bitmap.height(); i > 0; --i, ++p)
33
- *p = (*p & 0xff00ff00) | ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff);
34
- }
35
-
36
- FIBITMAP* ensure32bits(FIBITMAP* fib)
37
- {
38
- int bpp = FreeImage_GetBPP(fib);
39
- FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(fib);
40
- if (bpp != 32 && (image_type == FIT_BITMAP || image_type == FIT_RGBA16)) {
41
- FIBITMAP* fib32 = FreeImage_ConvertTo32Bits(fib);
42
- FreeImage_Unload(fib);
43
- fib = fib32;
44
- }
45
- return fib;
46
- }
47
-
48
- void fibToBitmap(Gosu::Bitmap& bitmap, FIBITMAP* fib, FREE_IMAGE_FORMAT fif)
49
- {
50
- bitmap.resize(FreeImage_GetWidth(fib), FreeImage_GetHeight(fib));
51
- fib = ensure32bits(fib);
52
- FreeImage_ConvertToRawBits(reinterpret_cast<BYTE*>(bitmap.data()),
53
- fib, bitmap.width() * 4, 32,
54
- FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE);
55
- FreeImage_Unload(fib);
56
- reshuffleBitmap(bitmap);
57
- if (fif == FIF_BMP)
58
- Gosu::applyColorKey(bitmap, Gosu::Color::FUCHSIA);
59
- }
60
-
61
- FIBITMAP* bitmapToFIB(Gosu::Bitmap bitmap, FREE_IMAGE_FORMAT fif)
62
- {
63
- reshuffleBitmap(bitmap);
64
- if (fif == FIF_BMP)
65
- unapplyColorKey(bitmap, Gosu::Color::FUCHSIA);
66
- return FreeImage_ConvertFromRawBits((BYTE*)bitmap.data(),
67
- bitmap.width(), bitmap.height(), bitmap.width() * 4, 32,
68
- FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true);
69
- }
70
-
71
- // Wrap Gosu::Writer as a FreeImageIO.
72
- unsigned DLL_CALLCONV WriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle)
73
- {
74
- ((Gosu::Writer*)handle)->write(buffer, size * count);
75
- return count;
76
- }
77
- int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin)
78
- {
79
- Gosu::Writer& writer = *(Gosu::Writer*)handle;
80
- switch (origin)
81
- {
82
- case SEEK_SET: writer.setPosition(offset); break;
83
- case SEEK_CUR: writer.seek(offset); break;
84
- case SEEK_END: writer.setPosition(writer.resource().size() - offset); break;
85
- };
86
- return 0;
87
- }
88
- long DLL_CALLCONV TellProc(fi_handle handle)
89
- {
90
- return ((Gosu::Writer*)handle)->position();
91
- }
92
-
93
- // TODO: This is not thread safe!
94
-
95
- std::string lastFreeImageError;
96
-
97
- void DLL_CALLCONV FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *message)
98
- {
99
- lastFreeImageError = (message && message[0]) ? message : "Unknown error";
100
- if (fif != FIF_UNKNOWN)
101
- if (const char* format = FreeImage_GetFormatFromFIF(fif))
102
- lastFreeImageError += std::string(" (in ") + format + " parser)";
103
- }
104
-
105
- void checkForFreeImageErrors(bool value = true)
106
- {
107
- if (!value || !lastFreeImageError.empty())
108
- {
109
- std::string message = lastFreeImageError;
110
- if (message.empty())
111
- message = "Unknown error";
112
- else
113
- lastFreeImageError.clear();
114
- throw std::runtime_error(message);
115
- }
116
- }
117
- }
118
-
119
- namespace Gosu
120
- {
121
- void FI(loadImageFile)(Bitmap& bitmap, const std::wstring& filename)
122
- {
123
- #ifdef GOSU_IS_WIN
124
- FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeU(filename.c_str());
125
- FIBITMAP* fib = FreeImage_LoadU(fif, filename.c_str(), GOSU_FIFLAGS);
126
- #else
127
- std::string utf8Filename = wstringToUTF8(filename);
128
- FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(utf8Filename.c_str());
129
- FIBITMAP* fib = FreeImage_Load(fif, utf8Filename.c_str(), GOSU_FIFLAGS);
130
- #endif
131
- checkForFreeImageErrors(fib != 0);
132
- fibToBitmap(bitmap, fib, fif);
133
- }
134
-
135
- void FI(loadImageFile)(Bitmap& bitmap, Gosu::Reader input)
136
- {
137
- // Read all available input
138
- std::vector<BYTE> data(input.resource().size() - input.position());
139
- input.read(&data[0], data.size());
140
- FIMEMORY* fim = FreeImage_OpenMemory(&data[0], data.size());
141
- FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(fim);
142
- FIBITMAP* fib = FreeImage_LoadFromMemory(fif, fim, GOSU_FIFLAGS);
143
- checkForFreeImageErrors(fib != 0);
144
- fibToBitmap(bitmap, fib, fif);
145
- }
146
-
147
- void FI(saveImageFile)(const Bitmap& bitmap, const std::wstring& filename)
148
- {
149
- std::string utf8Filename = wstringToUTF8(filename);
150
- FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(utf8Filename.c_str());
151
- FIBITMAP* fib = bitmapToFIB(bitmap, fif);
152
-
153
- #ifdef GOSU_IS_WIN
154
- FreeImage_SaveU(fif, fib, filename.c_str());
155
- #else
156
- FreeImage_Save(fif, fib, utf8Filename.c_str());
157
- #endif
158
- FreeImage_Unload(fib);
159
- checkForFreeImageErrors();
160
- }
161
-
162
- void FI(saveImageFile)(const Bitmap& bitmap, Gosu::Writer writer,
163
- const std::wstring& formatHint)
164
- {
165
- std::string utf8FormatHint = wstringToUTF8(formatHint);
166
- FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(utf8FormatHint.c_str());
167
- FIBITMAP* fib = bitmapToFIB(bitmap, fif);
168
-
169
- FreeImageIO fio = { NULL, WriteProc, SeekProc, TellProc };
170
- FreeImage_SaveToHandle(fif, fib, &fio, &writer);
171
- FreeImage_Unload(fib);
172
- checkForFreeImageErrors();
173
- }
174
- }
@@ -1,212 +0,0 @@
1
- #include <Gosu/Graphics.hpp>
2
- #include <Gosu/Bitmap.hpp>
3
- #include <Gosu/IO.hpp>
4
- #include <Gosu/Platform.hpp>
5
- #include <Gosu/TR1.hpp>
6
- #include <Gosu/Utility.hpp>
7
- #include <Gosu/WinUtility.hpp>
8
- #include <cwctype>
9
- #include <map>
10
-
11
- #include <objidl.h>
12
- #include <gdiplus.h>
13
- #include <windows.h>
14
-
15
- using namespace std;
16
-
17
- // TODO: Move into proper internal header
18
- namespace Gosu { bool isExtension(const wchar_t* str, const wchar_t* ext); }
19
-
20
- namespace
21
- {
22
- bool initialized = false;
23
- ULONG_PTR token;
24
- Gdiplus::GdiplusStartupInput input;
25
-
26
- // TODO: Merge with BitmapFreeImage.cpp, somehow
27
- void reshuffleBitmap(Gosu::Bitmap& bitmap)
28
- {
29
- // Since GDI+ only supports ARGB=BGRA formats, we
30
- // manually exchange the R and B channels to get to ABGR=RGBA.
31
- std::tr1::uint32_t* p = reinterpret_cast<std::tr1::uint32_t*>(bitmap.data());
32
- for (int i = bitmap.width() * bitmap.height(); i > 0; --i, ++p)
33
- *p = (*p & 0xff00ff00) | ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff);
34
- }
35
-
36
- void check(Gdiplus::Status status, const char* action)
37
- {
38
- if (status != Gdiplus::Ok)
39
- throw runtime_error(string("A GDI+ error occured while ") + action);
40
- }
41
-
42
- void closeGDIplus()
43
- {
44
- Gdiplus::GdiplusShutdown(token);
45
- }
46
-
47
- void requireGDIplus()
48
- {
49
- if (initialized)
50
- return;
51
- initialized = true;
52
- check(Gdiplus::GdiplusStartup(&token, &input, NULL), "initializing GDI+");
53
- atexit(closeGDIplus);
54
- }
55
-
56
- void gdiPlusToGosu(Gosu::Bitmap& result, Gdiplus::Bitmap& bitmap)
57
- {
58
- result.resize(bitmap.GetWidth(), bitmap.GetHeight());
59
-
60
- GUID guid;
61
- check(bitmap.GetRawFormat(&guid), "getting the format GUID");
62
- // TODO:
63
- // if (guid == Gdiplus::ImageFormatJPEG || guid == Gdiplus::ImageFormatPNG ||
64
- // guid == Gdiplus::ImageFormatGIF || guid == Gdiplus::ImageFormatBMP ||
65
- // guid == Gdiplus::ImageFormatTIFF || guid == Gdiplus::ImageFormatIcon)
66
- // else use FreeImage (via lazy linking...)
67
-
68
- Gdiplus::BitmapData target;
69
- target.Width = result.width();
70
- target.Height = result.height();
71
- target.PixelFormat = PixelFormat32bppARGB;
72
- target.Stride = result.width() * 4;
73
- target.Scan0 = result.data();
74
-
75
- Gdiplus::Rect rect(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
76
-
77
- check(bitmap.LockBits(&rect,
78
- Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf,
79
- PixelFormat32bppARGB, &target), "locking bits");
80
- check(bitmap.UnlockBits(&target), "unlocking bits");
81
-
82
- reshuffleBitmap(result);
83
-
84
- if (guid == Gdiplus::ImageFormatBMP)
85
- applyColorKey(result, Gosu::Color::FUCHSIA);
86
- }
87
-
88
- tr1::shared_ptr<IStream> readToIStream(Gosu::Reader reader)
89
- {
90
- unsigned remaining = reader.resource().size() - reader.position();
91
- HGLOBAL buffer = ::GlobalAlloc(GMEM_MOVEABLE, remaining);
92
- Gosu::Win::check(buffer);
93
- void* bufferPtr = ::GlobalLock(buffer);
94
- if (!bufferPtr)
95
- {
96
- ::GlobalFree(buffer);
97
- Gosu::Win::throwLastError();
98
- }
99
- reader.read(bufferPtr, reader.resource().size() - reader.position());
100
-
101
- IStream* stream = NULL;
102
- if (::CreateStreamOnHGlobal(buffer, TRUE, &stream) != S_OK)
103
- {
104
- ::GlobalFree(buffer);
105
- throw runtime_error("Could not create IStream");
106
- }
107
- return Gosu::Win::shareComPtr(stream);
108
- }
109
-
110
- CLSID& encoderFromMimeType(const wstring& mimeType)
111
- {
112
- static map<wstring, CLSID> cache;
113
- if (cache.count(mimeType))
114
- return cache[mimeType];
115
-
116
- UINT num = 0, size = 0;
117
- check(Gdiplus::GetImageEncodersSize(&num, &size), "counting encoders");
118
- // Do the eleet int-based ceil(size / sizeof)
119
- unsigned vecSize = (size + sizeof(Gdiplus::ImageCodecInfo) - 1) / sizeof(Gdiplus::ImageCodecInfo);
120
- vector<Gdiplus::ImageCodecInfo> codecs(vecSize);
121
- check(Gdiplus::GetImageEncoders(num, size,
122
- &codecs[0]), "enumerating encoders");
123
- for (int i = 0; i < num; ++i)
124
- if (codecs[i].MimeType == mimeType)
125
- return cache[mimeType] = codecs[i].Clsid;
126
- throw runtime_error("No encoder found for " + Gosu::wstringToUTF8(mimeType));
127
- }
128
-
129
- CLSID encoderFromHint(const wstring& formatHint)
130
- {
131
- wstring::size_type idx = formatHint.rfind('.');
132
- wstring mimeType = L"image/";
133
- if (idx == wstring::npos)
134
- mimeType += formatHint;
135
- else
136
- mimeType += formatHint.substr(idx + 1);
137
-
138
- for (int i = 0; i < mimeType.size(); ++i)
139
- mimeType[i] = towlower((wint_t)mimeType[i]);
140
-
141
- // Fix pitfalls
142
- if (mimeType == L"image/jpg")
143
- mimeType = L"image/jpeg";
144
- else if (mimeType == L"image/tif")
145
- mimeType = L"image/tiff";
146
-
147
- return encoderFromMimeType(mimeType);
148
- }
149
- }
150
-
151
- void Gosu::loadImageFile(Gosu::Bitmap& result, const wstring& filename)
152
- {
153
- requireGDIplus();
154
-
155
- Gdiplus::Bitmap bitmap(filename.c_str());
156
- check(bitmap.GetLastStatus(), ("loading " + wstringToUTF8(filename)).c_str());
157
- gdiPlusToGosu(result, bitmap);
158
- }
159
-
160
- void Gosu::loadImageFile(Gosu::Bitmap& result, Reader reader)
161
- {
162
- requireGDIplus();
163
-
164
- tr1::shared_ptr<IStream> stream = readToIStream(reader);
165
- Gdiplus::Bitmap bitmap(stream.get());
166
- check(bitmap.GetLastStatus(), "loading a bitmap from memory");
167
- gdiPlusToGosu(result, bitmap);
168
- }
169
-
170
- void Gosu::saveImageFile(const Bitmap& bitmap, const wstring& filename)
171
- {
172
- requireGDIplus();
173
-
174
- Bitmap input = bitmap;
175
- if (isExtension(filename.c_str(), L".bmp"))
176
- unapplyColorKey(input, Color::FUCHSIA);
177
- reshuffleBitmap(input);
178
- Gdiplus::Bitmap output(input.width(), input.height(), input.width() * 4,
179
- PixelFormat32bppARGB, (BYTE*)input.data());
180
- check(output.GetLastStatus(), "creating a bitmap in memory");
181
-
182
- check(output.Save(filename.c_str(), &encoderFromHint(filename)),
183
- ("writing to " + wstringToUTF8(filename)).c_str());
184
- }
185
-
186
- void Gosu::saveImageFile(const Bitmap& bitmap, Writer writer, const wstring& formatHint)
187
- {
188
- requireGDIplus();
189
-
190
- Bitmap input = bitmap;
191
- if (isExtension(formatHint.c_str(), L".bmp"))
192
- unapplyColorKey(input, Color::FUCHSIA);
193
- reshuffleBitmap(input);
194
- Gdiplus::Bitmap output(input.width(), input.height(), input.width() * 4,
195
- PixelFormat32bppARGB, (BYTE*)input.data());
196
- check(output.GetLastStatus(), "creating a bitmap in memory");
197
-
198
- IStream* stream = NULL;
199
- if (CreateStreamOnHGlobal(0, TRUE, &stream) != S_OK)
200
- throw runtime_error("Could not create IStream for writing");
201
- tr1::shared_ptr<IStream> streamGuard(Gosu::Win::shareComPtr(stream));
202
- check(output.Save(stream, &encoderFromHint(formatHint)),
203
- "saving a bitmap to memory");
204
-
205
- HGLOBAL buffer;
206
- GetHGlobalFromStream(stream, &buffer);
207
- void* bufferPtr = GlobalLock(buffer);
208
- if (!bufferPtr)
209
- Win::throwLastError();
210
- writer.write(bufferPtr, GlobalSize(buffer));
211
- GlobalUnlock(buffer);
212
- }