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, 2014 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "dynamicenvironment.h"
26 #include "shapescore.h"
30 #include "continuations.h"
36 using namespace Shapes
;
40 Kernel::SpecialUnitVariables::specialUnitService( Concrete::Length
* d
, double * a0
, double * a1
)
42 if( p0_
== 0 || p1_
== 0 )
44 throw Exceptions::InternalError( "The path points were not setup before calling specialUnitService" );
50 double ag0
; /* global angles that will later be compared with aRef */
53 if( reverseDirection_
)
59 ag0
= p1_
->rearAngle_
;
60 ag1
= p0_
->frontAngle_
;
68 ag0
= p0_
->frontAngle_
;
69 ag1
= p1_
->rearAngle_
;
72 Concrete::Length dx
= x3
- x0
;
73 Concrete::Length dy
= y3
- y0
;
75 *d
= hypotPhysical( dx
, dy
);
77 double aRef
= atan2( dy
.offtype
< 1, 0 >( ), dx
.offtype
< 1, 0 >( ) ); /* Angles will be relative to the angle pointing to the other mid point */
79 if( p0_
->frontState_
& Concrete::PathPoint2D::FREE_ANGLE
)
81 throw Exceptions::InternalError( "Found a free angle in specialUnitService." );
84 if( p1_
->rearState_
& Concrete::PathPoint2D::FREE_ANGLE
)
86 throw Exceptions::InternalError( "Found a free angle in specialUnitService." );
92 std::ostringstream msg
;
93 msg
<< "Using uninitialized adjacent angle in "
94 << "(" << Concrete::Length::offtype( x0
) << "bp," << Concrete::Length::offtype( y0
) << "bp)"
96 << "(" << Concrete::Length::offtype( x3
) << "bp," << Concrete::Length::offtype( y3
) << "bp)" ;
97 throw Exceptions::InternalError( strrefdup( msg
) );
101 double ar0
= aRef
- ag0
;
108 while( ar0
< - M_PI
);
118 double ar1
= ag1
- aRef
- M_PI
;
121 /* The angle is NaN is there is no opposite angle. The implicit direction is then towards the neighboring point.
133 while( ar1
< - M_PI
);
156 else if( ar1
> M_PI
)
165 Kernel::SystemDynamicVariables::SystemDynamicVariables( )
166 : graphicsState_( NullPtr
< const Kernel::GraphicsState
>( ) ),
167 facetState_( NullPtr
< const Kernel::FacetState
>( ) ),
168 textState_( NullPtr
< const Kernel::TextState
>( ) ),
169 eyez_( std::numeric_limits
< double >::signaling_NaN( ) ),
170 TeX_bleed_( std::numeric_limits
< double >::signaling_NaN( ) ),
171 defaultUnit_( NullPtr
< const Kernel::PolarHandlePromise
>( ) ),
172 blendSpace_( NullPtr
< const Lang::ColorSpace
>( ) )
175 Kernel::SystemDynamicVariables::SystemDynamicVariables( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
)
176 : graphicsState_( graphicsState
),
177 facetState_( new Kernel::FacetState( true ) ),
178 textState_( new Kernel::TextState( true ) ),
179 eyez_( 50 * 72 / 2.54 ), /* 50 cm */
180 TeX_bleed_( 0.5 ), /* 0.5 bp */
181 defaultUnit_( new Kernel::PolarHandleEmptyPromise( ) ),
182 blendSpace_( Lang::THE_INHERITED_COLOR_SPACE
)
186 Kernel::SystemDynamicVariables::addFrom( const SystemDynamicVariables
& other
)
188 if( graphicsState_
== NullPtr
< const Kernel::GraphicsState
>( ) )
190 graphicsState_
= other
.graphicsState_
;
192 else if( other
.graphicsState_
!= NullPtr
< const Kernel::GraphicsState
>( ) )
194 graphicsState_
= RefCountPtr
< const Kernel::GraphicsState
>( new Kernel::GraphicsState( *graphicsState_
, *other
.graphicsState_
) );
196 /* In the remaining situation, there is nothing to merge, so we're done. */
198 if( facetState_
== NullPtr
< const Kernel::FacetState
>( ) )
200 facetState_
= other
.facetState_
;
202 else if( other
.facetState_
!= NullPtr
< const Kernel::FacetState
>( ) )
204 facetState_
= RefCountPtr
< const Kernel::FacetState
>( new Kernel::FacetState( *facetState_
, *other
.facetState_
) );
206 /* In the remaining situation, there is nothing to merge, so we're done. */
208 if( textState_
== NullPtr
< const Kernel::TextState
>( ) )
210 textState_
= other
.textState_
;
212 else if( other
.textState_
!= NullPtr
< const Kernel::TextState
>( ) )
214 textState_
= RefCountPtr
< const Kernel::TextState
>( new Kernel::TextState( *textState_
, *other
.textState_
) );
216 /* In the remaining situation, there is nothing to merge, so we're done. */
218 if( IS_NAN( eyez_
) )
223 if( IS_NAN( TeX_bleed_
) )
225 TeX_bleed_
= other
.TeX_bleed_
;
228 if( defaultUnit_
== NullPtr
< const Kernel::PolarHandlePromise
>( ) )
230 defaultUnit_
= other
.defaultUnit_
;
233 if( blendSpace_
== NullPtr
< const Lang::ColorSpace
>( ) )
235 blendSpace_
= other
.blendSpace_
;
240 Kernel::SystemDynamicVariables::print( std::ostream
& os
, const std::string
& indentation
) const
242 const char * moreIndentation
= " ";
244 if( graphicsState_
!= NullPtr
< const Kernel::GraphicsState
>( ) )
246 os
<< indentation
<< "Graphics state bindings:" << std::endl
;
247 graphicsState_
->print( os
, indentation
+ moreIndentation
);
250 if( textState_
!= NullPtr
< const Kernel::TextState
>( ) )
252 os
<< indentation
<< "Text state bindings:" << std::endl
;
253 textState_
->print( os
, indentation
+ moreIndentation
);
256 if( facetState_
!= NullPtr
< const Kernel::FacetState
>( ) )
258 os
<< indentation
<< "Facet state bindings:" << std::endl
;
259 facetState_
->print( os
, indentation
+ moreIndentation
);
262 if( ! IS_NAN( eyez_
) )
265 Lang::DYNAMIC_VARIABLE_ID_EYEZ
.show( os
, Ast::Identifier::DYNAMIC_VARIABLE
);
266 os
<< ": " << eyez_
/ Interaction::displayUnit
<< Interaction::displayUnitName
<< std::endl
;
269 if( ! IS_NAN( TeX_bleed_
) )
272 Lang::DYNAMIC_VARIABLE_ID_TEX_BLEED
.show( os
, Ast::Identifier::DYNAMIC_VARIABLE
);
273 os
<< ": " << TeX_bleed_
/ Interaction::displayUnit
<< Interaction::displayUnitName
<< std::endl
;
276 if( defaultUnit_
!= NullPtr
< const Kernel::PolarHandlePromise
>( ) )
279 Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT
.show( os
, Ast::Identifier::DYNAMIC_VARIABLE
);
281 defaultUnit_
->show( os
);
285 if( blendSpace_
!= NullPtr
< const Lang::ColorSpace
>( ) )
288 Lang::DYNAMIC_VARIABLE_ID_BLEND_SPACE
.show( os
, Ast::Identifier::DYNAMIC_VARIABLE
);
290 if( blendSpace_
->isInherent( ) )
292 os
<< "< inherent >" << std::endl
;
296 os
<< blendSpace_
->name( ) << std::endl
;
303 Kernel::DynamicEnvironment::DynamicEnvironment( const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
)
304 : parent_( NullPtr
< Kernel::DynamicEnvironment
>( ) ), sysBindings_( new Kernel::SystemDynamicVariables( graphicsState
) ),
305 specialBindings_( 0 ), spanLast_( 0 ),
306 contId_( Lang::CONTINUATION_ID_ERROR
), contVal_( Kernel::ContRef( new Kernel::DefaultErrorContinuation( Ast::theProgram
->loc( ) ) ) )
309 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, const Lang::DynamicBindings
& bindings
)
310 : parent_( NullPtr
< Kernel::DynamicEnvironment
>( ) ), sysBindings_( 0 ), specialBindings_( 0 ), spanLast_( 0 ),
311 contId_( 0 ), contVal_( NullPtr
< Kernel::Continuation
>( ) )
313 bindings
.bind( bindings_
, & sysBindings_
);
314 if( sysBindings_
!= 0 &&
315 sysBindings_
->graphicsState_
!= NullPtr
< const Kernel::GraphicsState
>( ) )
317 sysBindings_
->graphicsState_
=
318 RefCountPtr
< const Kernel::GraphicsState
>( new Kernel::GraphicsState( *(sysBindings_
->graphicsState_
),
319 *(parent
->getGraphicsState( )) ) );
321 if( sysBindings_
!= 0 &&
322 sysBindings_
->facetState_
!= NullPtr
< const Kernel::FacetState
>( ) )
324 sysBindings_
->facetState_
=
325 RefCountPtr
< const Kernel::FacetState
>( new Kernel::FacetState( *(sysBindings_
->facetState_
),
326 *(parent
->getFacetState( )) ) );
328 if( sysBindings_
!= 0 &&
329 sysBindings_
->textState_
!= NullPtr
< const Kernel::TextState
>( ) )
331 sysBindings_
->textState_
=
332 RefCountPtr
< const Kernel::TextState
>( new Kernel::TextState( *(sysBindings_
->textState_
),
333 *(parent
->getTextState( )) ) );
335 parent_
= parent
->selectParent( parent
, bindings_
);
338 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, const RefCountPtr
< const Kernel::GraphicsState
> & graphicsState
)
339 : parent_( parent
), sysBindings_( new Kernel::SystemDynamicVariables( ) ), specialBindings_( 0 ), spanLast_( 0 ),
340 contId_( 0 ), contVal_( NullPtr
< Kernel::Continuation
>( ) )
342 sysBindings_
->graphicsState_
= graphicsState
;
345 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, Kernel::SystemDynamicVariables
* sysBindings
)
346 : parent_( parent
), sysBindings_( sysBindings
), specialBindings_( 0 ), spanLast_( 0 ),
347 contId_( 0 ), contVal_( NullPtr
< Kernel::Continuation
>( ) )
350 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, Kernel::SpecialUnitVariables
* specialBindings
)
351 : parent_( parent
), sysBindings_( 0 ), specialBindings_( specialBindings
), spanLast_( 0 ),
352 contId_( 0 ), contVal_( NullPtr
< Kernel::Continuation
>( ) )
355 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, const RefCountPtr
< const Lang::Value
> & spanLast
)
356 : parent_( parent
), sysBindings_( 0 ), specialBindings_( 0 ), spanLast_( new Kernel::SpanLastValue( spanLast
) ),
357 contId_( 0 ), contVal_( NullPtr
< Kernel::Continuation
>( ) )
361 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr
< Kernel::DynamicEnvironment
> parent
, const char * contId
, const Kernel::ContRef
& contVal
)
362 : parent_( parent
), sysBindings_( 0 ), specialBindings_( 0 ), spanLast_( 0 ),
363 contId_( contId
), contVal_( contVal
)
366 Kernel::DynamicEnvironment::~DynamicEnvironment( )
368 if( sysBindings_
!= 0 )
372 if( specialBindings_
!= 0 )
374 delete specialBindings_
;
383 Kernel::DynamicEnvironment::tackOn( const KeyType
& key
, Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
385 throw Exceptions::NotImplemented( "DynamicEnvironment::tackOn" );
386 // MapType::iterator i = bindings_.find( key );
387 // if( i == bindings_.end( ) )
389 // if( isBaseEnvironment( ) )
391 // throw Exceptions::InternalError( "Key of dynamic variable was not found in dynamic environment." );
393 // return parent_->tackOn( key, evalState, piece, callLoc );
395 // return i->second.first->tackOn( evalState, piece, callLoc );
399 Kernel::DynamicEnvironment::lookup( const KeyType
& key
, Kernel::EvalState
* evalState
) const
401 MapType::const_iterator i
= bindings_
.find( key
);
402 if( i
== bindings_
.end( ) )
404 if( isBaseEnvironment( ) )
406 throw NonLocalExit::DynamicBindingNotFound( );
408 return parent_
->lookup( key
, evalState
);
411 Kernel::ContRef cont
= evalState
->cont_
;
412 cont
->takeHandle( i
->second
.first
,
416 Kernel::VariableHandle
417 Kernel::DynamicEnvironment::getVarHandle( const KeyType
& key
) const
419 MapType::const_iterator i
= bindings_
.find( key
);
420 if( i
== bindings_
.end( ) )
422 if( isBaseEnvironment( ) )
424 throw NonLocalExit::DynamicBindingNotFound( );
426 return parent_
->getVarHandle( key
);
428 return i
->second
.first
;
431 RefCountPtr
< Kernel::DynamicEnvironment
>
432 Kernel::DynamicEnvironment::selectParent( RefCountPtr
< Kernel::DynamicEnvironment
> & self
, const MapType
& newBindings
)
434 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) ||
436 specialBindings_
!= 0 ||
443 MapType::const_iterator hint
= newBindings
.begin( );
444 for( MapType::const_iterator i
= bindings_
.begin( ); i
!= bindings_
.end( ); ++i
)
446 hint
= newBindings
.find( i
->first
);
447 if( hint
== newBindings
.end( ) )
453 return parent_
->selectParent( parent_
, newBindings
);
457 Kernel::DynamicEnvironment::gcMark( Kernel::GCMarkedSet
& marked
)
459 for( MapType::iterator i
= bindings_
.begin( ); i
!= bindings_
.end( ); ++i
)
461 i
->second
.first
->gcMark( marked
);
466 RefCountPtr
< const Kernel::GraphicsState
>
467 Kernel::DynamicEnvironment::getGraphicsState( ) const
469 if( sysBindings_
== 0 ||
470 sysBindings_
->graphicsState_
== NullPtr
< const Kernel::GraphicsState
>( ) )
472 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
474 throw Exceptions::InternalError( "The graphics state was needed but not defined." );
476 return parent_
->getGraphicsState( );
479 return sysBindings_
->graphicsState_
;
482 RefCountPtr
< const Kernel::FacetState
>
483 Kernel::DynamicEnvironment::getFacetState( ) const
485 if( sysBindings_
== 0 ||
486 sysBindings_
->facetState_
== NullPtr
< const Kernel::FacetState
>( ) )
488 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
490 throw Exceptions::InternalError( "The facet state was needed but not defined." );
492 return parent_
->getFacetState( );
495 return sysBindings_
->facetState_
;
498 RefCountPtr
< const Kernel::TextState
>
499 Kernel::DynamicEnvironment::getTextState( ) const
501 if( sysBindings_
== 0 ||
502 sysBindings_
->textState_
== NullPtr
< const Kernel::TextState
>( ) )
504 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
506 throw Exceptions::InternalError( "The text state was needed but not defined." );
508 return parent_
->getTextState( );
511 return sysBindings_
->textState_
;
515 Kernel::DynamicEnvironment::getEyeZ( ) const
517 if( sysBindings_
== 0 ||
518 IS_NAN( sysBindings_
->eyez_
) )
520 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
522 throw Exceptions::InternalError( "@eyez should allways be bound." );
524 return parent_
->getEyeZ( );
527 return sysBindings_
->eyez_
;
531 Kernel::DynamicEnvironment::getTeXBleed( ) const
533 if( sysBindings_
== 0 ||
534 IS_NAN( sysBindings_
->TeX_bleed_
) )
536 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
538 throw Exceptions::InternalError( "@TeX_bleed should allways be bound." );
540 return parent_
->getTeXBleed( );
543 return sysBindings_
->TeX_bleed_
;
546 RefCountPtr
< const Kernel::PolarHandlePromise
>
547 Kernel::DynamicEnvironment::getDefaultUnit( ) const
549 if( sysBindings_
== 0 ||
550 sysBindings_
->defaultUnit_
== NullPtr
< const Kernel::PolarHandlePromise
>( ) )
552 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
554 throw Exceptions::InternalError( "The default unit should allways be defined." );
556 return parent_
->getDefaultUnit( );
559 return sysBindings_
->defaultUnit_
;
562 RefCountPtr
< const Lang::Value
>
563 Kernel::DynamicEnvironment::getSpanLast( ) const
567 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
569 throw Exceptions::InternalError( "The value of %last is not determined by the current dynamic context." );
571 return parent_
->getSpanLast( );
574 return spanLast_
->last_
;
578 Kernel::DynamicEnvironment::getEscapeContinuation( const char * id
, const Ast::SourceLocation
& loc
) const
581 strcmp( contId_
, id
) != 0 )
583 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
585 throw Exceptions::UndefinedEscapeContinuation( id
, loc
);
587 return parent_
->getEscapeContinuation( id
, loc
);
593 RefCountPtr
< const Lang::ColorSpace
>
594 Kernel::DynamicEnvironment::getBlendSpace( ) const
596 if( sysBindings_
== 0 ||
597 sysBindings_
->blendSpace_
== NullPtr
< const Lang::ColorSpace
>( ) )
599 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
601 throw Exceptions::InternalError( "The blend space should allways be defined." );
603 return parent_
->getBlendSpace( );
606 return sysBindings_
->blendSpace_
;
610 Kernel::DynamicEnvironment::specialUnitService( Concrete::Length
* d
, double * a0
, double * a1
)
612 if( specialBindings_
!= 0 )
614 specialBindings_
->specialUnitService( d
, a0
, a1
);
618 if( parent_
== NullPtr
< Kernel::DynamicEnvironment
>( ) )
620 throw Exceptions::InternalError( "The special unit dynamic context was needed but not defined." );
622 parent_
->specialUnitService( d
, a0
, a1
);
627 Kernel::DynamicEnvironment::isBaseEnvironment( ) const
629 return parent_
== NullPtr
< Kernel::DynamicEnvironment
>( );
633 Kernel::DynamicEnvironment::print( std::ostream
& os
) const
635 std::set
< MapType::key_type
> shadowed
;
636 recursivePrint( os
, & shadowed
);
640 Kernel::DynamicEnvironment::recursivePrint( std::ostream
& os
, std::set
< MapType::key_type
> * shadowed
) const
642 std::set
< MapType::key_type
> shadowedBefore( *shadowed
);
645 if( ! isBaseEnvironment( ) )
647 for( MapType::const_iterator i
= bindings_
.begin( ); i
!= bindings_
.end( ); ++i
)
649 shadowed
->insert( shadowed
->begin( ), i
->first
);
651 depth
= parent_
->recursivePrint( os
, shadowed
) + 1;
654 std::string indentation
= std::string( depth
, ' ' );
656 os
<< indentation
<< "@@ -- -- -- -- -- -- -- -- @@" << std::endl
;
660 os
<< indentation
<< " (esc) " << "< escape continuation > " << contId_
<< ": " << contVal_
->traceLoc( ) << " (" << contVal_
->description( ) << ")" << std::endl
;
663 if( sysBindings_
!= 0 )
665 sysBindings_
->print( os
, indentation
+ " (sys) " ); /* The extra indentation matches " (num) " */
668 if( specialBindings_
!= 0 )
670 os
<< indentation
<< " (-- ) " << "< special unit points >: " << *(specialBindings_
->p0_
->mid_
) << ( (specialBindings_
->reverseDirection_
) ? " <-- " : " --> " ) << *(specialBindings_
->p1_
->mid_
) << std::endl
;
675 os
<< indentation
<< " (spn) " << "< %last >: " ;
676 spanLast_
->last_
->show( os
);
680 for( MapType::const_iterator i
= bindings_
.begin( ); i
!= bindings_
.end( ); ++i
)
683 if( shadowedBefore
.find( i
->first
) != shadowedBefore
.end( ) )
691 os
<< "(" << std::setw(3) << i
->first
<< ") " << Interaction::DYNAMIC_VARIABLE_PREFIX
<< i
->second
.second
->id( ) << ": " ;
692 if( i
->second
.first
== NullPtr
< Kernel::Variable
>( ) )
694 os
<< "< Uninitialized >" ;
696 else if( i
->second
.first
->isThunk( ) )
700 else if( dynamic_cast< const Lang::Instance
* >( i
->second
.first
->getUntyped( ).getPtr( ) ) == 0 )
702 i
->second
.first
->getUntyped( )->show( os
);
708 os
<< " (" << i
->second
.second
->idLoc( ) << ")" << std::endl
;
711 // os << indentation << "-- -- -- -- -- -- -- -- -- --" << std::endl ;
716 Lang::EyeZBinding::EyeZBinding( const Ast::PlacedIdentifier
* id
, const Ast::DynamicBindingExpression
* bindingExpr
, Concrete::Length val
)
717 : bindingExpr_( bindingExpr
), val_( val
), id_( id
)
720 Lang::EyeZBinding::~EyeZBinding( )
724 Lang::EyeZBinding::bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const
726 if( *sysBindings
== 0 )
728 *sysBindings
= new Kernel::SystemDynamicVariables( );
729 (*sysBindings
)->eyez_
= val_
;
733 if( ! IS_NAN( (*sysBindings
)->eyez_
) )
735 throw Exceptions::MultipleDynamicBind( id_
, bindingExpr_
->idLoc( ), Ast::THE_UNKNOWN_LOCATION
);
738 (*sysBindings
)->eyez_
= val_
;
742 Lang::EyeZBinding::show( std::ostream
& os
) const
744 os
<< Interaction::DYNAMIC_VARIABLE_PREFIX
<< id_
<< ":"
745 << val_
/ Interaction::displayUnit
<< Interaction::displayUnitName
;
749 Lang::EyeZBinding::gcMark( Kernel::GCMarkedSet
& marked
)
754 Kernel::EyeZDynamicVariableProperties::EyeZDynamicVariableProperties( const Ast::PlacedIdentifier
* id
)
755 : Kernel::DynamicVariableProperties( id
)
758 Kernel::EyeZDynamicVariableProperties::~EyeZDynamicVariableProperties( )
761 Kernel::VariableHandle
762 Kernel::EyeZDynamicVariableProperties::fetch( const Kernel::PassedDyn
& dyn
) const
764 return Helpers::newValHandle( new Lang::Length( dyn
->getEyeZ( ) ) );
768 Kernel::EyeZDynamicVariableProperties::makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const
772 RefCountPtr
< const Lang::Length
> len
= val
->tryVal
< const Lang::Length
>( );
773 Kernel::ContRef cont
= evalState
->cont_
;
774 cont
->takeValue( Kernel::ValueRef( new Lang::EyeZBinding( id_
, bindingExpr
, len
->get( ) ) ),
778 catch( const NonLocalExit::NotThisType
& ball
)
785 RefCountPtr
< const Lang::Float
> maybeInfinity
= val
->tryVal
< const Lang::Float
>( );
786 if( maybeInfinity
->val_
< HUGE_VAL
)
788 throw Exceptions::OutOfRange( bindingExpr
->exprLoc( ), strrefdup( "The only float value allowed here is infinity." ) );
790 Kernel::ContRef cont
= evalState
->cont_
;
791 cont
->takeValue( Kernel::ValueRef( new Lang::EyeZBinding( id_
, bindingExpr
, Concrete::HUGE_LENGTH
) ),
795 catch( const NonLocalExit::NotThisType
& ball
)
800 throw Exceptions::TypeMismatch( bindingExpr
->exprLoc( ), val
->getUntyped( )->getTypeName( ), Helpers::typeSetString( Lang::Length::staticTypeName( ), Lang::Float::staticTypeName( ) ) );
804 Lang::DefaultUnitBinding::DefaultUnitBinding( const Ast::PlacedIdentifier
* id
, const Ast::DynamicBindingExpression
* bindingExpr
, const RefCountPtr
< const Kernel::PolarHandlePromise
> & val
)
805 : bindingExpr_( bindingExpr
), val_( val
), id_( id
)
808 Lang::DefaultUnitBinding::~DefaultUnitBinding( )
812 Lang::DefaultUnitBinding::bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const
814 if( *sysBindings
== 0 )
816 *sysBindings
= new Kernel::SystemDynamicVariables( );
817 (*sysBindings
)->defaultUnit_
= val_
;
821 if( (*sysBindings
)->defaultUnit_
!= NullPtr
< const Kernel::PolarHandlePromise
>( ) )
823 throw Exceptions::MultipleDynamicBind( id_
, bindingExpr_
->idLoc( ), Ast::THE_UNKNOWN_LOCATION
);
826 (*sysBindings
)->defaultUnit_
= val_
;
830 Lang::DefaultUnitBinding::show( std::ostream
& os
) const
832 os
<< Interaction::DYNAMIC_VARIABLE_PREFIX
<< id_
<< ":<promise>" ;
836 Lang::DefaultUnitBinding::gcMark( Kernel::GCMarkedSet
& marked
)
838 val_
->gcMark( marked
);
842 Kernel::DefaultUnitDynamicVariableProperties::DefaultUnitDynamicVariableProperties( const Ast::PlacedIdentifier
* id
)
843 : Kernel::DynamicVariableProperties( id
)
846 Kernel::DefaultUnitDynamicVariableProperties::~DefaultUnitDynamicVariableProperties( )
849 Kernel::VariableHandle
850 Kernel::DefaultUnitDynamicVariableProperties::fetch( const Kernel::PassedDyn
& dyn
) const
852 throw Exceptions::MiscellaneousRequirement( "The default unit cannot be evaluated as a variable." );
856 Kernel::DefaultUnitDynamicVariableProperties::makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const
858 if( ! val
->isThunk( ) )
860 throw Exceptions::InternalError( "The default unit handle was not a thunk." );
863 Kernel::ContRef cont
= evalState
->cont_
;
864 cont
->takeValue( Kernel::ValueRef( new Lang::DefaultUnitBinding( id_
, bindingExpr
, RefCountPtr
< const Kernel::PolarHandlePromise
>( new Kernel::PolarHandleTruePromise( val
->copyThunk( ) ) ) ) ),
870 Lang::TeXBleedBinding::TeXBleedBinding( const Ast::PlacedIdentifier
* id
, const Ast::DynamicBindingExpression
* bindingExpr
, Concrete::Length val
)
871 : bindingExpr_( bindingExpr
), val_( val
), id_( id
)
874 Lang::TeXBleedBinding::~TeXBleedBinding( )
878 Lang::TeXBleedBinding::bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const
880 if( *sysBindings
== 0 )
882 *sysBindings
= new Kernel::SystemDynamicVariables( );
883 (*sysBindings
)->TeX_bleed_
= val_
;
887 if( ! IS_NAN( (*sysBindings
)->TeX_bleed_
) )
889 throw Exceptions::MultipleDynamicBind( id_
, bindingExpr_
->idLoc( ), Ast::THE_UNKNOWN_LOCATION
);
892 (*sysBindings
)->TeX_bleed_
= val_
;
896 Lang::TeXBleedBinding::show( std::ostream
& os
) const
898 os
<< Interaction::DYNAMIC_VARIABLE_PREFIX
<< id_
<< ":"
899 << val_
/ Interaction::displayUnit
<< Interaction::displayUnitName
;
903 Lang::TeXBleedBinding::gcMark( Kernel::GCMarkedSet
& marked
)
908 Kernel::TeXBleedDynamicVariableProperties::TeXBleedDynamicVariableProperties( const Ast::PlacedIdentifier
* id
)
909 : Kernel::DynamicVariableProperties( id
)
912 Kernel::TeXBleedDynamicVariableProperties::~TeXBleedDynamicVariableProperties( )
915 Kernel::VariableHandle
916 Kernel::TeXBleedDynamicVariableProperties::fetch( const Kernel::PassedDyn
& dyn
) const
918 return Helpers::newValHandle( new Lang::Length( dyn
->getTeXBleed( ) ) );
922 Kernel::TeXBleedDynamicVariableProperties::makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const
924 RefCountPtr
< const Lang::Length
> len
= val
->getVal
< const Lang::Length
>( bindingExpr
->exprLoc( ) );
925 Kernel::ContRef cont
= evalState
->cont_
;
926 cont
->takeValue( Kernel::ValueRef( new Lang::TeXBleedBinding( id_
, bindingExpr
, len
->get( ) ) ),
931 Lang::BlendSpaceBinding::BlendSpaceBinding( const Ast::PlacedIdentifier
* id
, const Ast::DynamicBindingExpression
* bindingExpr
, const RefCountPtr
< const Lang::ColorSpace
> & space
)
932 : bindingExpr_( bindingExpr
), space_( space
), id_( id
)
935 Lang::BlendSpaceBinding::~BlendSpaceBinding( )
939 Lang::BlendSpaceBinding::bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const
941 if( *sysBindings
== 0 )
943 *sysBindings
= new Kernel::SystemDynamicVariables( );
944 (*sysBindings
)->blendSpace_
= space_
;
948 if( (*sysBindings
)->blendSpace_
!= NullPtr
< const Lang::ColorSpace
>( ) )
950 throw Exceptions::MultipleDynamicBind( id_
, bindingExpr_
->idLoc( ), Ast::THE_UNKNOWN_LOCATION
);
953 (*sysBindings
)->blendSpace_
= space_
;
957 Lang::BlendSpaceBinding::show( std::ostream
& os
) const
959 os
<< Interaction::DYNAMIC_VARIABLE_PREFIX
<< id_
<< "" ;
964 Lang::BlendSpaceBinding::gcMark( Kernel::GCMarkedSet
& marked
)
969 Kernel::BlendSpaceDynamicVariableProperties::BlendSpaceDynamicVariableProperties( const Ast::PlacedIdentifier
* id
)
970 : Kernel::DynamicVariableProperties( id
)
973 Kernel::BlendSpaceDynamicVariableProperties::~BlendSpaceDynamicVariableProperties( )
976 Kernel::VariableHandle
977 Kernel::BlendSpaceDynamicVariableProperties::fetch( const Kernel::PassedDyn
& dyn
) const
979 return Kernel::VariableHandle( new Kernel::Variable( dyn
->getBlendSpace( ) ) );
983 Kernel::BlendSpaceDynamicVariableProperties::makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const
985 RefCountPtr
< const Lang::ColorSpace
> space
= val
->getVal
< const Lang::ColorSpace
>( bindingExpr
->exprLoc( ) );
986 if( ! space
->isBlendable( ) )
988 throw Exceptions::OutOfRange( bindingExpr
->exprLoc( ), strrefdup( "This color space cannot be used in blending." ) );
991 Kernel::ContRef cont
= evalState
->cont_
;
992 cont
->takeValue( Kernel::ValueRef( new Lang::BlendSpaceBinding( id_
, bindingExpr
, space
) ),
997 Kernel::SpotDynamicVariableProperties::SpotDynamicVariableProperties( const Ast::PlacedIdentifier
* id
)
998 : Kernel::DynamicVariableProperties( id
)
1001 Kernel::SpotDynamicVariableProperties::~SpotDynamicVariableProperties( )
1004 Kernel::VariableHandle
1005 Kernel::SpotDynamicVariableProperties::fetch( const Kernel::PassedDyn
& dyn
) const
1007 /* Note that this code should be very similar to Core_spot::call.
1010 static RefCountPtr
< const Lang::ElementaryPath2D
> pth
= RefCountPtr
< const Lang::ElementaryPath2D
>( NullPtr
< const Lang::ElementaryPath2D
>( ) );
1011 if( pth
== NullPtr
< const Lang::ElementaryPath2D
>( ) )
1013 Lang::ElementaryPath2D
* mem
= new Lang::ElementaryPath2D
;
1014 mem
->push_back( new Concrete::PathPoint2D( Concrete::ZERO_LENGTH
, Concrete::ZERO_LENGTH
) );
1015 if( Kernel::allowSingletonPaths
)
1021 mem
->push_back( new Concrete::PathPoint2D( Concrete::ZERO_LENGTH
, Concrete::ZERO_LENGTH
) );
1023 pth
= RefCountPtr
< const Lang::ElementaryPath2D
>( mem
);
1026 Kernel::GraphicsState
* capState( new Kernel::GraphicsState( *dyn
->getGraphicsState( ) ) );
1027 capState
->cap_
= Lang::CapStyle::CAP_ROUND
;
1029 return Helpers::newValHandle( new Lang::PaintedPath2D
1030 ( RefCountPtr
< const Kernel::GraphicsState
>( capState
),
1036 Kernel::SpotDynamicVariableProperties::makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const
1038 std::ostringstream msg
;
1039 msg
<< "The dynamic variable " ;
1040 id_
->show( msg
, Ast::Identifier::DYNAMIC_VARIABLE
);
1041 msg
<< " cannot be changed from its default." ;
1042 throw Exceptions::MiscellaneousRequirement( strrefdup( msg
) );
1046 Kernel::DynamicEnvironment::KeyType
Kernel::DynamicEnvironment::nextKey( 0 );
1048 Kernel::DynamicEnvironment::KeyType
1049 Kernel::DynamicEnvironment::getFreshKey( )
1057 Lang::DynamicExpression::DynamicExpression( Kernel::PassedEnv env
, Ast::Expression
* expr
)
1058 : env_( env
), expr_( expr
)
1061 Lang::DynamicExpression::~DynamicExpression( )
1064 RefCountPtr
< const Lang::Class
> Lang::DynamicExpression::TypeID( new Lang::SystemFinalClass( strrefdup( "DynamicExpression" ) ) );
1065 TYPEINFOIMPL( DynamicExpression
);
1068 Lang::DynamicExpression::evalHelper( Kernel::EvalState
* evalState
) const
1070 evalState
->env_
= env_
;
1071 evalState
->expr_
= expr_
;
1075 Lang::DynamicExpression::gcMark( Kernel::GCMarkedSet
& marked
)
1077 env_
->gcMark( marked
);
1082 Kernel::registerDynamic( Kernel::Environment
* env
)
1084 env
->initDefineDynamic( new Kernel::WidthDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_WIDTH
) );
1085 env
->initDefineDynamic( new Kernel::CapStyleDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "cap" ) ) );
1086 env
->initDefineDynamic( new Kernel::JoinStyleDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "join" ) ) );
1087 env
->initDefineDynamic( new Kernel::MiterLimitDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "miterlimit" ) ) );
1088 env
->initDefineDynamic( new Kernel::StrokingDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_STROKING
) );
1089 env
->initDefineDynamic( new Kernel::NonStrokingDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_NONSTROKING
) );
1090 env
->initDefineDynamic( new Kernel::DashDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "dash" ) ) );
1091 env
->initDefineDynamic( new Kernel::BlendModeDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "blend" ) ) );
1092 env
->initDefineDynamic( new Kernel::AlphaDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "nonstrokingalpha" ), false ) );
1093 env
->initDefineDynamic( new Kernel::AlphaDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits
, "strokingalpha" ), true ) );
1095 env
->initDefineDynamic( new Kernel::ReflectionsDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits_Light
, "reflections" ) ) );
1096 env
->initDefineDynamic( new Kernel::AutoIntensityDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY
) );
1097 env
->initDefineDynamic( new Kernel::AutoScatteringDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits_Light
, "autoscattering" ) ) );
1098 env
->initDefineDynamic( new Kernel::ViewResolutionDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits_Light
, "facetresolution" ) ) );
1099 env
->initDefineDynamic( new Kernel::ShadeOrderDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Traits_Light
, "shadeorder" ) ) );
1101 env
->initDefineDynamic( new Kernel::CharacterSpacingDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "characterspacing" ) ) );
1102 env
->initDefineDynamic( new Kernel::WordSpacingDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "wordspacing" ) ) );
1103 env
->initDefineDynamic( new Kernel::HorizontalScalingDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "horizontalscaling" ) ) );
1104 env
->initDefineDynamic( new Kernel::LeadingDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "leading" ) ) );
1105 env
->initDefineDynamic( new Kernel::FontDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_TEXT_FONT
) );
1106 env
->initDefineDynamic( new Kernel::TextSizeDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_TEXT_SIZE
) );
1107 env
->initDefineDynamic( new Kernel::TextRenderingModeDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "rendering" ) ) );
1108 env
->initDefineDynamic( new Kernel::TextRiseDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "rise" ) ) );
1109 env
->initDefineDynamic( new Kernel::TextKnockoutDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Text
, "knockout" ) ) );
1111 env
->initDefineDynamic( new Kernel::TeXBleedDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_TEX_BLEED
) );
1113 env
->initDefineDynamic( new Kernel::EyeZDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_EYEZ
) );
1114 env
->initDefineDynamic( new Kernel::DefaultUnitDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT
) );
1115 env
->initDefineDynamic( new Kernel::BlendSpaceDynamicVariableProperties( & Lang::DYNAMIC_VARIABLE_ID_BLEND_SPACE
) );
1117 env
->initDefineDynamic( new Kernel::SpotDynamicVariableProperties( Kernel::Environment::newPlacedIdentifier( Lang::THE_NAMESPACE_Shapes_Graphics
, "spot" ) ) );