Странная проблема с NSImage -lockFocusFlipped:

Я использую метод -lockFocusFlipped: NSImage для рисования изображения. Мой код выглядит так:

NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize(256, 256)];
[image lockFocusFlipped:YES];
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[NSColor blackColor]];
[shadow setShadowBlurRadius:6.0];
[shadow setShadowOffset:NSMakeSize(0, 3)];
[shadow set];
NSRect shapeRect = NSMakeRect(0, 0, 256, 100);
[[NSColor redColor] set];
NSRectFill(shapeRect);
[image unlockFocus];

Этот код работает до определенного момента. Я могу подтвердить, что контекст действительно перевернут, потому что [[NSGraphicsContext currentContext] isFlipped] возвращает YES, а также потому, что shapeRect рисуется в правой позиции (используя верхний левый угол в качестве источника). Тем не менее, NSShadow, похоже, не учитывает перевернутый статус контекста. Установка смещения тени на (0, 3) должна перемещать тень вниз при переворачивании контекста, но на самом деле она перемещается вверх (что и произошло бы в стандартном неперевернутом контексте). ).

Эта проблема кажется специфичной для -lockFocusFlipped, потому что, когда я рисую с использованием того же кода в CALayer с перевернутой системой координат, тень рисуется очень хорошо (с учетом переворота). Документация по -lockFocusFlipped также кажется довольно расплывчатой. Это все, что написано в документации класса NSImage:

Подготавливает изображение к получению команд рисования, используя указанное перевернутое состояние.

Я также нашел это примечание в примечаниях к выпуску Snow Leopard AppKit:

Есть случаи, например рисование напрямую через NSLayoutManager, которые требуют перевернутого контекста. Чтобы покрыть этот случай, мы добавим

- (void)lockFocusFlipped:(BOOL)flipped;

Это не изменяет состояние самого изображения, а только контекст, на котором заблокирован фокус. Это означает, что (0,0) находится вверху слева, а положительное значение по оси Y находится внизу в заблокированном контексте.

Ни один из документов, кажется, не объясняет поведение NSShadow в этом случае. И в результате дальнейшего тестирования кажется, что NSGradient, похоже, не учитывает перевернутое состояние контекста рисования, используемое NSImage.

Любое понимание очень ценится :-)


person indragie    schedule 18.03.2011    source источник


Ответы (1)


Из справочника по классу NSShadow:

Тени всегда рисуются в пользовательском пространстве координат по умолчанию, независимо от любых преобразований, примененных к этому пространству. Это означает, что повороты, перемещения и другие преобразования текущей матрицы преобразования (CTM) не влияют на результирующую тень.

И вот что в конечном счете представляет собой переворачивание: CH204-BCIHDAIJ" rel="nofollow">Перевести вверх, уменьшить масштаб в другую сторону.

Для NSGradient такого заявления нет, поэтому я предлагаю заявить об ошибке по этому поводу.

person Peter Hosey    schedule 19.03.2011
comment
Это имеет смысл, спасибо. Есть ли способ обойти это (чтобы тень рисовалась в правильном направлении независимо от преобразований)? - person indragie; 20.03.2011
comment
@indragie: Рисование независимо от преобразований — это то, что он делает, и именно поэтому он рисует в неправильном направлении. Чтобы отрисовать все, включая тени, последовательно, вам нужно нарисовать неотвернутое изображение, затем создать новое изображение и нарисовать первое изображение в перевернутом. - person Peter Hosey; 20.03.2011