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, 2010 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
25 #include "shapesexceptions.h"
27 #include "simplepdfi.h"
28 #include "autoonoff.h"
39 using namespace Shapes
;
46 RefCountPtr
< const Lang::TransparencyGroup
>
47 newSolidTransparencyGroup( const RefCountPtr
< const Lang::Drawable2D
> & obj2
, const RefCountPtr
< const Lang::Drawable2D
> & obj1
);
48 RefCountPtr
< const Lang::TransparencyGroup
>
49 newSolidTransparencyGroup( const RefCountPtr
< const Lang::Drawable2D
> & obj3
, const RefCountPtr
< const Lang::Drawable2D
> & obj2
, const RefCountPtr
< const Lang::Drawable2D
> & obj1
);
51 void stroke_helper_2D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
);
52 void stroke_helper_3D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
);
61 class Core_spot
: public Lang::CoreFunction
64 Core_spot( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
66 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
68 const size_t ARITY
= 1;
69 CHECK_ARITY( args
, ARITY
, id_
);
71 typedef const Lang::Coords2D ArgType
;
72 RefCountPtr
< ArgType
> p
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
74 ElementaryPath2D
* pth
= new ElementaryPath2D
;
75 pth
->push_back( new Concrete::PathPoint2D( p
->x_
.get( ), p
->y_
.get( ) ) );
76 if( Kernel::allowSingletonPaths
)
82 pth
->push_back( new Concrete::PathPoint2D( p
->x_
.get( ), p
->y_
.get( ) ) );
85 Kernel::GraphicsState
* capState( new Kernel::GraphicsState( *evalState
->dyn_
->getGraphicsState( ) ) );
86 capState
->cap_
= Lang::CapStyle::CAP_ROUND
;
88 Kernel::ContRef cont
= evalState
->cont_
;
89 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D
90 ( RefCountPtr
< const Kernel::GraphicsState
>( capState
),
91 RefCountPtr
< const Lang::ElementaryPath2D
>( pth
),
97 class Core_stroke
: public Lang::CoreFunction
101 Core_stroke( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
, bool fill
)
102 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) ), fill_( fill
)
104 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
105 formals_
->appendEvaluatedCoreFormal( "head", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_NO_ARROW
) ) );
106 formals_
->appendEvaluatedCoreFormal( "tail", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_NO_ARROW
) ) );
110 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
112 args
.applyDefaults( callLoc
);
116 typedef const Lang::ElementaryPath2D ArgType
;
117 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
118 Helpers::stroke_helper_2D( evalState
, arg
, args
, fill_
, callLoc
);
121 catch( const NonLocalExit::NotThisType
& ball
)
123 /* Wrong type; never mind!.. but see below!
129 typedef const Lang::ElementaryPath3D ArgType
;
130 RefCountPtr
< ArgType
> arg
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
131 Helpers::stroke_helper_3D( evalState
, arg
, args
, fill_
, callLoc
);
134 catch( const NonLocalExit::NotThisType
& ball
)
136 /* Wrong type; never mind!.. but see below!
140 const char * paintCmd
= fill_
? "B" : "S";
144 typedef const Lang::MultiPath2D ArgType
;
145 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
146 RefCountPtr
< const Lang::Function
> arrowHead
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( id_
, args
, 1, callLoc
);
147 RefCountPtr
< const Lang::Function
> arrowTail
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( id_
, args
, 2, callLoc
);
148 if( arrowHead
!= Lang::THE_NO_ARROW
||
149 arrowTail
!= Lang::THE_NO_ARROW
)
151 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrowheads/tails are not supported for composite paths." ) );
153 Kernel::ContRef cont
= evalState
->cont_
;
154 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, paintCmd
) ),
158 catch( const NonLocalExit::NotThisType
& ball
)
160 /* Wrong type; never mind!.. but see below!
166 typedef const Lang::MultiPath3D ArgType
;
167 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
168 RefCountPtr
< const Lang::Function
> arrowHead
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( id_
, args
, 1, callLoc
);
169 RefCountPtr
< const Lang::Function
> arrowTail
= Helpers::down_cast_CoreArgument
< const Lang::Function
>( id_
, args
, 2, callLoc
);
170 if( arrowHead
!= Lang::THE_NO_ARROW
||
171 arrowTail
!= Lang::THE_NO_ARROW
)
173 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrowheads/tails are not supported for composite paths." ) );
175 Kernel::ContRef cont
= evalState
->cont_
;
176 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, paintCmd
) ),
180 catch( const NonLocalExit::NotThisType
& ball
)
182 /* Wrong type; never mind!.. but see below!
186 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::ElementaryPath3D::staticTypeName( ) ) );
190 class Core_fill
: public Lang::CoreFunction
193 Core_fill( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
194 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
196 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
197 formals_
->appendEvaluatedCoreFormal( "tiebreaker", Kernel::THE_VOID_VARIABLE
);
201 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
203 args
.applyDefaults( callLoc
);
205 RefCountPtr
< const Lang::Length
> tiebreaker
= Helpers::down_cast_CoreArgument
< const Lang::Length
>( id_
, args
, 1, callLoc
, true );
209 typedef const Lang::ElementaryPath2D ArgType
;
210 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
211 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
213 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "The tiebreaker may not specified for 2D paths." );
215 Kernel::ContRef cont
= evalState
->cont_
;
216 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f" ) ),
220 catch( const NonLocalExit::NotThisType
& ball
)
222 /* Wrong type; never mind!.. but see below!
228 typedef const Lang::ElementaryPath3D ArgType
;
229 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
230 Concrete::Length tiebreakerVal
= Concrete::ZERO_LENGTH
;
231 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
233 tiebreakerVal
= tiebreaker
->get( );
235 Kernel::ContRef cont
= evalState
->cont_
;
236 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, "f", tiebreakerVal
) ),
240 catch( const NonLocalExit::NotThisType
& ball
)
242 /* Wrong type; never mind!.. but see below!
248 typedef const Lang::MultiPath2D ArgType
;
249 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
250 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
252 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "The tiebreaker may not specified for 2D paths." );
254 Kernel::ContRef cont
= evalState
->cont_
;
255 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f" ) ),
259 catch( const NonLocalExit::NotThisType
& ball
)
261 /* Wrong type; never mind!.. but see below!
267 typedef const Lang::MultiPath3D ArgType
;
268 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
269 Concrete::Length tiebreakerVal
= Concrete::ZERO_LENGTH
;
270 if( tiebreaker
!= NullPtr
< const Lang::Length
>( ) )
272 tiebreakerVal
= tiebreaker
->get( );
274 Kernel::ContRef cont
= evalState
->cont_
;
275 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, "f", tiebreakerVal
) ),
279 catch( const NonLocalExit::NotThisType
& ball
)
281 /* Wrong type; never mind!.. but see below!
285 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::MultiPath2D::staticTypeName( ), Lang::MultiPath3D::staticTypeName( ) ) );
289 class Core_fillstar
: public Lang::CoreFunction
292 Core_fillstar( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
294 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
296 const size_t ARITY
= 1;
297 CHECK_ARITY( args
, ARITY
, id_
);
301 typedef const Lang::ElementaryPath2D ArgType
;
302 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
303 Kernel::ContRef cont
= evalState
->cont_
;
304 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f*" ) ),
308 catch( const NonLocalExit::NotThisType
& ball
)
310 /* Wrong type; never mind!.. but see below!
316 typedef const Lang::MultiPath2D ArgType
;
317 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
318 Kernel::ContRef cont
= evalState
->cont_
;
319 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, "f*" ) ),
323 catch( const NonLocalExit::NotThisType
& ball
)
325 /* Wrong type; never mind!.. but see below!
329 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::MultiPath2D::staticTypeName( ) ) );
333 class Core_facetnormal
: public Lang::CoreFunction
336 Core_facetnormal( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
337 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
339 formals_
->appendEvaluatedCoreFormal( "location", Kernel::THE_SLOT_VARIABLE
);
340 formals_
->appendEvaluatedCoreFormal( "normal", Kernel::THE_SLOT_VARIABLE
);
344 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
346 args
.applyDefaults( callLoc
);
348 typedef const Lang::Coords3D LocationType
;
349 typedef const Lang::FloatTriple NormalType
;
351 RefCountPtr
< LocationType
> location
= Helpers::down_cast_CoreArgument
< LocationType
>( id_
, args
, 0, callLoc
, true );
352 RefCountPtr
< NormalType
> normal
= Helpers::down_cast_CoreArgument
< NormalType
>( id_
, args
, 1, callLoc
, true );
354 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
356 Kernel::ContRef cont
= evalState
->cont_
;
358 RefCountPtr
< const Lang::Color
> nonStroking
= evalState
->dyn_
->getGraphicsState( )->nonStrokingColor_
;
360 /* If both @nonstroking and @autointensity are Gray, then we create a FacetNormalGray, otherwise colors are converted when needed to RGB so that we can create
366 typedef const Lang::Gray ColorType
;
367 RefCountPtr
< ColorType
> lightMultiply
= Helpers::try_cast_CoreArgument
< ColorType
>( nonStroking
);
369 cont
->takeValue( Kernel::ValueRef( new Lang::FacetNormalGray( Concrete::Coords3D( location
->x_
.get( ),
371 location
->z_
.get( ) ),
372 facetState
->reflections_
,
373 Concrete::UnitFloatTriple( normal
->x_
, normal
->y_
, normal
->z_
),
374 lightMultiply
->components( ),
375 facetState
->autoScattering_
,
376 Helpers::try_cast_CoreArgument
< ColorType
>( facetState
->autoIntensity_
)->components( ) ) ),
380 catch( const NonLocalExit::NotThisType
& ball
)
382 /* Wrong type; never mind!.. but see below!
386 // When we reach here, we shall try to convert all colors to RGB.
388 typedef const Lang::RGB ColorType
;
389 Concrete::RGB
lightMultiply( 0, 0, 0 );
392 lightMultiply
= Helpers::try_cast_CoreArgument
< ColorType
>( nonStroking
)->components( );
395 catch( const NonLocalExit::NotThisType
& ball
)
397 /* Wrong type; never mind!.. but see below!
402 double a
= Helpers::try_cast_CoreArgument
< const Lang::Gray
>( nonStroking
)->components( ).gr_
;
403 lightMultiply
= Concrete::RGB( a
, a
, a
);
406 catch( const NonLocalExit::NotThisType
& ball
)
408 /* Wrong type; never mind!.. but see below!
411 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, id_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
,
412 nonStroking
->getTypeName( ),
413 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
416 Concrete::RGB
autoIntensity( 0, 0, 0 );
419 autoIntensity
= Helpers::try_cast_CoreArgument
< ColorType
>( facetState
->autoIntensity_
)->components( );
422 catch( const NonLocalExit::NotThisType
& ball
)
424 /* Wrong type; never mind!.. but see below!
429 double a
= Helpers::try_cast_CoreArgument
< const Lang::Gray
>( facetState
->autoIntensity_
)->components( ).gr_
;
430 autoIntensity
= Concrete::RGB( a
, a
, a
);
433 catch( const NonLocalExit::NotThisType
& ball
)
435 /* Wrong type; never mind!.. but see below!
438 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, id_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
,
439 nonStroking
->getTypeName( ),
440 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
443 cont
->takeValue( Kernel::ValueRef( new Lang::FacetNormalRGB( Concrete::Coords3D( location
->x_
.get( ),
445 location
->z_
.get( ) ),
446 facetState
->reflections_
,
447 Concrete::UnitFloatTriple( normal
->x_
, normal
->y_
, normal
->z_
),
449 facetState
->autoScattering_
,
456 class Core_facet
: public Lang::CoreFunction
459 Core_facet( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
460 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
462 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
463 formals_
->appendEvaluatedCoreFormal( "n1", Kernel::THE_VOID_VARIABLE
);
464 formals_
->appendEvaluatedCoreFormal( "n2", Kernel::THE_VOID_VARIABLE
);
465 formals_
->appendEvaluatedCoreFormal( "n3", Kernel::THE_VOID_VARIABLE
);
466 formals_
->appendEvaluatedCoreFormal( "tiebreaker", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( Concrete::ZERO_LENGTH
) ) ) ) );
467 formals_
->appendEvaluatedCoreFormal( "double", Kernel::THE_VOID_VARIABLE
);
471 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
473 args
.applyDefaults( callLoc
);
475 // Note that the <double> defaults to false if and only if there is at least one normal specifyed, and all normals agree on what is the outward normal.
477 typedef const Lang::ElementaryPath3D PathType
;
478 typedef const Lang::FacetNormalGray GrayNormalType
;
479 typedef const Lang::FacetNormalRGB RGBNormalType
;
480 typedef const Lang::Length TiebreakerType
;
481 typedef const Lang::Boolean DoubleSidedType
;
483 RefCountPtr
< PathType
> path
= Helpers::elementaryPathCast3D( id_
, args
, 0, callLoc
);
486 bool foundColor
= false;
487 size_t numNormals
= 0;
488 RefCountPtr
< GrayNormalType
> nGray1
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
489 RefCountPtr
< GrayNormalType
> nGray2
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
490 RefCountPtr
< GrayNormalType
> nGray3
= RefCountPtr
< GrayNormalType
>( NullPtr
< GrayNormalType
>( ) );
491 RefCountPtr
< RGBNormalType
> nRGB1
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
492 RefCountPtr
< RGBNormalType
> nRGB2
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
493 RefCountPtr
< RGBNormalType
> nRGB3
= RefCountPtr
< RGBNormalType
>( NullPtr
< RGBNormalType
>( ) );
494 Concrete::UnitFloatTriple
d1( 0, 0, 0, 1. );
495 Concrete::UnitFloatTriple
d2( 0, 0, 0, 1. );
496 Concrete::UnitFloatTriple
d3( 0, 0, 0, 1. );
499 typedef GrayNormalType NormalType
;
500 nGray1
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 1 ), true );
501 nGray2
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 2 ), true );
502 nGray3
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 3 ), true );
503 // If we reach here, numNormals will be zero.
504 if( nGray1
!= NullPtr
< NormalType
>( ) )
506 d1
= nGray1
->normal( );
509 if( nGray2
!= NullPtr
< NormalType
>( ) )
513 throw Exceptions::CoreOutOfRange( id_
, args
, 2, "The normal n1 must be provided before providing n2." );
515 d2
= nGray2
->normal( );
518 if( nGray3
!= NullPtr
< NormalType
>( ) )
522 throw Exceptions::CoreOutOfRange( id_
, args
, 2, "The normals n1 and n2 must be provided before providing n3." );
524 d3
= nGray3
->normal( );
530 catch( const NonLocalExit::NotThisType
& ball
)
532 /* Wrong type; never mind!.. but see below!
539 typedef RGBNormalType NormalType
;
540 nRGB1
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 1 ), true );
541 nRGB2
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 2 ), true );
542 nRGB3
= Helpers::try_cast_CoreArgument
< NormalType
>( args
.getValue( 3 ), true );
543 // If we reach here, numNormals will be zero.
544 if( nRGB1
!= NullPtr
< NormalType
>( ) )
547 d1
= nRGB1
->normal( );
549 if( nRGB2
!= NullPtr
< NormalType
>( ) )
553 throw Exceptions::CoreOutOfRange( id_
, args
, 2, "The normal n1 must be provided before providing n2." );
556 d2
= nRGB2
->normal( );
558 if( nRGB3
!= NullPtr
< NormalType
>( ) )
562 throw Exceptions::CoreOutOfRange( id_
, args
, 2, "The normals n1 and n2 must be provided before providing n3." );
565 d3
= nRGB3
->normal( );
569 catch( const NonLocalExit::NotThisType
& ball
)
571 /* Wrong type; never mind!.. but see below!
577 throw Exceptions::MiscellaneousRequirement( "The procided facet normals must either be all gray or all RGB." );
579 RefCountPtr
< const Lang::Color
> nonStroking
= evalState
->dyn_
->getGraphicsState( )->nonStrokingColor_
;
580 if( numNormals
== 0 )
582 isRGB
= dynamic_cast< const Lang::RGB
* >( nonStroking
.getPtr( ) ) != 0;
584 dynamic_cast< const Lang::Gray
* >( nonStroking
.getPtr( ) ) == 0 )
586 throw Exceptions::CoreDynamicTypeMismatch( callLoc
, id_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
,
587 nonStroking
->getTypeName( ),
588 Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
592 RefCountPtr
< TiebreakerType
> tiebreaker
= Helpers::down_cast_CoreArgument
< TiebreakerType
>( id_
, args
, 4, callLoc
);
593 RefCountPtr
< DoubleSidedType
> doubleSided
= Helpers::down_cast_CoreArgument
< DoubleSidedType
>( id_
, args
, 5, callLoc
, true );
595 if( path
->size( ) < 3 )
597 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "A facet path must have at least 3 points." );
599 if( ! path
->isClosed( ) )
601 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "A facet path must be closed." );
604 for( PathType::const_iterator i
= path
->begin( ); i
!= path
->end( ); ++i
)
606 if( (*i
)->front_
!= (*i
)->mid_
|| (*i
)->rear_
!= (*i
)->mid_
)
608 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "A facet path must be a polygon." );
613 Kernel::ContRef cont
= evalState
->cont_
;
615 Concrete::Coords3D
p0( 0, 0, 0 );
616 Concrete::Coords3D
p1( 0, 0, 0 );
617 Concrete::Coords3D
p2( 0, 0, 0 );
618 path
->getRepresentativePoints( Lang::THE_3D_IDENTITY
, & p0
, & p1
, & p2
);
620 Concrete::UnitFloatTriple
normal( 1., 0., 0., 1. );
623 normal
= Concrete::crossDirection( p2
- p0
, p1
- p0
);
625 catch( const NonLocalExit::CrossDirectionOfParallel
& ball
)
627 // This means that the crossDirection called failed because the vectors were parallel.
628 // A polygon of lower dimension is invisible, so we may just return an empty object.
629 cont
->takeValue( Lang::THE_NULL3D
,
635 if( doubleSided
!= NullPtr
< DoubleSidedType
>( ) )
637 isDoubleSided
= doubleSided
->val_
;
641 if( numNormals
== 0 )
643 isDoubleSided
= true;
647 bool allAgree
= true;
648 bool n1Agree
= Concrete::inner( normal
, d1
) > 0;
649 if( d2
.normSquaredThatOughtToBeOne( ) > 0.5 )
651 allAgree
= allAgree
&& ( ( Concrete::inner( normal
, d2
) > 0 ) == n1Agree
);
653 if( d3
.normSquaredThatOughtToBeOne( ) > 0.5 )
655 allAgree
= allAgree
&& ( ( Concrete::inner( normal
, d3
) > 0 ) == n1Agree
);
661 normal
= normal
.reverse( );
663 isDoubleSided
= false;
667 WARN_OR_THROW( Exceptions::MiscellaneousRequirement( "A facet without explicitly specified double-sidedness has normals pointing in crazy directions, and will be treated as double-sided." ) );
668 isDoubleSided
= true;
675 typedef RGBNormalType NormalType
;
676 RefCountPtr
< NormalType
> n1
= nRGB1
;
677 RefCountPtr
< NormalType
> n2
= nRGB2
;
678 RefCountPtr
< NormalType
> n3
= nRGB3
;
679 RefCountPtr
< const Computation::FacetInterpolatorRGB
> interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>( NullPtr
< const Computation::FacetInterpolatorRGB
>( ) );
681 if( numNormals
== 0 )
683 typedef const Lang::RGB ColorType
;
684 RefCountPtr
< ColorType
> lightMultiply
= Helpers::down_cast_CoreDynamic
< ColorType
>( id_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
, nonStroking
, callLoc
);
685 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
687 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
688 ( new Computation::FacetInterpolatorRGB1
689 ( RefCountPtr
< const Lang::FacetNormalRGB
>
690 ( new Lang::FacetNormalRGB
691 ( (1./3)*( p0
+ p1
+ p2
),
692 facetState
->reflections_
,
694 lightMultiply
->components( ),
695 facetState
->autoScattering_
,
696 Helpers::down_cast_CoreDynamic
< ColorType
>( id_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
, facetState
->autoIntensity_
, callLoc
)->components( ) ) ) ) );
698 else if( numNormals
== 1 )
700 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
701 ( new Computation::FacetInterpolatorRGB1( n1
) );
703 else if( numNormals
== 2 )
705 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
706 ( new Computation::FacetInterpolatorRGB2( n1
, n2
) );
708 else if( numNormals
== 3 )
710 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorRGB
>
711 ( new Computation::FacetInterpolatorRGB3( n1
, n2
, n3
) );
715 throw Exceptions::InternalError( "Number of facet normals is out of range!" );
718 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
720 cont
->takeValue( Kernel::ValueRef( new Lang::SingleSided3DRGB( path
, interpolator
,
721 ! isDoubleSided
, // Note that this argument refers to single-sidedness
722 normal
, Concrete::inner( normal
, p0
),
724 facetState
->viewResolution_
,
725 facetState
->shadeOrder_
) ),
730 typedef GrayNormalType NormalType
;
731 RefCountPtr
< NormalType
> n1
= nGray1
;
732 RefCountPtr
< NormalType
> n2
= nGray2
;
733 RefCountPtr
< NormalType
> n3
= nGray3
;
734 RefCountPtr
< const Computation::FacetInterpolatorGray
> interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>( NullPtr
< const Computation::FacetInterpolatorGray
>( ) );
736 if( numNormals
== 0 )
738 typedef const Lang::Gray ColorType
;
739 RefCountPtr
< ColorType
> lightMultiply
= Helpers::down_cast_CoreDynamic
< ColorType
>( id_
, Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
, nonStroking
, callLoc
);
740 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
742 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
743 ( new Computation::FacetInterpolatorGray1
744 ( RefCountPtr
< const Lang::FacetNormalGray
>
745 ( new Lang::FacetNormalGray
746 ( (1./3)*( p0
+ p1
+ p2
),
747 facetState
->reflections_
,
749 lightMultiply
->components( ),
750 facetState
->autoScattering_
,
751 Helpers::down_cast_CoreDynamic
< ColorType
>( id_
, Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
, facetState
->autoIntensity_
, callLoc
)->components( ) ) ) ) );
754 else if( numNormals
== 1 )
756 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
757 ( new Computation::FacetInterpolatorGray1( n1
) );
759 else if( numNormals
== 2 )
761 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
762 ( new Computation::FacetInterpolatorGray2( n1
, n2
) );
764 else if( numNormals
== 3 )
766 interpolator
= RefCountPtr
< const Computation::FacetInterpolatorGray
>
767 ( new Computation::FacetInterpolatorGray3( n1
, n2
, n3
) );
771 throw Exceptions::InternalError( "Number of facet normals is out of range!" );
774 RefCountPtr
< const Kernel::FacetState
> facetState
= evalState
->dyn_
->getFacetState( );
776 cont
->takeValue( Kernel::ValueRef( new Lang::SingleSided3DGray( path
, interpolator
,
777 ! isDoubleSided
, // Note that this argument refers to single-sidedness
778 normal
, Concrete::inner( normal
, p0
),
780 facetState
->viewResolution_
,
781 facetState
->shadeOrder_
) ),
787 class Core_from3Dto2D
: public Lang::CoreFunction
790 Core_from3Dto2D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
792 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
794 const size_t ARITY
= 1;
795 CHECK_ARITY( args
, ARITY
, id_
);
797 typedef const Lang::Geometric3D ArgType
;
798 RefCountPtr
< ArgType
> obj
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
800 Kernel::ContRef cont
= evalState
->cont_
;
801 cont
->takeValue( obj
->to2D( evalState
->dyn_
, obj
),
806 class Core_from2Dto3D
: public Lang::CoreFunction
809 Core_from2Dto3D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
811 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
813 const size_t ARITY
= 1;
814 CHECK_ARITY( args
, ARITY
, id_
);
816 typedef const Lang::Geometric2D ArgType
;
817 RefCountPtr
< ArgType
> obj
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
819 Kernel::ContRef cont
= evalState
->cont_
;
820 cont
->takeValue( obj
->to3D( obj
),
825 class Core_facing2Din3D
: public Lang::CoreFunction
828 Core_facing2Din3D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
829 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
831 formals_
->appendEvaluatedCoreFormal( "obj", Kernel::THE_SLOT_VARIABLE
);
832 formals_
->appendEvaluatedCoreFormal( "scale", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_FALSE
) ) );
833 formals_
->appendEvaluatedCoreFormal( "distort", Kernel::VariableHandle( new Kernel::Variable( Lang::THE_FALSE
) ) );
836 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
838 args
.applyDefaults( callLoc
);
842 typedef const Lang::Drawable2D ArgType
;
843 Kernel::ContRef cont
= evalState
->cont_
;
844 cont
->takeValue( Kernel::ValueRef( new Lang::Facing2Din3D( Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) ),
845 Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( id_
, args
, 1, callLoc
)->val_
,
846 Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( id_
, args
, 2, callLoc
)->val_
) ),
850 catch( const NonLocalExit::NotThisType
& ball
)
852 /* Wrong type; never mind!.. but see below!
858 typedef const Lang::Function ArgType
;
859 Kernel::ContRef cont
= evalState
->cont_
;
860 /* The scale and distort arguments will simply be ignored.
862 cont
->takeValue( Kernel::ValueRef( new Lang::FacingFunction3D( evalState
->dyn_
, Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) ) ) ),
866 catch( const NonLocalExit::NotThisType
& ball
)
868 /* Wrong type; never mind!.. but see below!
872 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Drawable2D::staticTypeName( ), Lang::Function::staticTypeName( ) ) );
876 class Core_bboxed
: public Lang::CoreFunction
879 Core_bboxed( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
880 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
882 formals_
->appendEvaluatedCoreFormal( "obj", Kernel::THE_SLOT_VARIABLE
);
883 formals_
->appendEvaluatedCoreFormal( "path", Kernel::THE_SLOT_VARIABLE
);
884 formals_
->appendEvaluatedCoreFormal( "type", Helpers::newValHandle( new Lang::Symbol( "bounding" ) ) );
887 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
889 args
.applyDefaults( callLoc
);
893 typedef const Lang::Drawable2D ArgType1
;
894 RefCountPtr
< ArgType1
> obj
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
898 typedef const Lang::ElementaryPath2D ArgType2
;
899 RefCountPtr
< ArgType2
> p
= Helpers::elementaryPathCast2D( id_
, args
, argsi
, callLoc
);
902 typedef const Lang::Symbol TypeType
;
903 RefCountPtr
< TypeType
> type
= Helpers::down_cast_CoreArgument
< TypeType
>( id_
, args
, argsi
, callLoc
);
904 Lang::BBoxed2D::BoxType bt
= Lang::BBoxed2D::BOUNDING
;
905 static Lang::Symbol
BOUNDING( "bounding" );
906 static Lang::Symbol
BLEED( "bleed" );
907 static Lang::Symbol
BOTH( "both" );
908 if( *type
== BOUNDING
)
910 bt
= Lang::BBoxed2D::BOUNDING
;
912 else if( *type
== BLEED
)
914 bt
= Lang::BBoxed2D::BLEED
;
916 else if( *type
== BOTH
)
918 bt
= Lang::BBoxed2D::BOTH
;
922 std::ostringstream msg
;
923 msg
<< "The only allowed symbols are { " ;
924 BOUNDING
.show( msg
);
930 throw Exceptions::CoreOutOfRange( id_
, args
, argsi
, strrefdup( msg
) );
933 Kernel::ContRef cont
= evalState
->cont_
;
934 cont
->takeValue( Kernel::ValueRef( new Lang::BBoxed2D( obj
, p
, bt
) ),
939 class Core_clip
: public Lang::CoreFunction
942 typedef enum { NONZERO_WINDING
, EVEN_ODD
} WindingRule
;
944 WindingRule windingRule_
;
946 Core_clip( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
, WindingRule windingRule
)
947 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) ),
948 windingRule_( windingRule
)
950 formals_
->appendEvaluatedCoreFormal( "obj", Kernel::THE_SLOT_VARIABLE
);
951 formals_
->appendEvaluatedCoreFormal( "mask", Kernel::THE_SLOT_VARIABLE
);
954 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
956 args
.applyDefaults( callLoc
);
960 typedef const Lang::Drawable2D ArgType1
;
961 RefCountPtr
< ArgType1
> obj
= Helpers::down_cast_CoreArgument
< ArgType1
>( id_
, args
, argsi
, callLoc
);
963 RefCountPtr
< Lang::Clipped2D
> res( new Lang::Clipped2D( obj
, ( windingRule_
== NONZERO_WINDING
) ? "W" : "W*" ) );
968 typedef const Lang::ElementaryPath2D ArgType
;
969 RefCountPtr
< ArgType
> path
= Helpers::elementaryPathTry2D( args
.getValue( argsi
) );
970 res
->addSubPath( path
);
973 catch( const NonLocalExit::NotThisType
& ball
)
975 /* Wrong type; never mind!.. but see below!
981 typedef const Lang::MultiPath2D ArgType
;
982 RefCountPtr
< ArgType
> path
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
983 for( Lang::MultiPath2D::const_iterator i
= path
->begin( ); i
!= path
->end( ); ++i
)
986 typedef const Lang::ElementaryPath2D ArgType
;
987 RefCountPtr
< ArgType
> subpath
= (*i
).down_cast
< ArgType
>( );
988 if( subpath
!= NullPtr
< ArgType
>( ) )
990 res
->addSubPath( subpath
);
996 typedef const Lang::Connection2D ArgType
;
997 ArgType
* subpath
= dynamic_cast< ArgType
* >( (*i
).getPtr( ) );
1000 res
->addSubPath( subpath
->getElementaryPath( ) );
1004 throw Exceptions::InternalError( "clip: Encountered a subpath of unexpected type" );
1008 catch( const NonLocalExit::NotThisType
& ball
)
1010 /* Wrong type; never mind!.. but see below!
1014 if( windingRule_
== EVEN_ODD
)
1016 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, argsi
, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::MultiPath2D::staticTypeName( ) ) );
1021 typedef const Lang::Text ArgType
;
1022 RefCountPtr
< ArgType
> mask
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
1023 Kernel::ContRef cont
= evalState
->cont_
;
1024 cont
->takeValue( RefCountPtr
< Lang::TextMasked2D
>( new Lang::TextMasked2D( obj
, mask
) ),
1028 catch( const NonLocalExit::NotThisType
& ball
)
1030 /* Wrong type; never mind!.. but see below!
1036 typedef const Lang::SoftMask ArgType
;
1037 RefCountPtr
< ArgType
> mask
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
1038 Kernel::ContRef cont
= evalState
->cont_
;
1039 cont
->takeValue( RefCountPtr
< Lang::SoftMasked2D
>( new Lang::SoftMasked2D( obj
, mask
) ),
1043 catch( const NonLocalExit::NotThisType
& ball
)
1045 /* Wrong type; never mind!.. but see below!
1049 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, argsi
, Helpers::typeSetString( Lang::ElementaryPath2D::staticTypeName( ), Lang::MultiPath2D::staticTypeName( ), Lang::Text::staticTypeName( ), Lang::SoftMask::staticTypeName( ) ) );
1052 Kernel::ContRef cont
= evalState
->cont_
;
1053 cont
->takeValue( res
,
1067 class ArrowheadReceiverFormals2D
: public Kernel::EvaluatedFormals
1070 ArrowheadReceiverFormals2D( )
1071 : Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< Arrowhead receiver >" ), true )
1073 appendEvaluatedCoreFormal( "picture", Kernel::THE_SLOT_VARIABLE
);
1074 appendEvaluatedCoreFormal( "cut", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( 0 ) ) ) ) );
1078 ArrowheadReceiverFormals2D theArrowheadReceiverFormals2D
;
1080 class Stroke2DCont_tail
: public Kernel::ForcedStructureContinuation
1082 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1083 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1084 Kernel::PassedEnv env_
;
1085 Kernel::PassedDyn dyn_
;
1086 Kernel::ContRef cont_
;
1088 Stroke2DCont_tail( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1089 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1090 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1092 virtual ~Stroke2DCont_tail( ) { }
1093 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1095 /* Argument 0: picture
1098 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1099 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1100 args
.applyDefaults( traceLoc_
);
1102 typedef const Lang::Drawable2D ArgType0
;
1103 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1105 typedef const Lang::Length ArgType1
;
1106 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1108 if( cutTail
->get( ) < 0 )
1110 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1112 else if( cutTail
->get( ) == 0 )
1114 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1115 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1120 Concrete::SplineTime t1
= path_
->arcTime( cutTail
->get( ) );
1121 Concrete::SplineTime
t2( HUGE_VAL
);
1122 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1123 if( ! subpath
->empty( ) )
1125 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1126 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1131 cont_
->takeValue( picture
,
1137 virtual Kernel::ContRef
up( ) const
1141 virtual RefCountPtr
< const char > description( ) const
1143 return strrefdup( "2D stroke's tail" );
1145 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1147 cont_
->gcMark( marked
);
1151 class Stroke2DCont_head
: public Kernel::ForcedStructureContinuation
1153 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1154 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1155 Kernel::PassedEnv env_
;
1156 Kernel::PassedDyn dyn_
;
1157 Kernel::ContRef cont_
;
1159 Stroke2DCont_head( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1160 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1161 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1163 virtual ~Stroke2DCont_head( ) { }
1164 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1166 /* Argument 0: picture
1169 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1170 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1171 args
.applyDefaults( traceLoc_
);
1173 typedef const Lang::Drawable2D ArgType0
;
1174 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1176 typedef const Lang::Length ArgType1
;
1177 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1179 if( cutHead
->get( ) < 0 )
1181 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow head cut length was negative." ) );
1183 else if( cutHead
->get( ) == 0 )
1185 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1186 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1191 Concrete::SplineTime
t1( 0 );
1192 Concrete::SplineTime t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1193 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1194 if( ! subpath
->empty( ) )
1196 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1197 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1202 cont_
->takeValue( picture
,
1207 virtual Kernel::ContRef
up( ) const
1211 virtual RefCountPtr
< const char > description( ) const
1213 return strrefdup( "2D stroke's head" );
1215 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1217 cont_
->gcMark( marked
);
1221 class Stroke2DCont_both2
: public Kernel::ForcedStructureContinuation
1223 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1224 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1225 RefCountPtr
< const Lang::Drawable2D
> tail_
;
1226 Lang::Length cutTail_
;
1227 Kernel::PassedEnv env_
;
1228 Kernel::PassedDyn dyn_
;
1229 Kernel::ContRef cont_
;
1231 Stroke2DCont_both2( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1232 const RefCountPtr
< const Lang::Drawable2D
> & tail
, Lang::Length cutTail
,
1233 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1234 : Kernel::ForcedStructureContinuation( "Stroke's arrow head receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), tail_( tail
), cutTail_( cutTail
), env_( env
), dyn_( dyn
), cont_( cont
)
1236 virtual ~Stroke2DCont_both2( ) { }
1237 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1239 /* Argument 0: picture
1242 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1243 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1244 args
.applyDefaults( traceLoc_
);
1246 typedef const Lang::Drawable2D ArgType0
;
1247 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1249 typedef const Lang::Length ArgType1
;
1250 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1252 if( cutHead
->get( ) < 0 )
1254 throw Exceptions::MiscellaneousRequirement( strrefdup( "Aarrow head cut length was negative." ) );
1257 if( cutTail_
.get( ) == 0 && cutHead
->get( ) == 0 )
1259 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1261 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, path_
, "S" ) ) ),
1266 Concrete::SplineTime
t1( 0 );
1267 if( cutTail_
.get( ) > 0 )
1269 t1
= path_
->arcTime( cutTail_
.get( ) );
1272 Concrete::SplineTime
t2( HUGE_VAL
);
1273 if( cutHead
->get( ) > 0 )
1275 t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1278 RefCountPtr
< const Lang::ElementaryPath2D
> subpath
= path_
->subpath( t1
, t2
);
1280 if( ! subpath
->empty( ) )
1282 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1284 RefCountPtr
< const Lang::Drawable2D
>( new Lang::PaintedPath2D( graphicsState_
, subpath
, "S" ) ) ),
1289 cont_
->takeValue( Helpers::newSolidTransparencyGroup( picture
,
1295 virtual Kernel::ContRef
up( ) const
1299 virtual RefCountPtr
< const char > description( ) const
1301 return strrefdup( "2D stroke's head & tail, second" );
1303 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1305 const_cast< Lang::Drawable2D
* >( tail_
.getPtr( ) )->gcMark( marked
);
1306 cont_
->gcMark( marked
);
1310 class Stroke2DCont_both1
: public Kernel::ForcedStructureContinuation
1312 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1313 RefCountPtr
< const Lang::ElementaryPath2D
> path_
;
1314 RefCountPtr
< const Lang::Function
> headFunction_
;
1315 Kernel::PassedEnv env_
;
1316 Kernel::PassedDyn dyn_
;
1317 Kernel::ContRef cont_
;
1319 Stroke2DCont_both1( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
,
1320 const RefCountPtr
< const Lang::Function
> & headFunction
,
1321 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1322 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), headFunction_( headFunction
), env_( env
), dyn_( dyn
), cont_( cont
)
1324 virtual ~Stroke2DCont_both1( ) { }
1325 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1327 /* Argument 0: picture
1330 Kernel::Arguments
args( & theArrowheadReceiverFormals2D
);
1331 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1332 args
.applyDefaults( traceLoc_
);
1334 typedef const Lang::Drawable2D ArgType0
;
1335 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1337 typedef const Lang::Length ArgType1
;
1338 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1340 if( cutTail
->get( ) < 0 )
1342 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1345 evalState
->env_
= env_
;
1346 evalState
->dyn_
= dyn_
;
1347 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_both2( graphicsState_
, path_
, picture
, *cutTail
, env_
, dyn_
, cont_
, traceLoc_
) );
1348 headFunction_
->call( evalState
, path_
->reverse( ), traceLoc_
);
1350 virtual Kernel::ContRef
up( ) const
1354 virtual RefCountPtr
< const char > description( ) const
1356 return strrefdup( "2D stroke's head & tail, first" );
1358 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1360 const_cast< Lang::Function
* >( headFunction_
.getPtr( ) )->gcMark( marked
);
1361 dyn_
->gcMark( marked
);
1362 cont_
->gcMark( marked
);
1372 Helpers::stroke_helper_2D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath2D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
)
1374 RefCountPtr
< const Lang::Function
> arrowHead
= args
.getHandle( 1 )->getVal
< const Lang::Function
>( "< core function stroke: head >" );
1375 RefCountPtr
< const Lang::Function
> arrowTail
= args
.getHandle( 2 )->getVal
< const Lang::Function
>( "< core function stroke: tail >" );
1376 if( ( arrowHead
== Lang::THE_NO_ARROW
&&
1377 arrowTail
== Lang::THE_NO_ARROW
) ||
1380 Kernel::ContRef cont
= evalState
->cont_
;
1381 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath2D( evalState
->dyn_
->getGraphicsState( ), path
, fill
? "B" : "S" ) ),
1387 /* The computation must continue outside here since functions are to be called, and resulting graphics collected.
1391 throw Exceptions::NotImplemented( "Arrowheads in fill-stroke command." );
1394 if( arrowTail
== Lang::THE_NO_ARROW
)
1396 /* There's only an arrow at the head.
1398 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_head( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1399 arrowHead
->call( evalState
, path
->reverse( ), callLoc
);
1403 if( arrowHead
== Lang::THE_NO_ARROW
)
1405 /* There's only an arrow at the tail.
1407 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_tail( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1408 arrowHead
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1412 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke2DCont_both1( evalState
->dyn_
->getGraphicsState( ), path
, arrowHead
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1413 arrowTail
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1423 class ArrowheadReceiverFormals3D
: public Kernel::EvaluatedFormals
1426 ArrowheadReceiverFormals3D( )
1427 : Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< Arrowhead receiver (3D) >" ), true )
1429 appendEvaluatedCoreFormal( "picture", Kernel::THE_SLOT_VARIABLE
);
1430 appendEvaluatedCoreFormal( "cut", Kernel::VariableHandle( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Length( 0 ) ) ) ) );
1434 ArrowheadReceiverFormals3D theArrowheadReceiverFormals3D
;
1436 class Stroke3DCont_tail
: public Kernel::ForcedStructureContinuation
1438 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1439 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1440 Kernel::PassedEnv env_
;
1441 Kernel::PassedDyn dyn_
;
1442 Kernel::ContRef cont_
;
1444 Stroke3DCont_tail( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1445 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1446 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1448 virtual ~Stroke3DCont_tail( ) { }
1449 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1451 /* Argument 0: picture
1454 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1455 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1456 args
.applyDefaults( traceLoc_
);
1458 typedef const Lang::Drawable3D ArgType0
;
1459 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1461 typedef const Lang::Length ArgType1
;
1462 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1464 if( cutTail
->get( ) < 0 )
1466 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1468 else if( cutTail
->get( ) == 0 )
1470 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1472 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1477 Concrete::SplineTime t1
= path_
->arcTime( cutTail
->get( ) );
1478 Concrete::SplineTime
t2( HUGE_VAL
);
1479 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1480 if( ! subpath
->empty( ) )
1482 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1484 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1489 cont_
->takeValue( picture
,
1495 virtual Kernel::ContRef
up( ) const
1499 virtual RefCountPtr
< const char > description( ) const
1501 return strrefdup( "3D stroke's tail" );
1503 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1505 cont_
->gcMark( marked
);
1509 class Stroke3DCont_head
: public Kernel::ForcedStructureContinuation
1511 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1512 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1513 Kernel::PassedEnv env_
;
1514 Kernel::PassedDyn dyn_
;
1515 Kernel::ContRef cont_
;
1517 Stroke3DCont_head( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1518 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1519 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), env_( env
), dyn_( dyn
), cont_( cont
)
1521 virtual ~Stroke3DCont_head( ) { }
1522 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1524 /* Argument 0: picture
1527 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1528 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1529 args
.applyDefaults( traceLoc_
);
1531 typedef const Lang::Drawable3D ArgType0
;
1532 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1534 typedef const Lang::Length ArgType1
;
1535 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1537 if( cutHead
->get( ) < 0 )
1539 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow head cut length was negative." ) );
1541 else if( cutHead
->get( ) == 0 )
1543 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1545 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1550 Concrete::SplineTime
t1( 0 );
1551 Concrete::SplineTime t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1552 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1553 if( ! subpath
->empty( ) )
1555 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1557 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1562 cont_
->takeValue( picture
,
1567 virtual Kernel::ContRef
up( ) const
1571 virtual RefCountPtr
< const char > description( ) const
1573 return strrefdup( "3D stroke's head" );
1575 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1577 cont_
->gcMark( marked
);
1581 class Stroke3DCont_both2
: public Kernel::ForcedStructureContinuation
1583 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1584 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1585 RefCountPtr
< const Lang::Drawable3D
> tail_
;
1586 Lang::Length cutTail_
;
1587 Kernel::PassedEnv env_
;
1588 Kernel::PassedDyn dyn_
;
1589 Kernel::ContRef cont_
;
1591 Stroke3DCont_both2( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1592 const RefCountPtr
< const Lang::Drawable3D
> & tail
, Lang::Length cutTail
,
1593 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1594 : Kernel::ForcedStructureContinuation( "Stroke's arrow head receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), tail_( tail
), cutTail_( cutTail
), env_( env
), dyn_( dyn
), cont_( cont
)
1596 virtual ~Stroke3DCont_both2( ) { }
1597 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1599 /* Argument 0: picture
1602 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1603 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1604 args
.applyDefaults( traceLoc_
);
1606 typedef const Lang::Drawable3D ArgType0
;
1607 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1609 typedef const Lang::Length ArgType1
;
1610 RefCountPtr
< ArgType1
> cutHead
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1612 if( cutHead
->get( ) < 0 )
1614 throw Exceptions::MiscellaneousRequirement( strrefdup( "Aarrow head cut length was negative." ) );
1617 if( cutTail_
.get( ) == 0 && cutHead
->get( ) == 0 )
1619 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1622 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, path_
, "S" ) ) ),
1627 Concrete::SplineTime
t1( 0 );
1628 if( cutTail_
.get( ) > 0 )
1630 t1
= path_
->arcTime( cutTail_
.get( ) );
1633 Concrete::SplineTime
t2( HUGE_VAL
);
1634 if( cutHead
->get( ) > 0 )
1636 t2
= path_
->arcTime( path_
->arcLength( ) - cutHead
->get( ) );
1639 RefCountPtr
< const Lang::ElementaryPath3D
> subpath
= path_
->subpath( t1
, t2
);
1641 if( ! subpath
->empty( ) )
1643 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1646 RefCountPtr
< const Lang::Drawable3D
>( new Lang::PaintedPath3D( graphicsState_
, subpath
, "S" ) ) ),
1651 cont_
->takeValue( Helpers::newGroup3D( evalState
->dyn_
->getGraphicsState( ),
1658 virtual Kernel::ContRef
up( ) const
1662 virtual RefCountPtr
< const char > description( ) const
1664 return strrefdup( "3D stroke's head & tail, second" );
1666 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1668 const_cast< Lang::Drawable3D
* >( tail_
.getPtr( ) )->gcMark( marked
);
1669 cont_
->gcMark( marked
);
1673 class Stroke3DCont_both1
: public Kernel::ForcedStructureContinuation
1675 RefCountPtr
< const Kernel::GraphicsState
> graphicsState_
;
1676 RefCountPtr
< const Lang::ElementaryPath3D
> path_
;
1677 RefCountPtr
< const Lang::Function
> headFunction_
;
1678 Kernel::PassedEnv env_
;
1679 Kernel::PassedDyn dyn_
;
1680 Kernel::ContRef cont_
;
1682 Stroke3DCont_both1( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
,
1683 const RefCountPtr
< const Lang::Function
> & headFunction
,
1684 const Kernel::PassedEnv
& env
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
1685 : Kernel::ForcedStructureContinuation( "Stroke's arrow tail receiver", traceLoc
), graphicsState_( graphicsState
), path_( path
), headFunction_( headFunction
), env_( env
), dyn_( dyn
), cont_( cont
)
1687 virtual ~Stroke3DCont_both1( ) { }
1688 virtual void takeStructure( const RefCountPtr
< const Lang::Structure
> & structure
, Kernel::EvalState
* evalState
) const
1690 /* Argument 0: picture
1693 Kernel::Arguments
args( & theArrowheadReceiverFormals3D
);
1694 structure
->argList_
->bind( & args
, structure
->values_
, env_
, dyn_
);
1695 args
.applyDefaults( traceLoc_
);
1697 typedef const Lang::Drawable3D ArgType0
;
1698 RefCountPtr
< ArgType0
> picture
= Helpers::down_cast_StructureContinuationArgument
< ArgType0
>( continuationName_
, args
, 0, traceLoc_
);
1700 typedef const Lang::Length ArgType1
;
1701 RefCountPtr
< ArgType1
> cutTail
= Helpers::down_cast_StructureContinuationArgument
< ArgType1
>( continuationName_
, args
, 1, traceLoc_
);
1703 if( cutTail
->get( ) < 0 )
1705 throw Exceptions::MiscellaneousRequirement( strrefdup( "Arrow tail cut length was negative." ) );
1708 evalState
->env_
= env_
;
1709 evalState
->dyn_
= dyn_
;
1710 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_both2( graphicsState_
, path_
, picture
, *cutTail
, env_
, dyn_
, cont_
, traceLoc_
) );
1711 headFunction_
->call( evalState
, path_
->reverse( ), traceLoc_
);
1713 virtual Kernel::ContRef
up( ) const
1717 virtual RefCountPtr
< const char > description( ) const
1719 return strrefdup( "3D stroke's head & tail, first" );
1721 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
1723 const_cast< Lang::Function
* >( headFunction_
.getPtr( ) )->gcMark( marked
);
1724 dyn_
->gcMark( marked
);
1725 cont_
->gcMark( marked
);
1734 Helpers::stroke_helper_3D( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::ElementaryPath3D
> & path
, Kernel::Arguments
& args
, bool fill
, const Ast::SourceLocation
& callLoc
)
1736 RefCountPtr
< const Lang::Function
> arrowHead
= args
.getHandle( 1 )->getVal
< const Lang::Function
>( "< core function stroke: head >" );
1737 RefCountPtr
< const Lang::Function
> arrowTail
= args
.getHandle( 2 )->getVal
< const Lang::Function
>( "< core function stroke: tail >" );
1738 if( ( arrowHead
== Lang::THE_NO_ARROW
&&
1739 arrowTail
== Lang::THE_NO_ARROW
) ||
1742 Kernel::ContRef cont
= evalState
->cont_
;
1743 cont
->takeValue( Kernel::ValueRef( new Lang::PaintedPath3D( evalState
->dyn_
->getGraphicsState( ), path
, fill
? "B" : "S" ) ),
1749 /* The computation must continue outside here since functions are to be called, and resulting graphics collected.
1753 throw Exceptions::NotImplemented( "Arrowheads in fill-stroke command." );
1756 if( arrowTail
== Lang::THE_NO_ARROW
)
1758 /* There's only an arrow at the head.
1760 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_head( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1761 arrowHead
->call( evalState
, path
->reverse( ), callLoc
);
1765 if( arrowHead
== Lang::THE_NO_ARROW
)
1767 /* There's only an arrow at the tail.
1769 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_tail( evalState
->dyn_
->getGraphicsState( ), path
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1770 arrowHead
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1774 evalState
->cont_
= Kernel::ContRef( new Kernel::Stroke3DCont_both1( evalState
->dyn_
->getGraphicsState( ), path
, arrowHead
, evalState
->env_
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
1775 arrowTail
->call( arrowTail
, evalState
, args
.getHandle( 0 ), callLoc
);
1782 Kernel::registerCore_draw( Kernel::Environment
* env
)
1784 env
->initDefineCoreFunction( new Lang::Core_spot( Lang::THE_NAMESPACE_Shapes_Graphics
, "spot" ) );
1785 env
->initDefineCoreFunction( new Lang::Core_stroke( Lang::THE_NAMESPACE_Shapes_Graphics
, "stroke", false ) );
1786 env
->initDefineCoreFunction( new Lang::Core_stroke( Lang::THE_NAMESPACE_Shapes_Graphics
, "fillstroke", true ) );
1787 env
->initDefineCoreFunction( new Lang::Core_fill( Lang::THE_NAMESPACE_Shapes_Graphics
, "fill" ) );
1788 env
->initDefineCoreFunction( new Lang::Core_fillstar( Lang::THE_NAMESPACE_Shapes_Graphics
, "fillodd" ) );
1789 env
->initDefineCoreFunction( new Lang::Core_facetnormal( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "facetnormal" ) );
1790 env
->initDefineCoreFunction( new Lang::Core_facet( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "facet" ) );
1792 env
->initDefineCoreFunction( new Lang::Core_bboxed( Lang::THE_NAMESPACE_Shapes_Layout
, "bboxed" ) );
1793 env
->initDefineCoreFunction( new Lang::Core_clip( Lang::THE_NAMESPACE_Shapes_Graphics
, "clip", Lang::Core_clip::NONZERO_WINDING
) );
1794 env
->initDefineCoreFunction( new Lang::Core_clip( Lang::THE_NAMESPACE_Shapes_Graphics
, "clipodd", Lang::Core_clip::EVEN_ODD
) );
1796 env
->initDefineCoreFunction( new Lang::Core_from3Dto2D( Lang::THE_NAMESPACE_Shapes_Geometry3D
, "view" ) );
1797 env
->initDefineCoreFunction( new Lang::Core_from2Dto3D( Lang::THE_NAMESPACE_Shapes_Geometry3D
, "immerse" ) );
1798 env
->initDefineCoreFunction( new Lang::Core_facing2Din3D( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "facing" ) );