Подтвердить что ты не робот

Графика iOS Core: рисовать ТОЛЬКО тени CGPath

Я рисую простой путь в iOS 5 с Core Graphics:

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(   path, NULL, center.x   , topMargin   );
CGPathAddLineToPoint(path, NULL, center.x+20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x   , topMargin+40);
CGPathAddLineToPoint(path, NULL, center.x-20, topMargin+50);
CGPathAddLineToPoint(path, NULL, center.x   , topMargin   );

Теперь я хочу заполнить его в режиме Overlay следующим образом:

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0.4] setFill];
CGContextAddPath(context, path);
CGContextSetBlendMode (context, kCGBlendModeOverlay);
CGContextFillPath(context);

Это дает мне точно ожидаемый результат. Но затем я хочу создать эффект тиснения. Я думал о том, чтобы использовать белую и черную тень для достижения такого эффекта:

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

[[UIColor colorWithRed:0 green:0 blue:0 alpha:0] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

Проблема заключается в том, что тени не рисуются, когда для альфы установлено значение 0.
Теперь вопрос: есть ли способ рисовать только тени без цвета заливки, но в полной альфе? Могу ли я каким-то образом предотвратить проникновение внутри моего пути? Или есть, возможно, более простой способ рисования двух теней для одного пути?

4b9b3361

Ответ 1

Я предлагаю вам установить путь обрезания контекста к обратному пути формы, настроить тень и заполнить форму нормально, с полной непрозрачностью. Обтравочный контур будет маскировать цвет заливки, и останется только тень.

CGContextSaveGState(context);
CGRect boundingRect = CGContextGetClipBoundingBox(context);
CGContextAddRect(context, boundingRect);
CGContextAddPath(context, path);
CGContextEOClip(context);

[[UIColor blackColor] setFill];
CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(1, 1), 1.0, highlightColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

CGContextAddPath(context, path);
CGContextSetShadowWithColor(context, CGSizeMake(-1, -1), 1.0, shadowColor);
CGContextSetBlendMode (context, kCGBlendModeNormal);
CGContextFillPath(context);

CGContextRestoreGState(context);

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