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
19 #include "Shapes_Helpers_decls.h"
23 #include "continuations.h"
24 #include "texttypes.h"
25 #include "fontmetrics.h"
28 #include "pdfstructure.h"
29 #include "timetypes.h"
30 #include "shapescore.h"
34 #include <sys/resource.h>
38 using namespace Shapes
;
41 Lang::Hot::Hot::Hot( )
47 RefCountPtr
< const Lang::Class
> Lang::Hot::TypeID( new Lang::SystemFinalClass( strrefdup( "Hot" ) ) );
51 Lang::HotTriple::HotTriple( const RefCountPtr
< const Lang::Value
> & init
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
52 : init_( init
), update_( update
), result_( result
)
55 Lang::HotTriple::~HotTriple( )
59 Lang::HotTriple::newState( ) const
61 return new Kernel::WarmTriple( init_
, update_
, result_
);
65 Lang::HotTriple::gcMark( Kernel::GCMarkedSet
& marked
)
67 const_cast< Lang::Value
* >( init_
.getPtr( ) )->gcMark( marked
);
68 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
69 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
74 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, Kernel::WarmRandomDevice
* dev
)
75 : sz_( sz
), state_( new char[ sz
] )
77 char * oldState
= initstate( 1, state_
, sz_
);
78 dev
->read( state_
, sz_
);
82 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, unsigned long seed
)
83 : sz_( sz
), state_( new char[ sz
] )
85 char * oldState
= initstate( seed
, state_
, sz_
);
89 Lang::HotRandomSeed::~HotRandomSeed( )
95 Lang::HotRandomSeed::newState( ) const
97 char * stateCopy
= new char[ sz_
];
98 memcpy( stateCopy
, state_
, sz_
);
99 return new Kernel::WarmRandomState( stateCopy
); // This handles ownership to the new state.
103 Lang::HotRandomSeed::gcMark( Kernel::GCMarkedSet
& marked
)
109 Kernel::WarmTriple::WarmTriple( const RefCountPtr
< const Lang::Value
> & pile
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
110 : pile_( pile
), update_( update
), result_( result
)
113 Kernel::WarmTriple::~WarmTriple( )
116 RefCountPtr
< const Lang::Class
> Kernel::WarmTriple::TypeID( new Lang::SystemFinalClass( strrefdup( "#UserState" ) ) );
117 TYPEINFOIMPL_STATE( WarmTriple
);
120 Kernel::WarmTriple::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
122 /* This seems dangerous. I have not verified that pile will still exist when the continuation below is invoked.
124 evalState
->cont_
= Kernel::ContRef( new Kernel::StmtStoreValueContinuation( & pile_
,
127 update_
->call( evalState
, pile_
, piece
, callLoc
);
131 Kernel::WarmTriple::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
133 /* The right continuation is set by the calling variable.
135 result_
->call( evalState
, pile_
, callLoc
);
139 Kernel::WarmTriple::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
141 /* The right continuation is set by the calling variable.
143 result_
->call( evalState
, pile_
, callLoc
);
147 Kernel::WarmTriple::gcMark( Kernel::GCMarkedSet
& marked
)
149 const_cast< Lang::Value
* >( pile_
.getPtr( ) )->gcMark( marked
);
150 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
151 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
155 Kernel::WarmIgnore::WarmIgnore( )
158 Kernel::WarmIgnore::~WarmIgnore( )
161 RefCountPtr
< const Lang::Class
> Kernel::WarmIgnore::TypeID( new Lang::SystemFinalClass( strrefdup( "#Ignore" ) ) );
162 TYPEINFOIMPL_STATE( WarmIgnore
);
165 Kernel::WarmIgnore::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
169 Kernel::ContRef cont
= evalState
->cont_
;
170 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
175 Kernel::WarmIgnore::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
177 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be frozen." ) );
181 Kernel::WarmIgnore::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
183 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be peeked." ) );
187 Kernel::WarmIgnore::gcMark( Kernel::GCMarkedSet
& marked
)
191 Kernel::WarmOstream::WarmOstream( std::ostream
& os
)
195 Kernel::WarmOstream::~WarmOstream( )
198 RefCountPtr
< const Lang::Class
> Kernel::WarmOstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#OutputStream" ) ) );
199 TYPEINFOIMPL_STATE( WarmOstream
);
202 Kernel::WarmOstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
205 Kernel::ContRef cont
= evalState
->cont_
;
206 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
211 Kernel::WarmOstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
213 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be frozen." ) );
217 Kernel::WarmOstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
219 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be peeked." ) );
223 Kernel::WarmOstream::gcMark( Kernel::GCMarkedSet
& marked
)
227 Kernel::Warm_ostringstream::Warm_ostringstream( )
230 Kernel::Warm_ostringstream::~Warm_ostringstream( )
233 RefCountPtr
< const Lang::Class
> Kernel::Warm_ostringstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#StringConcatenator" ) ) );
234 TYPEINFOIMPL_STATE( Warm_ostringstream
);
237 Kernel::Warm_ostringstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
240 Kernel::ContRef cont
= evalState
->cont_
;
241 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
246 Kernel::Warm_ostringstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
248 Kernel::ContRef cont
= evalState
->cont_
;
249 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
254 Kernel::Warm_ostringstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
256 Kernel::ContRef cont
= evalState
->cont_
;
257 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
262 Kernel::Warm_ostringstream::gcMark( Kernel::GCMarkedSet
& marked
)
271 class Mutator_erase
: public Lang::CoreFunction
274 Mutator_erase( const char * title
)
275 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
279 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
281 args
.applyDefaults( );
284 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
287 Kernel::ContRef cont
= evalState
->cont_
;
288 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
294 class Mutator_remove
: public Lang::CoreFunction
297 Mutator_remove( const char * title
)
298 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
300 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
303 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
305 args
.applyDefaults( );
307 typedef const Lang::Symbol KeyType
;
308 RefCountPtr
< KeyType
> key
= Helpers::down_cast_CoreArgument
< KeyType
>( title_
, args
, 0, callLoc
);
311 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
312 state
->remove( key
->getKey( ) );
314 Kernel::ContRef cont
= evalState
->cont_
;
315 cont
->takeValue( Lang::THE_VOID
,
324 Kernel::WarmGroup2D::WarmGroup2D( )
325 : pile_( Lang::THE_NULL2D
)
328 Kernel::WarmGroup2D::~WarmGroup2D( )
332 WarmGroup2D_register_mutators( Lang::SystemFinalClass
* dstClass
)
334 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup2D
>( "erase" ) );
335 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup2D
>( "remove" ) );
338 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup2D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group2D" ), WarmGroup2D_register_mutators
) );
339 TYPEINFOIMPL_STATE( WarmGroup2D
);
343 Kernel::WarmGroup2D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
345 typedef const Lang::Drawable2D ArgType
;
346 RefCountPtr
< ArgType
> arg
= Helpers::down_cast
< ArgType
>( piece
, callLoc
);
349 /* For objects of user-defined type, we also check that the class inherits from Drawable.
351 typedef const Lang::Instance UserType
;
352 UserType
* obj
= dynamic_cast< UserType
* >( arg
.getPtr( ) );
355 if( ! obj
->getClass( )->method_isa( Lang::Drawable2D::TypeID
) )
357 throw Exceptions::TypeMismatch( callLoc
, "2D insertion", piece
->getTypeName( ), ArgType::staticTypeName( ) );
362 pile_
= RefCountPtr
< const Lang::Group2D
>( new Lang::GroupPair2D( arg
,
364 evalState
->dyn_
->getGraphicsState( ) ) );
365 Kernel::ContRef cont
= evalState
->cont_
;
366 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
371 Kernel::WarmGroup2D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
373 Kernel::ContRef cont
= evalState
->cont_
;
374 cont
->takeValue( pile_
,
379 Kernel::WarmGroup2D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
381 Kernel::ContRef cont
= evalState
->cont_
;
382 cont
->takeValue( pile_
,
387 Kernel::WarmGroup2D::erase( )
389 pile_
= Lang::THE_NULL2D
;
393 Kernel::WarmGroup2D::remove( Lang::Symbol::KeyType key
)
395 pile_
= pile_
->removeShallow( key
);
399 Kernel::WarmGroup2D::gcMark( Kernel::GCMarkedSet
& marked
)
401 const_cast< Lang::Group2D
* >( pile_
.getPtr( ) )->gcMark( marked
);
406 Kernel::WarmGroup3D::WarmGroup3D( )
407 : pile_( Lang::THE_NULL3D
)
410 Kernel::WarmGroup3D::~WarmGroup3D( )
414 WarmGroup3D_register_mutators( Lang::SystemFinalClass
* dstClass
)
416 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup3D
>( "erase" ) );
417 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup3D
>( "remove" ) );
420 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup3D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group3D" ), WarmGroup3D_register_mutators
) );
421 TYPEINFOIMPL_STATE( WarmGroup3D
);
424 Kernel::WarmGroup3D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
426 pile_
= RefCountPtr
< const Lang::Group3D
>( new Lang::GroupPair3D( Helpers::down_cast
< const Lang::Drawable3D
>( piece
, callLoc
),
428 evalState
->dyn_
->getGraphicsState( ) ) );
429 Kernel::ContRef cont
= evalState
->cont_
;
430 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
435 Kernel::WarmGroup3D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
437 Kernel::ContRef cont
= evalState
->cont_
;
438 cont
->takeValue( pile_
,
443 Kernel::WarmGroup3D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
445 Kernel::ContRef cont
= evalState
->cont_
;
446 cont
->takeValue( pile_
,
451 Kernel::WarmGroup3D::erase( )
453 pile_
= Lang::THE_NULL3D
;
457 Kernel::WarmGroup3D::remove( Lang::Symbol::KeyType key
)
459 pile_
= pile_
->removeShallow( key
);
463 Kernel::WarmGroup3D::gcMark( Kernel::GCMarkedSet
& marked
)
465 const_cast< Lang::Group3D
* >( pile_
.getPtr( ) )->gcMark( marked
);
469 Kernel::WarmGroupLights::WarmGroupLights( )
470 : pile_( Lang::THE_NULL_LIGHTS
)
473 Kernel::WarmGroupLights::~WarmGroupLights( )
476 RefCountPtr
< const Lang::Class
> Kernel::WarmGroupLights::TypeID( new Lang::SystemFinalClass( strrefdup( "#GroupLights" ) ) );
477 TYPEINFOIMPL_STATE( WarmGroupLights
);
480 Kernel::WarmGroupLights::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
482 pile_
= RefCountPtr
< const Lang::LightGroup
>( new Lang::LightPair( Helpers::down_cast
< const Lang::LightSource
>( piece
, callLoc
),
484 Kernel::ContRef cont
= evalState
->cont_
;
485 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
490 Kernel::WarmGroupLights::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
492 Kernel::ContRef cont
= evalState
->cont_
;
493 cont
->takeValue( pile_
,
498 Kernel::WarmGroupLights::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
500 Kernel::ContRef cont
= evalState
->cont_
;
501 cont
->takeValue( pile_
,
506 Kernel::WarmGroupLights::gcMark( Kernel::GCMarkedSet
& marked
)
508 const_cast< Lang::LightGroup
* >( pile_
.getPtr( ) )->gcMark( marked
);
512 Kernel::WarmZBuf::WarmZBuf( )
515 Kernel::WarmZBuf::~WarmZBuf( )
518 RefCountPtr
< const Lang::Class
> Kernel::WarmZBuf::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZBuf" ) ) );
519 TYPEINFOIMPL_STATE( WarmZBuf
);
522 Kernel::WarmZBuf::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
526 typedef const Lang::Drawable3D ArgType
;
527 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
530 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
532 catch( const char * ball
)
534 std::ostringstream oss
;
535 oss
<< "Conversion to polygon failed with: " << ball
;
536 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
538 Kernel::ContRef cont
= evalState
->cont_
;
539 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
543 catch( const NonLocalExit::NotThisType
& ball
)
545 /* Wrong type; never mind!.. but see below!
551 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
552 Kernel::ContRef cont
= evalState
->cont_
;
553 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
557 catch( const NonLocalExit::NotThisType
& ball
)
559 /* Wrong type; never mind!.. but see below!
565 typedef const Lang::LightGroup ArgType
;
566 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
568 while( ! lights
->isNull( ) )
570 typedef const Lang::LightPair PairType
;
571 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
572 lightPile_
->push_back( p
->car( ) );
576 Kernel::ContRef cont
= evalState
->cont_
;
577 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
581 catch( const NonLocalExit::NotThisType
& ball
)
583 /* Wrong type; never mind!.. but see below!
587 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
591 Kernel::WarmZBuf::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
593 Kernel::ContRef cont
= evalState
->cont_
;
594 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZBuf( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
599 Kernel::WarmZBuf::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
601 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-buffer state cannot be peeked." ) );
605 Kernel::WarmZBuf::gcMark( Kernel::GCMarkedSet
& marked
)
608 typedef typeof *pile_ ListType
;
609 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
611 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
615 // typedef typeof *strokePile_ ListType;
616 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
618 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
622 typedef typeof *lightPile_ ListType
;
623 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
625 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
631 Kernel::WarmZSorter::WarmZSorter( )
634 Kernel::WarmZSorter::~WarmZSorter( )
637 RefCountPtr
< const Lang::Class
> Kernel::WarmZSorter::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZSorter" ) ) );
638 TYPEINFOIMPL_STATE( WarmZSorter
);
641 Kernel::WarmZSorter::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
645 typedef const Lang::Drawable3D ArgType
;
646 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
649 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
651 catch( const char * ball
)
653 std::ostringstream oss
;
654 oss
<< "Conversion to polygon failed with: " << ball
;
655 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
657 Kernel::ContRef cont
= evalState
->cont_
;
658 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
662 catch( const NonLocalExit::NotThisType
& ball
)
664 /* Wrong type; never mind!.. but see below!
670 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
671 Kernel::ContRef cont
= evalState
->cont_
;
672 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
676 catch( const NonLocalExit::NotThisType
& ball
)
678 /* Wrong type; never mind!.. but see below!
684 typedef const Lang::LightGroup ArgType
;
685 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
687 while( ! lights
->isNull( ) )
689 typedef const Lang::LightPair PairType
;
690 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
691 lightPile_
->push_back( p
->car( ) );
695 Kernel::ContRef cont
= evalState
->cont_
;
696 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
700 catch( const NonLocalExit::NotThisType
& ball
)
702 /* Wrong type; never mind!.. but see below!
706 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
710 Kernel::WarmZSorter::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
712 Kernel::ContRef cont
= evalState
->cont_
;
713 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZSorter( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
718 Kernel::WarmZSorter::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
720 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-sorter state cannot be peeked." ) );
724 Kernel::WarmZSorter::gcMark( Kernel::GCMarkedSet
& marked
)
727 typedef typeof *pile_ ListType
;
728 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
730 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
734 // typedef typeof *strokePile_ ListType;
735 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
737 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
741 typedef typeof *lightPile_ ListType
;
742 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
744 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
750 Kernel::WarmTimer::WarmTimer( )
753 int res
= getrusage( RUSAGE_SELF
, &ru
);
756 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
758 start_
= ru
.ru_utime
;
761 Kernel::WarmTimer::~WarmTimer( )
764 RefCountPtr
< const Lang::Class
> Kernel::WarmTimer::TypeID( new Lang::SystemFinalClass( strrefdup( "#Timer" ) ) );
765 TYPEINFOIMPL_STATE( WarmTimer
);
768 Kernel::WarmTimer::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
770 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm timer does not accept values. Please freeze to obtain the number of seconds since creation." ) );
774 Kernel::WarmTimer::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
777 int res
= getrusage( RUSAGE_SELF
, &ru
);
780 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
782 timeval stop
= ru
.ru_utime
;
783 double time1
= start_
.tv_usec
/ 1000000.0 + start_
.tv_sec
;
784 double time2
= stop
.tv_usec
/ 1000000.0 + stop
.tv_sec
;
786 Kernel::ContRef cont
= evalState
->cont_
;
787 cont
->takeValue( Kernel::ValueRef( new Lang::Float( time2
- time1
) ),
792 Kernel::WarmTimer::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
795 int res
= getrusage( RUSAGE_SELF
, &ru
);
798 throw Exceptions::InternalError( strrefdup( "grtrusage failed." ) );
800 timeval stop
= ru
.ru_utime
;
801 double time1
= start_
.tv_usec
/ 1000000.0 + start_
.tv_sec
;
802 double time2
= stop
.tv_usec
/ 1000000.0 + stop
.tv_sec
;
804 Kernel::ContRef cont
= evalState
->cont_
;
805 cont
->takeValue( Kernel::ValueRef( new Lang::Float( time2
- time1
) ),
810 Kernel::WarmTimer::gcMark( Kernel::GCMarkedSet
& marked
)
814 Kernel::WarmText::WarmText( )
817 Kernel::WarmText::~WarmText( )
820 RefCountPtr
< const Lang::Class
> Kernel::WarmText::TypeID( new Lang::SystemFinalClass( strrefdup( "#Text" ) ) );
821 TYPEINFOIMPL_STATE( WarmText
);
824 Kernel::WarmText::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
828 typedef const Lang::TextOperation ArgType
;
829 pile_
->push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
830 Kernel::ContRef cont
= evalState
->cont_
;
831 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
835 catch( const NonLocalExit::NotThisType
& ball
)
837 /* Wrong type; never mind!.. but see below!
843 typedef const Lang::String ArgType
;
844 RefCountPtr
< ArgType
> str
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
845 Lang::KernedText
* text
= new Lang::KernedText( evalState
->dyn_
->getTextState( ), evalState
->dyn_
->getGraphicsState( ) );
846 text
->pushString( str
);
847 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( text
) );
848 Kernel::ContRef cont
= evalState
->cont_
;
849 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
853 catch( const NonLocalExit::NotThisType
& ball
)
855 /* Wrong type; never mind!.. but see below!
861 typedef const Lang::Transform2D ArgType
;
862 RefCountPtr
< ArgType
> tf
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
863 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextMoveto( tf
) ) );
864 Kernel::ContRef cont
= evalState
->cont_
;
865 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
869 catch( const NonLocalExit::NotThisType
& ball
)
871 /* Wrong type; never mind!.. but see below!
877 typedef const Lang::Coords2D ArgType
;
878 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
879 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( t
->x_
.get( ), t
->y_
.get( ) ) ) );
880 Kernel::ContRef cont
= evalState
->cont_
;
881 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
885 catch( const NonLocalExit::NotThisType
& ball
)
887 /* Wrong type; never mind!.. but see below!
893 typedef const Lang::FloatPair ArgType
;
894 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
895 Concrete::Length sz
= evalState
->dyn_
->getTextState( )->size_
;
896 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( sz
* t
->x_
, sz
* t
->y_
) ) );
897 Kernel::ContRef cont
= evalState
->cont_
;
898 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
902 catch( const NonLocalExit::NotThisType
& ball
)
904 /* Wrong type; never mind!.. but see below!
908 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::TextOperation::staticTypeName( ), Lang::String::staticTypeName( ) ) );
912 Kernel::WarmText::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
914 if( pile_
->empty( ) )
916 Kernel::ContRef cont
= evalState
->cont_
;
917 cont
->takeValue( Lang::THE_NULL2D
,
922 Concrete::Length xmin
= Concrete::HUGE_LENGTH
;
923 Concrete::Length xmax
= -Concrete::HUGE_LENGTH
;
924 Concrete::Length ymin
= Concrete::HUGE_LENGTH
;
925 Concrete::Length ymax
= -Concrete::HUGE_LENGTH
;
928 Lang::Transform2D
textMatrix( 1, 0, 0, 1, 0, 0 );
929 Lang::Transform2D
textLineMatrix( 1, 0, 0, 1, 0, 0 );
930 typedef typeof *pile_ ListType
;
931 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
933 (*i
)->measure( & textMatrix
, & textLineMatrix
, & xmin
, & ymin
, & xmax
, & ymax
);
937 Lang::ElementaryPath2D
* bbox
= new Lang::ElementaryPath2D
;
939 if( xmin
< Concrete::HUGE_LENGTH
)
941 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymin
) );
942 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymax
) );
943 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymax
) );
944 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymin
) );
948 Kernel::ContRef cont
= evalState
->cont_
;
949 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Text( evalState
->dyn_
->getGraphicsState( ),
950 evalState
->dyn_
->getTextState( ),
952 RefCountPtr
< const Lang::ElementaryPath2D
>( bbox
) ) ),
957 Kernel::WarmText::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
959 throw Exceptions::MiscellaneousRequirement( strrefdup( "A text graphics state cannot be peeked." ) );
963 Kernel::WarmText::gcMark( Kernel::GCMarkedSet
& marked
)
965 typedef typeof *pile_ ListType
;
966 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
968 const_cast< Lang::TextOperation
* >( i
->getPtr( ) )->gcMark( marked
);
973 Kernel::WarmType3Font::WarmType3Font( )
974 : metrics_( new FontMetrics::AFM( ) ), size_( -1 )
976 metrics_
->capHeight_
= std::numeric_limits
< double >::signaling_NaN( );
977 metrics_
->xHeight_
= std::numeric_limits
< double >::signaling_NaN( );
978 metrics_
->ascender_
= std::numeric_limits
< double >::signaling_NaN( );
979 metrics_
->descender_
= std::numeric_limits
< double >::signaling_NaN( );
980 metrics_
->leading_
= std::numeric_limits
< double >::signaling_NaN( );
981 metrics_
->stdHW_
= std::numeric_limits
< double >::signaling_NaN( );
982 metrics_
->stdVW_
= std::numeric_limits
< double >::signaling_NaN( );
983 metrics_
->fontBBoxXMin_
= 0;
984 metrics_
->fontBBoxXMax_
= -1;
986 horizontalMetrics_typed_
= new FontMetrics::SingleByte_WritingDirectionMetrics( );
987 metrics_
->horizontalMetrics_
= RefCountPtr
< FontMetrics::WritingDirectionMetrics
>( horizontalMetrics_typed_
);
988 horizontalMetrics_typed_
->underlinePosition_
= std::numeric_limits
< double >::signaling_NaN( );
989 horizontalMetrics_typed_
->underlineThickness_
= std::numeric_limits
< double >::signaling_NaN( );
990 horizontalMetrics_typed_
->italicAngleRadians_
= std::numeric_limits
< double >::signaling_NaN( );
993 Kernel::WarmType3Font::~WarmType3Font( )
996 RefCountPtr
< const Lang::Class
> Kernel::WarmType3Font::TypeID( new Lang::SystemFinalClass( strrefdup( "#Type3Font" ) ) );
997 TYPEINFOIMPL_STATE( WarmType3Font
);
1000 Kernel::WarmType3Font::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
1004 typedef const Lang::Type3Glyph ArgType
;
1005 glyphs_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
1006 Kernel::ContRef cont
= evalState
->cont_
;
1007 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1011 catch( const NonLocalExit::NotThisType
& ball
)
1013 /* Wrong type; never mind!.. but see below!
1019 typedef const Lang::KernedText ArgType
;
1020 kernings_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
1021 Kernel::ContRef cont
= evalState
->cont_
;
1022 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1026 catch( const NonLocalExit::NotThisType
& ball
)
1028 /* Wrong type; never mind!.. but see below!
1034 typedef const Lang::TaggedValue2D ArgType
;
1035 RefCountPtr
< ArgType
> taggedVal
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
1037 RefCountPtr
< const char > tagMem
= Lang::Symbol::nameFromKey( taggedVal
->key( ) );
1038 const char * tag
= tagMem
.getPtr( );
1039 RefCountPtr
< const Lang::Value
> val
= taggedVal
->val( );
1041 if( strcmp( tag
, "size" ) == 0 )
1045 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1047 typedef const Lang::Length ValType
;
1048 size_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( );
1049 if( ! ( size_
> 0 ) )
1051 throw Exceptions::OutOfRange( callLoc
, "The size must be positive." );
1054 else if( strcmp( tag
, "FontName" ) == 0 )
1056 if( metrics_
->fontName_
!= NullPtr
< const char >( ) )
1058 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1060 typedef const Lang::Symbol ValType
;
1061 metrics_
->fontName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1063 else if( strcmp( tag
, "FullName" ) == 0 )
1065 if( metrics_
->fullName_
!= NullPtr
< const char >( ) )
1067 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1069 typedef const Lang::String ValType
;
1070 metrics_
->fullName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1072 else if( strcmp( tag
, "FamilyName" ) == 0 )
1074 if( metrics_
->familyName_
!= NullPtr
< const char >( ) )
1076 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1078 typedef const Lang::Symbol ValType
;
1079 metrics_
->familyName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1081 else if( strcmp( tag
, "Weight" ) == 0 )
1085 typedef const Lang::Symbol ValType
;
1086 RefCountPtr
< const char > typedVal
= Helpers::try_cast_CoreArgument
< ValType
>( val
)->name( );
1087 if( metrics_
->weight_
!= NullPtr
< const char >( ) )
1089 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1091 static std::set
< const char *, charPtrLess
> legalStretchValues
;
1092 if( legalStretchValues
.empty( ) )
1094 initializeLegalStrechValues( & legalStretchValues
);
1096 if( legalStretchValues
.find( typedVal
.getPtr( ) ) == legalStretchValues
.end( ) )
1098 throw Exceptions::OutOfRange( callLoc
, "The 'Weight value is illegal. Please refer to the PDF specification." );
1100 metrics_
->weight_
= typedVal
;
1103 catch( const NonLocalExit::NotThisType
& ball
)
1105 /* Wrong type; never mind!.. but see below!
1111 typedef const Lang::Integer ValType
;
1112 RefCountPtr
< ValType
> casted_val
= Helpers::try_cast_CoreArgument
< ValType
>( val
);
1113 if( metrics_
->weightNumber_
> 0 )
1115 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1117 if( casted_val
->val_
% 100 != 0 )
1119 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be divisible by 100." );
1121 if( casted_val
->val_
< 100 || casted_val
->val_
> 900 )
1123 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be in the range [ 100, 900 ]." );
1125 metrics_
->weightNumber_
= casted_val
->val_
;
1128 catch( const NonLocalExit::NotThisType
& ball
)
1130 /* Wrong type; never mind!.. but see below!
1134 throw Exceptions::TypeMismatch( callLoc
, val
->getTypeName( ), Helpers::typeSetString( Lang::String::staticTypeName( ), Lang::Integer::staticTypeName( ) ) );
1136 else if( strcmp( tag
, "Version" ) == 0 )
1138 if( metrics_
->version_
!= NullPtr
< const char >( ) )
1140 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1142 typedef const Lang::String ValType
;
1143 metrics_
->version_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1145 else if( strcmp( tag
, "Notice" ) == 0 )
1147 if( metrics_
->notice_
!= NullPtr
< const char >( ) )
1149 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1151 typedef const Lang::String ValType
;
1152 metrics_
->notice_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1154 else if( strcmp( tag
, "EncodingScheme" ) == 0 )
1156 if( metrics_
->encodingScheme_
!= NullPtr
< const char >( ) )
1158 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1160 typedef const Lang::Symbol ValType
;
1161 metrics_
->encodingScheme_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1163 else if( strcmp( tag
, "CharacterSet" ) == 0 )
1165 if( metrics_
->characterSet_
!= NullPtr
< const char >( ) )
1167 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1169 typedef const Lang::Symbol ValType
;
1170 metrics_
->characterSet_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1172 else if( strcmp( tag
, "Comment" ) == 0 )
1174 typedef const Lang::String ValType
;
1175 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1176 metrics_
->comments_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1178 else if( strcmp( tag
, "CapHeight" ) == 0 )
1180 if( ! IS_NAN( metrics_
->capHeight_
) )
1182 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1184 if( ! ( size_
> 0 ) )
1186 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1188 typedef const Lang::Length ValType
;
1189 metrics_
->capHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1191 else if( strcmp( tag
, "XHeight" ) == 0 )
1193 if( ! IS_NAN( metrics_
->xHeight_
) )
1195 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1197 if( ! ( size_
> 0 ) )
1199 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1201 typedef const Lang::Length ValType
;
1202 metrics_
->xHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1204 else if( strcmp( tag
, "Ascent" ) == 0 )
1206 if( ! IS_NAN( metrics_
->ascender_
) )
1208 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1210 if( ! ( size_
> 0 ) )
1212 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1214 typedef const Lang::Length ValType
;
1215 metrics_
->ascender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1217 else if( strcmp( tag
, "Descent" ) == 0 )
1219 if( ! IS_NAN( metrics_
->descender_
) )
1221 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1223 if( ! ( size_
> 0 ) )
1225 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1227 typedef const Lang::Length ValType
;
1228 metrics_
->descender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1230 else if( strcmp( tag
, "Leading" ) == 0 )
1232 if( ! IS_NAN( metrics_
->leading_
) )
1234 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1236 if( ! ( size_
> 0 ) )
1238 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1240 typedef const Lang::Length ValType
;
1241 metrics_
->leading_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1243 else if( strcmp( tag
, "StemH" ) == 0 )
1245 if( ! IS_NAN( metrics_
->stdHW_
) )
1247 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1249 if( ! ( size_
> 0 ) )
1251 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1253 typedef const Lang::Length ValType
;
1254 metrics_
->stdHW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1256 else if( strcmp( tag
, "StemV" ) == 0 )
1258 if( ! IS_NAN( metrics_
->stdVW_
) )
1260 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1262 if( ! ( size_
> 0 ) )
1264 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1266 typedef const Lang::Length ValType
;
1267 metrics_
->stdVW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1269 else if( strcmp( tag
, "FontBBox" ) == 0 )
1271 if( metrics_
->fontBBoxXMax_
>= metrics_
->fontBBoxXMin_
)
1273 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1275 if( ! ( size_
> 0 ) )
1277 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1279 typedef const Lang::ElementaryPath2D ValType
;
1280 RefCountPtr
< ValType
> casted_val
= Helpers::elementaryPathTry2D( val
);
1281 Concrete::Coords2D
llcorner( 0, 0 );
1282 Concrete::Coords2D
urcorner( 0, 0 );
1283 if( ! casted_val
->boundingRectangle( & llcorner
, & urcorner
) )
1285 throw Exceptions::OutOfRange( callLoc
, "The path was empty." );
1287 metrics_
->fontBBoxXMin_
= llcorner
.x_
/ size_
;
1288 metrics_
->fontBBoxYMin_
= llcorner
.y_
/ size_
;
1289 metrics_
->fontBBoxXMax_
= urcorner
.x_
/ size_
;
1290 metrics_
->fontBBoxYMax_
= urcorner
.y_
/ size_
;
1292 else if( strcmp( tag
, "UnderlinePosition" ) == 0 )
1294 if( ! IS_NAN( horizontalMetrics_typed_
->underlinePosition_
) )
1296 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1298 if( ! ( size_
> 0 ) )
1300 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1302 typedef const Lang::Length ValType
;
1303 horizontalMetrics_typed_
->underlinePosition_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1305 else if( strcmp( tag
, "UnderlineThickness" ) == 0 )
1307 if( ! IS_NAN( horizontalMetrics_typed_
->underlineThickness_
) )
1309 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1311 if( ! ( size_
> 0 ) )
1313 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1315 typedef const Lang::Length ValType
;
1316 horizontalMetrics_typed_
->underlineThickness_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1318 else if( strcmp( tag
, "ItalicAngle" ) == 0 )
1320 if( ! IS_NAN( horizontalMetrics_typed_
->italicAngleRadians_
) )
1322 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1324 typedef const Lang::Float ValType
;
1325 horizontalMetrics_typed_
->italicAngleRadians_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1329 typedef const Lang::String ValType
;
1330 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1331 metrics_
->assortedGlobalInfo_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1335 Kernel::ContRef cont
= evalState
->cont_
;
1336 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1340 catch( const NonLocalExit::NotThisType
& ball
)
1342 /* Wrong type; never mind!.. but see below!
1346 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Type3Glyph::staticTypeName( ), Lang::KernedText::staticTypeName( ), Lang::TaggedValue2D::staticTypeName( ) ) );
1350 Kernel::WarmType3Font::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1352 if( glyphs_
.empty( ) )
1354 throw Exceptions::OutOfRange( callLoc
, "A font without glyphs?!" );
1356 if( ! ( size_
> 0 ) )
1358 throw Exceptions::OutOfRange( callLoc
, "Missing 'size." );
1360 if( strlen( metrics_
->fontName_
.getPtr( ) ) == 0 )
1362 throw Exceptions::OutOfRange( callLoc
, "Missing 'FontName." );
1364 if( metrics_
->weightNumber_
== 0 )
1366 metrics_
->weightNumber_
= 400;
1368 bool findBBox
= false;
1369 if( metrics_
->fontBBoxXMax_
< metrics_
->fontBBoxXMin_
)
1374 Concrete::ReciprocalLength invSize
= 1 / size_
;
1376 metrics_
->charCount_
= glyphs_
.size( );
1377 metrics_
->isCIDFont_
= false;
1379 size_t firstChar
= INT_MAX
;
1380 size_t lastChar
= 0;
1382 // In the first scan of the glyphs, only firstChar and lastChar are computed. The other tasks are performed in the later scan.
1383 typedef typeof glyphs_ ListType
;
1384 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1386 size_t code
= (*i
)->code( );
1389 firstChar
= std::min( firstChar
, code
);
1390 lastChar
= std::max( lastChar
, code
);
1395 RefCountPtr
< SimplePDF::PDF_Vector
> widths
;
1397 RefCountPtr
< SimplePDF::PDF_Object
> stdWidth
= SimplePDF::newFloat( 0 );
1398 widths
->vec
.resize( lastChar
- firstChar
+ 1, stdWidth
);
1400 RefCountPtr
< SimplePDF::PDF_Dictionary
> charProcs
;
1401 RefCountPtr
< SimplePDF::PDF_Resources
> resources
;
1402 // RefCountPtr< SimplePDF::PDF_Stream_out > toUnicode;
1404 horizontalMetrics_typed_
->charData_
.reserve( glyphs_
.size( ) );
1407 // This is the main loop over all glyphs.
1408 typedef typeof glyphs_ ListType
;
1409 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1411 size_t code
= (*i
)->code( );
1414 widths
->vec
[ code
- firstChar
] = SimplePDF::newFloat( (*i
)->widthX( ) );
1417 RefCountPtr
< SimplePDF::PDF_Stream_out
> glyphStream
;
1418 (*i
)->shipout( glyphStream
->data
, resources
);
1419 charProcs
->dic
[ (*i
)->name( ).getPtr( ) ] = SimplePDF::indirect( glyphStream
, & Kernel::theIndirectObjectCount
);
1421 size_t pos
= horizontalMetrics_typed_
->charData_
.size( );
1422 FontMetrics::CharacterMetrics
* glyphMetrics
= new FontMetrics::CharacterMetrics( pos
);
1423 (*i
)->setupMetric( glyphMetrics
, invSize
);
1424 horizontalMetrics_typed_
->charData_
.push_back( glyphMetrics
);
1425 horizontalMetrics_typed_
->nameMap_
[ (*i
)->name( ) ] = pos
;
1428 horizontalMetrics_typed_
->codeMap_
[ code
] = pos
;
1433 (*i
)->enlargeBBox( & metrics_
->fontBBoxXMin_
, & metrics_
->fontBBoxYMin_
, & metrics_
->fontBBoxXMax_
, & metrics_
->fontBBoxYMax_
);
1438 RefCountPtr
< SimplePDF::PDF_Vector
> fontBBox( new SimplePDF::PDF_Vector( metrics_
->fontBBoxXMin_
, metrics_
->fontBBoxYMin_
,
1439 metrics_
->fontBBoxXMax_
, metrics_
->fontBBoxYMax_
) );
1440 RefCountPtr
< SimplePDF::PDF_Dictionary
> fontDescriptor
;
1441 (*fontDescriptor
)[ "Type" ] = SimplePDF::newName( "FontDescriptor" );
1442 (*fontDescriptor
)[ "FontName" ] = SimplePDF::newName( metrics_
->fontName_
.getPtr( ) );
1443 if( metrics_
->familyName_
.getPtr( ) != NullPtr
< const char >( ) )
1445 (*fontDescriptor
)[ "FontFamily" ] = SimplePDF::newName( metrics_
->familyName_
.getPtr( ) );
1447 if( metrics_
->weight_
.getPtr( ) != NullPtr
< const char >( ) )
1449 // It has already been asserted that this value is legal.
1450 (*fontDescriptor
)[ "FontStretch" ] = SimplePDF::newName( metrics_
->weight_
.getPtr( ) );
1452 if( metrics_
->weightNumber_
> 0 )
1454 // It has already been asserted that this value is legal.
1455 (*fontDescriptor
)[ "FontWeight" ] = SimplePDF::newInt( metrics_
->weightNumber_
);
1457 (*fontDescriptor
)[ "Flags" ] = SimplePDF::newInt( (size_t)(1) << ( 6 - 1 ) ); // This is just the "Nonsymbolic" flag.
1458 (*fontDescriptor
)[ "FontBBox" ] = fontBBox
;
1459 if( ! IS_NAN( horizontalMetrics_typed_
->italicAngleRadians_
) )
1461 (*fontDescriptor
)[ "ItalicAngle" ] = SimplePDF::newFloat( ( 180 / M_PI
) * horizontalMetrics_typed_
->italicAngleRadians_
);
1465 throw Exceptions::OutOfRange( callLoc
, "Missing 'ItalicAngle." );
1467 if( ! IS_NAN( metrics_
->ascender_
) )
1469 (*fontDescriptor
)[ "Ascent" ] = SimplePDF::newFloat( metrics_
->ascender_
);
1471 if( ! IS_NAN( metrics_
->descender_
) )
1473 (*fontDescriptor
)[ "Descent" ] = SimplePDF::newFloat( metrics_
->descender_
);
1475 if( ! IS_NAN( metrics_
->leading_
) )
1477 (*fontDescriptor
)[ "Leading" ] = SimplePDF::newFloat( metrics_
->leading_
);
1479 if( ! IS_NAN( metrics_
->capHeight_
) )
1481 (*fontDescriptor
)[ "CapHeight" ] = SimplePDF::newFloat( metrics_
->capHeight_
);
1483 if( ! IS_NAN( metrics_
->xHeight_
) )
1485 (*fontDescriptor
)[ "XHeight" ] = SimplePDF::newFloat( metrics_
->xHeight_
);
1487 if( ! IS_NAN( metrics_
->stdHW_
) )
1489 (*fontDescriptor
)[ "StemH" ] = SimplePDF::newFloat( metrics_
->stdHW_
);
1491 if( ! IS_NAN( metrics_
->stdVW_
) )
1493 (*fontDescriptor
)[ "StemV" ] = SimplePDF::newFloat( metrics_
->stdVW_
);
1496 Concrete::Length
the1bp( 1 );
1498 RefCountPtr
< SimplePDF::PDF_Dictionary
> dic
;
1499 RefCountPtr
< SimplePDF::PDF_Object
> indirection
= SimplePDF::indirect( dic
, & Kernel::theIndirectObjectCount
);
1500 (*dic
)[ "Type" ] = SimplePDF::newName( "Font" );
1501 (*dic
)[ "Subtype" ] = SimplePDF::newName( "Type3" );
1502 (*dic
)[ "Encoding" ] = SimplePDF::newName( "MacRomanEncoding" );
1503 (*dic
)[ "FontBBox" ] = fontBBox
;
1504 (*dic
)[ "FontMatrix" ] = RefCountPtr
< SimplePDF::PDF_Vector
>( new SimplePDF::PDF_Vector( the1bp
* invSize
, 0, 0, the1bp
* invSize
, 0, 0 ) );
1505 (*dic
)[ "CharProcs" ] = charProcs
;
1506 (*dic
)[ "FirstChar" ] = SimplePDF::newInt( firstChar
);
1507 (*dic
)[ "LastChar" ] = SimplePDF::newInt( lastChar
);
1508 (*dic
)[ "Widths" ] = widths
;
1509 (*dic
)[ "FontDescriptor" ] = fontDescriptor
;
1510 (*dic
)[ "Resources" ] = SimplePDF::indirect( resources
, & Kernel::theIndirectObjectCount
);
1513 // static bool shown = false;
1516 // std::cerr << "Warning: The ToUnicode CMap is not setup by Shapes." << std::endl ;
1520 // (*dic)[ "ToUnicode" ] = toUnicode;
1522 Kernel::ContRef cont
= evalState
->cont_
;
1523 cont
->takeValue( Kernel::ValueRef( new Lang::Type3Font( metrics_
->fontName_
,
1530 Kernel::WarmType3Font::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1532 throw Exceptions::MiscellaneousRequirement( strrefdup( "A type 3 font state cannot be peeked." ) );
1536 Kernel::WarmType3Font::gcMark( Kernel::GCMarkedSet
& marked
)
1539 typedef typeof kernings_ ListType
;
1540 for( ListType::const_iterator i
= kernings_
.begin( ); i
!= kernings_
.end( ); ++i
)
1542 const_cast< Lang::KernedText
* >( i
->getPtr( ) )->gcMark( marked
);
1546 typedef typeof glyphs_ ListType
;
1547 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1549 const_cast< Lang::Type3Glyph
* >( i
->getPtr( ) )->gcMark( marked
);
1556 Kernel::WarmType3Font::initializeLegalStrechValues( std::set
< const char *, charPtrLess
> * legalStretchValues
)
1558 legalStretchValues
->insert( "UltraCondensed" );
1559 legalStretchValues
->insert( "ExtraCondensed" );
1560 legalStretchValues
->insert( "Condensed" );
1561 legalStretchValues
->insert( "SemiCondensed" );
1562 legalStretchValues
->insert( "Normal" );
1563 legalStretchValues
->insert( "SemiExpanded" );
1564 legalStretchValues
->insert( "Expanded" );
1565 legalStretchValues
->insert( "ExtraExpanded" );
1566 legalStretchValues
->insert( "UltraExpanded" );
1570 Kernel::WarmRandomDevice::WarmRandomDevice( const char * deviceName
)
1571 : deviceName_( deviceName
)
1574 Kernel::WarmRandomDevice::~WarmRandomDevice( )
1577 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomDevice::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomDevice" ) ) );
1578 TYPEINFOIMPL_STATE( WarmRandomDevice
);
1581 Kernel::WarmRandomDevice::read( char * dst
, size_t sz
)
1583 if( ! idev_
.is_open( ) )
1585 idev_
.open( deviceName_
);
1586 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1588 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for input." ) ) );
1592 idev_
.read( dst
, sz
);
1596 Kernel::WarmRandomDevice::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
1598 if( ! odev_
.is_open( ) )
1600 odev_
.open( deviceName_
);
1601 if( ! odev_
.is_open( ) || ! odev_
.good( ) )
1603 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1607 piece
->show( odev_
);
1608 Kernel::ContRef cont
= evalState
->cont_
;
1609 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1614 Kernel::WarmRandomDevice::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1616 throw Exceptions::MiscellaneousRequirement( strrefdup( "The random device cannot be frozen." ) );
1620 Kernel::WarmRandomDevice::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1622 if( ! idev_
.is_open( ) )
1624 idev_
.open( deviceName_
);
1625 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1627 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1632 idev_
.read( reinterpret_cast< char * >( & tmp
), 1 );
1633 Kernel::ContRef cont
= evalState
->cont_
;
1634 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1639 Kernel::WarmRandomDevice::gcMark( Kernel::GCMarkedSet
& marked
)
1643 Kernel::WarmTime::WarmTime( )
1646 Kernel::WarmTime::~WarmTime( )
1649 RefCountPtr
< const Lang::Class
> Kernel::WarmTime::TypeID( new Lang::SystemFinalClass( strrefdup( "#Time" ) ) );
1650 TYPEINFOIMPL_STATE( WarmTime
);
1653 Kernel::WarmTime::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
1655 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time does not accept values." ) );
1659 Kernel::WarmTime::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1661 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time cannot be frozen." ) );
1665 Kernel::WarmTime::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1667 time_t t
= time( 0 );
1668 Kernel::ContRef cont
= evalState
->cont_
;
1669 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ChronologicalTime( t
) ),
1674 Kernel::WarmTime::gcMark( Kernel::GCMarkedSet
& marked
)
1678 Kernel::WarmRandomState::WarmRandomState( char * state
)
1682 Kernel::WarmRandomState::~WarmRandomState( )
1684 delete state_
; // Let's hope this is not in use!
1687 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomState::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomState" ) ) );
1688 TYPEINFOIMPL_STATE( WarmRandomState
);
1691 Kernel::WarmRandomState::setState( )
1697 Kernel::WarmRandomState::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
1699 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state does not accept values." ) );
1703 Kernel::WarmRandomState::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1705 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state cannot be frozen." ) );
1709 Kernel::WarmRandomState::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1712 long tmp
= random( );
1713 Kernel::ContRef cont
= evalState
->cont_
;
1714 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1719 Kernel::WarmRandomState::gcMark( Kernel::GCMarkedSet
& marked
)
1723 Kernel::WarmColorInterpolator::WarmColorInterpolator( )
1724 : hasKey_( false ), colorType_( Lang::ColorInterpolator::UNDEFINED
)
1727 Kernel::WarmColorInterpolator::~WarmColorInterpolator( )
1730 RefCountPtr
< const Lang::Class
> Kernel::WarmColorInterpolator::TypeID( new Lang::SystemFinalClass( strrefdup( "#ColorInterpolator" ) ) );
1731 TYPEINFOIMPL_STATE( WarmColorInterpolator
);
1734 Kernel::WarmColorInterpolator::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
1738 switch( colorType_
)
1740 case Lang::ColorInterpolator::UNDEFINED
:
1743 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1744 colorType_
= Lang::ColorInterpolator::RGB
;
1747 catch( const Exceptions::TypeMismatch
& )
1752 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1753 colorType_
= Lang::ColorInterpolator::GRAY
;
1756 catch( const Exceptions::TypeMismatch
& )
1761 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1762 colorType_
= Lang::ColorInterpolator::CMYK
;
1765 catch( const Exceptions::TypeMismatch
& )
1767 throw Exceptions::MiscellaneousRequirement( strrefdup( "Only colors can be passed to an interpolator." ) );
1769 case Lang::ColorInterpolator::RGB
:
1770 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1773 case Lang::ColorInterpolator::GRAY
:
1774 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1777 case Lang::ColorInterpolator::CMYK
:
1778 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1784 typedef const Lang::Float ArgType
;
1785 double key
= Helpers::down_cast
< ArgType
>( piece
, callLoc
)->val_
;
1786 if( !key_
->empty( ) && key
< key_
->back( ) )
1788 throw Exceptions::MiscellaneousRequirement( strrefdup( "Keys must be added in nondecreasing order to an interpolator." ) );
1792 key_
->push_back( key
);
1796 hasKey_
= ! hasKey_
;
1798 Kernel::ContRef cont
= evalState
->cont_
;
1799 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1804 Kernel::WarmColorInterpolator::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1806 if( key_
->empty( ) )
1808 throw Exceptions::MiscellaneousRequirement( strrefdup( "There are no colors that define the interpolation." ) );
1812 throw Exceptions::MiscellaneousRequirement( strrefdup( "Missing color for the last key." ) );
1815 Kernel::ContRef cont
= evalState
->cont_
;
1816 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ColorInterpolator( key_
, RGBcolor_
, graycolor_
, CMYKcolor_
, colorType_
) ),
1821 Kernel::WarmColorInterpolator::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1823 throw Exceptions::MiscellaneousRequirement( strrefdup( "An interpolator cannot be peeked." ) );
1827 Kernel::WarmColorInterpolator::gcMark( Kernel::GCMarkedSet
& marked
)
1836 class Mutator_vector_size
: public Lang::CoreFunction
1839 Mutator_vector_size( const char * title
)
1840 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1844 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1846 args
.applyDefaults( );
1848 typedef Warm_vector StateType
;
1849 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1851 Kernel::ContRef cont
= evalState
->cont_
;
1852 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( state
->mem_
->size( ) ) ),
1857 class Mutator_vector_resize
: public Lang::CoreFunction
1860 Mutator_vector_resize( const char * title
)
1861 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1863 formals_
->appendEvaluatedCoreFormal( "size", Kernel::THE_SLOT_VARIABLE
);
1864 formals_
->appendEvaluatedCoreFormal( "fill", Kernel::THE_VOID_VARIABLE
);
1867 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1869 args
.applyDefaults( );
1871 typedef const Lang::Integer IndexType
;
1872 IndexType::ValueType tmp
= Helpers::down_cast_CoreArgument
< IndexType
>( title_
, args
, 0, callLoc
)->val_
;
1875 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The size must be non-negative." );
1877 size_t newSize
= static_cast< size_t >( tmp
);
1879 typedef Warm_vector StateType
;
1880 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1882 if( newSize
< state
->mem_
->size( ) )
1884 while( newSize
< state
->mem_
->size( ) )
1886 state
->mem_
->pop_back( );
1891 state
->mem_
->reserve( newSize
);
1892 RefCountPtr
< const Lang::Value
> fill
= args
.getValue( 1 );
1893 while( newSize
> state
->mem_
->size( ) )
1895 state
->mem_
->push_back( fill
);
1899 Kernel::ContRef cont
= evalState
->cont_
;
1900 cont
->takeValue( Lang::THE_VOID
,
1905 class Mutator_vector_reserve
: public Lang::CoreFunction
1908 Mutator_vector_reserve( const char * title
)
1909 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1911 formals_
->appendEvaluatedCoreFormal( "size", Kernel::THE_SLOT_VARIABLE
);
1914 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1916 args
.applyDefaults( );
1918 typedef const Lang::Integer IndexType
;
1919 IndexType::ValueType tmp
= Helpers::down_cast_CoreArgument
< IndexType
>( title_
, args
, 0, callLoc
)->val_
;
1922 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The size must be non-negative." );
1924 size_t newSize
= static_cast< size_t >( tmp
);
1926 typedef Warm_vector StateType
;
1927 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1929 state
->mem_
->reserve( newSize
);
1931 Kernel::ContRef cont
= evalState
->cont_
;
1932 cont
->takeValue( Lang::THE_VOID
,
1937 class Mutator_vector_set
: public Lang::CoreFunction
1940 Mutator_vector_set( const char * title
)
1941 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1943 formals_
->appendEvaluatedCoreFormal( "index", Kernel::THE_SLOT_VARIABLE
);
1944 formals_
->appendEvaluatedCoreFormal( "value", Kernel::THE_SLOT_VARIABLE
);
1947 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1949 args
.applyDefaults( );
1951 typedef Warm_vector StateType
;
1952 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1954 typedef const Lang::Integer IndexType
;
1955 IndexType::ValueType tmp
= Helpers::down_cast_CoreArgument
< IndexType
>( title_
, args
, 0, callLoc
)->val_
;
1958 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The index must be non-negative." );
1960 size_t index
= static_cast< size_t >( tmp
);
1961 if( index
>= state
->mem_
->size( ) )
1963 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The index is out of range." );
1966 (*state
->mem_
)[ index
] = args
.getValue( 1 );
1968 Kernel::ContRef cont
= evalState
->cont_
;
1969 cont
->takeValue( Lang::THE_VOID
,
1974 class Mutator_vector_get
: public Lang::CoreFunction
1977 Mutator_vector_get( const char * title
)
1978 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1980 formals_
->appendEvaluatedCoreFormal( "index", Kernel::THE_SLOT_VARIABLE
);
1983 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1985 args
.applyDefaults( );
1987 typedef Warm_vector StateType
;
1988 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1990 typedef const Lang::Integer IndexType
;
1991 IndexType::ValueType tmp
= Helpers::down_cast_CoreArgument
< IndexType
>( title_
, args
, 0, callLoc
)->val_
;
1994 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The index must be non-negative." );
1996 size_t index
= static_cast< size_t >( tmp
);
1997 if( index
>= state
->mem_
->size( ) )
1999 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The index is out of range." );
2002 Kernel::ContRef cont
= evalState
->cont_
;
2003 cont
->takeValue( (*state
->mem_
)[ index
],
2011 Kernel::Warm_vector::Warm_vector( )
2012 : mem_( new std::vector
< Kernel::ValueRef
> )
2015 Kernel::Warm_vector::~Warm_vector( )
2024 WarmVector_register_mutators( Lang::SystemFinalClass
* dstClass
)
2026 dstClass
->registerMutator( new Kernel::Mutator_vector_size( "size" ) );
2027 dstClass
->registerMutator( new Kernel::Mutator_vector_resize( "resize" ) );
2028 dstClass
->registerMutator( new Kernel::Mutator_vector_reserve( "reserve" ) );
2029 dstClass
->registerMutator( new Kernel::Mutator_vector_set( "set" ) );
2030 dstClass
->registerMutator( new Kernel::Mutator_vector_get( "get" ) );
2033 RefCountPtr
< const Lang::Class
> Kernel::Warm_vector::TypeID( new Lang::SystemFinalClass( strrefdup( "#Array" ), WarmVector_register_mutators
) );
2034 TYPEINFOIMPL_STATE( Warm_vector
);
2037 Kernel::Warm_vector::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
,const Ast::SourceLocation
& callLoc
)
2039 mem_
->push_back( piece
);
2040 Kernel::ContRef cont
= evalState
->cont_
;
2041 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
2046 Kernel::Warm_vector::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
2048 Kernel::ContRef cont
= evalState
->cont_
;
2049 cont
->takeValue( Kernel::ValueRef( new Lang::VectorFunction( mem_
) ),
2051 mem_
= 0; /* The VectorFunction owns the memory now. */
2055 Kernel::Warm_vector::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
2057 throw Exceptions::MiscellaneousRequirement( strrefdup( "An array state cannot be peeked. To inspect one entry at at time, use the <get> mutator." ) );
2061 Kernel::Warm_vector::gcMark( Kernel::GCMarkedSet
& marked
)
2066 Kernel::registerHot( Kernel::Environment
* env
)
2068 env
->initDefine( Lang::CANVAS_ID
, new Kernel::WarmGroup2D
);
2069 env
->initDefine( Lang::CATALOG_ID
, new Kernel::WarmCatalog
);
2070 env
->initDefine( "stdout", new Kernel::WarmOstream( std::cout
) );
2071 env
->initDefine( "stderr", new Kernel::WarmOstream( std::cerr
) );
2072 env
->initDefine( "randomdevice", new Kernel::WarmRandomDevice( "/dev/urandom" ) );
2073 env
->initDefine( "time", new Kernel::WarmTime
);
2074 env
->initDefine( "ignore", new Kernel::WarmIgnore
);
2076 env
->initDefine( "newIgnore", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmIgnore
> ) );
2077 env
->initDefine( "newGroup", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup2D
> ) );
2078 env
->initDefine( "newGroup3D", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup3D
> ) );
2079 env
->initDefine( "newZBuf", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZBuf
> ) );
2080 env
->initDefine( "newZSorter", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZSorter
> ) );
2081 env
->initDefine( "newString", Kernel::ValueRef( new Lang::HotDefault
< Kernel::Warm_ostringstream
> ) );
2082 env
->initDefine( "newLights", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroupLights
> ) );
2083 env
->initDefine( "newTimer", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmTimer
> ) );
2084 env
->initDefine( "newText", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmText
> ) );
2085 env
->initDefine( "newFont", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmType3Font
> ) );
2086 env
->initDefine( "newColorInterpolator", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmColorInterpolator
> ) );
2087 env
->initDefine( "newArray", Kernel::ValueRef( new Lang::HotDefault
< Kernel::Warm_vector
> ) );