GDI - неожиданный результат для функции OffsetRgn () - PullRequest
0 голосов
/ 09 февраля 2019

Я использую Embarcadero RAD Studio C ++ Builder XE7.

Для функции рисования с использованием Windows GDI мне нужно добавить область клипа в контекст устройства холста.

Протестировав мой код, я заметил, что иногда область отсечения была меньше ожидаемого размера.Я искал почему и обнаружил странное поведение функции OffsetRgn (), которая позволяет мне немного озадачиться.

Чтобы применить область клипа, я использую код, подобный следующему:

std::unique_ptr<TBitmap> pBitmap(new TBitmap());
pBitmap->PixelFormat = pf32bit;
pBitmap->AlphaFormat = afDefined;
pBitmap->SetSize(60, 7);

TCanvas* pCanvas = pBitmap->Canvas;

::SelectClipRgn(pCanvas->Handle, NULL);

const TRect sourceRect = pCanvas->ClipRect;

HRGN pClipRegion = ::CreateRectRgn(50, -2, 60, 8);

::SelectClipRgn(pCanvas->Handle, pClipRegion);

const TRect intermediateRect = pCanvas->ClipRect;

const int deltaX = pCanvas->ClipRect.Left - 50;
const int deltaY = pCanvas->ClipRect.Top  - (-2);

::OffsetRgn(pClipRegion, -deltaX, -deltaY);

::SelectClipRgn(pCanvas->Handle, pClipRegion);

const TRect finalRect = pCanvas->ClipRect;

ПРИМЕЧАНИЕ написано так и вне его контекста, приведенный выше код на самом деле не имеет смысла, и я знаю, что это нелогично.Пожалуйста, не судите о его качестве, это не цель моего вопроса.Я собрал несколько отрывков, которые я сгруппировал в исполняемый код для постановки проблемы.

Жестко закодированные значения являются примером значений, которые я получаю в своем приложении при возникновении проблемы.Если я выполняю приведенный выше код, я измеряю:

  • left = 0, top = 0, right = 60, bottom = 7 в значении sourceRect
  • left = 50, top = 0, справа = 60, снизу = 7 в промежуточном значении Rect
  • слева = 50, сверху = 0, справа = 60, снизу = 6 в окончательном виде

Iоднако ожидается, что нижнее значение также должно быть равно 7 в finalRect, который является пределом холста, поскольку я только переместил регион и ничего больше.Так почему же его значение внезапно стало меньше ожидаемого?

1 Ответ

0 голосов
/ 14 февраля 2019

Итак, я наконец нашел суть дела.Основываясь на этом посте:

Почему вызов GetRgnBox для результата GetClipRgn возвращает совершенно другой прямоугольник, чем GetClipRect?

Область клипа применяется в логических единицах относительноисточник холста, в то время как прямоугольник отсечения, который я пытался применить, был измерен в пикселях от источника [0, 0].

Поскольку я неправильно думал в моем коде, что источник всегда был [0, 0] для обеих систем , результирующая область может быть неправильной в нескольких особых случаях, вызывая это странное смещение, которое я иногда замечал между реально примененным отсечением и тем, которое я ожидал.

Измерение источника холста с помощью GetWindowOrgEx() функция выдвинула на первый план проблему.

Однако для показанного выше случая проблема возникла из-за того, что область клипа была сдвинута со смещением -2, принимая значение -4 сверху и 6 снизу, чтозатем обрезается, чтобы соответствовать границам холста, пока применяется область клипа, что приводит к отсечению со значением 0 насверху и 6 снизу.

...