2013-06-25 17:13:37 +00:00
/ *
OpalGState . m
Copyright ( C ) 2013 Free Software Foundation , Inc .
Author : Ivan Vucica < ivan @ vucica . net >
Date : June 2013
This file is part of GNUstep .
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
License along with this library ; see the file COPYING . LIB .
2013-09-29 17:10:26 +00:00
If not , see < http : // www . gnu . org / licenses / > or write to the
Free Software Foundation , 51 Franklin Street , Fifth Floor ,
2013-06-25 17:13:37 +00:00
Boston , MA 02110 -1301 , USA .
* /
2013-07-11 20:44:32 +00:00
# import < CoreGraphics / CoreGraphics . h >
2013-08-01 22:28:57 +00:00
# import < AppKit / NSGraphics . h > // NS * ColorSpace
2013-09-23 19:51:59 +00:00
# import < AppKit / NSAffineTransform . h >
2013-09-29 07:30:20 +00:00
# import < AppKit / NSBezierPath . h >
2013-06-25 17:13:37 +00:00
# import "opal/OpalGState.h"
2013-07-11 20:44:32 +00:00
# import "opal/OpalSurface.h"
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
# import "opal/OpalFontInfo.h"
2013-06-25 17:13:37 +00:00
2013-09-23 18:04:06 +00:00
# define CGCTX [ self CGContext ]
2013-07-15 15:24:04 +00:00
2013-09-23 18:04:06 +00:00
static inline NSString * _CGRectRepr ( CGRect rect )
{
return [ NSString stringWithFormat : @ "(%g,%g,%g,%g)" ,
rect . origin . x , rect . origin . y ,
rect . size . width , rect . size . height ] ;
}
2013-09-29 07:30:20 +00:00
2013-09-23 18:04:06 +00:00
static inline CGRect _CGRectFromNSRect ( NSRect nsrect )
{
return CGRectMake ( nsrect . origin . x , nsrect . origin . y ,
nsrect . size . width , nsrect . size . height ) ;
}
2013-07-23 23:18:48 +00:00
2013-09-29 17:10:26 +00:00
static inline NSPoint _NSPointFromCGPoint ( CGPoint cgpoint )
{
return NSMakePoint ( cgpoint . x , cgpoint . y ) ;
}
2013-06-25 17:13:37 +00:00
@ implementation OpalGState
2013-09-29 07:30:20 +00:00
- ( id ) copyWithZone : ( NSZone * ) zone
2013-06-25 17:13:37 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 07:30:20 +00:00
OpalGState * theCopy = ( OpalGState * ) [ super copyWithZone : zone ] ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-29 07:30:20 +00:00
[ _opalSurface retain ] ;
2013-09-29 17:10:26 +00:00
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
theCopy -> _opGState = OPContextCopyGState ( cgctx ) ;
2013-09-29 07:30:20 +00:00
}
return theCopy ;
2013-06-25 17:13:37 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) setOffset : ( NSPoint ) theOffset
2013-06-25 17:13:37 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , theOffset . x , theOffset . y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
OPContextSetCairoDeviceOffset ( cgctx , - theOffset . x ,
2013-09-29 07:30:20 +00:00
theOffset . y - [ _opalSurface size ] . height ) ;
}
[ super setOffset : theOffset ] ;
}
@ end
@ implementation OpalGState ( Ops )
- ( void ) DPSsetalpha : ( CGFloat ) a
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - alpha %g" , self , [ self class ] , __PRETTY _FUNCTION __ , a ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextSetAlpha ( cgctx , a ) ;
2013-09-29 07:30:20 +00:00
}
[ super DPSsetalpha : a ] ;
2013-06-25 17:13:37 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetgray : ( CGFloat ) gray
2013-06-25 17:13:37 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-15 15:24:04 +00:00
2013-09-29 17:10:26 +00:00
const CGFloat alpha = 1.0 ; // TODO : is this correct ?
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2015-12-13 17:55:23 +00:00
CGContextSetGrayStrokeColor ( cgctx , gray , alpha ) ;
2013-09-29 17:10:26 +00:00
CGContextSetGrayFillColor ( cgctx , gray , alpha ) ;
2013-09-29 07:30:20 +00:00
}
[ super DPSsetgray : gray ] ;
2013-06-25 17:13:37 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetrgbcolor : ( CGFloat ) r : ( CGFloat ) g : ( CGFloat ) b
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
const CGFloat alpha = 1.0 ; // TODO : is this correct ?
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextSetRGBStrokeColor ( cgctx , r , g , b , alpha ) ;
2015-12-13 17:55:23 +00:00
CGContextSetRGBFillColor ( cgctx , r , g , b , alpha ) ;
2013-09-29 07:30:20 +00:00
}
[ super DPSsetrgbcolor : r : g : b ] ;
}
2015-12-13 17:55:23 +00:00
- ( void ) DPSsetcmykcolor : ( CGFloat ) c : ( CGFloat ) m : ( CGFloat ) y : ( CGFloat ) k
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
CGContextRef cgctx = CGCTX ;
const CGFloat alpha = 1.0 ; // TODO : is this correct ?
if ( cgctx )
{
CGContextSetCMYKFillColor ( cgctx , c , m , y , k , alpha ) ;
CGContextSetCMYKStrokeColor ( cgctx , c , m , y , k , alpha ) ;
}
[ super DPSsetcmykcolor : c : m : y : k ] ;
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSshow : ( const char * ) s
2013-06-25 17:13:37 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-23 23:18:48 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextSaveGState ( cgctx ) ;
CGContextSetRGBFillColor ( cgctx , 0 , 1 , 0 , 1 ) ;
CGContextFillRect ( cgctx , CGRectMake ( 0 , 0 , strlen ( s ) * 12 , 12 ) ) ;
CGContextRestoreGState ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
}
2013-08-01 22:28:57 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) GSShowText : ( const char * ) s : ( size_t ) length
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-08-01 22:28:57 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextSaveGState ( cgctx ) ;
CGContextSetRGBFillColor ( cgctx , 0 , 1 , 0 , 1 ) ;
CGContextFillRect ( cgctx , CGRectMake ( 0 , 0 , length * 12 , 12 ) ) ;
CGContextRestoreGState ( cgctx ) ;
// TODO : implement !
}
2013-09-29 07:30:20 +00:00
}
2013-08-01 22:28:57 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) GSSetFont : ( GSFontInfo * ) fontref
{
const CGFloat * matrix ;
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
[ super GSSetFont : fontref ] ;
2013-08-01 22:28:57 +00:00
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-08-01 22:28:57 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGFontRef opalFont = ( CGFontRef ) [ ( ( OpalFontInfo * ) fontref ) -> _faceInfo fontFace ] ;
CGContextSetFont ( cgctx , opalFont ) ;
CGContextSetFontSize ( cgctx , 1 ) ;
matrix = [ fontref matrix ] ;
CGAffineTransform cgAT = CGAffineTransformMake ( matrix [ 0 ] , matrix [ 1 ] ,
2013-09-29 07:30:20 +00:00
matrix [ 2 ] , matrix [ 3 ] ,
matrix [ 4 ] , matrix [ 5 ] ) ;
2013-09-29 17:10:26 +00:00
CGContextSetTextMatrix ( cgctx , cgAT ) ;
}
2013-06-25 17:13:37 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) GSShowGlyphsWithAdvances : ( const NSGlyph * ) glyphs : ( const NSSize * ) advances : ( size_t ) length
2013-06-25 17:13:37 +00:00
{
2013-09-29 07:30:20 +00:00
size_t i ;
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
2013-09-23 18:04:06 +00:00
{
2013-09-29 17:10:26 +00:00
// NSGlyph = unsigned int , CGGlyph = unsigned short
CGGlyph cgglyphs [ length ] ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
for ( i = 0 ; i < length ; i + + )
{
cgglyphs [ i ] = glyphs [ i ] ;
}
CGPoint pt = CGContextGetPathCurrentPoint ( cgctx ) ;
// FIXME : why * 0.66 ?
pt . y + = [ self -> font defaultLineHeightForFont ] * 0.66 ;
CGContextSetTextPosition ( cgctx , pt . x , pt . y ) ;
CGContextShowGlyphsWithAdvances ( cgctx , cgglyphs , ( const CGSize * ) advances ,
length ) ;
}
2013-09-23 18:04:06 +00:00
}
2013-09-29 07:30:20 +00:00
- ( NSPoint ) currentPoint
2013-09-23 18:04:06 +00:00
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGPoint pt = CGContextGetPathCurrentPoint ( cgctx ) ;
return _NSPointFromCGPoint ( pt ) ;
}
else
{
return NSZeroPoint ;
}
2013-09-29 07:30:20 +00:00
}
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetdash : ( const CGFloat * ) pat
: ( NSInteger ) size
: ( CGFloat ) dashOffset
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
if ( ! pat && size ! = 0 )
{
NSLog ( @ "%s: null 'pat' passed with size %d. Fixing by setting size to 0." , pat , ( int ) size ) ;
size = 0 ;
// TODO : looking at opal , it does not seem to have a tolerance for
// pat = NULL although CGContextSetLineDash ( ) explicitly specifies that
// as a possible argument
2013-09-23 18:04:06 +00:00
}
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextSetLineDash ( cgctx , dashOffset , pat , size ) ;
}
2013-09-23 18:04:06 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetlinecap : ( int ) linecap
2013-09-23 18:04:06 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
// TODO : ensure match of linecap constants between Opal and DPS
CGContextSetLineCap ( cgctx , linecap ) ;
}
2013-09-29 07:30:20 +00:00
}
2013-09-23 18:38:40 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetlinejoin : ( int ) linejoin
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextSetLineJoin ( cgctx , linejoin ) ;
}
2013-09-29 07:30:20 +00:00
}
2013-07-21 11:58:05 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetlinewidth : ( CGFloat ) width
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextSetLineWidth ( cgctx , width ) ;
}
2013-09-23 18:04:06 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetmiterlimit : ( CGFloat ) miterlimit
2013-09-23 18:04:06 +00:00
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-23 18:38:40 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextSetMiterLimit ( cgctx , miterlimit ) ;
}
2013-06-25 17:13:37 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSsetstrokeadjust : ( int ) b
2013-06-25 17:13:37 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
// TODO : Opal doesn ' t implement this private API of Core Graphics
2013-07-15 15:24:04 +00:00
}
2013-09-29 07:30:20 +00:00
/ * Matrix operations * /
- ( void ) DPSconcat : ( const CGFloat * ) m
2013-07-15 15:24:04 +00:00
{
2013-09-29 17:10:26 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g %g %g %g %g" , self ,
[ self class ] , __PRETTY _FUNCTION __ ,
2013-09-29 07:30:20 +00:00
m [ 0 ] , m [ 1 ] , m [ 2 ] , m [ 3 ] , m [ 4 ] , m [ 5 ] ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-06-25 17:13:37 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextConcatCTM ( cgctx ,
CGAffineTransformMake ( m [ 0 ] , m [ 1 ] , m [ 2 ] ,
m [ 3 ] , m [ 4 ] , m [ 5 ] ) ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSconcat : m ] ;
2013-07-15 15:24:04 +00:00
}
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) DPSinitmatrix
2013-07-15 15:24:04 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
OPContextSetIdentityCTM ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSinitmatrix ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 17:10:26 +00:00
- ( void ) DPSrotate : ( CGFloat ) angle
2013-08-01 22:28:57 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextRotateCTM ( cgctx , angle ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSrotate : angle ] ;
2013-08-01 22:28:57 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSscale : ( CGFloat ) x
2013-09-29 17:10:26 +00:00
: ( CGFloat ) y
2013-08-01 22:28:57 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextScaleCTM ( cgctx , x , y ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSscale : x : y ] ;
2013-08-01 22:28:57 +00:00
}
2013-07-11 20:44:32 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPStranslate : ( CGFloat ) x
2013-09-29 17:10:26 +00:00
: ( CGFloat ) y
2013-09-19 22:39:11 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - x %g y %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextTranslateCTM ( cgctx , x , y ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPStranslate : x : y ] ;
2013-09-19 22:39:11 +00:00
}
2013-09-29 07:30:20 +00:00
- ( NSAffineTransform * ) GSCurrentCTM
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-07-11 20:44:32 +00:00
2013-09-29 07:30:20 +00:00
return [ super GSCurrentCTM ] ;
2013-07-11 20:44:32 +00:00
2013-09-29 07:30:20 +00:00
/ *
CGAffineTransform cgCTM = CGContextGetCTM ( CGCTX ) ;
NSAffineTransform * affineTransform = [ NSAffineTransform transform ] ;
2013-07-11 20:44:32 +00:00
2013-09-29 17:10:26 +00:00
// This depends on CGAffineTransform and NSAffineTransformStruct having
2013-09-29 07:30:20 +00:00
// the same in - memory layout .
// Here ' s an elementary check if that is true .
// We should probably check this in - back ' s "configure" script .
assert ( sizeof ( CGAffineTransform ) = = sizeof ( NSAffineTransformStruct ) ) ;
2013-07-11 20:44:32 +00:00
2013-09-29 07:30:20 +00:00
NSAffineTransformStruct nsCTM = * ( NSAffineTransformStruct * ) & cgCTM ;
[ affineTransform setTransformStruct : nsCTM ] ;
2013-09-29 17:10:26 +00:00
2013-09-29 07:30:20 +00:00
return affineTransform ;
* /
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) GSSetCTM : ( NSAffineTransform * ) newCTM
2013-07-11 20:44:32 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-11 20:44:32 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
// This depends on CGAffineTransform and NSAffineTransformStruct having
// the same in - memory layout .
// Here ' s an elementary check if that is true .
// We should probably check this in - back ' s "configure" script .
assert ( sizeof ( CGAffineTransform ) = = sizeof ( NSAffineTransformStruct ) ) ;
NSAffineTransformStruct nsAT = [ newCTM transformStruct ] ;
CGAffineTransform cgAT = * ( CGAffineTransform * ) & nsAT ;
OPContextSetIdentityCTM ( cgctx ) ;
CGContextConcatCTM ( cgctx , cgAT ) ;
}
2013-07-11 20:44:32 +00:00
2013-09-29 07:30:20 +00:00
[ super GSSetCTM : newCTM ] ;
}
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) GSConcatCTM : ( NSAffineTransform * ) newCTM
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-23 18:04:06 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
assert ( sizeof ( CGAffineTransform ) = = sizeof ( NSAffineTransformStruct ) ) ;
NSAffineTransformStruct nsAT = [ newCTM transformStruct ] ;
CGAffineTransform cgAT = * ( CGAffineTransform * ) & nsAT ;
CGContextConcatCTM ( cgctx , cgAT ) ;
}
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
[ super GSConcatCTM : newCTM ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
// MARK : Path operations
2013-07-11 20:44:32 +00:00
// MARK : -
2013-09-29 17:10:26 +00:00
- ( void ) DPSarc : ( CGFloat ) x : ( CGFloat ) y : ( CGFloat ) r : ( CGFloat ) angle1 : ( CGFloat ) angle2
2013-07-15 15:24:04 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextAddArc ( cgctx , x , y , r , angle1 , angle2 , YES ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSarc : x : y : r : angle1 : angle2 ] ;
2013-07-15 15:24:04 +00:00
}
2013-07-11 20:44:32 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) DPSarcn : ( CGFloat ) x : ( CGFloat ) y : ( CGFloat ) r : ( CGFloat ) angle1 : ( CGFloat ) angle2
2013-09-19 22:39:11 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextAddArc ( cgctx , x , y , r , angle1 , angle2 , NO ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSarcn : x : y : r : angle1 : angle2 ] ;
2013-09-19 22:39:11 +00:00
}
2013-09-29 17:10:26 +00:00
- ( void ) DPSarct : ( CGFloat ) x1 : ( CGFloat ) y1 : ( CGFloat ) x2 : ( CGFloat ) y2 : ( CGFloat ) r
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextAddArcToPoint ( cgctx , x1 , y1 , x1 , y2 , r ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSarct : x1 : y1 : x2 : y2 : r ] ;
2013-09-19 22:39:11 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSclip
2013-07-11 20:44:32 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextClip ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
2013-07-11 20:44:32 +00:00
}
2013-07-21 11:58:05 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) DPSclosepath
2013-07-11 20:44:32 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextClosePath ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSclosepath ] ;
2013-07-11 20:44:32 +00:00
}
2013-07-15 15:24:04 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPScurveto : ( CGFloat ) x1 : ( CGFloat ) y1 : ( CGFloat ) x2 : ( CGFloat ) y2
2013-09-29 17:10:26 +00:00
: ( CGFloat ) x3 : ( CGFloat ) y3
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextAddCurveToPoint ( cgctx , x1 , y1 , x2 , y2 , x3 , y3 ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPScurveto : x1 : y1 : x2 : y2 : x3 : y3 ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSeoclip
2013-07-15 15:24:04 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextEOClip ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
2013-07-15 15:24:04 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSeofill
2013-07-11 20:44:32 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextEOFillPath ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSfill
2013-07-11 20:44:32 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-15 15:24:04 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextFillPath ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSinitclip
2013-07-11 20:44:32 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
OPContextResetClip ( cgctx ) ;
}
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSlineto : ( CGFloat ) x
: ( CGFloat ) y
2013-07-11 20:44:32 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextAddLineToPoint ( cgctx , x , y ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSlineto : x : y ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
2013-07-15 15:24:04 +00:00
- ( void ) DPSmoveto : ( CGFloat ) x
: ( CGFloat ) y
2013-07-11 20:44:32 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-15 15:24:04 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextMoveToPoint ( cgctx , x , y ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSmoveto : x : y ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) DPSnewpath
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextBeginPath ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
}
- ( void ) DPSrcurveto : ( CGFloat ) x1 : ( CGFloat ) y1 : ( CGFloat ) x2 : ( CGFloat ) y2
2013-09-29 17:10:26 +00:00
: ( CGFloat ) x3 : ( CGFloat ) y3
{
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGFloat x , y ;
[ self DPScurrentpoint : & x : & y ] ;
x1 + = x ;
y1 + = y ;
x2 + = x ;
y2 + = y ;
x3 + = x ;
y3 + = y ;
CGContextAddCurveToPoint ( cgctx , x1 , y1 , x2 , y2 , x3 , y3 ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSrcurveto : x1 : y1 : x2 : y2 : x3 : y3 ] ;
}
- ( void ) DPSrectclip : ( CGFloat ) x : ( CGFloat ) y : ( CGFloat ) w : ( CGFloat ) h
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y , w , h ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextClipToRect ( cgctx , CGRectMake ( x , y , w , h ) ) ;
}
2013-09-29 07:30:20 +00:00
}
- ( void ) DPSrectfill : ( CGFloat ) x : ( CGFloat ) y : ( CGFloat ) w : ( CGFloat ) h
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - rect %g %g %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y , w , h ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextFillRect ( cgctx , CGRectMake ( x , y , w , h ) ) ;
}
2013-09-29 07:30:20 +00:00
}
- ( void ) DPSrectstroke : ( CGFloat ) x : ( CGFloat ) y : ( CGFloat ) w : ( CGFloat ) h
{
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextStrokeRect ( cgctx , CGRectMake ( x , y , w , h ) ) ;
}
2013-09-29 07:30:20 +00:00
}
- ( void ) DPSrlineto : ( CGFloat ) x
: ( CGFloat ) y
2013-07-11 20:44:32 +00:00
{
2013-07-23 23:18:48 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGFloat x2 , y2 ;
2013-07-15 15:24:04 +00:00
2013-09-29 17:10:26 +00:00
[ self DPScurrentpoint : & x2 : & y2 ] ;
x2 + = x ;
y2 + = y ;
CGContextAddLineToPoint ( cgctx , x , y ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSrlineto : x : y ] ;
2013-07-11 20:44:32 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSrmoveto : ( CGFloat ) x
: ( CGFloat ) y
2013-07-21 11:58:05 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %g %g" , self , [ self class ] , __PRETTY _FUNCTION __ , x , y ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGFloat x2 , y2 ;
2013-07-15 15:24:04 +00:00
2013-09-29 17:10:26 +00:00
[ self DPScurrentpoint : & x2 : & y2 ] ;
x2 + = x ;
y2 + = y ;
CGContextMoveToPoint ( cgctx , x2 , y2 ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSrmoveto : x : y ] ;
2013-07-21 11:58:05 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSstroke
2013-07-23 23:18:48 +00:00
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextStrokePath ( cgctx ) ;
}
2013-09-29 07:30:20 +00:00
[ super DPSnewpath ] ;
}
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) GSSendBezierPath : ( NSBezierPath * ) newpath
{
NSInteger count = [ newpath elementCount ] ;
NSInteger i ;
SEL elmsel = @ selector ( elementAtIndex : associatedPoints : ) ;
NSBezierPathElement (*elmidx)(id, SEL, NSInteger, NSPoint*) =
( NSBezierPathElement (*)(id, SEL, NSInteger, NSPoint*) ) [ newpath methodForSelector : elmsel ] ;
2013-07-23 23:18:48 +00:00
2013-09-29 07:30:20 +00:00
[ super GSSendBezierPath : newpath ] ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-07-23 23:18:48 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
{
CGContextBeginPath ( cgctx ) ;
for ( i = 0 ; i < count ; i + + )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
NSBezierPathElement type ;
NSPoint points [ 3 ] ;
type = ( NSBezierPathElement ) ( * elmidx ) ( newpath , elmsel , i , points ) ;
switch ( type )
{
case NSMoveToBezierPathElement :
CGContextMoveToPoint ( cgctx , points [ 0 ] . x , points [ 0 ] . y ) ;
break ;
case NSLineToBezierPathElement :
CGContextAddLineToPoint ( cgctx , points [ 0 ] . x , points [ 0 ] . y ) ;
break ;
case NSCurveToBezierPathElement :
CGContextAddCurveToPoint ( cgctx , points [ 0 ] . x , points [ 0 ] . y ,
points [ 1 ] . x , points [ 1 ] . y ,
points [ 2 ] . x , points [ 2 ] . y ) ;
break ;
case NSClosePathBezierPathElement :
CGContextClosePath ( cgctx ) ;
break ;
default :
break ;
}
2013-09-29 07:30:20 +00:00
}
}
2013-07-23 23:18:48 +00:00
}
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
- ( NSDictionary * ) GSReadRect : ( NSRect ) r
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
return nil ;
}
2013-09-29 07:30:20 +00:00
- ( void ) DPSimage : ( NSAffineTransform * ) matrix
: ( NSInteger ) pixelsWide
: ( NSInteger ) pixelsHigh
: ( NSInteger ) bitsPerSample // is this used correctly ?
: ( NSInteger ) samplesPerPixel // < unused
: ( NSInteger ) bitsPerPixel
: ( NSInteger ) bytesPerRow
: ( BOOL ) isPlanar // < unused
2013-09-29 17:10:26 +00:00
: ( BOOL ) hasAlpha
2013-09-29 07:30:20 +00:00
: ( NSString * ) colorSpaceName
: ( const unsigned char * const [ 5 ] ) data
2013-09-23 18:04:06 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
NSDebugLLog ( @ "OpalGState" , @ " %s - %@ - cgctx %@" , __PRETTY _FUNCTION __ , _opalSurface , [ self CGContext ] ) ;
2013-09-29 17:10:26 +00:00
NSDebugLLog ( @ "OpalGState" , @ "Bits per component : bitspersample = %d" , bitsPerSample ) ;
NSDebugLLog ( @ "OpalGState" , @ "Bits per pixel : bitsperpixel = %d" , bitsPerPixel ) ;
NSDebugLLog ( @ "OpalGState" , @ " : samplesperpixel = %d" , samplesPerPixel ) ;
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "tf: %@ x %@" , matrix , [ self GSCurrentCTM ] ) ;
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
// TODO :
// We may want to normalize colorspace names between Opal and - gui ,
// to avoid this conversion ?
2013-09-29 17:10:26 +00:00
if ( [ colorSpaceName isEqualToString : NSCalibratedRGBColorSpace ] )
2013-09-29 07:30:20 +00:00
colorSpaceName = kCGColorSpaceGenericRGB ; // SRGB ?
2013-09-29 17:10:26 +00:00
else if ( [ colorSpaceName isEqualToString : NSDeviceRGBColorSpace ] )
2013-09-29 07:30:20 +00:00
colorSpaceName = kCGColorSpaceGenericRGB ;
2013-09-29 17:10:26 +00:00
else if ( [ colorSpaceName isEqualToString : NSCalibratedWhiteColorSpace ] )
2013-09-29 07:30:20 +00:00
colorSpaceName = kCGColorSpaceGenericGray ;
2013-09-29 17:10:26 +00:00
else if ( [ colorSpaceName isEqualToString : NSDeviceWhiteColorSpace ] )
2013-09-29 07:30:20 +00:00
colorSpaceName = kCGColorSpaceGenericGray ;
else
2013-09-23 18:04:06 +00:00
{
2013-09-29 07:30:20 +00:00
NSLog ( @ "Opal backend: Unhandled colorspace: %@" , colorSpaceName ) ;
return ;
2013-09-23 18:04:06 +00:00
}
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
2013-09-29 07:30:20 +00:00
2013-09-29 17:10:26 +00:00
if ( cgctx )
2013-09-29 07:30:20 +00:00
{
2013-09-29 17:10:26 +00:00
// This depends on CGAffineTransform and NSAffineTransformStruct having
// the same in - memory layout .
// Here ' s an elementary check if that is true .
// We should probably check this in - back ' s "configure" script .
assert ( sizeof ( CGAffineTransform ) = = sizeof ( NSAffineTransformStruct ) ) ;
NSAffineTransformStruct nsAT = [ matrix transformStruct ] ;
CGAffineTransform cgAT = * ( CGAffineTransform * ) & nsAT ;
CGContextSaveGState ( cgctx ) ;
CGContextConcatCTM ( cgctx , cgAT ) ;
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName ( colorSpaceName ) ;
NSData * nsData = [ NSData dataWithBytesNoCopy : ( void * ) * data
length : pixelsHigh * bytesPerRow
freeWhenDone : NO ] ;
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData ( nsData ) ;
CGImageRef img = CGImageCreate ( pixelsWide , pixelsHigh , bitsPerSample ,
bitsPerPixel , bytesPerRow , colorSpace ,
2015-12-13 17:55:23 +00:00
kCGBitmapByteOrder32Big | ( hasAlpha ? kCGImageAlphaPremultipliedLast : 0 ) ,
2013-09-29 17:10:26 +00:00
dataProvider ,
NULL , / * const CGFloat decode [ ] is what ? * /
false , / * shouldInterpolate ? * /
kCGRenderingIntentDefault ) ;
if ( img ! = nil )
{
CGContextDrawImage ( cgctx , CGRectMake ( 0 , 0 , pixelsWide , pixelsHigh ) , img ) ;
}
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
2013-09-29 17:10:26 +00:00
CGImageRelease ( img ) ;
CGDataProviderRelease ( dataProvider ) ;
CGColorSpaceRelease ( colorSpace ) ;
CGContextRestoreGState ( cgctx ) ;
2013-09-29 07:30:20 +00:00
}
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
}
2013-09-29 07:30:20 +00:00
- ( void ) compositeGState : ( OpalGState * ) source
2013-09-29 17:10:26 +00:00
fromRect : ( NSRect ) srcRect
toPoint : ( NSPoint ) destPoint
2013-09-29 07:30:20 +00:00
op : ( NSCompositingOperation ) op
fraction : ( CGFloat ) delta
destCGContext : ( CGContextRef ) destCGContext
2013-07-25 14:49:44 +00:00
{
2013-09-29 07:30:20 +00:00
// NOTE : This method seems to need to paint to X11 context , too .
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - from %@ of gstate %p (cgctx %p) to %@ of %p (cgctx %p)" , self , [ self class ] , __PRETTY _FUNCTION __ , NSStringFromRect ( srcRect ) , source , [ source CGContext ] , NSStringFromPoint ( destPoint ) , self , [ self CGContext ] ) ;
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
2013-09-29 07:30:20 +00:00
NSSize ssize = [ source -> _opalSurface size ] ;
srcRect = [ source rectInMatrixSpace : srcRect ] ;
destPoint = [ self pointInMatrixSpace : destPoint ] ;
* Source/opal/OpalFontInfo.m: Move font space to user space conversion
to a separate method. Implement -glyphIsEncoded:, -advancementForGlyph:,
-glyphForCharacter:, -glyphWithName:.
For -boundingRectForGlyph:, and -widthOfString:, return fake, fixed
values.
* Source/opal/OpalContext.m: Fix -isDrawingToScreen implementation;
it now returns YES. This has the unfortunate side effect of breaking
image drawing... but, on the positive side, causes NSLayoutManager
to make calls to GSShowGlyphsWithAdvances in batches of up to
16 glyphs, instead of one at a time...!
* Source/opal/OpalGState.m: Implement -GSSetFont:, and make
-GSShowGlyphsWithAdvances: call CGContextShowGlyphsWithAdvances
Overall state is glyphs are drawn.. they appear upside down,
and the glyph runs only seem to draw at (0, 0).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@37087 72102866-910b-0410-8b05-ffd578937521
2013-09-17 06:53:08 +00:00
2013-09-29 07:30:20 +00:00
srcRect . origin . y = ssize . height - srcRect . origin . y - srcRect . size . height ;
2013-09-17 19:42:01 +00:00
2013-09-29 07:30:20 +00:00
CGRect srcCGRect = _CGRectFromNSRect ( srcRect ) ;
CGRect destCGRect = CGRectMake ( destPoint . x , destPoint . y ,
srcRect . size . width , srcRect . size . height ) ;
NSDebugLLog ( @ "OpalGState" , @ "Source cgctx: %p, self: %p - from %@ to %@ with ctm %@" , [ source CGContext ] , self , _CGRectRepr ( srcCGRect ) , _CGRectRepr ( destCGRect ) , [ self GSCurrentCTM ] ) ;
// FIXME : this presumes that the backing CGContext of ' source ' is
// an OpalSurface with a backing CGBitmapContext
2013-09-29 17:10:26 +00:00
CGImageRef backingImage = CGBitmapContextCreateImage ( [ source CGContext ] ) ;
2013-09-29 07:30:20 +00:00
CGImageRef subImage = CGImageCreateWithImageInRect ( backingImage , srcCGRect ) ;
2013-07-25 14:49:44 +00:00
2013-09-29 07:30:20 +00:00
CGContextSaveGState ( destCGContext ) ;
OPContextSetIdentityCTM ( destCGContext ) ;
OPContextSetCairoDeviceOffset ( destCGContext , 0 , 0 ) ;
// TODO : this ignores op
// TODO : this ignores delta
CGContextDrawImage ( destCGContext , destCGRect , subImage ) ;
2013-09-29 17:10:26 +00:00
OPContextSetCairoDeviceOffset ( CGCTX , - offset . x ,
2013-09-29 07:30:20 +00:00
offset . y - [ _opalSurface size ] . height ) ;
CGContextRestoreGState ( destCGContext ) ;
CGImageRelease ( subImage ) ;
CGImageRelease ( backingImage ) ;
2013-07-25 14:49:44 +00:00
}
2013-09-17 19:42:01 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) compositeGState : ( OpalGState * ) source
fromRect : ( NSRect ) srcRect
toPoint : ( NSPoint ) destPoint
op : ( NSCompositingOperation ) op
fraction : ( CGFloat ) delta
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
CGContextRef destContexts [ 2 ] = { [ _opalSurface backingCGContext ] , [ _opalSurface x11CGContext ] } ;
/ * x11 context needs to have correct ctm applied * /
CGContextSaveGState ( [ _opalSurface x11CGContext ] ) ;
OPContextSetIdentityCTM ( [ _opalSurface x11CGContext ] ) ;
CGContextConcatCTM ( [ _opalSurface x11CGContext ] , CGContextGetCTM ( [ _opalSurface backingCGContext ] ) ) ;
int i ;
for ( i = 0 ; i < 1 ; i + + ) // not drawing into x11cgctx after all .
{
CGContextRef ctx = destContexts [ i ] ;
[ self compositeGState : source
fromRect : srcRect
toPoint : destPoint
op : op
fraction : delta
destCGContext : ctx ] ;
}
/ * restore x11 context ' s previous state * /
CGContextRestoreGState ( [ _opalSurface x11CGContext ] ) ;
}
/ * * Unlike - compositeGState , - drawGSstate fully respects the AppKit CTM but
2013-09-29 07:30:20 +00:00
doesn ' t support to use the receiver cairo target as the source . * /
/ * This method is required if - [ OpalContext supportsDrawGState ] returns YES * /
2013-09-29 17:10:26 +00:00
- ( void ) drawGState : ( OpalGState * ) source
fromRect : ( NSRect ) srcRect
toPoint : ( NSPoint ) destPoint
2013-09-29 07:30:20 +00:00
op : ( NSCompositingOperation ) op
fraction : ( CGFloat ) delta
destCGContext : ( CGContextRef ) destCGContext
2013-09-16 22:46:45 +00:00
{
2013-09-29 07:30:20 +00:00
// TODO : CairoGState has a lot more complex implementation .
// For now , we ' ll just call compositeGState and live
// with the fact that CTM is not respected .
2013-09-16 22:46:45 +00:00
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 17:10:26 +00:00
CGRect srcCGRect = CGRectMake ( srcRect . origin . x , srcRect . origin . y ,
2013-09-29 07:30:20 +00:00
srcRect . size . width , srcRect . size . height ) ;
CGRect destCGRect = CGRectMake ( destPoint . x , destPoint . y ,
srcRect . size . width , srcRect . size . height ) ;
2013-09-29 17:10:26 +00:00
CGImageRef backingImage = CGBitmapContextCreateImage ( [ source CGContext ] ) ;
2013-09-29 07:30:20 +00:00
CGImageRef subImage = CGImageCreateWithImageInRect ( backingImage , srcCGRect ) ;
// TODO : this ignores op
// TODO : this ignores delta
CGContextDrawImage ( destCGContext , destCGRect , subImage ) ;
CGImageRelease ( subImage ) ;
CGImageRelease ( backingImage ) ;
2013-09-16 22:46:45 +00:00
}
2013-09-17 19:42:01 +00:00
2013-09-29 17:10:26 +00:00
- ( void ) drawGState : ( OpalGState * ) source
fromRect : ( NSRect ) srcRect
toPoint : ( NSPoint ) destPoint
op : ( NSCompositingOperation ) op
fraction : ( CGFloat ) delta
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
CGContextRef destContexts [ 2 ] = { [ _opalSurface backingCGContext ] , [ _opalSurface x11CGContext ] } ;
int i ;
for ( i = 0 ; i < 1 ; i + + )
{
CGContextRef ctx = destContexts [ i ] ;
[ self drawGState : source
fromRect : srcRect
toPoint : destPoint
op : op
fraction : delta
destCGContext : ctx ] ;
}
}
2013-09-29 07:30:20 +00:00
- ( void ) compositerect : ( NSRect ) aRect
op : ( NSCompositingOperation ) op
2013-07-25 14:49:44 +00:00
{
2013-09-29 07:30:20 +00:00
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %@" , self , [ self class ] , __PRETTY _FUNCTION __ , NSStringFromRect ( aRect ) ) ;
2013-09-29 17:10:26 +00:00
CGContextRef cgctx = CGCTX ;
if ( cgctx )
{
CGContextSaveGState ( cgctx ) ;
OPContextSetIdentityCTM ( cgctx ) ;
// FIXME : Set operator
CGContextFillRect ( cgctx ,
CGRectMake ( aRect . origin . x ,
[ _opalSurface size ] . height - aRect . origin . y ,
aRect . size . width , aRect . size . height ) ) ;
CGContextRestoreGState ( cgctx ) ;
}
2013-07-23 23:18:48 +00:00
}
2013-09-23 18:04:06 +00:00
2013-09-29 07:30:20 +00:00
@ end
// MARK : Initialization methods
// MARK : -
@ implementation OpalGState ( InitializationMethods )
- ( void ) DPSinitgraphics
2013-09-23 18:04:06 +00:00
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 07:30:20 +00:00
[ super DPSinitgraphics ] ;
2013-09-29 17:10:26 +00:00
[ self DPSinitmatrix ] ;
2013-09-23 18:04:06 +00:00
}
2013-09-23 18:57:10 +00:00
2013-09-29 07:30:20 +00:00
/ * SOME NOTES :
- GState approximates a cairo context : a drawing state .
- Surface approximates a cairo surface : a place to draw things .
- CGContext seems to be a mix of these two : surface + state .
Should we unite these two somehow ? Can we unite these two somehow ?
Possibly not . We still need to support bitmap contexts , pdf contexts
etc which contain both state and contents .
So , we will still need surfaces ( containing CGContexts , hence including
state ) and GState as a wrapper around whatever context happens to be
the current one .
* /
/ * *
Makes the specified surface active in the current graphics state ,
ready for use . Also , sets the device offset to specified coordinates .
* * /
- ( void ) GSSetSurface : ( OpalSurface * ) opalSurface
: ( int ) x
: ( int ) y
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s - %@ %d %d" , self , [ self class ] , __PRETTY _FUNCTION __ , opalSurface , x , y ) ;
ASSIGN ( _opalSurface , opalSurface ) ;
[ self setOffset : NSMakePoint ( x , y ) ] ;
2013-09-29 17:10:26 +00:00
[ self DPSinitgraphics ] ;
2013-09-29 07:30:20 +00:00
}
- ( void ) GSCurrentSurface : ( OpalSurface * * ) surface
: ( int * ) x
: ( int * ) y
2013-09-23 18:57:10 +00:00
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
2013-09-29 07:30:20 +00:00
if ( x )
* x = offset . x ;
if ( y )
* y = offset . y ;
if ( surface )
{
* surface = _opalSurface ;
}
2013-09-23 18:57:10 +00:00
}
2013-09-29 07:30:20 +00:00
2013-07-15 15:24:04 +00:00
@ end
2013-09-29 07:30:20 +00:00
// MARK : Accessors
2013-07-15 15:24:04 +00:00
// MARK : -
2013-09-29 07:30:20 +00:00
@ implementation OpalGState ( Accessors )
2013-07-15 15:24:04 +00:00
2013-09-29 07:30:20 +00:00
- ( CGContextRef ) CGContext
{
if ( ! _opalSurface )
2013-09-29 17:10:26 +00:00
{
NSDebugMLLog ( @ "OpalGState" , @ "No OpalSurface" ) ;
return nil ;
}
else
{
CGContextRef context = [ _opalSurface CGContext ] ;
if ( ! context )
{
NSDebugMLLog ( @ "OpalGState" , @ "No OpalSurface CGContext" ) ;
return nil ;
}
return context ;
}
2013-09-29 07:30:20 +00:00
}
2013-07-15 15:24:04 +00:00
2013-09-29 07:30:20 +00:00
- ( OPGStateRef ) OPGState
2013-07-25 14:49:44 +00:00
{
2013-09-29 07:30:20 +00:00
return _opGState ;
}
- ( void ) setOPGState : ( OPGStateRef ) opGState
{
ASSIGN ( _opGState , opGState ) ;
2013-07-25 14:49:44 +00:00
}
2013-07-15 15:24:04 +00:00
@ end
2013-09-29 07:30:20 +00:00
// MARK : Non - required methods
// MARK : -
@ implementation OpalGState ( NonrequiredMethods )
2013-07-15 15:24:04 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPSgsave
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
if ( CGCTX )
2013-07-15 15:24:04 +00:00
{
2013-09-29 07:30:20 +00:00
CGContextSaveGState ( CGCTX ) ;
}
}
2013-07-15 15:24:04 +00:00
2013-09-29 07:30:20 +00:00
- ( void ) DPSgrestore
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
if ( CGCTX )
{
CGContextRestoreGState ( CGCTX ) ;
2013-07-15 15:24:04 +00:00
}
}
2013-09-29 07:30:20 +00:00
@ end
@ implementation OpalGState ( PatternColor )
- ( void * ) saveClip
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
CGRect * r = calloc ( sizeof ( CGRect ) , 1 ) ;
* r = CGContextGetClipBoundingBox ( CGCTX ) ;
return r ;
}
- ( void ) restoreClip : ( void * ) savedClip
{
NSDebugLLog ( @ "OpalGState" , @ "%p (%@): %s" , self , [ self class ] , __PRETTY _FUNCTION __ ) ;
OPContextResetClip ( CGCTX ) ;
CGContextClipToRect ( CGCTX , * ( CGRect * ) savedClip ) ;
free ( savedClip ) ;
}
2013-06-25 17:13:37 +00:00
@ end