* 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:
Stephan Aßmus 2006-08-05 16:06:09 +00:00
parent 6b422a8c22
commit 4122cbb09a
2 changed files with 190 additions and 2 deletions

View File

@ -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)

View File

@ -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