How do I create a "stencil" component?


#1

What’s the best way to create a stencil component in JUCE such that the component has an opaque background and anything drawn is displayed as transparent “holes” through which any content behind the component is shown. Like a stencil.

I tried something like the following:

Image image(Image::ARGB, w, h, false);
Graphics g(image);
g.fillAll(Colours::red);
g.setColour(Colours::white);
drawStuff(g);
DrawableImage drawable;
drawable.setImage(image);
drawable.replaceColour(Colours::white, Colours::transparentBlack);

But:

  1. the replaceColour() doesn’t work
  2. presumably even if it did work, I’d just end up with a red background and not a stencil of elements drawn with drawStuff()

So I’m guessing this is the wrong approach…


#2

Not 100% what you mean, but probably a job for some clip regions with Graphics::reduceClipRegion


#3

OK, I can kind of achieve what I want with:

RectangleList<int> mask;
image.createSolidAreaMask(mask, 0.01);
for (auto rect : mask)
{
    g.excludeClipRegion(rect);
}
g.fillAll(backgroundColour);

Are there any disadvantages to using a RectangleList mask in this way?


#4

Well, it’s insanely inefficient!
If you really need to use an image then it’d be better to invert the image’s alpha and clip to the image in one step.


#5

I don’t need to use an image, if the same outcome can be achieved in better way, I’d rather use that.

Re:

invert the image’s alpha and clip to the image in one step

How do I invert the image’s alpha? This sounds like the critical ingredient I’m missing here.


#6

Masking with a path would be better than using an image, if you can.

Inverting the alpha channel would involve using Image::BitmapData and messing with each pixel’s alpha channel