mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-23 20:19:40 +00:00
Support for images, shading, layers, shadows, global alpha... for the AntiGrain context (not 100% complete yet)
This commit is contained in:
parent
364fc85990
commit
0df24ed140
@ -755,20 +755,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
CGContextSaveGState(context);
|
||||
|
||||
if(fraction!=1.0){
|
||||
// fraction is accomplished with a 1x1 alpha mask
|
||||
// FIXME: could use a float format image to completely preserve fraction
|
||||
uint8_t bytes[1]={ MIN(MAX(0,fraction*255),255) };
|
||||
CGDataProviderRef provider=CGDataProviderCreateWithData(NULL,bytes,1,NULL);
|
||||
CGImageRef mask=CGImageMaskCreate(1,1,8,8,1,provider,NULL,NO);
|
||||
|
||||
CGContextClipToMask(context,rect,mask);
|
||||
CGImageRelease(mask);
|
||||
CGDataProviderRelease(provider);
|
||||
}
|
||||
|
||||
[[NSGraphicsContext currentContext] setCompositingOperation:operation];
|
||||
|
||||
if ([context supportsGlobalAlpha] == NO) {
|
||||
// That should really be done by setting the context alpha - and the compositing done in the context implementation
|
||||
if(fraction!=1.0){
|
||||
// fraction is accomplished with a 1x1 alpha mask
|
||||
// FIXME: could use a float format image to completely preserve fraction
|
||||
uint8_t bytes[1]={ MIN(MAX(0,fraction*255),255) };
|
||||
CGDataProviderRef provider=CGDataProviderCreateWithData(NULL,bytes,1,NULL);
|
||||
CGImageRef mask=CGImageMaskCreate(1,1,8,8,1,provider,NULL,NO);
|
||||
|
||||
CGContextClipToMask(context,rect,mask);
|
||||
CGImageRelease(mask);
|
||||
CGDataProviderRelease(provider);
|
||||
}
|
||||
} else {
|
||||
CGContextSetAlpha(context, fraction);
|
||||
}
|
||||
[[NSGraphicsContext currentContext] setCompositingOperation:operation];
|
||||
|
||||
[self drawRepresentation:drawRep inRect:rect];
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
|
@ -4,6 +4,11 @@
|
||||
#ifdef ANTIGRAIN_PRESENT
|
||||
#include <agg_basics.h>
|
||||
#include <agg_pixfmt_rgba.h>
|
||||
#include <agg_pixfmt_gray.h>
|
||||
#include <agg_alpha_mask_u8.h>
|
||||
#include <agg_scanline_p.h>
|
||||
#include <agg_scanline_u.h>
|
||||
#include <agg_alpha_mask_u8.h>
|
||||
#include <agg_path_storage.h>
|
||||
#include <agg_renderer_base.h>
|
||||
#include <agg_renderer_mclip.h>
|
||||
@ -14,22 +19,46 @@
|
||||
#include <agg_conv_stroke.h>
|
||||
#include <agg_conv_adaptor_vcgen.h>
|
||||
|
||||
typedef agg::comp_op_adaptor_rgba<agg::rgba8, agg::order_bgra> blender_type;
|
||||
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
|
||||
@class O2Context_AntiGrain;
|
||||
|
||||
typedef agg::renderer_base<pixfmt_type> renderer_base;
|
||||
class context_renderer;
|
||||
|
||||
typedef agg::pixfmt_gray8 pixfmt_alphaMaskType;
|
||||
typedef agg::renderer_base<pixfmt_alphaMaskType> BaseRendererWithAlphaMaskType;
|
||||
typedef agg::rasterizer_scanline_aa<> RasterizerType; // We use an anti-aliased scanline rasterizer for AGG rendering.
|
||||
|
||||
@interface O2Context_AntiGrain : O2Context_builtin_gdi {
|
||||
agg::rendering_buffer *renderingBuffer;
|
||||
pixfmt_type *pixelFormat;
|
||||
agg::rasterizer_scanline_aa<> *rasterizer;
|
||||
renderer_base *ren_base;
|
||||
agg::path_storage *path;
|
||||
agg::rendering_buffer *renderingBuffer;
|
||||
|
||||
// Rendering buffer to use for shadow rendering
|
||||
uint8_t *pixelShadowBytes;
|
||||
agg::rendering_buffer *renderingBufferShadow;
|
||||
|
||||
agg::path_storage *path;
|
||||
RasterizerType *rasterizer;
|
||||
|
||||
context_renderer *renderer;
|
||||
|
||||
// Rendering buffer to use for alpha masking (bezier path clipping)
|
||||
agg::rendering_buffer* rBufAlphaMask[2];
|
||||
agg::alpha_mask_gray8* alphaMask[2];
|
||||
pixfmt_alphaMaskType* pixelFormatAlphaMask[2];
|
||||
BaseRendererWithAlphaMaskType* baseRendererAlphaMask[2];
|
||||
agg::renderer_scanline_aa_solid<BaseRendererWithAlphaMaskType>* solidScanlineRendererAlphaMask[2];
|
||||
int currentMask;
|
||||
|
||||
NSArray *savedClipPhases;
|
||||
BOOL maskValid;
|
||||
BOOL useMask;
|
||||
}
|
||||
|
||||
- (BOOL)useMask;
|
||||
- (agg::alpha_mask_gray8*)currentMask;
|
||||
- (RasterizerType *)rasterizer;
|
||||
- (context_renderer *)renderer;
|
||||
@end
|
||||
|
||||
#else
|
||||
#import <Onyx2D/O2Context_builtin_gdi.h>
|
||||
|
||||
@interface O2Context_AntiGrain : O2Context_builtin_gdi
|
||||
@end
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -80,6 +80,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
0AA1909FFE8422F4C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
4931E7B913B1042600CEF331 /* partial_stack_blur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = partial_stack_blur.h; sourceTree = "<group>"; };
|
||||
8D576316048677EA00EA77CD /* O2Context_AntiGrain.cgContext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = O2Context_AntiGrain.cgContext; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
FE5C8312121D81470063E96F /* O2Context_AntiGrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = O2Context_AntiGrain.h; sourceTree = "<group>"; };
|
||||
@ -105,6 +106,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FEE163EC137C6DC600B2F340 /* AppKit.xcodeproj */,
|
||||
4931E7B913B1042600CEF331 /* partial_stack_blur.h */,
|
||||
FE5C8312121D81470063E96F /* O2Context_AntiGrain.h */,
|
||||
FE5C8313121D81470063E96F /* O2Context_AntiGrain.mm */,
|
||||
089C167CFE841241C02AAC07 /* Resources */,
|
||||
|
310
O2Context_AntiGrain/partial_stack_blur.h
Normal file
310
O2Context_AntiGrain/partial_stack_blur.h
Normal file
@ -0,0 +1,310 @@
|
||||
/*
|
||||
* partial_stack_blur.h
|
||||
* O2Context_AntiGrain
|
||||
*
|
||||
* Created by Airy ANDRE on 21/06/11.
|
||||
* Copyright 2011 plasq. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PARTIAL_BLUR_INCLUDED
|
||||
#define PARTIAL_BLUR_INCLUDED
|
||||
|
||||
#include <agg_blur.h>
|
||||
|
||||
// Adapted from stack_blur_rgba32 to allow partial blurring - blame the original for the lack of comments
|
||||
namespace agg
|
||||
{
|
||||
//======================================================= partial_stack_blur_rgba32
|
||||
template<class Img>
|
||||
void partial_stack_blur_rgba32(Img& img, unsigned rx, unsigned ry, unsigned startX, unsigned endX, unsigned startY, unsigned endY)
|
||||
{
|
||||
typedef typename Img::color_type color_type;
|
||||
typedef typename Img::order_type order_type;
|
||||
enum order_e
|
||||
{
|
||||
R = order_type::R,
|
||||
G = order_type::G,
|
||||
B = order_type::B,
|
||||
A = order_type::A
|
||||
};
|
||||
|
||||
unsigned x, y, xp, yp, i;
|
||||
unsigned stack_ptr;
|
||||
unsigned stack_start;
|
||||
|
||||
const int8u* src_pix_ptr;
|
||||
int8u* dst_pix_ptr;
|
||||
color_type* stack_pix_ptr;
|
||||
|
||||
unsigned sum_r;
|
||||
unsigned sum_g;
|
||||
unsigned sum_b;
|
||||
unsigned sum_a;
|
||||
unsigned sum_in_r;
|
||||
unsigned sum_in_g;
|
||||
unsigned sum_in_b;
|
||||
unsigned sum_in_a;
|
||||
unsigned sum_out_r;
|
||||
unsigned sum_out_g;
|
||||
unsigned sum_out_b;
|
||||
unsigned sum_out_a;
|
||||
|
||||
unsigned w = endX;
|
||||
unsigned h = endY;
|
||||
unsigned wm = w - 1;
|
||||
unsigned hm = h - 1;
|
||||
|
||||
unsigned div;
|
||||
unsigned mul_sum;
|
||||
unsigned shr_sum;
|
||||
|
||||
pod_vector<color_type> stack;
|
||||
|
||||
if(rx > 0)
|
||||
{
|
||||
if(rx > 254) rx = 254;
|
||||
div = rx * 2 + 1;
|
||||
mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx];
|
||||
shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx];
|
||||
stack.allocate(div);
|
||||
|
||||
for(y = startY; y < endY; y++)
|
||||
{
|
||||
sum_r =
|
||||
sum_g =
|
||||
sum_b =
|
||||
sum_a =
|
||||
sum_in_r =
|
||||
sum_in_g =
|
||||
sum_in_b =
|
||||
sum_in_a =
|
||||
sum_out_r =
|
||||
sum_out_g =
|
||||
sum_out_b =
|
||||
sum_out_a = 0;
|
||||
|
||||
src_pix_ptr = img.pix_ptr(startX, y);
|
||||
for(i = 0; i <= rx; i++)
|
||||
{
|
||||
stack_pix_ptr = &stack[i];
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
sum_r += src_pix_ptr[R] * (i + 1);
|
||||
sum_g += src_pix_ptr[G] * (i + 1);
|
||||
sum_b += src_pix_ptr[B] * (i + 1);
|
||||
sum_a += src_pix_ptr[A] * (i + 1);
|
||||
sum_out_r += src_pix_ptr[R];
|
||||
sum_out_g += src_pix_ptr[G];
|
||||
sum_out_b += src_pix_ptr[B];
|
||||
sum_out_a += src_pix_ptr[A];
|
||||
}
|
||||
for(i = 1; i <= rx; i++)
|
||||
{
|
||||
if(i <= wm) src_pix_ptr += Img::pix_width;
|
||||
stack_pix_ptr = &stack[i + rx];
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
sum_r += src_pix_ptr[R] * (rx + 1 - i);
|
||||
sum_g += src_pix_ptr[G] * (rx + 1 - i);
|
||||
sum_b += src_pix_ptr[B] * (rx + 1 - i);
|
||||
sum_a += src_pix_ptr[A] * (rx + 1 - i);
|
||||
sum_in_r += src_pix_ptr[R];
|
||||
sum_in_g += src_pix_ptr[G];
|
||||
sum_in_b += src_pix_ptr[B];
|
||||
sum_in_a += src_pix_ptr[A];
|
||||
}
|
||||
|
||||
stack_ptr = rx;
|
||||
xp = rx + startX;
|
||||
if(xp > wm) xp = wm;
|
||||
src_pix_ptr = img.pix_ptr(xp, y);
|
||||
dst_pix_ptr = img.pix_ptr(startX, y);
|
||||
for(x = startX; x < endX; x++)
|
||||
{
|
||||
dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr += Img::pix_width;
|
||||
|
||||
sum_r -= sum_out_r;
|
||||
sum_g -= sum_out_g;
|
||||
sum_b -= sum_out_b;
|
||||
sum_a -= sum_out_a;
|
||||
|
||||
stack_start = stack_ptr + div - rx;
|
||||
if(stack_start >= div) stack_start -= div;
|
||||
stack_pix_ptr = &stack[stack_start];
|
||||
|
||||
sum_out_r -= stack_pix_ptr->r;
|
||||
sum_out_g -= stack_pix_ptr->g;
|
||||
sum_out_b -= stack_pix_ptr->b;
|
||||
sum_out_a -= stack_pix_ptr->a;
|
||||
|
||||
if(xp < wm)
|
||||
{
|
||||
src_pix_ptr += Img::pix_width;
|
||||
++xp;
|
||||
}
|
||||
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
|
||||
sum_in_r += src_pix_ptr[R];
|
||||
sum_in_g += src_pix_ptr[G];
|
||||
sum_in_b += src_pix_ptr[B];
|
||||
sum_in_a += src_pix_ptr[A];
|
||||
sum_r += sum_in_r;
|
||||
sum_g += sum_in_g;
|
||||
sum_b += sum_in_b;
|
||||
sum_a += sum_in_a;
|
||||
|
||||
++stack_ptr;
|
||||
if(stack_ptr >= div) stack_ptr = 0;
|
||||
stack_pix_ptr = &stack[stack_ptr];
|
||||
|
||||
sum_out_r += stack_pix_ptr->r;
|
||||
sum_out_g += stack_pix_ptr->g;
|
||||
sum_out_b += stack_pix_ptr->b;
|
||||
sum_out_a += stack_pix_ptr->a;
|
||||
sum_in_r -= stack_pix_ptr->r;
|
||||
sum_in_g -= stack_pix_ptr->g;
|
||||
sum_in_b -= stack_pix_ptr->b;
|
||||
sum_in_a -= stack_pix_ptr->a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ry > 0)
|
||||
{
|
||||
if(ry > 254) ry = 254;
|
||||
div = ry * 2 + 1;
|
||||
mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry];
|
||||
shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry];
|
||||
stack.allocate(div);
|
||||
|
||||
int stride = img.stride();
|
||||
for(x = startX; x < w; x++)
|
||||
{
|
||||
sum_r =
|
||||
sum_g =
|
||||
sum_b =
|
||||
sum_a =
|
||||
sum_in_r =
|
||||
sum_in_g =
|
||||
sum_in_b =
|
||||
sum_in_a =
|
||||
sum_out_r =
|
||||
sum_out_g =
|
||||
sum_out_b =
|
||||
sum_out_a = 0;
|
||||
|
||||
src_pix_ptr = img.pix_ptr(x, startY);
|
||||
for(i = 0; i <= ry; i++)
|
||||
{
|
||||
stack_pix_ptr = &stack[i];
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
sum_r += src_pix_ptr[R] * (i + 1);
|
||||
sum_g += src_pix_ptr[G] * (i + 1);
|
||||
sum_b += src_pix_ptr[B] * (i + 1);
|
||||
sum_a += src_pix_ptr[A] * (i + 1);
|
||||
sum_out_r += src_pix_ptr[R];
|
||||
sum_out_g += src_pix_ptr[G];
|
||||
sum_out_b += src_pix_ptr[B];
|
||||
sum_out_a += src_pix_ptr[A];
|
||||
}
|
||||
for(i = 1; i <= ry; i++)
|
||||
{
|
||||
if(i <= hm) src_pix_ptr += stride;
|
||||
stack_pix_ptr = &stack[i + ry];
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
sum_r += src_pix_ptr[R] * (ry + 1 - i);
|
||||
sum_g += src_pix_ptr[G] * (ry + 1 - i);
|
||||
sum_b += src_pix_ptr[B] * (ry + 1 - i);
|
||||
sum_a += src_pix_ptr[A] * (ry + 1 - i);
|
||||
sum_in_r += src_pix_ptr[R];
|
||||
sum_in_g += src_pix_ptr[G];
|
||||
sum_in_b += src_pix_ptr[B];
|
||||
sum_in_a += src_pix_ptr[A];
|
||||
}
|
||||
|
||||
stack_ptr = ry;
|
||||
yp = startY + ry;
|
||||
if(yp > hm) yp = hm;
|
||||
src_pix_ptr = img.pix_ptr(x, yp);
|
||||
dst_pix_ptr = img.pix_ptr(x, startY);
|
||||
for(y = startY; y < h; y++)
|
||||
{
|
||||
dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum;
|
||||
dst_pix_ptr += stride;
|
||||
|
||||
sum_r -= sum_out_r;
|
||||
sum_g -= sum_out_g;
|
||||
sum_b -= sum_out_b;
|
||||
sum_a -= sum_out_a;
|
||||
|
||||
stack_start = stack_ptr + div - ry;
|
||||
if(stack_start >= div) stack_start -= div;
|
||||
|
||||
stack_pix_ptr = &stack[stack_start];
|
||||
sum_out_r -= stack_pix_ptr->r;
|
||||
sum_out_g -= stack_pix_ptr->g;
|
||||
sum_out_b -= stack_pix_ptr->b;
|
||||
sum_out_a -= stack_pix_ptr->a;
|
||||
|
||||
if(yp < hm)
|
||||
{
|
||||
src_pix_ptr += stride;
|
||||
++yp;
|
||||
}
|
||||
|
||||
stack_pix_ptr->r = src_pix_ptr[R];
|
||||
stack_pix_ptr->g = src_pix_ptr[G];
|
||||
stack_pix_ptr->b = src_pix_ptr[B];
|
||||
stack_pix_ptr->a = src_pix_ptr[A];
|
||||
|
||||
sum_in_r += src_pix_ptr[R];
|
||||
sum_in_g += src_pix_ptr[G];
|
||||
sum_in_b += src_pix_ptr[B];
|
||||
sum_in_a += src_pix_ptr[A];
|
||||
sum_r += sum_in_r;
|
||||
sum_g += sum_in_g;
|
||||
sum_b += sum_in_b;
|
||||
sum_a += sum_in_a;
|
||||
|
||||
++stack_ptr;
|
||||
if(stack_ptr >= div) stack_ptr = 0;
|
||||
stack_pix_ptr = &stack[stack_ptr];
|
||||
|
||||
sum_out_r += stack_pix_ptr->r;
|
||||
sum_out_g += stack_pix_ptr->g;
|
||||
sum_out_b += stack_pix_ptr->b;
|
||||
sum_out_a += stack_pix_ptr->a;
|
||||
sum_in_r -= stack_pix_ptr->r;
|
||||
sum_in_g -= stack_pix_ptr->g;
|
||||
sum_in_b -= stack_pix_ptr->b;
|
||||
sum_in_a -= stack_pix_ptr->a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -187,6 +187,8 @@ O2ColorRef O2ContextFillColor(O2ContextRef self);
|
||||
|
||||
-(void)clipToState:(O2ClipState *)clipState;
|
||||
|
||||
-(void)supportsGlobalAlpha;
|
||||
|
||||
O2ContextRef O2ContextRetain(O2ContextRef self);
|
||||
void O2ContextRelease(O2ContextRef self);
|
||||
|
||||
|
@ -235,6 +235,20 @@ O2ColorRef O2ContextFillColor(O2ContextRef self) {
|
||||
O2ContextSetCMYKFillColor(self,c,m,y,k,alpha);
|
||||
}
|
||||
|
||||
-(void)setAlpha:(float)alpha
|
||||
{
|
||||
O2GStateSetAlpha(O2ContextCurrentGState(self), alpha);
|
||||
if ([self supportsGlobalAlpha] == NO) {
|
||||
[self setStrokeAlpha:alpha];
|
||||
[self setFillAlpha:alpha];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)supportsGlobalAlpha
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
-(void)drawPath:(O2PathDrawingMode)pathMode {
|
||||
O2InvalidAbstractInvocation();
|
||||
// reset path in subclass
|
||||
@ -874,8 +888,7 @@ void O2ContextSetAlpha(O2ContextRef self,O2Float alpha) {
|
||||
if(self==nil)
|
||||
return;
|
||||
|
||||
[self setStrokeAlpha:alpha];
|
||||
[self setFillAlpha:alpha];
|
||||
[self setAlpha:alpha];
|
||||
}
|
||||
|
||||
void O2ContextSetPatternPhase(O2ContextRef self,O2Size phase) {
|
||||
|
@ -165,6 +165,15 @@ void O2DContextClipAndFillEdges(O2Context_builtin *self,int fillRuleMask);
|
||||
[self->_layerStack addObject:layer];
|
||||
O2LayerRelease(layer);
|
||||
O2ContextSaveGState(self);
|
||||
|
||||
/**
|
||||
* From Cocoa doc :
|
||||
* graphics state parameters remain unchanged except for alpha (which is set to 1), shadow (which is turned off), blend mode (which is set to normal),
|
||||
* and other parameters that affect the final composite.
|
||||
*/
|
||||
O2GStateSetBlendMode(O2ContextCurrentGState(self), kO2BlendModeNormal);
|
||||
[O2ContextCurrentGState(self) setShadowOffset:O2SizeZero blur:0. color:nil];
|
||||
O2GStateSetAlpha(O2ContextCurrentGState(self), 1.);
|
||||
}
|
||||
|
||||
-(void)endTransparencyLayer {
|
||||
|
@ -50,6 +50,7 @@ extern "C" {
|
||||
float *_dashLengths;
|
||||
O2ColorRenderingIntent _renderingIntent;
|
||||
O2BlendMode _blendMode;
|
||||
float _alpha;
|
||||
float _flatness;
|
||||
O2InterpolationQuality _interpolationQuality;
|
||||
O2Size _shadowOffset;
|
||||
@ -143,6 +144,8 @@ void O2GStateSetLineDash(O2GState *self,float phase,const float *lengths,unsigne
|
||||
-(void)setRenderingIntent:(O2ColorRenderingIntent)intent;
|
||||
O2BlendMode O2GStateBlendMode(O2GState *self);
|
||||
void O2GStateSetBlendMode(O2GState *self,O2BlendMode mode);
|
||||
float O2GStateAlpha(O2GState *self);
|
||||
void O2GStateSetAlpha(O2GState *self,float alpha);
|
||||
|
||||
-(void)setFlatness:(float)flatness;
|
||||
-(void)setInterpolationQuality:(O2InterpolationQuality)quality;
|
||||
|
@ -40,6 +40,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
_interpolationQuality=kO2InterpolationDefault;
|
||||
_shouldAntialias=YES;
|
||||
_antialiasingQuality=64;
|
||||
_alpha = 1.;
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -98,6 +99,8 @@ O2GState *O2GStateCopyWithZone(O2GState *self,NSZone *zone) {
|
||||
|
||||
copy->_shadowKernel=O2GaussianKernelRetain(self->_shadowKernel);
|
||||
|
||||
copy->_alpha = self->_alpha;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
@ -384,11 +387,19 @@ void O2GStateSetLineDash(O2GState *self,float phase,const float *lengths,unsigne
|
||||
}
|
||||
|
||||
O2BlendMode O2GStateBlendMode(O2GState *self) {
|
||||
return self->_blendMode;
|
||||
return self->_blendMode;
|
||||
}
|
||||
|
||||
void O2GStateSetBlendMode(O2GState *self,O2BlendMode mode){
|
||||
self->_blendMode=mode;
|
||||
self->_blendMode=mode;
|
||||
}
|
||||
|
||||
float O2GStateAlpha(O2GState *self) {
|
||||
return self->_alpha;
|
||||
}
|
||||
|
||||
void O2GStateSetAlpha(O2GState *self,float alpha){
|
||||
self->_alpha=alpha;
|
||||
}
|
||||
|
||||
-(void)setFlatness:(float)flatness {
|
||||
|
@ -1545,7 +1545,7 @@ void O2ImageReadPatternSpan_largb32f_PRE(O2Image *self,O2Float x, O2Float y, O2a
|
||||
}
|
||||
|
||||
-(NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@:%p> width=%d,height=%d,bpc=%d,bpp=%d,bpr=%d, data length=%d",isa,self,_width,_height,_bitsPerComponent,_bitsPerPixel,_bytesPerRow,[_provider length]];
|
||||
return [NSString stringWithFormat:@"<%@:%p> width=%d,height=%d,bpc=%d,bpp=%d,bpr=%d,bminfo=%x data length=%d",isa,self,_width,_height,_bitsPerComponent,_bitsPerPixel,_bytesPerRow,_bitmapInfo,[_provider length]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -19,7 +19,6 @@ O2Surface *O2LayerGetSurface(O2LayerRef self) {
|
||||
|
||||
O2LayerRef O2LayerCreateWithContext(O2ContextRef context,O2Size size,NSDictionary *unused) {
|
||||
O2LayerRef self=NSAllocateObject([O2Layer class],0,NULL);
|
||||
|
||||
self->_context=[context createCompatibleContextWithSize:size unused:unused];
|
||||
self->_size=size;
|
||||
self->_unused=[unused copy];
|
||||
@ -44,4 +43,10 @@ O2ContextRef O2LayerGetContext(O2LayerRef self) {
|
||||
return self->_context;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_context release];
|
||||
[_unused release];
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
||||
|
@ -422,13 +422,20 @@ static inline void purgeGlyphCache(O2Context_builtin_gdi *self){
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// Use the current layer context if any
|
||||
O2Context_builtin_gdi *context = self;
|
||||
O2LayerRef layer=[self->_layerStack lastObject];
|
||||
if (layer) {
|
||||
context = (O2Context_builtin_gdi *)O2LayerGetContext(layer);
|
||||
}
|
||||
|
||||
if(gState->_fontIsDirty){
|
||||
O2GStateClearFontIsDirty(gState);
|
||||
[self->_gdiFont release];
|
||||
self->_gdiFont=[(O2Font_gdi *)font createGDIFontSelectedInDC:self->_dc pointSize:ABS(fontSize.height)];
|
||||
self->_gdiFont=[(O2Font_gdi *)font createGDIFontSelectedInDC:context->_dc pointSize:ABS(fontSize.height)];
|
||||
}
|
||||
|
||||
SetTextColor(self->_dc,COLORREFFromColor(O2ContextFillColor(self)));
|
||||
SelectObject(context->_dc,[self->_gdiFont fontHandle]);
|
||||
SetTextColor(context->_dc,COLORREFFromColor(O2ContextFillColor(self)));
|
||||
|
||||
INT dx[count];
|
||||
|
||||
@ -437,7 +444,7 @@ static inline void purgeGlyphCache(O2Context_builtin_gdi *self){
|
||||
dx[i]=lroundf(O2SizeApplyAffineTransform(advances[i],Trm).width);
|
||||
}
|
||||
|
||||
ExtTextOutW(self->_dc,lroundf(point.x),lroundf(point.y),ETO_GLYPH_INDEX,NULL,(void *)glyphs,count,(advances!=NULL)?dx:NULL);
|
||||
ExtTextOutW(context->_dc,lroundf(point.x),lroundf(point.y),ETO_GLYPH_INDEX,NULL,(void *)glyphs,count,(advances!=NULL)?dx:NULL);
|
||||
#endif
|
||||
}
|
||||
else if(O2FontGetPlatformType(font)==O2FontPlatformTypeFreeType){
|
||||
|
Loading…
Reference in New Issue
Block a user