diff --git a/src/kits/storage/AppFileInfo.cpp b/src/kits/storage/AppFileInfo.cpp index a01b16d9d8..bdea3a3cbe 100644 --- a/src/kits/storage/AppFileInfo.cpp +++ b/src/kits/storage/AppFileInfo.cpp @@ -831,6 +831,13 @@ BAppFileInfo::GetIconForType(const char* type, BBitmap* icon, if (!icon || icon->InitCheck() != B_OK) return B_BAD_VALUE; + // TODO: for consistency with attribute based icon reading, we + // could also prefer B_CMAP8 icons here if the provided bitmap + // is in that format. Right now, an existing B_CMAP8 icon resource + // would be ignored as soon as a vector icon is present. On the other + // hand, maybe this still results in a more consistent user interface, + // since Tracker/Deskbar would surely show the vector icon. + // try vector icon first BString vectorAttributeName(kIconAttribute); diff --git a/src/libs/icon/IconUtils.cpp b/src/libs/icon/IconUtils.cpp index 48f0e689cd..6b09696ad9 100644 --- a/src/libs/icon/IconUtils.cpp +++ b/src/libs/icon/IconUtils.cpp @@ -19,6 +19,7 @@ #include #include +#include "AutoDeleter.h" #include "Icon.h" #include "IconRenderer.h" #include "FlatIconImporter.h" @@ -165,8 +166,16 @@ BIconUtils::GetVectorIcon(const uint8* buffer, size_t size, if (ret < B_OK) return ret; - if (result->ColorSpace() != B_RGBA32 && result->ColorSpace() != B_RGB32) - return B_BAD_VALUE; + BBitmap* temp = result; + ObjectDeleter deleter; + + if (result->ColorSpace() != B_RGBA32 && result->ColorSpace() != B_RGB32) { + temp = new (nothrow) BBitmap(result->Bounds(), + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + deleter.SetTo(temp); + if (!temp || temp->InitCheck() != B_OK) + return B_NO_MEMORY; + } Icon icon; ret = icon.InitCheck(); @@ -178,11 +187,19 @@ BIconUtils::GetVectorIcon(const uint8* buffer, size_t size, if (ret < B_OK) return ret; - IconRenderer renderer(result); + IconRenderer renderer(temp); renderer.SetIcon(&icon); - renderer.SetScale((result->Bounds().Width() + 1.0) / 64.0); + renderer.SetScale((temp->Bounds().Width() + 1.0) / 64.0); renderer.Render(); + if (temp != result) { + uint8* src = (uint8*)temp->Bits(); + uint32 width = temp->Bounds().IntegerWidth() + 1; + uint32 height = temp->Bounds().IntegerHeight() + 1; + uint32 srcBPR = temp->BytesPerRow(); + ret = ConvertToCMAP8(src, width, height, srcBPR, result); + } + // TODO: would be nice to get rid of this // (B_RGBA32_PREMULTIPLIED or better yet, new blending_mode) // NOTE: probably not necessary only because @@ -191,7 +208,7 @@ BIconUtils::GetVectorIcon(const uint8* buffer, size_t size, // app_server uses correct blending // renderer.Demultiply(); - return B_OK; + return ret; } // #pragma mark - @@ -465,6 +482,9 @@ BIconUtils::ConvertToCMAP8(const uint8* src, if (ret < B_OK) return ret; + if (result->ColorSpace() != B_CMAP8) + return B_BAD_VALUE; + uint32 dstWidth = result->Bounds().IntegerWidth() + 1; uint32 dstHeight = result->Bounds().IntegerHeight() + 1; @@ -483,13 +503,12 @@ memset(result->Bits(), 255, result->BitsLength()); // //#else - if (result->ColorSpace() != B_CMAP8) - return B_BAD_VALUE; - uint8* dst = (uint8*)result->Bits(); uint32 dstBPR = result->BytesPerRow(); const color_map* colorMap = system_colors(); + if (!colorMap) + return B_NO_INIT; uint16 index; for (uint32 y = 0; y < height; y++) {