Я пытаюсь реализовать html5 canvas globalCompositeOperation, используя CGContextSetBlendMode и переводя html5 операторов холста (source-in, source-atop и др. c.) В его аналоги CGBlendMode (kCGBlendModeSourceIn, kCGBlendModeSourceAtop, * *.).
Вот ожидаемые результаты в соответствии со спецификациями:
![globalCompositeOperation](https://i.stack.imgur.com/aWJrf.png)
С CGContextSetBlendMode я получаю это вместо:
![enter image description here](https://i.stack.imgur.com/nGtyi.png)
Некоторые результаты неверны. Например, source-out (kCGBlendModeSourceOut в Quartz 2D) не обрезает синий прямоугольник.
Какая реализация верна, я не уверен. Но мой вопрос, есть ли обходной путь? После некоторой переделки я пришел к этому решению, которое предварительно обрабатывает пункт назначения перед применением операции:
- Обрезать все, кроме источника (то есть красный круг)
- Удалить пункт назначения (оставив только изображение в кружке)
Вот шаг предварительной обработки, который делает это (при условии, что исходный путь уже установлен):
auto save = CGContextCopyPath(ctx);
CGContextSaveGState(ctx);
CGContextAddRect(ctx, CGRectInfinite);
CGContextEOClip(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGContextAddRect(ctx, CGRectInfinite);
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
CGContextAddPath(ctx, save);
CGPathRelease(save);
С обходным путем я получаю почти то, что Я хочу:
![enter image description here](https://i.stack.imgur.com/1wlnD.png)
за исключением этого артефакта в исходном состоянии с некоторыми (сглаживающими?) Полосами в контуре круга.
Есть ли лучший способ? Я делаю это неправильно? Я что-то упустил?
Заранее большое спасибо, и, пожалуйста, простите за этот длинный sh вопрос.