New standard continuation: error.
[shapes.git] / source / dynamicenvironment.cc
bloba4a685a48431b73c3dacf06ffa1a3b5192f528f1
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
6 * any later version.
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 Henrik Tidefelt
19 #include <cmath>
21 #include "Shapes_Helpers_decls.h"
23 #include "dynamicenvironment.h"
24 #include "hottypes.h"
25 #include "globals.h"
26 #include "shapescore.h"
27 #include "ast.h"
28 #include "astvar.h"
29 #include "isnan.h"
30 #include "continuations.h"
31 #include "check.h"
33 #include <limits>
34 #include <iomanip>
36 using namespace Shapes;
39 void
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" );
46 Concrete::Length x0;
47 Concrete::Length y0;
48 Concrete::Length x3;
49 Concrete::Length y3;
50 double ag0; /* global angles that will later be compared with aRef */
51 double ag1;
53 if( reverseDirection_ )
55 x0 = p1_->mid_->x_;
56 y0 = p1_->mid_->y_;
57 x3 = p0_->mid_->x_;
58 y3 = p0_->mid_->y_;
59 ag0 = p1_->rearAngle_;
60 ag1 = p0_->frontAngle_;
62 else
64 x0 = p0_->mid_->x_;
65 y0 = p0_->mid_->y_;
66 x3 = p1_->mid_->x_;
67 y3 = p1_->mid_->y_;
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." );
89 CHECK(
90 if( IS_NAN( ag0 ) )
92 std::ostringstream msg;
93 msg << "Using uninitialized adjacent angle in "
94 << "(" << Concrete::Length::offtype( x0 ) << "bp," << Concrete::Length::offtype( y0 ) << "bp)"
95 << "--"
96 << "(" << Concrete::Length::offtype( x3 ) << "bp," << Concrete::Length::offtype( y3 ) << "bp)" ;
97 throw Exceptions::InternalError( strrefdup( msg ) );
101 double ar0 = aRef - ag0;
102 if( ar0 < - M_PI )
106 ar0 += 2 * M_PI;
108 while( ar0 < - M_PI );
110 else
112 while( ar0 > M_PI )
114 ar0 -= 2 * M_PI;
118 double ar1 = ag1 - aRef - M_PI;
119 if( IS_NAN( ag1 ) )
121 /* The angle is NaN is there is no opposite angle. The implicit direction is then towards the neighboring point.
123 ar1 = 0;
125 else
127 if( ar1 < - M_PI )
131 ar1 += 2 * M_PI;
133 while( ar1 < - M_PI );
135 else
137 while( ar1 > M_PI )
139 ar1 -= 2 * M_PI;
144 if( ar0 < 0 )
146 ar0 = - ar0;
147 ar1 = - ar1;
150 ar1 -= ar0;
152 if( ar1 < - M_PI )
154 ar1 += 2 * M_PI;
156 else if( ar1 > M_PI )
158 ar1 -= 2 * M_PI;
161 *a0 = ar0;
162 *a1 = ar1;
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 )
185 void
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_ ) )
220 eyez_ = other.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_;
239 void
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_ ) )
264 os << indentation << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_EYEZ << ": " << eyez_ / Interaction::displayUnit << Interaction::displayUnitName << std::endl ;
267 if( ! IS_NAN( TeX_bleed_ ) )
269 os << indentation << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_TEX_BLEED << ": " << TeX_bleed_ / Interaction::displayUnit << Interaction::displayUnitName << std::endl ;
272 if( defaultUnit_ != NullPtr< const Kernel::PolarHandlePromise >( ) )
274 os << indentation << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT << ": " ;
275 defaultUnit_->show( os );
276 os << std::endl ;
279 if( blendSpace_ != NullPtr< const Lang::ColorSpace >( ) )
281 os << indentation << Interaction::DYNAMIC_VARIABLE_PREFIX << Lang::DYNAMIC_VARIABLE_ID_BLEND_SPACE << ": " ;
282 if( blendSpace_->isInherent( ) )
284 os << "< inherent >" << std::endl ;
286 else
288 os << blendSpace_->name( ) << std::endl ;
295 Kernel::DynamicEnvironment::DynamicEnvironment( const RefCountPtr< const Kernel::GraphicsState > & graphicsState )
296 : parent_( NullPtr< Kernel::DynamicEnvironment >( ) ), sysBindings_( new Kernel::SystemDynamicVariables( graphicsState ) ), specialBindings_( 0 ),
297 contId_( Lang::CONTINUATION_ID_ERROR ), contVal_( Kernel::ContRef( new Kernel::DefaultErrorContinuation( Ast::theProgram->loc( ) ) ) )
300 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr< Kernel::DynamicEnvironment > parent, const Lang::DynamicBindings & bindings )
301 : parent_( NullPtr< Kernel::DynamicEnvironment >( ) ), sysBindings_( 0 ), specialBindings_( 0 ),
302 contId_( 0 ), contVal_( NullPtr< Kernel::Continuation >( ) )
304 bindings.bind( bindings_, & sysBindings_ );
305 if( sysBindings_ != 0 &&
306 sysBindings_->graphicsState_ != NullPtr< const Kernel::GraphicsState >( ) )
308 sysBindings_->graphicsState_ =
309 RefCountPtr< const Kernel::GraphicsState >( new Kernel::GraphicsState( *(sysBindings_->graphicsState_),
310 *(parent->getGraphicsState( )) ) );
312 if( sysBindings_ != 0 &&
313 sysBindings_->facetState_ != NullPtr< const Kernel::FacetState >( ) )
315 sysBindings_->facetState_ =
316 RefCountPtr< const Kernel::FacetState >( new Kernel::FacetState( *(sysBindings_->facetState_),
317 *(parent->getFacetState( )) ) );
319 if( sysBindings_ != 0 &&
320 sysBindings_->textState_ != NullPtr< const Kernel::TextState >( ) )
322 sysBindings_->textState_ =
323 RefCountPtr< const Kernel::TextState >( new Kernel::TextState( *(sysBindings_->textState_),
324 *(parent->getTextState( )) ) );
326 parent_ = parent->selectParent( parent, bindings_ );
329 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr< Kernel::DynamicEnvironment > parent, const RefCountPtr< const Kernel::GraphicsState > & graphicsState )
330 : parent_( parent ), sysBindings_( new Kernel::SystemDynamicVariables( ) ), specialBindings_( 0 ),
331 contId_( 0 ), contVal_( NullPtr< Kernel::Continuation >( ) )
333 sysBindings_->graphicsState_ = graphicsState;
336 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr< Kernel::DynamicEnvironment > parent, Kernel::SystemDynamicVariables * sysBindings )
337 : parent_( parent ), sysBindings_( sysBindings ), specialBindings_( 0 ),
338 contId_( 0 ), contVal_( NullPtr< Kernel::Continuation >( ) )
341 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr< Kernel::DynamicEnvironment > parent, Kernel::SpecialUnitVariables * specialBindings )
342 : parent_( parent ), sysBindings_( 0 ), specialBindings_( specialBindings ),
343 contId_( 0 ), contVal_( NullPtr< Kernel::Continuation >( ) )
346 Kernel::DynamicEnvironment::DynamicEnvironment( RefCountPtr< Kernel::DynamicEnvironment > parent, const char * contId, const Kernel::ContRef & contVal )
347 : parent_( parent ), sysBindings_( 0 ), specialBindings_( 0 ),
348 contId_( contId ), contVal_( contVal )
351 Kernel::DynamicEnvironment::~DynamicEnvironment( )
353 if( sysBindings_ != 0 )
355 delete sysBindings_;
357 if( specialBindings_ != 0 )
359 delete specialBindings_;
363 void
364 Kernel::DynamicEnvironment::tackOn( const KeyType & key, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Value > & piece, const Ast::SourceLocation & callLoc )
366 throw Exceptions::NotImplemented( "DynamicEnvironment::tackOn" );
367 // MapType::iterator i = bindings_.find( key );
368 // if( i == bindings_.end( ) )
369 // {
370 // if( isBaseEnvironment( ) )
371 // {
372 // throw Exceptions::InternalError( "Key of dynamic variable was not found in dynamic environment." );
373 // }
374 // return parent_->tackOn( key, evalState, piece, callLoc );
375 // }
376 // return i->second.first->tackOn( evalState, piece, callLoc );
379 void
380 Kernel::DynamicEnvironment::lookup( const KeyType & key, Kernel::EvalState * evalState ) const
382 MapType::const_iterator i = bindings_.find( key );
383 if( i == bindings_.end( ) )
385 if( isBaseEnvironment( ) )
387 throw NonLocalExit::DynamicBindingNotFound( );
389 return parent_->lookup( key, evalState );
392 Kernel::ContRef cont = evalState->cont_;
393 cont->takeHandle( i->second.first,
394 evalState );
397 Kernel::VariableHandle
398 Kernel::DynamicEnvironment::getVarHandle( const KeyType & key ) const
400 MapType::const_iterator i = bindings_.find( key );
401 if( i == bindings_.end( ) )
403 if( isBaseEnvironment( ) )
405 throw NonLocalExit::DynamicBindingNotFound( );
407 return parent_->getVarHandle( key );
409 return i->second.first;
412 RefCountPtr< Kernel::DynamicEnvironment >
413 Kernel::DynamicEnvironment::selectParent( RefCountPtr< Kernel::DynamicEnvironment > & self, const MapType & newBindings )
415 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) ||
416 sysBindings_ != 0 ||
417 specialBindings_ != 0 ||
418 contId_ != 0 )
420 return self;
423 MapType::const_iterator hint = newBindings.begin( );
424 for( MapType::const_iterator i = bindings_.begin( ); i != bindings_.end( ); ++i )
426 hint = newBindings.find( i->first );
427 if( hint == newBindings.end( ) )
429 return self;
433 return parent_->selectParent( parent_, newBindings );
436 void
437 Kernel::DynamicEnvironment::gcMark( Kernel::GCMarkedSet & marked )
439 for( MapType::iterator i = bindings_.begin( ); i != bindings_.end( ); ++i )
441 i->second.first->gcMark( marked );
446 RefCountPtr< const Kernel::GraphicsState >
447 Kernel::DynamicEnvironment::getGraphicsState( ) const
449 if( sysBindings_ == 0 ||
450 sysBindings_->graphicsState_ == NullPtr< const Kernel::GraphicsState >( ) )
452 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
454 throw Exceptions::InternalError( "The graphics state was needed but not defined." );
456 return parent_->getGraphicsState( );
459 return sysBindings_->graphicsState_;
462 RefCountPtr< const Kernel::FacetState >
463 Kernel::DynamicEnvironment::getFacetState( ) const
465 if( sysBindings_ == 0 ||
466 sysBindings_->facetState_ == NullPtr< const Kernel::FacetState >( ) )
468 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
470 throw Exceptions::InternalError( "The facet state was needed but not defined." );
472 return parent_->getFacetState( );
475 return sysBindings_->facetState_;
478 RefCountPtr< const Kernel::TextState >
479 Kernel::DynamicEnvironment::getTextState( ) const
481 if( sysBindings_ == 0 ||
482 sysBindings_->textState_ == NullPtr< const Kernel::TextState >( ) )
484 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
486 throw Exceptions::InternalError( "The text state was needed but not defined." );
488 return parent_->getTextState( );
491 return sysBindings_->textState_;
494 Concrete::Length
495 Kernel::DynamicEnvironment::getEyeZ( ) const
497 if( sysBindings_ == 0 ||
498 IS_NAN( sysBindings_->eyez_ ) )
500 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
502 throw Exceptions::InternalError( "@eyez should allways be bound." );
504 return parent_->getEyeZ( );
507 return sysBindings_->eyez_;
510 Concrete::Length
511 Kernel::DynamicEnvironment::getTeXBleed( ) const
513 if( sysBindings_ == 0 ||
514 IS_NAN( sysBindings_->TeX_bleed_ ) )
516 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
518 throw Exceptions::InternalError( "@TeX_bleed should allways be bound." );
520 return parent_->getTeXBleed( );
523 return sysBindings_->TeX_bleed_;
526 RefCountPtr< const Kernel::PolarHandlePromise >
527 Kernel::DynamicEnvironment::getDefaultUnit( ) const
529 if( sysBindings_ == 0 ||
530 sysBindings_->defaultUnit_ == NullPtr< const Kernel::PolarHandlePromise >( ) )
532 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
534 throw Exceptions::InternalError( "The default unit should allways be defined." );
536 return parent_->getDefaultUnit( );
539 return sysBindings_->defaultUnit_;
542 Kernel::ContRef
543 Kernel::DynamicEnvironment::getEscapeContinuation( const char * id, const Ast::SourceLocation & loc ) const
545 if( contId_ == 0 ||
546 strcmp( contId_, id ) != 0 )
548 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
550 throw Exceptions::UndefinedEscapeContinuation( id, loc );
552 return parent_->getEscapeContinuation( id, loc );
555 return contVal_;
558 RefCountPtr< const Lang::ColorSpace >
559 Kernel::DynamicEnvironment::getBlendSpace( ) const
561 if( sysBindings_ == 0 ||
562 sysBindings_->blendSpace_ == NullPtr< const Lang::ColorSpace >( ) )
564 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
566 throw Exceptions::InternalError( "The blend space should allways be defined." );
568 return parent_->getBlendSpace( );
571 return sysBindings_->blendSpace_;
574 void
575 Kernel::DynamicEnvironment::specialUnitService( Concrete::Length * d, double * a0, double * a1 )
577 if( specialBindings_ != 0 )
579 specialBindings_->specialUnitService( d, a0, a1 );
581 else
583 if( parent_ == NullPtr< Kernel::DynamicEnvironment >( ) )
585 throw Exceptions::InternalError( "The special unit dynamic context was needed but not defined." );
587 parent_->specialUnitService( d, a0, a1 );
591 bool
592 Kernel::DynamicEnvironment::isBaseEnvironment( ) const
594 return parent_ == NullPtr< Kernel::DynamicEnvironment >( );
597 void
598 Kernel::DynamicEnvironment::print( std::ostream & os ) const
600 std::set< MapType::key_type > shadowed;
601 recursivePrint( os, & shadowed );
604 size_t
605 Kernel::DynamicEnvironment::recursivePrint( std::ostream & os, std::set< MapType::key_type > * shadowed ) const
607 std::set< MapType::key_type > shadowedBefore( *shadowed );
609 size_t depth = 0;
610 if( ! isBaseEnvironment( ) )
612 for( MapType::const_iterator i = bindings_.begin( ); i != bindings_.end( ); ++i )
614 shadowed->insert( shadowed->begin( ), i->first );
616 depth = parent_->recursivePrint( os, shadowed ) + 1;
619 std::string indentation = std::string( depth, ' ' );
621 os << indentation << "@@ -- -- -- -- -- -- -- -- @@" << std::endl ;
623 if( contId_ != 0 )
625 os << indentation << " (esc) " << "< escape continuation > " << contId_ << ": " << contVal_->traceLoc( ) << " (" << contVal_->description( ) << ")" << std::endl ;
628 if( sysBindings_ != 0 )
630 sysBindings_->print( os, indentation + " (sys) " ); /* The extra indentation matches " (num) " */
633 if( specialBindings_ != 0 )
635 os << indentation << " (-- ) " << "< special unit points >: " << *(specialBindings_->p0_->mid_) << ( (specialBindings_->reverseDirection_) ? " <-- " : " --> " ) << *(specialBindings_->p1_->mid_) << std::endl ;
638 for( MapType::const_iterator i = bindings_.begin( ); i != bindings_.end( ); ++i )
640 os << indentation ;
641 if( shadowedBefore.find( i->first ) != shadowedBefore.end( ) )
643 os << "#" ;
645 else
647 os << " " ;
649 os << "(" << std::setw(3) << i->first << ") " << Interaction::DYNAMIC_VARIABLE_PREFIX << i->second.second->id( ) << ": " ;
650 if( i->second.first == NullPtr< Kernel::Variable >( ) )
652 os << "< Uninitialized >" ;
654 else if( i->second.first->isThunk( ) )
656 os << "< thunk >" ;
658 else if( dynamic_cast< const Lang::Instance * >( i->second.first->getUntyped( ).getPtr( ) ) == 0 )
660 i->second.first->getUntyped( )->show( os );
662 else
664 os << "..." ;
666 os << " (" << i->second.second->idLoc( ) << ")" << std::endl ;
669 // os << indentation << "-- -- -- -- -- -- -- -- -- --" << std::endl ;
671 return depth;
674 Lang::EyeZBinding::EyeZBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, Concrete::Length val )
675 : bindingExpr_( bindingExpr ), val_( val ), id_( id )
678 Lang::EyeZBinding::~EyeZBinding( )
681 void
682 Lang::EyeZBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
684 if( *sysBindings == 0 )
686 *sysBindings = new Kernel::SystemDynamicVariables( );
687 (*sysBindings)->eyez_ = val_;
688 return;
691 if( ! IS_NAN( (*sysBindings)->eyez_ ) )
693 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
696 (*sysBindings)->eyez_ = val_;
699 void
700 Lang::EyeZBinding::show( std::ostream & os ) const
702 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":"
703 << val_ / Interaction::displayUnit << Interaction::displayUnitName ;
706 void
707 Lang::EyeZBinding::gcMark( Kernel::GCMarkedSet & marked )
712 Kernel::EyeZDynamicVariableProperties::EyeZDynamicVariableProperties( const char * _name )
713 : Kernel::DynamicVariableProperties( _name )
716 Kernel::EyeZDynamicVariableProperties::~EyeZDynamicVariableProperties( )
719 Kernel::VariableHandle
720 Kernel::EyeZDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
722 return Helpers::newValHandle( new Lang::Length( dyn->getEyeZ( ) ) );
725 void
726 Kernel::EyeZDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
730 RefCountPtr< const Lang::Length > len = val->tryVal< const Lang::Length >( );
731 Kernel::ContRef cont = evalState->cont_;
732 cont->takeValue( Kernel::ValueRef( new Lang::EyeZBinding( name_, bindingExpr, len->get( ) ) ),
733 evalState );
734 return;
736 catch( const NonLocalExit::NotThisType & ball )
738 /* never mind */
743 RefCountPtr< const Lang::Float > maybeInfinity = val->tryVal< const Lang::Float >( );
744 if( maybeInfinity->val_ < HUGE_VAL )
746 throw Exceptions::OutOfRange( bindingExpr->exprLoc( ), strrefdup( "The only float value allowed here is infinity." ) );
748 Kernel::ContRef cont = evalState->cont_;
749 cont->takeValue( Kernel::ValueRef( new Lang::EyeZBinding( name_, bindingExpr, Concrete::HUGE_LENGTH ) ),
750 evalState );
751 return;
753 catch( const NonLocalExit::NotThisType & ball )
755 /* never mind */
758 throw Exceptions::TypeMismatch( bindingExpr->exprLoc( ), val->getUntyped( )->getTypeName( ), Helpers::typeSetString( Lang::Length::staticTypeName( ), Lang::Float::staticTypeName( ) ) );
762 Lang::DefaultUnitBinding::DefaultUnitBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const RefCountPtr< const Kernel::PolarHandlePromise > & val )
763 : bindingExpr_( bindingExpr ), val_( val ), id_( id )
766 Lang::DefaultUnitBinding::~DefaultUnitBinding( )
769 void
770 Lang::DefaultUnitBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
772 if( *sysBindings == 0 )
774 *sysBindings = new Kernel::SystemDynamicVariables( );
775 (*sysBindings)->defaultUnit_ = val_;
776 return;
779 if( (*sysBindings)->defaultUnit_ != NullPtr< const Kernel::PolarHandlePromise >( ) )
781 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
784 (*sysBindings)->defaultUnit_ = val_;
787 void
788 Lang::DefaultUnitBinding::show( std::ostream & os ) const
790 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":<promise>" ;
793 void
794 Lang::DefaultUnitBinding::gcMark( Kernel::GCMarkedSet & marked )
796 val_->gcMark( marked );
800 Kernel::DefaultUnitDynamicVariableProperties::DefaultUnitDynamicVariableProperties( const char * _name )
801 : Kernel::DynamicVariableProperties( _name )
804 Kernel::DefaultUnitDynamicVariableProperties::~DefaultUnitDynamicVariableProperties( )
807 Kernel::VariableHandle
808 Kernel::DefaultUnitDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
810 throw Exceptions::MiscellaneousRequirement( "The default unit cannot be evaluated as a variable." );
813 void
814 Kernel::DefaultUnitDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
816 if( ! val->isThunk( ) )
818 throw Exceptions::InternalError( "The default unit handle was not a thunk." );
821 Kernel::ContRef cont = evalState->cont_;
822 cont->takeValue( Kernel::ValueRef( new Lang::DefaultUnitBinding( name_, bindingExpr, RefCountPtr< const Kernel::PolarHandlePromise >( new Kernel::PolarHandleTruePromise( val->copyThunk( ) ) ) ) ),
823 evalState );
824 return;
828 Lang::TeXBleedBinding::TeXBleedBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, Concrete::Length val )
829 : bindingExpr_( bindingExpr ), val_( val ), id_( id )
832 Lang::TeXBleedBinding::~TeXBleedBinding( )
835 void
836 Lang::TeXBleedBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
838 if( *sysBindings == 0 )
840 *sysBindings = new Kernel::SystemDynamicVariables( );
841 (*sysBindings)->TeX_bleed_ = val_;
842 return;
845 if( ! IS_NAN( (*sysBindings)->TeX_bleed_ ) )
847 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
850 (*sysBindings)->TeX_bleed_ = val_;
853 void
854 Lang::TeXBleedBinding::show( std::ostream & os ) const
856 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << ":"
857 << val_ / Interaction::displayUnit << Interaction::displayUnitName ;
860 void
861 Lang::TeXBleedBinding::gcMark( Kernel::GCMarkedSet & marked )
866 Kernel::TeXBleedDynamicVariableProperties::TeXBleedDynamicVariableProperties( const char * _name )
867 : Kernel::DynamicVariableProperties( _name )
870 Kernel::TeXBleedDynamicVariableProperties::~TeXBleedDynamicVariableProperties( )
873 Kernel::VariableHandle
874 Kernel::TeXBleedDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
876 return Helpers::newValHandle( new Lang::Length( dyn->getTeXBleed( ) ) );
879 void
880 Kernel::TeXBleedDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
882 RefCountPtr< const Lang::Length > len = val->getVal< const Lang::Length >( bindingExpr->exprLoc( ) );
883 Kernel::ContRef cont = evalState->cont_;
884 cont->takeValue( Kernel::ValueRef( new Lang::TeXBleedBinding( name_, bindingExpr, len->get( ) ) ),
885 evalState );
889 Lang::BlendSpaceBinding::BlendSpaceBinding( const char * id, const Ast::DynamicBindingExpression * bindingExpr, const RefCountPtr< const Lang::ColorSpace > & space )
890 : bindingExpr_( bindingExpr ), space_( space ), id_( id )
893 Lang::BlendSpaceBinding::~BlendSpaceBinding( )
896 void
897 Lang::BlendSpaceBinding::bind( MapType & bindings, Kernel::SystemDynamicVariables ** sysBindings ) const
899 if( *sysBindings == 0 )
901 *sysBindings = new Kernel::SystemDynamicVariables( );
902 (*sysBindings)->blendSpace_ = space_;
903 return;
906 if( (*sysBindings)->blendSpace_ != NullPtr< const Lang::ColorSpace >( ) )
908 throw Exceptions::MultipleDynamicBind( id_, bindingExpr_->idLoc( ), Ast::THE_UNKNOWN_LOCATION );
911 (*sysBindings)->blendSpace_ = space_;
914 void
915 Lang::BlendSpaceBinding::show( std::ostream & os ) const
917 os << Interaction::DYNAMIC_VARIABLE_PREFIX << id_ << "" ;
918 space_->show( os );
921 void
922 Lang::BlendSpaceBinding::gcMark( Kernel::GCMarkedSet & marked )
927 Kernel::BlendSpaceDynamicVariableProperties::BlendSpaceDynamicVariableProperties( const char * _name )
928 : Kernel::DynamicVariableProperties( _name )
931 Kernel::BlendSpaceDynamicVariableProperties::~BlendSpaceDynamicVariableProperties( )
934 Kernel::VariableHandle
935 Kernel::BlendSpaceDynamicVariableProperties::fetch( const Kernel::PassedDyn & dyn ) const
937 return Kernel::VariableHandle( new Kernel::Variable( dyn->getBlendSpace( ) ) );
940 void
941 Kernel::BlendSpaceDynamicVariableProperties::makeBinding( Kernel::VariableHandle val, const Ast::DynamicBindingExpression * bindingExpr, Kernel::EvalState * evalState ) const
943 RefCountPtr< const Lang::ColorSpace > space = val->getVal< const Lang::ColorSpace >( bindingExpr->exprLoc( ) );
944 if( ! space->isBlendable( ) )
946 throw Exceptions::OutOfRange( bindingExpr->exprLoc( ), strrefdup( "This color space cannot be used in blending." ) );
949 Kernel::ContRef cont = evalState->cont_;
950 cont->takeValue( Kernel::ValueRef( new Lang::BlendSpaceBinding( name_, bindingExpr, space ) ),
951 evalState );
955 Kernel::DynamicEnvironment::KeyType Kernel::DynamicEnvironment::nextKey( 0 );
957 Kernel::DynamicEnvironment::KeyType
958 Kernel::DynamicEnvironment::getFreshKey( )
960 ++nextKey;
961 return nextKey;
966 Lang::DynamicExpression::DynamicExpression( Kernel::PassedEnv env, Ast::Expression * expr )
967 : env_( env ), expr_( expr )
970 Lang::DynamicExpression::~DynamicExpression( )
973 RefCountPtr< const Lang::Class > Lang::DynamicExpression::TypeID( new Lang::SystemFinalClass( strrefdup( "DynamicExpression" ) ) );
974 TYPEINFOIMPL( DynamicExpression );
976 void
977 Lang::DynamicExpression::evalHelper( Kernel::EvalState * evalState ) const
979 evalState->env_ = env_;
980 evalState->expr_ = expr_;
983 void
984 Lang::DynamicExpression::gcMark( Kernel::GCMarkedSet & marked )
986 env_->gcMark( marked );
990 void
991 Kernel::registerDynamic( Kernel::Environment * env )
993 env->initDefineDynamic( new Kernel::WidthDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_WIDTH ) );
994 env->initDefineDynamic( new Kernel::CapStyleDynamicVariableProperties( "cap" ) );
995 env->initDefineDynamic( new Kernel::JoinStyleDynamicVariableProperties( "join" ) );
996 env->initDefineDynamic( new Kernel::MiterLimitDynamicVariableProperties( "miterlimit" ) );
997 env->initDefineDynamic( new Kernel::StrokingDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_STROKING ) );
998 env->initDefineDynamic( new Kernel::NonStrokingDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_NONSTROKING ) );
999 env->initDefineDynamic( new Kernel::DashDynamicVariableProperties( "dash" ) );
1000 env->initDefineDynamic( new Kernel::BlendModeDynamicVariableProperties( "blend" ) );
1001 env->initDefineDynamic( new Kernel::AlphaDynamicVariableProperties( "nonstrokingalpha", false ) );
1002 env->initDefineDynamic( new Kernel::AlphaDynamicVariableProperties( "strokingalpha", true ) );
1004 env->initDefineDynamic( new Kernel::ReflectionsDynamicVariableProperties( "reflections" ) );
1005 env->initDefineDynamic( new Kernel::AutoIntensityDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_AUTOINTENSITY ) );
1006 env->initDefineDynamic( new Kernel::AutoScatteringDynamicVariableProperties( "autoscattering" ) );
1007 env->initDefineDynamic( new Kernel::ViewResolutionDynamicVariableProperties( "facetresolution" ) );
1008 env->initDefineDynamic( new Kernel::ShadeOrderDynamicVariableProperties( "shadeorder" ) );
1010 env->initDefineDynamic( new Kernel::CharacterSpacingDynamicVariableProperties( "text_characterspacing" ) );
1011 env->initDefineDynamic( new Kernel::WordSpacingDynamicVariableProperties( "text_wordspacing" ) );
1012 env->initDefineDynamic( new Kernel::HorizontalScalingDynamicVariableProperties( "text_horizontalscaling" ) );
1013 env->initDefineDynamic( new Kernel::LeadingDynamicVariableProperties( "text_leading" ) );
1014 env->initDefineDynamic( new Kernel::FontDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_TEXT_FONT ) );
1015 env->initDefineDynamic( new Kernel::TextSizeDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_TEXT_SIZE ) );
1016 env->initDefineDynamic( new Kernel::TextRenderingModeDynamicVariableProperties( "text_rendering" ) );
1017 env->initDefineDynamic( new Kernel::TextRiseDynamicVariableProperties( "text_rise" ) );
1018 env->initDefineDynamic( new Kernel::TextKnockoutDynamicVariableProperties( "text_knockout" ) );
1020 env->initDefineDynamic( new Kernel::TeXBleedDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_TEX_BLEED ) );
1022 env->initDefineDynamic( new Kernel::EyeZDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_EYEZ ) );
1023 env->initDefineDynamic( new Kernel::DefaultUnitDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_DEFAULT_UNIT ) );
1024 env->initDefineDynamic( new Kernel::BlendSpaceDynamicVariableProperties( Lang::DYNAMIC_VARIABLE_ID_BLEND_SPACE ) );