* copied code from BNodeInfo over to BIconUtils
* implemented a simple "GetIcon" function which loads whatever icon fits most depending on the available icons and the colorspace/size of the pre-allocated bitmap passed to the function git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18404 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
6b422a8c22
commit
4122cbb09a
@ -4,10 +4,12 @@
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* Ingo Weinhold <bonefish@cs.tu-berlin.de>
|
||||
*/
|
||||
|
||||
#include "IconUtils.h"
|
||||
|
||||
#include <new>
|
||||
#include <fs_attr.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
@ -18,12 +20,85 @@
|
||||
#include "IconRenderer.h"
|
||||
#include "FlatIconImporter.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
// TODO: put into HaikuCompatibility.h
|
||||
#ifndef __HAIKU__
|
||||
# define B_BITMAP_NO_SERVER_LINK 0
|
||||
# define B_BAD_DATA B_ERROR
|
||||
# define B_MINI_ICON_TYPE 'MICN'
|
||||
# define B_LARGE_ICON_TYPE 'ICON'
|
||||
#endif
|
||||
|
||||
|
||||
// GetIcon
|
||||
status_t
|
||||
BIconUtils::GetIcon(BNode* node,
|
||||
const char* vectorIconAttrName,
|
||||
const char* smallIconAttrName,
|
||||
const char* largeIconAttrName,
|
||||
icon_size size,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!result || result->InitCheck())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = B_ERROR;
|
||||
|
||||
switch (result->ColorSpace()) {
|
||||
case B_RGBA32:
|
||||
case B_RGB32:
|
||||
// prefer vector icon
|
||||
ret = GetVectorIcon(node, vectorIconAttrName, result);
|
||||
if (ret < B_OK) {
|
||||
// try to fallback to B_CMAP8 icons
|
||||
// (converting to B_RGBA32 is handled)
|
||||
ret = GetCMAP8Icon(node,
|
||||
smallIconAttrName,
|
||||
largeIconAttrName,
|
||||
size, result);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_CMAP8:
|
||||
// prefer old B_CMAP8 icons
|
||||
ret = GetCMAP8Icon(node,
|
||||
smallIconAttrName,
|
||||
largeIconAttrName,
|
||||
size, result);
|
||||
if (ret < B_OK) {
|
||||
// try to fallback to vector icon
|
||||
BBitmap temp(result->Bounds(),
|
||||
B_BITMAP_NO_SERVER_LINK, B_RGBA32);
|
||||
ret = temp.InitCheck();
|
||||
if (ret < B_OK)
|
||||
break;
|
||||
ret = GetVectorIcon(node, vectorIconAttrName, &temp);
|
||||
if (ret < B_OK)
|
||||
break;
|
||||
uint32 width = temp.Bounds().IntegerWidth() + 1;
|
||||
uint32 height = temp.Bounds().IntegerHeight() + 1;
|
||||
uint32 bytesPerRow = temp.BytesPerRow();
|
||||
ret = ConvertFromCMAP8((uint8*)temp.Bits(),
|
||||
width,height, bytesPerRow, result);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// GetVectorIcon
|
||||
status_t
|
||||
BIconUtils::GetVectorIcon(BNode* node, const char* attrName,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!node || !attrName)
|
||||
if (!node || node->InitCheck() < B_OK || !attrName)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
#if TIME_VECTOR_ICONS
|
||||
@ -108,6 +183,95 @@ BIconUtils::GetVectorIcon(const uint8* buffer, size_t size,
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
status_t
|
||||
BIconUtils::GetCMAP8Icon(BNode* node,
|
||||
const char* smallIconAttrName,
|
||||
const char* largeIconAttrName,
|
||||
icon_size size,
|
||||
BBitmap* icon)
|
||||
{
|
||||
// check parameters and initialization
|
||||
if (!icon || icon->InitCheck() != B_OK
|
||||
|| !node || node->InitCheck() != B_OK
|
||||
|| !smallIconAttrName || !largeIconAttrName)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = B_OK;
|
||||
// set some icon size related variables
|
||||
const char *attribute = NULL;
|
||||
BRect bounds;
|
||||
uint32 attrType = 0;
|
||||
size_t attrSize = 0;
|
||||
switch (size) {
|
||||
case B_MINI_ICON:
|
||||
attribute = smallIconAttrName;
|
||||
bounds.Set(0, 0, 15, 15);
|
||||
attrType = B_MINI_ICON_TYPE;
|
||||
attrSize = 16 * 16;
|
||||
break;
|
||||
case B_LARGE_ICON:
|
||||
attribute = largeIconAttrName;
|
||||
bounds.Set(0, 0, 31, 31);
|
||||
attrType = B_LARGE_ICON_TYPE;
|
||||
attrSize = 32 * 32;
|
||||
break;
|
||||
default:
|
||||
ret = B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: relax this requirement?
|
||||
if (icon->Bounds() != bounds)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get the attribute info and check type and size of the attr contents
|
||||
attr_info attrInfo;
|
||||
if (ret == B_OK)
|
||||
ret = node->GetAttrInfo(attribute, &attrInfo);
|
||||
if (ret == B_OK && attrInfo.type != attrType)
|
||||
ret = B_BAD_TYPE;
|
||||
if (ret == B_OK && attrInfo.size != attrSize)
|
||||
ret = B_BAD_DATA;
|
||||
|
||||
// read the attribute
|
||||
if (ret == B_OK) {
|
||||
bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
||||
uint8* buffer = NULL;
|
||||
ssize_t read;
|
||||
if (otherColorSpace) {
|
||||
// other color space than stored in attribute
|
||||
buffer = new(nothrow) uint8[attrSize];
|
||||
if (!buffer)
|
||||
ret = B_NO_MEMORY;
|
||||
if (ret == B_OK) {
|
||||
read = node->ReadAttr(attribute, attrType, 0, buffer,
|
||||
attrSize);
|
||||
}
|
||||
} else {
|
||||
read = node->ReadAttr(attribute, attrType, 0, icon->Bits(),
|
||||
attrSize);
|
||||
}
|
||||
if (ret == B_OK) {
|
||||
if (read < 0)
|
||||
ret = read;
|
||||
else if (read != attrInfo.size)
|
||||
ret = B_ERROR;
|
||||
}
|
||||
if (otherColorSpace) {
|
||||
// other color space than stored in attribute
|
||||
if (ret == B_OK) {
|
||||
ret = ConvertFromCMAP8(buffer,
|
||||
(uint32)size, (uint32)size,
|
||||
(uint32)size, icon);
|
||||
}
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// ConvertFromCMAP8
|
||||
status_t
|
||||
BIconUtils::ConvertFromCMAP8(BBitmap* source, BBitmap* result)
|
||||
|
@ -7,7 +7,7 @@
|
||||
#ifndef ICON_UTILS_H
|
||||
#define ICON_UTILS_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <Mime.h>
|
||||
|
||||
class BBitmap;
|
||||
class BNode;
|
||||
@ -23,6 +23,20 @@ class BIconUtils {
|
||||
|
||||
public:
|
||||
|
||||
// Utility function to import an icon from the node that
|
||||
// has either of the provided attribute names. Which icon type
|
||||
// is preferred (vector, small or large B_CMAP8 icon) depends
|
||||
// on the colorspace of the provided bitmap. If the colorspace
|
||||
// is B_CMAP8, B_CMAP8 icons are preferred. If no vector icon
|
||||
// is available, the bitmap size must match the provided
|
||||
// icon_size "size"!
|
||||
static status_t GetIcon(BNode* node,
|
||||
const char* vectorIconAttrName,
|
||||
const char* smallIconAttrName,
|
||||
const char* largeIconAttrName,
|
||||
icon_size size,
|
||||
BBitmap* result);
|
||||
|
||||
// Utility functions to import a vector icon in "flat icon"
|
||||
// format from a BNode attribute or from a flat buffer in
|
||||
// memory into the preallocated BBitmap "result".
|
||||
@ -40,6 +54,16 @@ class BIconUtils {
|
||||
size_t size,
|
||||
BBitmap* result);
|
||||
|
||||
// Utility function to import an "old" BeOS icon in B_CMAP8
|
||||
// colorspace from either the small icon attribute or the
|
||||
// large icon attribute as given in "smallIconAttrName" and
|
||||
// "largeIconAttrName". Which icon is loaded depends on
|
||||
// the given "size".
|
||||
static status_t GetCMAP8Icon(BNode* node,
|
||||
const char* smallIconAttrName,
|
||||
const char* largeIconAttrName,
|
||||
icon_size size,
|
||||
BBitmap* icon);
|
||||
|
||||
// Utility functions to convert from old icon colorspace
|
||||
// into colorspace of BBitmap "result" (should be B_RGBA32
|
||||
|
Loading…
Reference in New Issue
Block a user