c++direct2d

What does negative top and left mean in D2D1_RECT_F returned from GetImageLocalBounds?


I'm struggling getting the size of the result of gaussian blur ID2D1Effect (CLSID_D2D1GaussianBlur).

I want to draw a shadow box behind a rectangle where the shadow will be positioned such that the rectangle is in the center of the shadow.

I start by creating an IWICBitmap with the size of the rectangle in DIPs like this:

ComPtr<IWICBitmap> bitmap;
HRESULT hr = wic_factory_->CreateBitmap(size.w, size.h, convert_format(ImageFormat::argb32_premultiplied),
        WICBitmapCacheOnDemand, &bitmap);

Then I fill this bitmap with black (or the shadow color) and make ID2D1Bitmap from it:

ComPtr<ID2D1Bitmap> shadow_bitmap;
HRESULT hr = render_target_->CreateBitmapFromWicBitmap(wic_bitmap.Get(), &shadow_bitmap);

I verify that the size of bitmap in DIPs returned from shadow_bitmap->GetSize() almost equals the size of the rectangle (due to float ceiling when creating the wic bitmap)

After that I create the effect and apply it:

ComPtr<ID2D1Effect> blur_effect;
d2d_context_->CreateEffect(CLSID_D2D1GaussianBlur, &blur_effect);
blur_effect->SetInput(0, shadow_bitmap.Get());
blur_effect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, shadow_opts.width * 3);
blur_effect->SetValue(D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION, D2D1_DIRECTIONALBLUR_OPTIMIZATION_QUALITY);

Microsoft docs say that the blur radius (width increase of shadow) is the deviation (in DIPs) multiplied by 3 hence I'm doing so.

Then I get the output and get the local bounds in DIPs (the transform of the target will be applied when drawing the image)

ComPtr<ID2D1Image> out_img;
blur_effect->GetOutput(&out_img);
D2D1_RECT_F img_rect{};
d2d_context_->GetImageLocalBounds(out_img.Get(), &img_rect);

Thing I didn't expect start from here:

Output bitmap growth (X and Y) = StandardDeviation (DIPs)6((User DPI)/96)

Also, the document is unclear (or I didn't understand well) is this growth in pixels or DIPs?

Due to the above I'm having trouble positioning the shadow so the rectangle is in its center


Solution

  • Seems to have got it now! The GetImageLocalBounds outputs a rectangle whose fields are interpreted as follows:

    In case of blur effect the horizontal increase is the same in each side and equals left / 2. The same for vertical increase also.

    When you pass the image to DrawImage and pass an offset of (0, 0) the output image' top left point will not be drawn at (0, 0) but instead at (left, top) of its bound rectangle.

    There is still another thing about direct2d bluring I didn't manage to do it: control the growth of the image.