1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salgdiutils.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include "basebmp/scanlineformats.hxx"
38 #include "basebmp/color.hxx"
39 #include "basegfx/range/b2drectangle.hxx"
40 #include "basegfx/range/b2irange.hxx"
41 #include "basegfx/vector/b2ivector.hxx"
42 #include "basegfx/polygon/b2dpolygon.hxx"
43 #include "basegfx/polygon/b2dpolygontools.hxx"
44 #include <boost/bind.hpp>
46 #include "vcl/svapp.hxx"
47 #include "saldata.hxx"
49 // ----------------------------------------------------------------------
51 void AquaSalGraphics::SetWindowGraphics( AquaSalFrame
* pFrame
)
60 void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext
, long nDPIX
, long nDPIY
, double fScale
)
67 mfFakeDPIScale
= fScale
;
73 CGContextSetFillColorSpace( mrContext
, GetSalData()->mxRGBSpace
);
74 CGContextSetStrokeColorSpace( mrContext
, GetSalData()->mxRGBSpace
);
75 CGContextSaveGState( mrContext
);
80 void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer
, CGContextRef xContext
,
87 // set graphics properties
90 mnBitmapDepth
= nBitmapDepth
;
92 // return early if the virdev is being destroyed
96 // get new graphics properties
99 mnWidth
= CGBitmapContextGetWidth( mrContext
);
100 mnHeight
= CGBitmapContextGetHeight( mrContext
);
104 const CGSize aSize
= CGLayerGetSize( mxLayer
);
105 mnWidth
= static_cast<int>(aSize
.width
);
106 mnHeight
= static_cast<int>(aSize
.height
);
109 // prepare graphics for drawing
110 const CGColorSpaceRef aCGColorSpace
= GetSalData()->mxRGBSpace
;
111 CGContextSetFillColorSpace( mrContext
, aCGColorSpace
);
112 CGContextSetStrokeColorSpace( mrContext
, aCGColorSpace
);
114 // re-enable XorEmulation for the new context
117 mpXorEmulation
->SetTarget( mnWidth
, mnHeight
, mnBitmapDepth
, mrContext
, mxLayer
);
118 if( mpXorEmulation
->IsEnabled() )
119 mrContext
= mpXorEmulation
->GetMaskContext();
122 // initialize stack of CGContext states
123 CGContextSaveGState( mrContext
);
127 // ----------------------------------------------------------------------
129 void AquaSalGraphics::SetState()
131 CGContextRestoreGState( mrContext
);
132 CGContextSaveGState( mrContext
);
137 CGContextBeginPath( mrContext
); // discard any existing path
138 CGContextAddPath( mrContext
, mxClipPath
); // set the current path to the clipping path
139 CGContextClip( mrContext
); // use it for clipping
142 // set RGB colorspace and line and fill colors
143 CGContextSetFillColor( mrContext
, maFillColor
.AsArray() );
144 CGContextSetStrokeColor( mrContext
, maLineColor
.AsArray() );
145 CGContextSetShouldAntialias( mrContext
, false );
147 CGContextSetBlendMode( mrContext
, kCGBlendModeDifference
);
150 // ----------------------------------------------------------------------
152 bool AquaSalGraphics::CheckContext()
154 if( mbWindow
&& mpFrame
!= NULL
)
156 const unsigned int nWidth
= mpFrame
->maGeometry
.nWidth
;
157 const unsigned int nHeight
= mpFrame
->maGeometry
.nHeight
;
159 CGContextRef rReleaseContext
= 0;
160 CGLayerRef rReleaseLayer
= NULL
;
162 // check if a new drawing context is needed (e.g. after a resize)
163 if( (unsigned(mnWidth
) != nWidth
) || (unsigned(mnHeight
) != nHeight
) )
167 // prepare to release the corresponding resources
168 rReleaseContext
= mrContext
;
169 rReleaseLayer
= mxLayer
;
176 const CGSize aLayerSize
= {nWidth
,nHeight
};
177 NSGraphicsContext
* pNSGContext
= [NSGraphicsContext graphicsContextWithWindow
: mpFrame
->getWindow()];
178 CGContextRef xCGContext
= reinterpret_cast<CGContextRef
>([pNSGContext graphicsPort
]);
179 mxLayer
= CGLayerCreateWithContext( xCGContext
, aLayerSize
, NULL
);
181 mrContext
= CGLayerGetContext( mxLayer
);
185 // copy original layer to resized layer
187 CGContextDrawLayerAtPoint( mrContext
, CGPointZero
, rReleaseLayer
);
189 CGContextTranslateCTM( mrContext
, 0, nHeight
);
190 CGContextScaleCTM( mrContext
, 1.0, -1.0 );
191 CGContextSetFillColorSpace( mrContext
, GetSalData()->mxRGBSpace
);
192 CGContextSetStrokeColorSpace( mrContext
, GetSalData()->mxRGBSpace
);
193 CGContextSaveGState( mrContext
);
196 // re-enable XOR emulation for the new context
198 mpXorEmulation
->SetTarget( mnWidth
, mnHeight
, mnBitmapDepth
, mrContext
, mxLayer
);
203 CGLayerRelease( rReleaseLayer
);
204 else if( rReleaseContext
)
205 CGContextRelease( rReleaseContext
);
208 DBG_ASSERT( mrContext
, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
209 return (mrContext
!= NULL
);
213 void AquaSalGraphics::RefreshRect(float lX
, float lY
, float lWidth
, float lHeight
)
215 if( ! mbWindow
) // view only on Window graphics
220 // update a little more around the designated rectangle
221 // this helps with antialiased rendering
222 const Rectangle
aVclRect(Point(static_cast<long int>(lX
-1),
223 static_cast<long int>(lY
-1) ),
224 Size( static_cast<long int>(lWidth
+2),
225 static_cast<long int>(lHeight
+2) ) );
226 mpFrame
->maInvalidRect
.Union( aVclRect
);
230 CGPoint
* AquaSalGraphics::makeCGptArray(ULONG nPoints
, const SalPoint
* pPtAry
)
232 CGPoint
*CGpoints
= new (CGPoint
[nPoints
]);
235 for(ULONG i
=0;i
<nPoints
;i
++)
237 CGpoints
[i
].x
= (float)(pPtAry
[i
].mnX
);
238 CGpoints
[i
].y
= (float)(pPtAry
[i
].mnY
);
244 // -----------------------------------------------------------------------
246 void AquaSalGraphics::UpdateWindow( NSRect
& rRect
)
250 NSGraphicsContext
* pContext
= [NSGraphicsContext currentContext
];
251 if( (mxLayer
!= NULL
) && (pContext
!= NULL
) )
253 CGContextRef rCGContext
= reinterpret_cast<CGContextRef
>([pContext graphicsPort
]);
255 CGMutablePathRef rClip
= mpFrame
->getClipPath();
258 CGContextSaveGState( rCGContext
);
259 CGContextBeginPath( rCGContext
);
260 CGContextAddPath( rCGContext
, rClip
);
261 CGContextClip( rCGContext
);
265 CGContextDrawLayerAtPoint( rCGContext
, CGPointZero
, mxLayer
);
266 if( rClip
) // cleanup clipping
267 CGContextRestoreGState( rCGContext
);
270 DBG_ASSERT( mpFrame
->mbInitShow
, "UpdateWindow called on uneligible graphics" );
273 // -----------------------------------------------------------------------