1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2009 Henrik Tidefelt
21 #include "shapescore.h"
24 #include "shapesexceptions.h"
26 #include "simplepdfi.h"
27 #include "pdffunctiontypes.h"
35 using namespace Shapes
;
43 class Core_dashpattern
: public Lang::CoreFunction
46 Core_dashpattern( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
48 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
50 RefCountPtr
< std::list
< Concrete::Length
> > pat
;
54 Concrete::Length totalLength
= 0;
56 typedef const Lang::Length ArgType
;
62 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
);
65 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "This dashpattern length is negative." );
67 totalLength
+= arg
->get( );
68 pat
->push_back( arg
->get( ) );
71 if( totalLength
== 0 )
73 throw Exceptions::CoreOutOfRange( id_
, args
, args
.size( ) - 1, "The total length of the dashpattern is 0." );
77 Kernel::ContRef cont
= evalState
->cont_
;
78 cont
->takeValue( Kernel::ValueRef( new Lang::Dash( pat
, 0, 1 ) ),
83 class Core_noArrow
: public Lang::CoreFunction
86 Core_noArrow( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
88 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
90 const size_t ARITY
= 1;
91 CHECK_ARITY( args
, ARITY
, id_
);
93 // We don't even check the type here, even though we could have done so...
95 Kernel::ContRef cont
= evalState
->cont_
;
96 cont
->takeValue( Kernel::ValueRef( new Lang::Length( 0 ) ),
101 class Core_gray
: public Lang::CoreFunction
104 Core_gray( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
106 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
108 const size_t ARITY
= 1;
109 CHECK_ARITY( args
, ARITY
, id_
);
111 typedef const Lang::Float ArgType
;
112 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
116 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The gray level is less than 0." );
120 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The gray level is greater than 1." );
123 Kernel::ContRef cont
= evalState
->cont_
;
124 cont
->takeValue( Kernel::ValueRef( new Lang::Gray( Concrete::Gray( arg
->val_
) ) ),
129 class Core_rgb
: public Lang::CoreFunction
132 Core_rgb( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
134 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
136 const size_t ARITY
= 3;
137 CHECK_ARITY( args
, ARITY
, id_
);
139 double parts
[ ARITY
];
141 typedef const Lang::Float ArgType
;
142 double * dst( parts
);
147 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
);
150 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "This RGB level is less than 0." );
154 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "This RGB level is greater than 1." );
159 Kernel::ContRef cont
= evalState
->cont_
;
160 cont
->takeValue( Kernel::ValueRef( new Lang::RGB( Concrete::RGB( parts
[0], parts
[1], parts
[2] ) ) ),
165 class Core_cmyk
: public Lang::CoreFunction
168 Core_cmyk( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
170 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
172 const size_t ARITY
= 4;
173 CHECK_ARITY( args
, ARITY
, id_
);
175 double parts
[ ARITY
];
177 typedef const Lang::Float ArgType
;
178 double * dst( parts
);
183 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
);
186 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "This CMYK level is less than 0." );
190 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "This CMYK level is greater than 1." );
195 Kernel::ContRef cont
= evalState
->cont_
;
196 cont
->takeValue( Kernel::ValueRef( new Lang::CMYK( Concrete::CMYK( parts
[0], parts
[1], parts
[2], parts
[3] ) ) ),
201 class Core_shape
: public Lang::CoreFunction
204 Core_shape( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
206 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
208 const size_t ARITY
= 1;
209 CHECK_ARITY( args
, ARITY
, id_
);
211 typedef const Lang::Float ArgType
;
212 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
216 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The alpha level is less than 0." );
220 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The alpha level is greater than 1." );
223 Kernel::ContRef cont
= evalState
->cont_
;
224 cont
->takeValue( Kernel::ValueRef( new Lang::Alpha( true, arg
->val_
) ),
229 class Core_opacity
: public Lang::CoreFunction
232 Core_opacity( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
234 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
236 const size_t ARITY
= 1;
237 CHECK_ARITY( args
, ARITY
, id_
);
239 typedef const Lang::Float ArgType
;
240 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
244 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The alpha level is less than 0." );
248 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The alpha level is greater than 1." );
251 Kernel::ContRef cont
= evalState
->cont_
;
252 cont
->takeValue( Kernel::ValueRef( new Lang::Alpha( false, arg
->val_
) ),
257 class Core_alphamask
: public Lang::CoreFunction
260 Core_alphamask( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
261 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
263 formals_
->appendEvaluatedCoreFormal( "group", Kernel::THE_SLOT_VARIABLE
);
264 formals_
->appendEvaluatedCoreFormal( "transform", Kernel::THE_VOID_VARIABLE
);
267 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
269 args
.applyDefaults( callLoc
);
273 typedef const Lang::TransparencyGroup ArgType0
;
274 RefCountPtr
< ArgType0
> group
= Helpers::down_cast_CoreArgument
< ArgType0
>( id_
, args
, i
, callLoc
);
277 typedef const Lang::PDF_Function ArgType1
;
278 RefCountPtr
< ArgType1
> transform
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, i
, callLoc
, true );
279 if( transform
!= NullPtr
< ArgType1
>( ) &&
280 ! transform
->matchesDimensions( 1, 1 ) )
282 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "The transform function must have dimensions ( 1, 1 )." );
285 Kernel::ContRef cont
= evalState
->cont_
;
286 cont
->takeValue( Kernel::ValueRef( new Lang::SoftMask( Lang::SoftMask::ALPHA
,
288 RefCountPtr
< const Lang::Color
>( NullPtr
< const Lang::Color
>( ) ),
294 class Core_luminositymask
: public Lang::CoreFunction
297 Core_luminositymask( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
298 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
300 formals_
->appendEvaluatedCoreFormal( "group", Kernel::THE_SLOT_VARIABLE
);
301 formals_
->appendEvaluatedCoreFormal( "background", Kernel::THE_VOID_VARIABLE
);
302 formals_
->appendEvaluatedCoreFormal( "transform", Kernel::THE_VOID_VARIABLE
);
305 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
307 args
.applyDefaults( callLoc
);
311 typedef const Lang::TransparencyGroup ArgType0
;
312 RefCountPtr
< ArgType0
> group
= Helpers::down_cast_CoreArgument
< ArgType0
>( id_
, args
, i
, callLoc
);
313 if( group
->colorSpace( )->isInherent( ) )
315 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "The transparency group must not use an inherited blend space." );
319 typedef const Lang::Color ArgType1
;
320 RefCountPtr
< ArgType1
> background
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, i
, callLoc
, true );
323 typedef const Lang::PDF_Function ArgType2
;
324 RefCountPtr
< ArgType2
> transform
= Helpers::down_cast_CoreArgument
< ArgType2
>( id_
, args
, i
, callLoc
, true );
325 if( transform
!= NullPtr
< ArgType2
>( ) &&
326 ! transform
->matchesDimensions( 1, 1 ) )
328 throw Exceptions::CoreOutOfRange( id_
, args
, i
, "The transform function must have dimensions ( 1, 1 )." );
331 Kernel::ContRef cont
= evalState
->cont_
;
332 cont
->takeValue( Kernel::ValueRef( new Lang::SoftMask( Lang::SoftMask::LUMINOSITY
,
344 RefCountPtr
< const Lang::CoreFunction
> Lang::THE_NO_ARROW( new Lang::Core_noArrow( Lang::THE_NAMESPACE_Shapes_Graphics
, "NO_ARROW" ) );
347 Kernel::registerCore_state( Kernel::Environment
* env
)
349 env
->initDefineCoreFunction( new Lang::Core_dashpattern( Lang::THE_NAMESPACE_Shapes_Traits
, "dashpattern" ) );
350 env
->initDefineCoreFunction( new Lang::Core_gray( Lang::THE_NAMESPACE_Shapes_Traits
, "gray" ) );
351 env
->initDefineCoreFunction( new Lang::Core_rgb( Lang::THE_NAMESPACE_Shapes_Traits
, "rgb" ) );
352 env
->initDefineCoreFunction( new Lang::Core_cmyk( Lang::THE_NAMESPACE_Shapes_Traits
, "cmyk" ) );
353 env
->initDefineCoreFunction( new Lang::Core_shape( Lang::THE_NAMESPACE_Shapes_Traits
, "alphashape" ) );
354 env
->initDefineCoreFunction( new Lang::Core_opacity( Lang::THE_NAMESPACE_Shapes_Traits
, "alphaopacity" ) );
355 env
->initDefineCoreFunction( new Lang::Core_alphamask( Lang::THE_NAMESPACE_Shapes_Traits
, "alphamask" ) );
356 env
->initDefineCoreFunction( new Lang::Core_luminositymask( Lang::THE_NAMESPACE_Shapes_Traits
, "luminositymask" ) );