diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index 17a31491..ad2c8a6c 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -131,7 +131,10 @@ namespace nana void setsta(); ///< Clears the status if the graphics object had been changed void set_changed(); void release(); - void save_as_file(const char*) const; // saves image as a bitmap file + + /// Saves images as a windows bitmap file + /// @param file_utf8 A UTF-8 string to a filename + void save_as_file(const char* file_utf8) const throw(); void set_color(const ::nana::color&); void set_text_color(const ::nana::color&); diff --git a/source/paint/detail/image_png.hpp b/source/paint/detail/image_png.hpp index cab432cd..eda096e7 100644 --- a/source/paint/detail/image_png.hpp +++ b/source/paint/detail/image_png.hpp @@ -21,10 +21,6 @@ namespace nana : public image::image_impl_interface { public: - image_png() - { - } - bool open(const nana::char_t* png_file) override { #ifdef NANA_UNICODE @@ -148,6 +144,12 @@ namespace nana return is_opened; } + bool open(const void* data, std::size_t bytes) override + { + throw std::logic_error("PNG is not supported for raw data buffer"); + return false; + } + bool alpha_channel() const override { return pixbuf_.alpha_channel(); diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 2a997679..cba4b272 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -817,7 +817,7 @@ namespace paint size_.width = size_.height = 0; } - void graphics::save_as_file(const char* file) const + void graphics::save_as_file(const char* file_utf8) const throw() { if(handle_) { @@ -831,25 +831,28 @@ namespace paint bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 24; + const size_t lineBytes = ((bmpInfo.bmiHeader.biWidth * 3) + 3) & (~3); + const size_t imageBytes = iHeight * lineBytes; + HDC hdcMem = ::CreateCompatibleDC(handle_->context); BYTE *pData = nullptr; - HBITMAP hBmp = CreateDIBSection(hdcMem, &bmpInfo, DIB_RGB_COLORS, reinterpret_cast(&pData), 0, 0); + HBITMAP hBmp = ::CreateDIBSection(hdcMem, &bmpInfo, DIB_RGB_COLORS, reinterpret_cast(&pData), 0, 0); ::SelectObject(hdcMem, hBmp); BitBlt(hdcMem, 0, 0, iWidth, iHeight, handle_->context, 0, 0, SRCCOPY); - BITMAPFILEHEADER bmFileHeader = {0}; + BITMAPFILEHEADER bmFileHeader = { 0 }; bmFileHeader.bfType = 0x4d42; //bmp bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biHeight) * 3); ///3=(24 / 8) + bmFileHeader.bfSize = bmFileHeader.bfOffBits + imageBytes; - HANDLE hFile = CreateFileA(file,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); + HANDLE hFile = ::CreateFileW(static_cast(::nana::charset(file_utf8, ::nana::unicode::utf8)).data(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); DWORD dwWrite = 0; - WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL); - WriteFile(hFile,&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL); - WriteFile(hFile,pData, iWidth * iHeight * 3,&dwWrite,NULL); - CloseHandle(hFile); + ::WriteFile(hFile, &bmFileHeader, sizeof(BITMAPFILEHEADER), &dwWrite, nullptr); + ::WriteFile(hFile, &bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), &dwWrite, nullptr); + ::WriteFile(hFile, pData, imageBytes, &dwWrite, nullptr); + ::CloseHandle(hFile); ::DeleteObject(hBmp); ::DeleteDC(hdcMem);