Bug 1403989 - Automatically treat black menu icons as templates, so that they get drawn inverted in hovered menuitems. r=jrmuizel,spohl

MozReview-Commit-ID: Bn69Ij0BfRa

--HG--
extra : rebase_source : 9d2d7d0797d89d0b7cf6685d29e458795f518e9d
extra : source : 7b389e4f44679c086a4a510da264f2f0531267ec
This commit is contained in:
Markus Stange 2018-04-16 15:23:23 -04:00
Родитель fdf815d622
Коммит d649a6d091
3 изменённых файлов: 41 добавлений и 3 удалений

Просмотреть файл

@ -271,10 +271,14 @@ public:
The caller owns the <code>CGImageRef</code>.
@param aFrame the frame to convert
@param aResult the resulting CGImageRef
@param aIsEntirelyBlack an outparam that, if non-null, will be set to a
bool that indicates whether the RGB values on all
pixels are zero
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateCGImageFromSurface(SourceSurface* aSurface,
CGImageRef* aResult);
CGImageRef* aResult,
bool* aIsEntirelyBlack = nullptr);
/** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>.
Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>.

Просмотреть файл

@ -361,8 +361,28 @@ void data_ss_release_callback(void *aDataSourceSurface,
}
}
// This function assumes little endian byte order.
static bool
ComputeIsEntirelyBlack(const DataSourceSurface::MappedSurface& aMap,
const IntSize& aSize)
{
for (int32_t y = 0; y < aSize.height; y++) {
size_t rowStart = y * aMap.mStride;
for (int32_t x = 0; x < aSize.width; x++) {
size_t index = rowStart + x * 4;
if (aMap.mData[index + 0] != 0 ||
aMap.mData[index + 1] != 0 ||
aMap.mData[index + 2] != 0) {
return false;
}
}
}
return true;
}
nsresult nsCocoaUtils::CreateCGImageFromSurface(SourceSurface* aSurface,
CGImageRef* aResult)
CGImageRef* aResult,
bool* aIsEntirelyBlack)
{
RefPtr<DataSourceSurface> dataSurface;
@ -390,6 +410,10 @@ nsresult nsCocoaUtils::CreateCGImageFromSurface(SourceSurface* aSurface,
}
// The Unmap() call happens in data_ss_release_callback
if (aIsEntirelyBlack) {
*aIsEntirelyBlack = ComputeIsEntirelyBlack(map, dataSurface->GetSize());
}
// Create a CGImageRef with the bits from the image, taking into account
// the alpha ordering and endianness of the machine so we don't have to
// touch the bits ourselves.

Просмотреть файл

@ -355,7 +355,9 @@ nsMenuItemIconX::OnFrameComplete(imgIRequest* aRequest)
}
CGImageRef origImage = NULL;
nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &origImage);
bool isEntirelyBlack = false;
nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &origImage,
&isEntirelyBlack);
if (NS_FAILED(rv) || !origImage) {
[mNativeMenuItem setImage:nil];
return NS_ERROR_FAILURE;
@ -388,6 +390,14 @@ nsMenuItemIconX::OnFrameComplete(imgIRequest* aRequest)
return NS_ERROR_FAILURE;
}
// If all the color channels in the image are black, treat the image as a
// template. This will cause macOS to use the image's alpha channel as a mask
// and it will fill it with a color that looks good in the context that it's
// used in. For example, for regular menu items, the image will be black, but
// when the menu item is hovered (and its background is blue), it will be
// filled with white.
[newImage setTemplate:isEntirelyBlack];
[newImage setSize:NSMakeSize(kIconWidth, kIconHeight)];
[mNativeMenuItem setImage:newImage];