1 #include "Shapes_Helpers_decls.h"
5 #include "continuations.h"
7 #include "fontmetrics.h"
10 #include "pdfstructure.h"
11 #include "timetypes.h"
12 #include "shapescore.h"
16 #include <sys/resource.h>
20 using namespace Shapes
;
23 Lang::Hot::Hot::Hot( )
29 RefCountPtr
< const Lang::Class
> Lang::Hot::TypeID( new Lang::SystemFinalClass( strrefdup( "Hot" ) ) );
33 Lang::HotTriple::HotTriple( const RefCountPtr
< const Lang::Value
> & init
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
34 : init_( init
), update_( update
), result_( result
)
37 Lang::HotTriple::~HotTriple( )
41 Lang::HotTriple::newState( ) const
43 return new Kernel::WarmTriple( init_
, update_
, result_
);
47 Lang::HotTriple::gcMark( Kernel::GCMarkedSet
& marked
)
49 const_cast< Lang::Value
* >( init_
.getPtr( ) )->gcMark( marked
);
50 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
51 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
56 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, Kernel::WarmRandomDevice
* dev
)
57 : sz_( sz
), state_( new char[ sz
] )
59 char * oldState
= initstate( 1, state_
, sz_
);
60 dev
->read( state_
, sz_
);
64 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, unsigned long seed
)
65 : sz_( sz
), state_( new char[ sz
] )
67 char * oldState
= initstate( seed
, state_
, sz_
);
71 Lang::HotRandomSeed::~HotRandomSeed( )
77 Lang::HotRandomSeed::newState( ) const
79 char * stateCopy
= new char[ sz_
];
80 memcpy( stateCopy
, state_
, sz_
);
81 return new Kernel::WarmRandomState( stateCopy
); // This handles ownership to the new state.
85 Lang::HotRandomSeed::gcMark( Kernel::GCMarkedSet
& marked
)
91 Kernel::WarmTriple::WarmTriple( const RefCountPtr
< const Lang::Value
> & pile
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
92 : pile_( pile
), update_( update
), result_( result
)
95 Kernel::WarmTriple::~WarmTriple( )
98 RefCountPtr
< const Lang::Class
> Kernel::WarmTriple::TypeID( new Lang::SystemFinalClass( strrefdup( "#UserState" ) ) );
99 TYPEINFOIMPL_STATE( WarmTriple
);
102 Kernel::WarmTriple::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
104 /* This seems dangerous. I have not verified that pile will still exist when the continuation below is invoked.
106 evalState
->cont_
= Kernel::ContRef( new Kernel::StmtStoreValueContinuation( & pile_
,
109 update_
->call( evalState
, pile_
, piece
, callLoc
);
113 Kernel::WarmTriple::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
115 /* The right continuation is set by the calling variable.
117 result_
->call( evalState
, pile_
, callLoc
);
121 Kernel::WarmTriple::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
123 /* The right continuation is set by the calling variable.
125 result_
->call( evalState
, pile_
, callLoc
);
129 Kernel::WarmTriple::gcMark( Kernel::GCMarkedSet
& marked
)
131 const_cast< Lang::Value
* >( pile_
.getPtr( ) )->gcMark( marked
);
132 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
133 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
137 Kernel::WarmIgnore::WarmIgnore( )
140 Kernel::WarmIgnore::~WarmIgnore( )
143 RefCountPtr
< const Lang::Class
> Kernel::WarmIgnore::TypeID( new Lang::SystemFinalClass( strrefdup( "#Ignore" ) ) );
144 TYPEINFOIMPL_STATE( WarmIgnore
);
147 Kernel::WarmIgnore::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
151 Kernel::ContRef cont
= evalState
->cont_
;
152 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
157 Kernel::WarmIgnore::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
159 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be frozen." ) );
163 Kernel::WarmIgnore::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
165 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be peeked." ) );
169 Kernel::WarmIgnore::gcMark( Kernel::GCMarkedSet
& marked
)
173 Kernel::WarmOstream::WarmOstream( std::ostream
& os
)
177 Kernel::WarmOstream::~WarmOstream( )
180 RefCountPtr
< const Lang::Class
> Kernel::WarmOstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#OutputStream" ) ) );
181 TYPEINFOIMPL_STATE( WarmOstream
);
184 Kernel::WarmOstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
187 Kernel::ContRef cont
= evalState
->cont_
;
188 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
193 Kernel::WarmOstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
195 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be frozen." ) );
199 Kernel::WarmOstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
201 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be peeked." ) );
205 Kernel::WarmOstream::gcMark( Kernel::GCMarkedSet
& marked
)
209 Kernel::Warm_ostringstream::Warm_ostringstream( )
212 Kernel::Warm_ostringstream::~Warm_ostringstream( )
215 RefCountPtr
< const Lang::Class
> Kernel::Warm_ostringstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#StringConcatenator" ) ) );
216 TYPEINFOIMPL_STATE( Warm_ostringstream
);
219 Kernel::Warm_ostringstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
222 Kernel::ContRef cont
= evalState
->cont_
;
223 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
228 Kernel::Warm_ostringstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
230 Kernel::ContRef cont
= evalState
->cont_
;
231 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
236 Kernel::Warm_ostringstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
238 Kernel::ContRef cont
= evalState
->cont_
;
239 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
244 Kernel::Warm_ostringstream::gcMark( Kernel::GCMarkedSet
& marked
)
253 class Mutator_erase
: public Lang::CoreFunction
256 Mutator_erase( const char * title
)
257 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
261 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
263 args
.applyDefaults( );
266 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
269 Kernel::ContRef cont
= evalState
->cont_
;
270 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
276 class Mutator_remove
: public Lang::CoreFunction
279 Mutator_remove( const char * title
)
280 : CoreFunction( title
, new Kernel::EvaluatedFormals( title
, true ) )
282 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
285 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
287 args
.applyDefaults( );
289 typedef const Lang::Symbol KeyType
;
290 RefCountPtr
< KeyType
> key
= Helpers::down_cast_CoreArgument
< KeyType
>( title_
, args
, 0, callLoc
);
293 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
294 state
->remove( key
->getKey( ) );
296 Kernel::ContRef cont
= evalState
->cont_
;
297 cont
->takeValue( Lang::THE_VOID
,
306 Kernel::WarmGroup2D::WarmGroup2D( )
307 : pile_( Lang::THE_NULL2D
)
310 Kernel::WarmGroup2D::~WarmGroup2D( )
314 WarmGroup2D_register_mutators( Lang::SystemFinalClass
* dstClass
)
316 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup2D
>( "erase" ) );
317 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup2D
>( "remove" ) );
320 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup2D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group2D" ), WarmGroup2D_register_mutators
) );
321 TYPEINFOIMPL_STATE( WarmGroup2D
);
325 Kernel::WarmGroup2D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
327 typedef const Lang::Drawable2D ArgType
;
328 RefCountPtr
< ArgType
> arg
= Helpers::down_cast
< ArgType
>( piece
, callLoc
);
331 /* For objects of user-defined type, we also check that the class inherits from Drawable.
333 typedef const Lang::Instance UserType
;
334 UserType
* obj
= dynamic_cast< UserType
* >( arg
.getPtr( ) );
337 if( ! obj
->getClass( )->method_isa( Lang::Drawable2D::TypeID
) )
339 throw Exceptions::TypeMismatch( callLoc
, "2D insertion", piece
->getTypeName( ), ArgType::staticTypeName( ) );
344 pile_
= RefCountPtr
< const Lang::Group2D
>( new Lang::GroupPair2D( arg
,
346 dyn
->getGraphicsState( ) ) );
347 Kernel::ContRef cont
= evalState
->cont_
;
348 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
353 Kernel::WarmGroup2D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
355 Kernel::ContRef cont
= evalState
->cont_
;
356 cont
->takeValue( pile_
,
361 Kernel::WarmGroup2D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
363 Kernel::ContRef cont
= evalState
->cont_
;
364 cont
->takeValue( pile_
,
369 Kernel::WarmGroup2D::erase( )
371 pile_
= Lang::THE_NULL2D
;
375 Kernel::WarmGroup2D::remove( Lang::Symbol::KeyType key
)
377 pile_
= pile_
->removeShallow( key
);
381 Kernel::WarmGroup2D::gcMark( Kernel::GCMarkedSet
& marked
)
383 const_cast< Lang::Group2D
* >( pile_
.getPtr( ) )->gcMark( marked
);
388 Kernel::WarmGroup3D::WarmGroup3D( )
389 : pile_( Lang::THE_NULL3D
)
392 Kernel::WarmGroup3D::~WarmGroup3D( )
396 WarmGroup3D_register_mutators( Lang::SystemFinalClass
* dstClass
)
398 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup3D
>( "erase" ) );
399 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup3D
>( "remove" ) );
402 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup3D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group3D" ), WarmGroup3D_register_mutators
) );
403 TYPEINFOIMPL_STATE( WarmGroup3D
);
406 Kernel::WarmGroup3D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
408 pile_
= RefCountPtr
< const Lang::Group3D
>( new Lang::GroupPair3D( Helpers::down_cast
< const Lang::Drawable3D
>( piece
, callLoc
),
410 dyn
->getGraphicsState( ) ) );
411 Kernel::ContRef cont
= evalState
->cont_
;
412 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
417 Kernel::WarmGroup3D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
419 Kernel::ContRef cont
= evalState
->cont_
;
420 cont
->takeValue( pile_
,
425 Kernel::WarmGroup3D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
427 Kernel::ContRef cont
= evalState
->cont_
;
428 cont
->takeValue( pile_
,
433 Kernel::WarmGroup3D::erase( )
435 pile_
= Lang::THE_NULL3D
;
439 Kernel::WarmGroup3D::remove( Lang::Symbol::KeyType key
)
441 pile_
= pile_
->removeShallow( key
);
445 Kernel::WarmGroup3D::gcMark( Kernel::GCMarkedSet
& marked
)
447 const_cast< Lang::Group3D
* >( pile_
.getPtr( ) )->gcMark( marked
);
451 Kernel::WarmGroupLights::WarmGroupLights( )
452 : pile_( Lang::THE_NULL_LIGHTS
)
455 Kernel::WarmGroupLights::~WarmGroupLights( )
458 RefCountPtr
< const Lang::Class
> Kernel::WarmGroupLights::TypeID( new Lang::SystemFinalClass( strrefdup( "#GroupLights" ) ) );
459 TYPEINFOIMPL_STATE( WarmGroupLights
);
462 Kernel::WarmGroupLights::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
464 pile_
= RefCountPtr
< const Lang::LightGroup
>( new Lang::LightPair( Helpers::down_cast
< const Lang::LightSource
>( piece
, callLoc
),
466 Kernel::ContRef cont
= evalState
->cont_
;
467 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
472 Kernel::WarmGroupLights::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
474 Kernel::ContRef cont
= evalState
->cont_
;
475 cont
->takeValue( pile_
,
480 Kernel::WarmGroupLights::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
482 Kernel::ContRef cont
= evalState
->cont_
;
483 cont
->takeValue( pile_
,
488 Kernel::WarmGroupLights::gcMark( Kernel::GCMarkedSet
& marked
)
490 const_cast< Lang::LightGroup
* >( pile_
.getPtr( ) )->gcMark( marked
);
494 Kernel::WarmZBuf::WarmZBuf( )
497 Kernel::WarmZBuf::~WarmZBuf( )
500 RefCountPtr
< const Lang::Class
> Kernel::WarmZBuf::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZBuf" ) ) );
501 TYPEINFOIMPL_STATE( WarmZBuf
);
504 Kernel::WarmZBuf::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
508 typedef const Lang::Drawable3D ArgType
;
509 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
512 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
514 catch( const char * ball
)
516 std::ostringstream oss
;
517 oss
<< "Conversion to polygon failed with: " << ball
;
518 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
520 Kernel::ContRef cont
= evalState
->cont_
;
521 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
525 catch( const NonLocalExit::NotThisType
& ball
)
527 /* Wrong type; never mind!.. but see below!
533 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
534 Kernel::ContRef cont
= evalState
->cont_
;
535 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
539 catch( const NonLocalExit::NotThisType
& ball
)
541 /* Wrong type; never mind!.. but see below!
547 typedef const Lang::LightGroup ArgType
;
548 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
550 while( ! lights
->isNull( ) )
552 typedef const Lang::LightPair PairType
;
553 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
554 lightPile_
->push_back( p
->car( ) );
558 Kernel::ContRef cont
= evalState
->cont_
;
559 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
563 catch( const NonLocalExit::NotThisType
& ball
)
565 /* Wrong type; never mind!.. but see below!
569 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
573 Kernel::WarmZBuf::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
575 Kernel::ContRef cont
= evalState
->cont_
;
576 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZBuf( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
581 Kernel::WarmZBuf::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
583 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-buffer state cannot be peeked." ) );
587 Kernel::WarmZBuf::gcMark( Kernel::GCMarkedSet
& marked
)
590 typedef typeof *pile_ ListType
;
591 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
593 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
597 // typedef typeof *strokePile_ ListType;
598 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
600 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
604 typedef typeof *lightPile_ ListType
;
605 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
607 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
613 Kernel::WarmZSorter::WarmZSorter( )
616 Kernel::WarmZSorter::~WarmZSorter( )
619 RefCountPtr
< const Lang::Class
> Kernel::WarmZSorter::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZSorter" ) ) );
620 TYPEINFOIMPL_STATE( WarmZSorter
);
623 Kernel::WarmZSorter::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
627 typedef const Lang::Drawable3D ArgType
;
628 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
631 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
633 catch( const char * ball
)
635 std::ostringstream oss
;
636 oss
<< "Conversion to polygon failed with: " << ball
;
637 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
639 Kernel::ContRef cont
= evalState
->cont_
;
640 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
644 catch( const NonLocalExit::NotThisType
& ball
)
646 /* Wrong type; never mind!.. but see below!
652 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
653 Kernel::ContRef cont
= evalState
->cont_
;
654 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
658 catch( const NonLocalExit::NotThisType
& ball
)
660 /* Wrong type; never mind!.. but see below!
666 typedef const Lang::LightGroup ArgType
;
667 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
669 while( ! lights
->isNull( ) )
671 typedef const Lang::LightPair PairType
;
672 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
673 lightPile_
->push_back( p
->car( ) );
677 Kernel::ContRef cont
= evalState
->cont_
;
678 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
682 catch( const NonLocalExit::NotThisType
& ball
)
684 /* Wrong type; never mind!.. but see below!
688 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
692 Kernel::WarmZSorter::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
694 Kernel::ContRef cont
= evalState
->cont_
;
695 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZSorter( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
700 Kernel::WarmZSorter::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
702 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-sorter state cannot be peeked." ) );
706 Kernel::WarmZSorter::gcMark( Kernel::GCMarkedSet
& marked
)
709 typedef typeof *pile_ ListType
;
710 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
712 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
716 // typedef typeof *strokePile_ ListType;
717 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
719 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
723 typedef typeof *lightPile_ ListType
;
724 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
726 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
732 Kernel::WarmTimer::WarmTimer( )
735 int res
= getrusage( RUSAGE_SELF
, &ru
);
738 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
740 start_
= ru
.ru_utime
;
743 Kernel::WarmTimer::~WarmTimer( )
746 RefCountPtr
< const Lang::Class
> Kernel::WarmTimer::TypeID( new Lang::SystemFinalClass( strrefdup( "#Timer" ) ) );
747 TYPEINFOIMPL_STATE( WarmTimer
);
750 Kernel::WarmTimer::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
752 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm timer does not accept values. Please freeze to obtain the number of seconds since creation." ) );
756 Kernel::WarmTimer::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
759 int res
= getrusage( RUSAGE_SELF
, &ru
);
762 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
764 timeval stop
= ru
.ru_utime
;
765 double time1
= start_
.tv_usec
/ 1000000.0 + start_
.tv_sec
;
766 double time2
= stop
.tv_usec
/ 1000000.0 + stop
.tv_sec
;
768 Kernel::ContRef cont
= evalState
->cont_
;
769 cont
->takeValue( Kernel::ValueRef( new Lang::Float( time2
- time1
) ),
774 Kernel::WarmTimer::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
777 int res
= getrusage( RUSAGE_SELF
, &ru
);
780 throw Exceptions::InternalError( strrefdup( "grtrusage 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::gcMark( Kernel::GCMarkedSet
& marked
)
796 Kernel::WarmText::WarmText( )
799 Kernel::WarmText::~WarmText( )
802 RefCountPtr
< const Lang::Class
> Kernel::WarmText::TypeID( new Lang::SystemFinalClass( strrefdup( "#Text" ) ) );
803 TYPEINFOIMPL_STATE( WarmText
);
806 Kernel::WarmText::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
810 typedef const Lang::TextOperation ArgType
;
811 pile_
->push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
812 Kernel::ContRef cont
= evalState
->cont_
;
813 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
817 catch( const NonLocalExit::NotThisType
& ball
)
819 /* Wrong type; never mind!.. but see below!
825 typedef const Lang::String ArgType
;
826 RefCountPtr
< ArgType
> str
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
827 Lang::KernedText
* text
= new Lang::KernedText( evalState
->dyn_
->getTextState( ), evalState
->dyn_
->getGraphicsState( ) );
828 text
->pushString( str
);
829 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( text
) );
830 Kernel::ContRef cont
= evalState
->cont_
;
831 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
835 catch( const NonLocalExit::NotThisType
& ball
)
837 /* Wrong type; never mind!.. but see below!
843 typedef const Lang::Transform2D ArgType
;
844 RefCountPtr
< ArgType
> tf
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
845 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextMoveto( tf
) ) );
846 Kernel::ContRef cont
= evalState
->cont_
;
847 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
851 catch( const NonLocalExit::NotThisType
& ball
)
853 /* Wrong type; never mind!.. but see below!
859 typedef const Lang::Coords2D ArgType
;
860 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
861 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( t
->x_
.get( ), t
->y_
.get( ) ) ) );
862 Kernel::ContRef cont
= evalState
->cont_
;
863 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
867 catch( const NonLocalExit::NotThisType
& ball
)
869 /* Wrong type; never mind!.. but see below!
875 typedef const Lang::FloatPair ArgType
;
876 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
877 Concrete::Length sz
= evalState
->dyn_
->getTextState( )->size_
;
878 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( sz
* t
->x_
, sz
* t
->y_
) ) );
879 Kernel::ContRef cont
= evalState
->cont_
;
880 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
884 catch( const NonLocalExit::NotThisType
& ball
)
886 /* Wrong type; never mind!.. but see below!
890 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::TextOperation::staticTypeName( ), Lang::String::staticTypeName( ) ) );
894 Kernel::WarmText::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
896 if( pile_
->empty( ) )
898 Kernel::ContRef cont
= evalState
->cont_
;
899 cont
->takeValue( Lang::THE_NULL2D
,
904 Concrete::Length xmin
= Concrete::HUGE_LENGTH
;
905 Concrete::Length xmax
= -Concrete::HUGE_LENGTH
;
906 Concrete::Length ymin
= Concrete::HUGE_LENGTH
;
907 Concrete::Length ymax
= -Concrete::HUGE_LENGTH
;
910 Lang::Transform2D
textMatrix( 1, 0, 0, 1, 0, 0 );
911 Lang::Transform2D
textLineMatrix( 1, 0, 0, 1, 0, 0 );
912 typedef typeof *pile_ ListType
;
913 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
915 (*i
)->measure( & textMatrix
, & textLineMatrix
, & xmin
, & ymin
, & xmax
, & ymax
);
919 Lang::ElementaryPath2D
* bbox
= new Lang::ElementaryPath2D
;
921 if( xmin
< Concrete::HUGE_LENGTH
)
923 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymin
) );
924 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymax
) );
925 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymax
) );
926 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymin
) );
930 Kernel::ContRef cont
= evalState
->cont_
;
931 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Text( evalState
->dyn_
->getGraphicsState( ),
932 evalState
->dyn_
->getTextState( ),
934 RefCountPtr
< const Lang::ElementaryPath2D
>( bbox
) ) ),
939 Kernel::WarmText::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
941 throw Exceptions::MiscellaneousRequirement( strrefdup( "A text graphics state cannot be peeked." ) );
945 Kernel::WarmText::gcMark( Kernel::GCMarkedSet
& marked
)
947 typedef typeof *pile_ ListType
;
948 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
950 const_cast< Lang::TextOperation
* >( i
->getPtr( ) )->gcMark( marked
);
955 Kernel::WarmType3Font::WarmType3Font( )
956 : metrics_( new FontMetrics::BaseFont( ) ), size_( -1 )
958 metrics_
->capHeight_
= std::numeric_limits
< double >::signaling_NaN( );
959 metrics_
->xHeight_
= std::numeric_limits
< double >::signaling_NaN( );
960 metrics_
->ascender_
= std::numeric_limits
< double >::signaling_NaN( );
961 metrics_
->descender_
= std::numeric_limits
< double >::signaling_NaN( );
962 metrics_
->leading_
= std::numeric_limits
< double >::signaling_NaN( );
963 metrics_
->stdHW_
= std::numeric_limits
< double >::signaling_NaN( );
964 metrics_
->stdVW_
= std::numeric_limits
< double >::signaling_NaN( );
965 metrics_
->fontBBoxXMin_
= 0;
966 metrics_
->fontBBoxXMax_
= -1;
968 metrics_
->horizontalMetrics_
= RefCountPtr
< FontMetrics::WritingDirectionMetrics
>( new FontMetrics::WritingDirectionMetrics( ) );
969 metrics_
->horizontalMetrics_
->underlinePosition_
= std::numeric_limits
< double >::signaling_NaN( );
970 metrics_
->horizontalMetrics_
->underlineThickness_
= std::numeric_limits
< double >::signaling_NaN( );
971 metrics_
->horizontalMetrics_
->italicAngleRadians_
= std::numeric_limits
< double >::signaling_NaN( );
974 Kernel::WarmType3Font::~WarmType3Font( )
977 RefCountPtr
< const Lang::Class
> Kernel::WarmType3Font::TypeID( new Lang::SystemFinalClass( strrefdup( "#Type3Font" ) ) );
978 TYPEINFOIMPL_STATE( WarmType3Font
);
981 Kernel::WarmType3Font::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
985 typedef const Lang::Type3Glyph ArgType
;
986 glyphs_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
987 Kernel::ContRef cont
= evalState
->cont_
;
988 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
992 catch( const NonLocalExit::NotThisType
& ball
)
994 /* Wrong type; never mind!.. but see below!
1000 typedef const Lang::KernedText ArgType
;
1001 kernings_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
1002 Kernel::ContRef cont
= evalState
->cont_
;
1003 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
1007 catch( const NonLocalExit::NotThisType
& ball
)
1009 /* Wrong type; never mind!.. but see below!
1015 typedef const Lang::TaggedValue2D ArgType
;
1016 RefCountPtr
< ArgType
> taggedVal
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
1018 RefCountPtr
< const char > tagMem
= Lang::Symbol::nameFromKey( taggedVal
->key( ) );
1019 const char * tag
= tagMem
.getPtr( );
1020 RefCountPtr
< const Lang::Value
> val
= taggedVal
->val( );
1022 if( strcmp( tag
, "size" ) == 0 )
1026 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1028 typedef const Lang::Length ValType
;
1029 size_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( );
1030 if( ! ( size_
> 0 ) )
1032 throw Exceptions::OutOfRange( callLoc
, "The size must be positive." );
1035 else if( strcmp( tag
, "FontName" ) == 0 )
1037 if( metrics_
->fontName_
!= NullPtr
< const char >( ) )
1039 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1041 typedef const Lang::Symbol ValType
;
1042 metrics_
->fontName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1044 else if( strcmp( tag
, "FullName" ) == 0 )
1046 if( metrics_
->fullName_
!= NullPtr
< const char >( ) )
1048 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1050 typedef const Lang::String ValType
;
1051 metrics_
->fullName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1053 else if( strcmp( tag
, "FamilyName" ) == 0 )
1055 if( metrics_
->familyName_
!= NullPtr
< const char >( ) )
1057 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1059 typedef const Lang::Symbol ValType
;
1060 metrics_
->familyName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1062 else if( strcmp( tag
, "Weight" ) == 0 )
1066 typedef const Lang::Symbol ValType
;
1067 RefCountPtr
< const char > typedVal
= Helpers::try_cast_CoreArgument
< ValType
>( val
)->name( );
1068 if( metrics_
->weight_
!= NullPtr
< const char >( ) )
1070 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1072 static std::set
< const char *, charPtrLess
> legalStretchValues
;
1073 if( legalStretchValues
.empty( ) )
1075 initializeLegalStrechValues( & legalStretchValues
);
1077 if( legalStretchValues
.find( typedVal
.getPtr( ) ) == legalStretchValues
.end( ) )
1079 throw Exceptions::OutOfRange( callLoc
, "The 'Weight value is illegal. Please refer to the PDF specification." );
1081 metrics_
->weight_
= typedVal
;
1084 catch( const NonLocalExit::NotThisType
& ball
)
1086 /* Wrong type; never mind!.. but see below!
1092 typedef const Lang::Integer ValType
;
1093 RefCountPtr
< ValType
> casted_val
= Helpers::try_cast_CoreArgument
< ValType
>( val
);
1094 if( metrics_
->weightNumber_
> 0 )
1096 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1098 if( casted_val
->val_
% 100 != 0 )
1100 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be divisible by 100." );
1102 if( casted_val
->val_
< 100 || casted_val
->val_
> 900 )
1104 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be in the range [ 100, 900 ]." );
1106 metrics_
->weightNumber_
= casted_val
->val_
;
1109 catch( const NonLocalExit::NotThisType
& ball
)
1111 /* Wrong type; never mind!.. but see below!
1115 throw Exceptions::TypeMismatch( callLoc
, val
->getTypeName( ), Helpers::typeSetString( Lang::String::staticTypeName( ), Lang::Integer::staticTypeName( ) ) );
1117 else if( strcmp( tag
, "Version" ) == 0 )
1119 if( metrics_
->version_
!= NullPtr
< const char >( ) )
1121 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1123 typedef const Lang::String ValType
;
1124 metrics_
->version_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1126 else if( strcmp( tag
, "Notice" ) == 0 )
1128 if( metrics_
->notice_
!= NullPtr
< const char >( ) )
1130 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1132 typedef const Lang::String ValType
;
1133 metrics_
->notice_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1135 else if( strcmp( tag
, "EncodingScheme" ) == 0 )
1137 if( metrics_
->encodingScheme_
!= NullPtr
< const char >( ) )
1139 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1141 typedef const Lang::Symbol ValType
;
1142 metrics_
->encodingScheme_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1144 else if( strcmp( tag
, "CharacterSet" ) == 0 )
1146 if( metrics_
->characterSet_
!= NullPtr
< const char >( ) )
1148 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1150 typedef const Lang::Symbol ValType
;
1151 metrics_
->characterSet_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1153 else if( strcmp( tag
, "Comment" ) == 0 )
1155 typedef const Lang::String ValType
;
1156 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1157 metrics_
->comments_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1159 else if( strcmp( tag
, "CapHeight" ) == 0 )
1161 if( ! IS_NAN( metrics_
->capHeight_
) )
1163 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1165 if( ! ( size_
> 0 ) )
1167 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1169 typedef const Lang::Length ValType
;
1170 metrics_
->capHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1172 else if( strcmp( tag
, "XHeight" ) == 0 )
1174 if( ! IS_NAN( metrics_
->xHeight_
) )
1176 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1178 if( ! ( size_
> 0 ) )
1180 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1182 typedef const Lang::Length ValType
;
1183 metrics_
->xHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1185 else if( strcmp( tag
, "Ascent" ) == 0 )
1187 if( ! IS_NAN( metrics_
->ascender_
) )
1189 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1191 if( ! ( size_
> 0 ) )
1193 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1195 typedef const Lang::Length ValType
;
1196 metrics_
->ascender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1198 else if( strcmp( tag
, "Descent" ) == 0 )
1200 if( ! IS_NAN( metrics_
->descender_
) )
1202 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1204 if( ! ( size_
> 0 ) )
1206 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1208 typedef const Lang::Length ValType
;
1209 metrics_
->descender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1211 else if( strcmp( tag
, "Leading" ) == 0 )
1213 if( ! IS_NAN( metrics_
->leading_
) )
1215 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1217 if( ! ( size_
> 0 ) )
1219 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1221 typedef const Lang::Length ValType
;
1222 metrics_
->leading_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1224 else if( strcmp( tag
, "StemH" ) == 0 )
1226 if( ! IS_NAN( metrics_
->stdHW_
) )
1228 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1230 if( ! ( size_
> 0 ) )
1232 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1234 typedef const Lang::Length ValType
;
1235 metrics_
->stdHW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1237 else if( strcmp( tag
, "StemV" ) == 0 )
1239 if( ! IS_NAN( metrics_
->stdVW_
) )
1241 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1243 if( ! ( size_
> 0 ) )
1245 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1247 typedef const Lang::Length ValType
;
1248 metrics_
->stdVW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1250 else if( strcmp( tag
, "FontBBox" ) == 0 )
1252 if( metrics_
->fontBBoxXMax_
>= metrics_
->fontBBoxXMin_
)
1254 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1256 if( ! ( size_
> 0 ) )
1258 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1260 typedef const Lang::ElementaryPath2D ValType
;
1261 RefCountPtr
< ValType
> casted_val
= Helpers::elementaryPathTry2D( val
);
1262 Concrete::Coords2D
llcorner( 0, 0 );
1263 Concrete::Coords2D
urcorner( 0, 0 );
1264 if( ! casted_val
->boundingRectangle( & llcorner
, & urcorner
) )
1266 throw Exceptions::OutOfRange( callLoc
, "The path was empty." );
1268 metrics_
->fontBBoxXMin_
= llcorner
.x_
/ size_
;
1269 metrics_
->fontBBoxYMin_
= llcorner
.y_
/ size_
;
1270 metrics_
->fontBBoxXMax_
= urcorner
.x_
/ size_
;
1271 metrics_
->fontBBoxYMax_
= urcorner
.y_
/ size_
;
1273 else if( strcmp( tag
, "UnderlinePosition" ) == 0 )
1275 if( ! IS_NAN( metrics_
->horizontalMetrics_
->underlinePosition_
) )
1277 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1279 if( ! ( size_
> 0 ) )
1281 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1283 typedef const Lang::Length ValType
;
1284 metrics_
->horizontalMetrics_
->underlinePosition_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1286 else if( strcmp( tag
, "UnderlineThickness" ) == 0 )
1288 if( ! IS_NAN( metrics_
->horizontalMetrics_
->underlineThickness_
) )
1290 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1292 if( ! ( size_
> 0 ) )
1294 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1296 typedef const Lang::Length ValType
;
1297 metrics_
->horizontalMetrics_
->underlineThickness_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1299 else if( strcmp( tag
, "ItalicAngle" ) == 0 )
1301 if( ! IS_NAN( metrics_
->horizontalMetrics_
->italicAngleRadians_
) )
1303 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1305 typedef const Lang::Float ValType
;
1306 metrics_
->horizontalMetrics_
->italicAngleRadians_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1310 typedef const Lang::String ValType
;
1311 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1312 metrics_
->assortedGlobalInfo_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1316 Kernel::ContRef cont
= evalState
->cont_
;
1317 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
1321 catch( const NonLocalExit::NotThisType
& ball
)
1323 /* Wrong type; never mind!.. but see below!
1327 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Type3Glyph::staticTypeName( ), Lang::KernedText::staticTypeName( ), Lang::TaggedValue2D::staticTypeName( ) ) );
1331 Kernel::WarmType3Font::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1333 if( glyphs_
.empty( ) )
1335 throw Exceptions::OutOfRange( callLoc
, "A font without glyphs?!" );
1337 if( ! ( size_
> 0 ) )
1339 throw Exceptions::OutOfRange( callLoc
, "Missing 'size." );
1341 if( strlen( metrics_
->fontName_
.getPtr( ) ) == 0 )
1343 throw Exceptions::OutOfRange( callLoc
, "Missing 'FontName." );
1345 if( metrics_
->weightNumber_
== 0 )
1347 metrics_
->weightNumber_
= 400;
1349 bool findBBox
= false;
1350 if( metrics_
->fontBBoxXMax_
< metrics_
->fontBBoxXMin_
)
1355 Concrete::ReciprocalLength invSize
= 1 / size_
;
1357 metrics_
->charCount_
= glyphs_
.size( );
1358 metrics_
->isCIDFont_
= false;
1360 size_t firstChar
= INT_MAX
;
1361 size_t lastChar
= 0;
1363 // In the first scan of the glyphs, only firstChar and lastChar are computed. The other tasks are performed in the later scan.
1364 typedef typeof glyphs_ ListType
;
1365 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1367 size_t code
= (*i
)->code( );
1370 firstChar
= std::min( firstChar
, code
);
1371 lastChar
= std::max( lastChar
, code
);
1376 RefCountPtr
< SimplePDF::PDF_Vector
> widths
;
1378 RefCountPtr
< SimplePDF::PDF_Object
> stdWidth
= SimplePDF::newFloat( 0 );
1379 widths
->vec
.resize( lastChar
- firstChar
+ 1, stdWidth
);
1381 RefCountPtr
< SimplePDF::PDF_Dictionary
> charProcs
;
1382 RefCountPtr
< SimplePDF::PDF_Resources
> resources
;
1383 // RefCountPtr< SimplePDF::PDF_Stream_out > toUnicode;
1385 RefCountPtr
< FontMetrics::WritingDirectionMetrics
> horizontal
= metrics_
->horizontalMetrics_
;
1386 horizontal
->charData_
.reserve( glyphs_
.size( ) );
1389 // This is the main loop over all glyphs.
1390 typedef typeof glyphs_ ListType
;
1391 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1393 size_t code
= (*i
)->code( );
1396 widths
->vec
[ code
- firstChar
] = SimplePDF::newFloat( (*i
)->widthX( ) );
1399 RefCountPtr
< SimplePDF::PDF_Stream_out
> glyphStream
;
1400 (*i
)->shipout( glyphStream
->data
, resources
);
1401 charProcs
->dic
[ (*i
)->name( ).getPtr( ) ] = SimplePDF::indirect( glyphStream
, & Kernel::theIndirectObjectCount
);
1403 size_t pos
= horizontal
->charData_
.size( );
1404 FontMetrics::CharacterMetrics
* glyphMetrics
= new FontMetrics::CharacterMetrics( pos
);
1405 (*i
)->setupMetric( glyphMetrics
, invSize
);
1406 horizontal
->charData_
.push_back( glyphMetrics
);
1407 horizontal
->nameMap_
[ (*i
)->name( ) ] = pos
;
1410 horizontal
->codeMap_
[ code
] = pos
;
1415 (*i
)->enlargeBBox( & metrics_
->fontBBoxXMin_
, & metrics_
->fontBBoxYMin_
, & metrics_
->fontBBoxXMax_
, & metrics_
->fontBBoxYMax_
);
1420 RefCountPtr
< SimplePDF::PDF_Vector
> fontBBox( new SimplePDF::PDF_Vector( metrics_
->fontBBoxXMin_
, metrics_
->fontBBoxYMin_
,
1421 metrics_
->fontBBoxXMax_
, metrics_
->fontBBoxYMax_
) );
1422 RefCountPtr
< SimplePDF::PDF_Dictionary
> fontDescriptor
;
1423 (*fontDescriptor
)[ "Type" ] = SimplePDF::newName( "FontDescriptor" );
1424 (*fontDescriptor
)[ "FontName" ] = SimplePDF::newName( metrics_
->fontName_
.getPtr( ) );
1425 if( metrics_
->familyName_
.getPtr( ) != NullPtr
< const char >( ) )
1427 (*fontDescriptor
)[ "FontFamily" ] = SimplePDF::newName( metrics_
->familyName_
.getPtr( ) );
1429 if( metrics_
->weight_
.getPtr( ) != NullPtr
< const char >( ) )
1431 // It has already been asserted that this value is legal.
1432 (*fontDescriptor
)[ "FontStretch" ] = SimplePDF::newName( metrics_
->weight_
.getPtr( ) );
1434 if( metrics_
->weightNumber_
> 0 )
1436 // It has already been asserted that this value is legal.
1437 (*fontDescriptor
)[ "FontWeight" ] = SimplePDF::newInt( metrics_
->weightNumber_
);
1439 (*fontDescriptor
)[ "Flags" ] = SimplePDF::newInt( (size_t)(1) << ( 6 - 1 ) ); // This is just the "Nonsymbolic" flag.
1440 (*fontDescriptor
)[ "FontBBox" ] = fontBBox
;
1441 if( ! IS_NAN( horizontal
->italicAngleRadians_
) )
1443 (*fontDescriptor
)[ "ItalicAngle" ] = SimplePDF::newFloat( ( 180 / M_PI
) * horizontal
->italicAngleRadians_
);
1447 throw Exceptions::OutOfRange( callLoc
, "Missing 'ItalicAngle." );
1449 if( ! IS_NAN( metrics_
->ascender_
) )
1451 (*fontDescriptor
)[ "Ascent" ] = SimplePDF::newFloat( metrics_
->ascender_
);
1453 if( ! IS_NAN( metrics_
->descender_
) )
1455 (*fontDescriptor
)[ "Descent" ] = SimplePDF::newFloat( metrics_
->descender_
);
1457 if( ! IS_NAN( metrics_
->leading_
) )
1459 (*fontDescriptor
)[ "Leading" ] = SimplePDF::newFloat( metrics_
->leading_
);
1461 if( ! IS_NAN( metrics_
->capHeight_
) )
1463 (*fontDescriptor
)[ "CapHeight" ] = SimplePDF::newFloat( metrics_
->capHeight_
);
1465 if( ! IS_NAN( metrics_
->xHeight_
) )
1467 (*fontDescriptor
)[ "XHeight" ] = SimplePDF::newFloat( metrics_
->xHeight_
);
1469 if( ! IS_NAN( metrics_
->stdHW_
) )
1471 (*fontDescriptor
)[ "StemH" ] = SimplePDF::newFloat( metrics_
->stdHW_
);
1473 if( ! IS_NAN( metrics_
->stdVW_
) )
1475 (*fontDescriptor
)[ "StemV" ] = SimplePDF::newFloat( metrics_
->stdVW_
);
1478 Concrete::Length
the1bp( 1 );
1480 RefCountPtr
< SimplePDF::PDF_Dictionary
> dic
;
1481 RefCountPtr
< SimplePDF::PDF_Object
> indirection
= SimplePDF::indirect( dic
, & Kernel::theIndirectObjectCount
);
1482 (*dic
)[ "Type" ] = SimplePDF::newName( "Font" );
1483 (*dic
)[ "Subtype" ] = SimplePDF::newName( "Type3" );
1484 (*dic
)[ "Encoding" ] = SimplePDF::newName( "MacRomanEncoding" );
1485 (*dic
)[ "FontBBox" ] = fontBBox
;
1486 (*dic
)[ "FontMatrix" ] = RefCountPtr
< SimplePDF::PDF_Vector
>( new SimplePDF::PDF_Vector( the1bp
* invSize
, 0, 0, the1bp
* invSize
, 0, 0 ) );
1487 (*dic
)[ "CharProcs" ] = charProcs
;
1488 (*dic
)[ "FirstChar" ] = SimplePDF::newInt( firstChar
);
1489 (*dic
)[ "LastChar" ] = SimplePDF::newInt( lastChar
);
1490 (*dic
)[ "Widths" ] = widths
;
1491 (*dic
)[ "FontDescriptor" ] = fontDescriptor
;
1492 (*dic
)[ "Resources" ] = SimplePDF::indirect( resources
, & Kernel::theIndirectObjectCount
);
1495 // static bool shown = false;
1498 // std::cerr << "Warning: The ToUnicode CMap is not setup by Shapes." << std::endl ;
1502 // (*dic)[ "ToUnicode" ] = toUnicode;
1504 Kernel::ContRef cont
= evalState
->cont_
;
1505 cont
->takeValue( Kernel::ValueRef( new Lang::Font( metrics_
->fontName_
,
1512 Kernel::WarmType3Font::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1514 throw Exceptions::MiscellaneousRequirement( strrefdup( "A type 3 font state cannot be peeked." ) );
1518 Kernel::WarmType3Font::gcMark( Kernel::GCMarkedSet
& marked
)
1521 typedef typeof kernings_ ListType
;
1522 for( ListType::const_iterator i
= kernings_
.begin( ); i
!= kernings_
.end( ); ++i
)
1524 const_cast< Lang::KernedText
* >( i
->getPtr( ) )->gcMark( marked
);
1528 typedef typeof glyphs_ ListType
;
1529 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1531 const_cast< Lang::Type3Glyph
* >( i
->getPtr( ) )->gcMark( marked
);
1538 Kernel::WarmType3Font::initializeLegalStrechValues( std::set
< const char *, charPtrLess
> * legalStretchValues
)
1540 legalStretchValues
->insert( "UltraCondensed" );
1541 legalStretchValues
->insert( "ExtraCondensed" );
1542 legalStretchValues
->insert( "Condensed" );
1543 legalStretchValues
->insert( "SemiCondensed" );
1544 legalStretchValues
->insert( "Normal" );
1545 legalStretchValues
->insert( "SemiExpanded" );
1546 legalStretchValues
->insert( "Expanded" );
1547 legalStretchValues
->insert( "ExtraExpanded" );
1548 legalStretchValues
->insert( "UltraExpanded" );
1552 Kernel::WarmRandomDevice::WarmRandomDevice( const char * deviceName
)
1553 : deviceName_( deviceName
)
1556 Kernel::WarmRandomDevice::~WarmRandomDevice( )
1559 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomDevice::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomDevice" ) ) );
1560 TYPEINFOIMPL_STATE( WarmRandomDevice
);
1563 Kernel::WarmRandomDevice::read( char * dst
, size_t sz
)
1565 if( ! idev_
.is_open( ) )
1567 idev_
.open( deviceName_
);
1568 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1570 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for input." ) ) );
1574 idev_
.read( dst
, sz
);
1578 Kernel::WarmRandomDevice::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
1580 if( ! odev_
.is_open( ) )
1582 odev_
.open( deviceName_
);
1583 if( ! odev_
.is_open( ) || ! odev_
.good( ) )
1585 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1589 piece
->show( odev_
);
1590 Kernel::ContRef cont
= evalState
->cont_
;
1591 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
1596 Kernel::WarmRandomDevice::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1598 throw Exceptions::MiscellaneousRequirement( strrefdup( "The random device cannot be frozen." ) );
1602 Kernel::WarmRandomDevice::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1604 if( ! idev_
.is_open( ) )
1606 idev_
.open( deviceName_
);
1607 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1609 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1614 idev_
.read( reinterpret_cast< char * >( & tmp
), 1 );
1615 Kernel::ContRef cont
= evalState
->cont_
;
1616 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1621 Kernel::WarmRandomDevice::gcMark( Kernel::GCMarkedSet
& marked
)
1625 Kernel::WarmTime::WarmTime( )
1628 Kernel::WarmTime::~WarmTime( )
1631 RefCountPtr
< const Lang::Class
> Kernel::WarmTime::TypeID( new Lang::SystemFinalClass( strrefdup( "#Time" ) ) );
1632 TYPEINFOIMPL_STATE( WarmTime
);
1635 Kernel::WarmTime::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
1637 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time does not accept values." ) );
1641 Kernel::WarmTime::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1643 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time cannot be frozen." ) );
1647 Kernel::WarmTime::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1649 time_t t
= time( 0 );
1650 Kernel::ContRef cont
= evalState
->cont_
;
1651 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ChronologicalTime( t
) ),
1656 Kernel::WarmTime::gcMark( Kernel::GCMarkedSet
& marked
)
1660 Kernel::WarmRandomState::WarmRandomState( char * state
)
1664 Kernel::WarmRandomState::~WarmRandomState( )
1666 delete state_
; // Let's hope this is not in use!
1669 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomState::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomState" ) ) );
1670 TYPEINFOIMPL_STATE( WarmRandomState
);
1673 Kernel::WarmRandomState::setState( )
1679 Kernel::WarmRandomState::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
1681 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state does not accept values." ) );
1685 Kernel::WarmRandomState::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1687 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state cannot be frozen." ) );
1691 Kernel::WarmRandomState::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1694 long tmp
= random( );
1695 Kernel::ContRef cont
= evalState
->cont_
;
1696 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1701 Kernel::WarmRandomState::gcMark( Kernel::GCMarkedSet
& marked
)
1705 Kernel::WarmColorInterpolator::WarmColorInterpolator( )
1706 : hasKey_( false ), colorType_( Lang::ColorInterpolator::UNDEFINED
)
1709 Kernel::WarmColorInterpolator::~WarmColorInterpolator( )
1712 RefCountPtr
< const Lang::Class
> Kernel::WarmColorInterpolator::TypeID( new Lang::SystemFinalClass( strrefdup( "#ColorInterpolator" ) ) );
1713 TYPEINFOIMPL_STATE( WarmColorInterpolator
);
1716 Kernel::WarmColorInterpolator::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& callLoc
)
1720 switch( colorType_
)
1722 case Lang::ColorInterpolator::UNDEFINED
:
1725 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1726 colorType_
= Lang::ColorInterpolator::RGB
;
1729 catch( const Exceptions::TypeMismatch
& )
1734 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1735 colorType_
= Lang::ColorInterpolator::GRAY
;
1738 catch( const Exceptions::TypeMismatch
& )
1743 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1744 colorType_
= Lang::ColorInterpolator::CMYK
;
1747 catch( const Exceptions::TypeMismatch
& )
1749 throw Exceptions::MiscellaneousRequirement( strrefdup( "Only colors can be passed to an interpolator." ) );
1751 case Lang::ColorInterpolator::RGB
:
1752 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1755 case Lang::ColorInterpolator::GRAY
:
1756 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1759 case Lang::ColorInterpolator::CMYK
:
1760 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1766 typedef const Lang::Float ArgType
;
1767 double key
= Helpers::down_cast
< ArgType
>( piece
, callLoc
)->val_
;
1768 if( !key_
->empty( ) && key
< key_
->back( ) )
1770 throw Exceptions::MiscellaneousRequirement( strrefdup( "Keys must be added in nondecreasing order to an interpolator." ) );
1774 key_
->push_back( key
);
1778 hasKey_
= ! hasKey_
;
1780 Kernel::ContRef cont
= evalState
->cont_
;
1781 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
1786 Kernel::WarmColorInterpolator::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1788 if( key_
->empty( ) )
1790 throw Exceptions::MiscellaneousRequirement( strrefdup( "There are no colors that define the interpolation." ) );
1794 throw Exceptions::MiscellaneousRequirement( strrefdup( "Missing color for the last key." ) );
1797 Kernel::ContRef cont
= evalState
->cont_
;
1798 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ColorInterpolator( key_
, RGBcolor_
, graycolor_
, CMYKcolor_
, colorType_
) ),
1803 Kernel::WarmColorInterpolator::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1805 throw Exceptions::MiscellaneousRequirement( strrefdup( "An interpolator cannot be peeked." ) );
1809 Kernel::WarmColorInterpolator::gcMark( Kernel::GCMarkedSet
& marked
)
1815 Kernel::registerHot( Kernel::Environment
* env
)
1817 env
->initDefine( Lang::CANVAS_ID
, new Kernel::WarmGroup2D
);
1818 env
->initDefine( Lang::CATALOG_ID
, new Kernel::WarmCatalog
);
1819 env
->initDefine( "stdout", new Kernel::WarmOstream( std::cout
) );
1820 env
->initDefine( "stderr", new Kernel::WarmOstream( std::cerr
) );
1821 env
->initDefine( "randomdevice", new Kernel::WarmRandomDevice( "/dev/urandom" ) );
1822 env
->initDefine( "time", new Kernel::WarmTime
);
1823 env
->initDefine( "ignore", new Kernel::WarmIgnore
);
1825 env
->initDefine( "newIgnore", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmIgnore
> ) );
1826 env
->initDefine( "newGroup", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup2D
> ) );
1827 env
->initDefine( "newGroup3D", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup3D
> ) );
1828 env
->initDefine( "newZBuf", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZBuf
> ) );
1829 env
->initDefine( "newZSorter", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZSorter
> ) );
1830 env
->initDefine( "newString", Kernel::ValueRef( new Lang::HotDefault
< Kernel::Warm_ostringstream
> ) );
1831 env
->initDefine( "newLights", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroupLights
> ) );
1832 env
->initDefine( "newTimer", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmTimer
> ) );
1833 env
->initDefine( "newText", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmText
> ) );
1834 env
->initDefine( "newFont", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmType3Font
> ) );
1835 env
->initDefine( "newColorInterpolator", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmColorInterpolator
> ) );