Merge branch 'hotfix-1.4.1' into develop
This commit is contained in:
commit
352a8ddef1
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Menu implementation
|
* A Menu implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2009-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2009-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -48,6 +48,8 @@ namespace nana
|
|||||||
item_proxy& checked(bool);
|
item_proxy& checked(bool);
|
||||||
bool checked() const;
|
bool checked() const;
|
||||||
|
|
||||||
|
std::string text() const;
|
||||||
|
|
||||||
std::size_t index() const;
|
std::size_t index() const;
|
||||||
private:
|
private:
|
||||||
std::size_t index_;
|
std::size_t index_;
|
||||||
@ -123,8 +125,19 @@ namespace nana
|
|||||||
~menu();
|
~menu();
|
||||||
|
|
||||||
/// Appends an item to the menu.
|
/// Appends an item to the menu.
|
||||||
item_proxy append(std::string text_utf8, const event_fn_t& callback= event_fn_t());
|
item_proxy append(std::string text_utf8, const event_fn_t& handler = {});
|
||||||
void append_splitter();
|
void append_splitter();
|
||||||
|
|
||||||
|
/// Inserts new item at specified position
|
||||||
|
/**
|
||||||
|
* It will invalidate the existing item proxies from the specified position.
|
||||||
|
* @param pos The position where new item to be inserted
|
||||||
|
* @param text_utf8 The title of item
|
||||||
|
* @param handler The event handler for the item.
|
||||||
|
* @return the item proxy to the new inserted item.
|
||||||
|
*/
|
||||||
|
item_proxy insert(std::size_t pos, std::string text_utf8, const event_fn_t& handler = {});
|
||||||
|
|
||||||
void clear(); ///< Erases all of the items.
|
void clear(); ///< Erases all of the items.
|
||||||
/// Closes the menu. It does not destroy the menu; just close the window for the menu.
|
/// Closes the menu. It does not destroy the menu; just close the window for the menu.
|
||||||
void close();
|
void close();
|
||||||
|
@ -845,7 +845,7 @@ namespace nana { namespace experimental { namespace filesystem
|
|||||||
GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
|
GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
|
||||||
if (get_file_size_ex)
|
if (get_file_size_ex)
|
||||||
{
|
{
|
||||||
HANDLE handle = ::CreateFile(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
HANDLE handle = ::CreateFile(p.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
if (INVALID_HANDLE_VALUE != handle)
|
if (INVALID_HANDLE_VALUE != handle)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Menu implementation
|
* A Menu implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2009-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2009-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -86,6 +86,11 @@ namespace nana
|
|||||||
return item_.flags.checked;
|
return item_.flags.checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string menu_item_type::item_proxy::text() const
|
||||||
|
{
|
||||||
|
return item_.text;
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t menu_item_type::item_proxy::index() const
|
std::size_t menu_item_type::item_proxy::index() const
|
||||||
{
|
{
|
||||||
return index_;
|
return index_;
|
||||||
@ -1117,10 +1122,11 @@ namespace nana
|
|||||||
delete impl_;
|
delete impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto menu::append(std::string text_utf8, const menu::event_fn_t& callback) -> item_proxy
|
auto menu::append(std::string text_utf8, const menu::event_fn_t& handler) -> item_proxy
|
||||||
{
|
{
|
||||||
impl_->mbuilder.data().items.emplace_back(new item_type(std::move(text_utf8), callback));
|
std::unique_ptr<item_type> item{ new item_type{ std::move(text_utf8), handler } };
|
||||||
return item_proxy(size() - 1, *impl_->mbuilder.data().items.back());
|
impl_->mbuilder.data().items.emplace_back(item.get());
|
||||||
|
return item_proxy(size() - 1, *item.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu::append_splitter()
|
void menu::append_splitter()
|
||||||
@ -1128,6 +1134,18 @@ namespace nana
|
|||||||
impl_->mbuilder.data().items.emplace_back(new item_type);
|
impl_->mbuilder.data().items.emplace_back(new item_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto menu::insert(std::size_t pos, std::string text_utf8, const event_fn_t& handler) -> item_proxy
|
||||||
|
{
|
||||||
|
auto & items = impl_->mbuilder.data().items;
|
||||||
|
if (pos > items.size())
|
||||||
|
throw std::out_of_range("menu: a new item inserted to an invalid position");
|
||||||
|
|
||||||
|
std::unique_ptr<item_type> item{ new item_type{ std::move(text_utf8), handler } };
|
||||||
|
impl_->mbuilder.data().items.emplace(impl_->mbuilder.data().items.cbegin() + pos, item.get());
|
||||||
|
|
||||||
|
return item_proxy{ pos, *item.release() };
|
||||||
|
}
|
||||||
|
|
||||||
void menu::clear()
|
void menu::clear()
|
||||||
{
|
{
|
||||||
internal_scope_guard lock;
|
internal_scope_guard lock;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Bitmap Format Graphics Implementation
|
* Bitmap Format Graphics Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
|
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||||
*
|
*
|
||||||
* Distributed under the Boost Software License, Version 1.0.
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@ -30,6 +30,15 @@ namespace nana{ namespace paint
|
|||||||
unsigned bfOffBits;
|
unsigned bfOffBits;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct bitmap_core_header
|
||||||
|
{
|
||||||
|
unsigned biSize;
|
||||||
|
unsigned short biWidth;
|
||||||
|
unsigned short biHeight;
|
||||||
|
unsigned short biPlanes;
|
||||||
|
unsigned short biBitCount;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct bitmap_info_header {
|
struct bitmap_info_header {
|
||||||
unsigned biSize;
|
unsigned biSize;
|
||||||
int biWidth;
|
int biWidth;
|
||||||
@ -51,15 +60,10 @@ namespace nana{ namespace paint
|
|||||||
unsigned char rgbRed;
|
unsigned char rgbRed;
|
||||||
unsigned char rgbReserved;
|
unsigned char rgbReserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bitmap_info
|
|
||||||
{
|
|
||||||
bitmap_info_header bmiHeader;
|
|
||||||
rgb_quad bmiColors[1];
|
|
||||||
}__attribute__((packed));
|
|
||||||
#else
|
#else
|
||||||
typedef BITMAPFILEHEADER bitmap_file_header;
|
typedef BITMAPFILEHEADER bitmap_file_header;
|
||||||
typedef BITMAPINFO bitmap_info;
|
typedef BITMAPCOREHEADER bitmap_core_header;
|
||||||
|
typedef BITMAPINFOHEADER bitmap_info_header;
|
||||||
typedef RGBQUAD rgb_quad;
|
typedef RGBQUAD rgb_quad;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -67,244 +71,42 @@ namespace nana{ namespace paint
|
|||||||
:public basic_image_pixbuf
|
:public basic_image_pixbuf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
image_bmp(){}
|
|
||||||
|
|
||||||
~image_bmp()
|
~image_bmp()
|
||||||
{
|
{
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool open(const void* data, std::size_t bytes) override
|
bool open(const void* file_data, std::size_t bytes) override
|
||||||
{
|
{
|
||||||
auto bmp_data = reinterpret_cast<const char*>(data);
|
auto bmp_file = reinterpret_cast<const bitmap_file_header*>(file_data);
|
||||||
|
if ((bmp_file->bfType != 0x4D42) || (bmp_file->bfSize != bytes))
|
||||||
auto header = reinterpret_cast<const bitmap_file_header*>(bmp_data);
|
|
||||||
if ((header->bfType != 0x4D42) || (header->bfSize != bytes))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto bits = reinterpret_cast<const unsigned char*>(bmp_data + header->bfOffBits);
|
auto const header_bytes = *reinterpret_cast<const unsigned long*>(bmp_file + 1);
|
||||||
auto info = reinterpret_cast<const bitmap_info *>(header + 1);
|
|
||||||
|
//There are two kind of base headers. Determinate it by size of header(The first ulong of header).
|
||||||
|
//Only Windows Bitmap(BITMAPINFOHEADER) is supported.
|
||||||
|
if (sizeof(bitmap_core_header) == header_bytes)
|
||||||
|
{
|
||||||
|
//The OS/2 BITMAPCOREHEADER is not supported.
|
||||||
|
throw std::invalid_argument("BMP with OS/2 BITMAPCOREHEADER is not supported now.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto header = reinterpret_cast<const bitmap_info_header *>(bmp_file + 1);
|
||||||
|
|
||||||
|
const std::size_t bmp_height = std::abs(header->biHeight);
|
||||||
|
|
||||||
//Bitmap file is 4byte-aligned for each line.
|
//Bitmap file is 4byte-aligned for each line.
|
||||||
std::size_t bytes_per_line;
|
auto bytes_per_line = (((header->biWidth * header->biBitCount + 31) & ~31) >> 3);
|
||||||
const std::size_t height_pixels = std::abs(info->bmiHeader.biHeight);
|
|
||||||
if (0 == info->bmiHeader.biSizeImage)
|
pixbuf_.open(header->biWidth, bmp_height);
|
||||||
bytes_per_line = (((info->bmiHeader.biWidth * info->bmiHeader.biBitCount + 31) & ~31) >> 3);
|
|
||||||
|
auto bits = reinterpret_cast<const unsigned char*>(reinterpret_cast<const char*>(file_data) + bmp_file->bfOffBits);
|
||||||
|
|
||||||
|
if (16 <= header->biBitCount)
|
||||||
|
pixbuf_.put(bits, header->biWidth, bmp_height, header->biBitCount, bytes_per_line, (header->biHeight < 0));
|
||||||
else
|
else
|
||||||
bytes_per_line = info->bmiHeader.biSizeImage / height_pixels;
|
_m_put_with_palette(header, bits, bytes_per_line);
|
||||||
|
|
||||||
pixbuf_.open(info->bmiHeader.biWidth, height_pixels);
|
|
||||||
|
|
||||||
auto d = pixbuf_.raw_ptr(0);
|
|
||||||
|
|
||||||
if (16 <= info->bmiHeader.biBitCount)
|
|
||||||
{
|
|
||||||
pixbuf_.put(bits, info->bmiHeader.biWidth, height_pixels, info->bmiHeader.biBitCount, bytes_per_line, (info->bmiHeader.biHeight < 0));
|
|
||||||
}
|
|
||||||
else if (8 == info->bmiHeader.biBitCount)
|
|
||||||
{
|
|
||||||
const auto lend = d + info->bmiHeader.biWidth * height_pixels;
|
|
||||||
|
|
||||||
if (info->bmiHeader.biHeight < 0)
|
|
||||||
{
|
|
||||||
auto s = bits;
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
auto s_p = s;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
auto & rgb = info->bmiColors[*s_p++];
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s += bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto* s = bits + bytes_per_line * (height_pixels - 1);
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto* const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
const auto * s_p = s;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
auto & rgb = info->bmiColors[*s_p++];
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s -= bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (4 == info->bmiHeader.biBitCount)
|
|
||||||
{
|
|
||||||
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
|
||||||
if (info->bmiHeader.biHeight < 0)
|
|
||||||
{
|
|
||||||
const unsigned char* s = bits;
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
auto & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s += bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto* s = bits + bytes_per_line * (height_pixels - 1);
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
auto & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s -= bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (2 == info->bmiHeader.biBitCount)
|
|
||||||
{
|
|
||||||
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
|
||||||
if (info->bmiHeader.biHeight < 0)
|
|
||||||
{
|
|
||||||
const unsigned char* s = bits;
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
|
|
||||||
auto& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift)) >> shift];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s += bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto* s = bits + bytes_per_line * (height_pixels - 1);
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2
|
|
||||||
auto& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift)) >> shift];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s -= bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (1 == info->bmiHeader.biBitCount)
|
|
||||||
{
|
|
||||||
const auto * const lend = d + info->bmiHeader.biWidth * height_pixels;
|
|
||||||
if (info->bmiHeader.biHeight < 0)
|
|
||||||
{
|
|
||||||
const auto* s = bits;
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
unsigned bi = (7 - (index & 7)); //(index % 8)
|
|
||||||
auto & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s += bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto* s = bits + bytes_per_line * (height_pixels - 1);
|
|
||||||
while (d < lend)
|
|
||||||
{
|
|
||||||
auto d_p = d;
|
|
||||||
auto * const dpend = d_p + info->bmiHeader.biWidth;
|
|
||||||
|
|
||||||
unsigned index = 0;
|
|
||||||
while (d_p != dpend)
|
|
||||||
{
|
|
||||||
unsigned bi = (7 - (index & 7));
|
|
||||||
auto & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi];
|
|
||||||
|
|
||||||
d_p->element.red = rgb.rgbRed;
|
|
||||||
d_p->element.green = rgb.rgbGreen;
|
|
||||||
d_p->element.blue = rgb.rgbBlue;
|
|
||||||
d_p->element.alpha_channel = rgb.rgbReserved;
|
|
||||||
++d_p;
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
d = dpend;
|
|
||||||
s -= bytes_per_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -312,20 +114,15 @@ namespace nana{ namespace paint
|
|||||||
bool open(const std::experimental::filesystem::path& filename) override
|
bool open(const std::experimental::filesystem::path& filename) override
|
||||||
{
|
{
|
||||||
std::ifstream ifs(filename.string(), std::ios::binary);
|
std::ifstream ifs(filename.string(), std::ios::binary);
|
||||||
if(ifs)
|
|
||||||
|
auto const bytes = static_cast<unsigned>(std::experimental::filesystem::file_size(filename));
|
||||||
|
if (ifs && (bytes > static_cast<int>(sizeof(bitmap_file_header))))
|
||||||
{
|
{
|
||||||
ifs.seekg(0, std::ios::end);
|
std::unique_ptr<char[]> buffer{ new char[bytes] };
|
||||||
auto size = static_cast<std::size_t>(ifs.tellg());
|
|
||||||
ifs.seekg(0, std::ios::beg);
|
|
||||||
|
|
||||||
if(size <= static_cast<int>(sizeof(bitmap_file_header)))
|
ifs.read(buffer.get(), bytes);
|
||||||
return false;
|
if (bytes == static_cast<std::size_t>(ifs.gcount()))
|
||||||
|
return open(buffer.get(), bytes);
|
||||||
std::unique_ptr<char[]> buffer(new char[static_cast<int>(size)]);
|
|
||||||
|
|
||||||
ifs.read(buffer.get(), size);
|
|
||||||
if (size == static_cast<std::size_t>(ifs.gcount()))
|
|
||||||
return open(buffer.get(), size);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -334,6 +131,96 @@ namespace nana{ namespace paint
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
void _m_put_with_palette(const bitmap_info_header* header, const unsigned char* pixel_indexes, unsigned line_bytes)
|
||||||
|
{
|
||||||
|
auto const image_height = std::abs(header->biHeight);
|
||||||
|
const std::size_t total_pixels = header->biWidth * static_cast<std::size_t>(image_height);
|
||||||
|
|
||||||
|
auto const color_table = reinterpret_cast<const rgb_quad*>(reinterpret_cast<const unsigned char*>(header) + header->biSize);
|
||||||
|
|
||||||
|
auto dst_px = pixbuf_.raw_ptr(0);
|
||||||
|
auto const end_dst_px = dst_px + total_pixels;
|
||||||
|
|
||||||
|
int line_pos = image_height - 1;
|
||||||
|
int delta = -1;
|
||||||
|
if (header->biHeight < 0)
|
||||||
|
{
|
||||||
|
line_pos = 0;
|
||||||
|
delta = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (8 == header->biBitCount)
|
||||||
|
{
|
||||||
|
while (dst_px < end_dst_px)
|
||||||
|
{
|
||||||
|
auto px_indexes = pixel_indexes + line_bytes * line_pos;
|
||||||
|
auto const line_end_dst_px = dst_px + header->biWidth;
|
||||||
|
while (dst_px != line_end_dst_px)
|
||||||
|
{
|
||||||
|
auto & rgb = color_table[*px_indexes++];
|
||||||
|
dst_px->element.red = rgb.rgbRed;
|
||||||
|
dst_px->element.green = rgb.rgbGreen;
|
||||||
|
dst_px->element.blue = rgb.rgbBlue;
|
||||||
|
dst_px->element.alpha_channel = rgb.rgbReserved;
|
||||||
|
|
||||||
|
++dst_px;
|
||||||
|
}
|
||||||
|
line_pos += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (dst_px < end_dst_px)
|
||||||
|
{
|
||||||
|
auto px_indexes = pixel_indexes + line_bytes * line_pos;
|
||||||
|
auto const line_end_dst_px = dst_px + header->biWidth;
|
||||||
|
std::size_t pos = 0;
|
||||||
|
switch (header->biBitCount)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
while (dst_px != line_end_dst_px)
|
||||||
|
{
|
||||||
|
auto & rgb = color_table[((pos & 1) ? px_indexes[pos >> 1] : (px_indexes[pos >> 1] >> 4)) & 0xF];
|
||||||
|
dst_px->element.red = rgb.rgbRed;
|
||||||
|
dst_px->element.green = rgb.rgbGreen;
|
||||||
|
dst_px->element.blue = rgb.rgbBlue;
|
||||||
|
dst_px->element.alpha_channel = rgb.rgbReserved;
|
||||||
|
++dst_px;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
while (dst_px != line_end_dst_px)
|
||||||
|
{
|
||||||
|
//auto const shift = ((3 - (pos & 0x3)) << 1); // (index % 4) * 2
|
||||||
|
auto& rgb = color_table[(px_indexes[pos >> 2] >> ((3 - (pos & 0x3)) << 1)) & 0x3];
|
||||||
|
dst_px->element.red = rgb.rgbRed;
|
||||||
|
dst_px->element.green = rgb.rgbGreen;
|
||||||
|
dst_px->element.blue = rgb.rgbBlue;
|
||||||
|
dst_px->element.alpha_channel = rgb.rgbReserved;
|
||||||
|
++dst_px;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
while (dst_px != line_end_dst_px)
|
||||||
|
{
|
||||||
|
auto & rgb = color_table[(px_indexes[pos >> 3] >> (7 - (pos & 7))) & 1];
|
||||||
|
|
||||||
|
dst_px->element.red = rgb.rgbRed;
|
||||||
|
dst_px->element.green = rgb.rgbGreen;
|
||||||
|
dst_px->element.blue = rgb.rgbBlue;
|
||||||
|
dst_px->element.alpha_channel = rgb.rgbReserved;
|
||||||
|
++dst_px;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line_pos += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};//end class bmpfile
|
};//end class bmpfile
|
||||||
}//end namespace detail
|
}//end namespace detail
|
||||||
}//end namespace paint
|
}//end namespace paint
|
||||||
|
Loading…
x
Reference in New Issue
Block a user