* cleanup for consistency in FlatIconFormat.h
* used Axels proposals for vector icon attribute name * added a BIconUtils class, currently only dealing with vector icons, it will render a vector icon from either a BNode attribute or a flat buffer in memory into a provided bitmap. The bitmap needs to be of B_RGBA32 colorspace, the size of the bitmap determines the scaling of the vector icon, width and height should currently be the same (square bitmap) * TODO: - add reading of "old" BeOS icons / move icon reading from other places (BMimeType?) into BIconUtils - add reading icons from resources? - suggestions? git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18400 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
faa8b41dac
commit
70f4b8c0ae
@ -122,6 +122,13 @@ Icon::~Icon()
|
||||
delete fStyles;
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
Icon::InitCheck() const
|
||||
{
|
||||
return fStyles && fPaths && fShapes ? B_OK : B_NO_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef ICON_O_MATIC
|
||||
// ShapeAdded
|
||||
void
|
||||
|
@ -44,6 +44,8 @@ class Icon {
|
||||
Icon(const Icon& other);
|
||||
virtual ~Icon();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
StyleContainer* Styles() const
|
||||
{ return fStyles; }
|
||||
PathContainer* Paths() const
|
||||
|
195
src/libs/icon/IconUtils.cpp
Normal file
195
src/libs/icon/IconUtils.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#include "IconUtils.h"
|
||||
|
||||
#include <fs_attr.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Node.h>
|
||||
#include <TypeConstants.h>
|
||||
|
||||
#include "Icon.h"
|
||||
#include "IconRenderer.h"
|
||||
#include "FlatIconImporter.h"
|
||||
|
||||
// GetVectorIcon
|
||||
status_t
|
||||
BIconUtils::GetVectorIcon(BNode* node, const char* attrName,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!node || !attrName)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
#if TIME_VECTOR_ICONS
|
||||
bigtime_t startTime = system_time();
|
||||
#endif
|
||||
|
||||
// get the attribute info and check type and size of the attr contents
|
||||
attr_info attrInfo;
|
||||
status_t ret = node->GetAttrInfo(attrName, &attrInfo);
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
type_code attrType = B_RAW_TYPE;
|
||||
// TODO: introduce special type?
|
||||
|
||||
if (attrInfo.type != attrType)
|
||||
return B_BAD_TYPE;
|
||||
|
||||
// chicken out on unrealisticly large attributes
|
||||
if (attrInfo.size > 16 * 1024)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
uint8 buffer[attrInfo.size];
|
||||
node->ReadAttr(attrName, attrType, 0, buffer, attrInfo.size);
|
||||
|
||||
#if TIME_VECTOR_ICONS
|
||||
bigtime_t importTime = system_time();
|
||||
#endif
|
||||
|
||||
ret = GetVectorIcon(buffer, attrInfo.size, result);
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
#if TIME_VECTOR_ICONS
|
||||
bigtime_t finishTime = system_time();
|
||||
printf("read: %lld, import: %lld\n", importTime - startTime, finishTime - importTime);
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// GetVectorIcon
|
||||
status_t
|
||||
BIconUtils::GetVectorIcon(const uint8* buffer, size_t size,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!result)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = result->InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
if (result->ColorSpace() != B_RGBA32 && result->ColorSpace() != B_RGB32)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
Icon icon;
|
||||
ret = icon.InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
FlatIconImporter importer;
|
||||
ret = importer.Import(&icon, const_cast<uint8*>(buffer), size);
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
IconRenderer renderer(result);
|
||||
renderer.SetIcon(&icon);
|
||||
renderer.SetScale((result->Bounds().Width() + 1.0) / 64.0);
|
||||
renderer.Render();
|
||||
|
||||
// TODO: would be nice to get rid of this
|
||||
// (B_RGBA32_PREMULTIPLIED or better yes, new blending_mode)
|
||||
// NOTE: probably not necessary only because
|
||||
// transparent colors are "black" in all existing icons
|
||||
// lighter transparent colors should be too dark if
|
||||
// app_server uses correct blending
|
||||
// renderer.Demultiply();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// ConvertFromCMAP8
|
||||
status_t
|
||||
BIconUtils::ConvertFromCMAP8(BBitmap* source, BBitmap* result)
|
||||
{
|
||||
if (!source)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = source->InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
uint8* src = (uint8*)source->Bits();
|
||||
uint32 srcBPR = source->BytesPerRow();
|
||||
uint32 width = source->Bounds().IntegerWidth() + 1;
|
||||
uint32 height = source->Bounds().IntegerHeight() + 1;
|
||||
|
||||
return ConvertFromCMAP8(src, width, height, srcBPR, result);
|
||||
}
|
||||
|
||||
// ConvertFromCMAP8
|
||||
status_t
|
||||
BIconUtils::ConvertFromCMAP8(const uint8* src,
|
||||
uint32 width, uint32 height, uint32 srcBPR,
|
||||
BBitmap* result)
|
||||
{
|
||||
if (!src || !result || srcBPR == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status_t ret = result->InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
uint32 dstWidth = result->Bounds().IntegerWidth() + 1;
|
||||
uint32 dstHeight = result->Bounds().IntegerHeight() + 1;
|
||||
|
||||
if (dstWidth < width || dstHeight < height) {
|
||||
// TODO: down scaling
|
||||
return B_ERROR;
|
||||
} else if (dstWidth > width || dstHeight > height) {
|
||||
// TODO: up scaling
|
||||
// (currently copies bitmap into result at left-top)
|
||||
}
|
||||
|
||||
#if __HAIKU__
|
||||
|
||||
return result->ImportBits(src, height * srcBPR, srcBPR, 0, B_CMAP8);
|
||||
|
||||
#else
|
||||
|
||||
if (result->ColorSpace() != B_RGBA32 && result->ColorSpace() != B_RGB32) {
|
||||
// TODO: support other color spaces
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
uint8* dst = (uint8*)result->Bits();
|
||||
uint32 dstBPR = result->BytesPerRow();
|
||||
|
||||
const rgb_color* colorMap = system_colors()->color_list;
|
||||
|
||||
for (uint32 y = 0; y < dstHeight; y++) {
|
||||
uint32* d = (uint32*)dst;
|
||||
const uint8* s = src;
|
||||
for (uint32 x = 0; x < dstWidth; x++) {
|
||||
const rgb_color c = colorMap[*s];
|
||||
uint8 alpha = 255;
|
||||
if (*s == B_TRANSPARENT_MAGIC_CMAP8)
|
||||
alpha = 0;
|
||||
*d = (alpha << 24) | (c.red << 16) | (c.green << 8) | (c.blue);
|
||||
s++;
|
||||
d++;
|
||||
}
|
||||
src += srcBPR;
|
||||
dst += dstBPR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
#endif // __HAIKU__
|
||||
}
|
||||
|
||||
// #pragma mark - forbidden
|
||||
|
||||
BIconUtils::BIconUtils() {}
|
||||
BIconUtils::~BIconUtils() {}
|
||||
BIconUtils::BIconUtils(const BIconUtils&) {}
|
||||
BIconUtils& BIconUtils::operator=(const BIconUtils&) { return *this; }
|
||||
|
44
src/libs/icon/IconUtils.h
Normal file
44
src/libs/icon/IconUtils.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ICON_UTILS_H
|
||||
#define ICON_UTILS_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class BBitmap;
|
||||
class BNode;
|
||||
|
||||
// This class is a little different from many other classes.
|
||||
// You don't create an instance of it; you just call its various
|
||||
// static member functions for utility-like operations.
|
||||
class BIconUtils {
|
||||
BIconUtils();
|
||||
~BIconUtils();
|
||||
BIconUtils(const BIconUtils&);
|
||||
BIconUtils& operator=(const BIconUtils&);
|
||||
|
||||
public:
|
||||
|
||||
static status_t GetVectorIcon(BNode* node,
|
||||
const char* attrName,
|
||||
BBitmap* result);
|
||||
|
||||
static status_t GetVectorIcon(const uint8* buffer,
|
||||
size_t size,
|
||||
BBitmap* result);
|
||||
|
||||
|
||||
static status_t ConvertFromCMAP8(BBitmap* source,
|
||||
BBitmap* result);
|
||||
|
||||
static status_t ConvertFromCMAP8(const uint8* data,
|
||||
uint32 width, uint32 height,
|
||||
uint32 bytesPerRow,
|
||||
BBitmap* result);
|
||||
};
|
||||
|
||||
#endif // ICON_UTILS_H
|
@ -54,5 +54,6 @@ StaticLibrary libicon.a :
|
||||
|
||||
Icon.cpp
|
||||
IconRenderer.cpp
|
||||
IconUtils.cpp
|
||||
;
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
const uint32 FLAT_ICON_MAGIC = 'ficn';
|
||||
|
||||
const char* kVectorAttrNodeName = "BEOS:I:STD_ICON";
|
||||
const char* kVectorAttrMimeName = "META:I:STD_ICON";
|
||||
const char* kVectorAttrNodeName = "BEOS:ICON";
|
||||
const char* kVectorAttrMimeName = "META:ICON";
|
||||
|
||||
// read_coord
|
||||
bool
|
||||
|
@ -12,20 +12,21 @@
|
||||
#include <SupportDefs.h>
|
||||
|
||||
extern const uint32 FLAT_ICON_MAGIC;
|
||||
|
||||
extern const char* kVectorAttrNodeName;
|
||||
extern const char* kVectorAttrMimeName;
|
||||
|
||||
enum {
|
||||
TAG_STYLE_SOLID_COLOR = 1,
|
||||
TAG_STYLE_GRADIENT = 2,
|
||||
TAG_STYLE_SOLID_COLOR_NO_ALPHA = 3,
|
||||
STYLE_TYPE_SOLID_COLOR = 1,
|
||||
STYLE_TYPE_GRADIENT = 2,
|
||||
STYLE_TYPE_SOLID_COLOR_NO_ALPHA = 3,
|
||||
|
||||
TAG_SHAPE_PATH_SOURCE = 10,
|
||||
SHAPE_TYPE_PATH_SOURCE = 10,
|
||||
|
||||
TAG_TRANSFORMER_AFFINE = 20,
|
||||
TAG_TRANSFORMER_CONTOUR = 21,
|
||||
TAG_TRANSFORMER_PERSPECTIVE = 22,
|
||||
TAG_TRANSFORMER_STROKE = 23,
|
||||
TRANSFORMER_TYPE_AFFINE = 20,
|
||||
TRANSFORMER_TYPE_CONTOUR = 21,
|
||||
TRANSFORMER_TYPE_PERSPECTIVE = 22,
|
||||
TRANSFORMER_TYPE_STROKE = 23,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -35,9 +36,9 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
PATH_FLAGS_CLOSED = 1 << 1,
|
||||
PATH_FLAGS_USES_COMMANDS = 1 << 2,
|
||||
PATH_FLAGS_NO_CURVES = 1 << 3,
|
||||
PATH_FLAG_CLOSED = 1 << 1,
|
||||
PATH_FLAG_USES_COMMANDS = 1 << 2,
|
||||
PATH_FLAG_NO_CURVES = 1 << 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -243,17 +243,17 @@ FlatIconImporter::_ParseStyles(LittleEndianBuffer& buffer,
|
||||
if (!buffer.Read(styleType))
|
||||
return B_ERROR;
|
||||
Style* style = NULL;
|
||||
if (styleType == TAG_STYLE_SOLID_COLOR) {
|
||||
if (styleType == STYLE_TYPE_SOLID_COLOR) {
|
||||
// solid color
|
||||
style = _ReadColorStyle(buffer, true);
|
||||
if (!style)
|
||||
return B_NO_MEMORY;
|
||||
} else if (styleType == TAG_STYLE_SOLID_COLOR_NO_ALPHA) {
|
||||
} else if (styleType == STYLE_TYPE_SOLID_COLOR_NO_ALPHA) {
|
||||
// solid color without alpha
|
||||
style = _ReadColorStyle(buffer, false);
|
||||
if (!style)
|
||||
return B_NO_MEMORY;
|
||||
} else if (styleType == TAG_STYLE_GRADIENT) {
|
||||
} else if (styleType == STYLE_TYPE_GRADIENT) {
|
||||
// gradient
|
||||
style = _ReadGradientStyle(buffer);
|
||||
if (!style)
|
||||
@ -351,10 +351,10 @@ FlatIconImporter::_ParsePaths(LittleEndianBuffer& buffer,
|
||||
|
||||
// chose path reading strategy depending on path flags
|
||||
bool error = false;
|
||||
if (pathFlags & PATH_FLAGS_NO_CURVES) {
|
||||
if (pathFlags & PATH_FLAG_NO_CURVES) {
|
||||
if (!read_path_no_curves(buffer, path, pointCount))
|
||||
error = true;
|
||||
} else if (pathFlags & PATH_FLAGS_USES_COMMANDS) {
|
||||
} else if (pathFlags & PATH_FLAG_USES_COMMANDS) {
|
||||
if (!read_path_with_commands(buffer, path, pointCount))
|
||||
error = true;
|
||||
} else {
|
||||
@ -368,7 +368,7 @@ FlatIconImporter::_ParsePaths(LittleEndianBuffer& buffer,
|
||||
}
|
||||
// post process path to clean it up
|
||||
path->CleanUp();
|
||||
if (pathFlags & PATH_FLAGS_CLOSED)
|
||||
if (pathFlags & PATH_FLAG_CLOSED)
|
||||
path->SetClosed(true);
|
||||
// add path to container
|
||||
if (!paths->AddPath(path)) {
|
||||
@ -389,7 +389,7 @@ _ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source)
|
||||
return NULL;
|
||||
|
||||
switch (transformerType) {
|
||||
case TAG_TRANSFORMER_AFFINE: {
|
||||
case TRANSFORMER_TYPE_AFFINE: {
|
||||
AffineTransformer* affine
|
||||
= new (nothrow) AffineTransformer(source);
|
||||
if (!affine)
|
||||
@ -406,7 +406,7 @@ _ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source)
|
||||
affine->load_from(matrix);
|
||||
return affine;
|
||||
}
|
||||
case TAG_TRANSFORMER_CONTOUR: {
|
||||
case TRANSFORMER_TYPE_CONTOUR: {
|
||||
ContourTransformer* contour
|
||||
= new (nothrow) ContourTransformer(source);
|
||||
uint8 width;
|
||||
@ -424,14 +424,14 @@ _ReadTransformer(LittleEndianBuffer& buffer, VertexSource& source)
|
||||
contour->miter_limit(miterLimit);
|
||||
return contour;
|
||||
}
|
||||
case TAG_TRANSFORMER_PERSPECTIVE: {
|
||||
case TRANSFORMER_TYPE_PERSPECTIVE: {
|
||||
PerspectiveTransformer* perspective
|
||||
= new (nothrow) PerspectiveTransformer(source);
|
||||
// TODO: upgrade AGG to be able to support storage of
|
||||
// trans_perspective
|
||||
return perspective;
|
||||
}
|
||||
case TAG_TRANSFORMER_STROKE: {
|
||||
case TRANSFORMER_TYPE_STROKE: {
|
||||
StrokeTransformer* stroke
|
||||
= new (nothrow) StrokeTransformer(source);
|
||||
uint8 width;
|
||||
@ -566,7 +566,7 @@ FlatIconImporter::_ParseShapes(LittleEndianBuffer& buffer,
|
||||
if (!buffer.Read(shapeType))
|
||||
return B_ERROR;
|
||||
Shape* shape = NULL;
|
||||
if (shapeType == TAG_SHAPE_PATH_SOURCE) {
|
||||
if (shapeType == SHAPE_TYPE_PATH_SOURCE) {
|
||||
// path source shape
|
||||
shape = _ReadPathSourceShape(buffer, styles, paths);
|
||||
if (!shape)
|
||||
|
Loading…
Reference in New Issue
Block a user