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, 2013 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"
35 #include <sys/resource.h>
39 using namespace Shapes
;
42 Lang::HotTriple::HotTriple( const RefCountPtr
< const Lang::Value
> & init
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
43 : init_( init
), update_( update
), result_( result
)
46 Lang::HotTriple::~HotTriple( )
50 Lang::HotTriple::newState( ) const
52 return new Kernel::WarmTriple( init_
, update_
, result_
);
56 Lang::HotTriple::gcMark( Kernel::GCMarkedSet
& marked
)
58 const_cast< Lang::Value
* >( init_
.getPtr( ) )->gcMark( marked
);
59 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
60 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
65 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, Kernel::WarmRandomDevice
* dev
)
66 : sz_( sz
), state_( new char[ sz
] )
68 char * oldState
= initstate( 1, state_
, sz_
);
69 dev
->read( state_
, sz_
);
73 Lang::HotRandomSeed::HotRandomSeed( size_t sz
, unsigned long seed
)
74 : sz_( sz
), state_( new char[ sz
] )
76 char * oldState
= initstate( seed
, state_
, sz_
);
80 Lang::HotRandomSeed::~HotRandomSeed( )
86 Lang::HotRandomSeed::newState( ) const
88 char * stateCopy
= new char[ sz_
];
89 memcpy( stateCopy
, state_
, sz_
);
90 return new Kernel::WarmRandomState( stateCopy
); // This handles ownership to the new state.
94 Lang::HotRandomSeed::gcMark( Kernel::GCMarkedSet
& marked
)
100 Kernel::WarmTriple::WarmTriple( const RefCountPtr
< const Lang::Value
> & pile
, RefCountPtr
< const Lang::Function
> update
, RefCountPtr
< const Lang::Function
> result
)
101 : pile_( pile
), update_( update
), result_( result
)
104 Kernel::WarmTriple::~WarmTriple( )
107 RefCountPtr
< const Lang::Class
> Kernel::WarmTriple::TypeID( new Lang::SystemFinalClass( strrefdup( "#UserState" ) ) );
108 TYPEINFOIMPL_STATE( WarmTriple
);
111 Kernel::WarmTriple::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
113 /* This seems dangerous. I have not verified that pile will still exist when the continuation below is invoked.
115 evalState
->cont_
= Kernel::ContRef( new Kernel::StmtStoreValueContinuation( & pile_
,
118 update_
->call( evalState
, pile_
, piece
, callLoc
);
122 Kernel::WarmTriple::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
124 /* The right continuation is set by the calling variable.
126 result_
->call( evalState
, pile_
, callLoc
);
130 Kernel::WarmTriple::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
132 /* The right continuation is set by the calling variable.
134 result_
->call( evalState
, pile_
, callLoc
);
138 Kernel::WarmTriple::gcMark( Kernel::GCMarkedSet
& marked
)
140 const_cast< Lang::Value
* >( pile_
.getPtr( ) )->gcMark( marked
);
141 const_cast< Lang::Function
* >( update_
.getPtr( ) )->gcMark( marked
);
142 const_cast< Lang::Function
* >( result_
.getPtr( ) )->gcMark( marked
);
146 Kernel::WarmIgnore::WarmIgnore( )
149 Kernel::WarmIgnore::~WarmIgnore( )
152 RefCountPtr
< const Lang::Class
> Kernel::WarmIgnore::TypeID( new Lang::SystemFinalClass( strrefdup( "#Ignore" ) ) );
153 TYPEINFOIMPL_STATE( WarmIgnore
);
156 Kernel::WarmIgnore::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
160 Kernel::ContRef cont
= evalState
->cont_
;
161 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
166 Kernel::WarmIgnore::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
168 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be frozen." ) );
172 Kernel::WarmIgnore::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
174 throw Exceptions::MiscellaneousRequirement( strrefdup( "An ignore state cannot be peeked." ) );
178 Kernel::WarmIgnore::gcMark( Kernel::GCMarkedSet
& marked
)
182 Kernel::WarmOstream::WarmOstream( std::ostream
& os
)
186 Kernel::WarmOstream::~WarmOstream( )
189 RefCountPtr
< const Lang::Class
> Kernel::WarmOstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#OutputStream" ) ) );
190 TYPEINFOIMPL_STATE( WarmOstream
);
193 Kernel::WarmOstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
196 Kernel::ContRef cont
= evalState
->cont_
;
197 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
202 Kernel::WarmOstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
204 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be frozen." ) );
208 Kernel::WarmOstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
210 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm ostream cannot be peeked." ) );
214 Kernel::WarmOstream::gcMark( Kernel::GCMarkedSet
& marked
)
218 Kernel::Warm_ostringstream::Warm_ostringstream( )
221 Kernel::Warm_ostringstream::~Warm_ostringstream( )
224 RefCountPtr
< const Lang::Class
> Kernel::Warm_ostringstream::TypeID( new Lang::SystemFinalClass( strrefdup( "#StringConcatenator" ) ) );
225 TYPEINFOIMPL_STATE( Warm_ostringstream
);
228 Kernel::Warm_ostringstream::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
231 Kernel::ContRef cont
= evalState
->cont_
;
232 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
237 Kernel::Warm_ostringstream::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
239 Kernel::ContRef cont
= evalState
->cont_
;
240 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
245 Kernel::Warm_ostringstream::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
247 Kernel::ContRef cont
= evalState
->cont_
;
248 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( os_
.str( ).c_str( ) ) ) ),
253 Kernel::Warm_ostringstream::gcMark( Kernel::GCMarkedSet
& marked
)
262 class Mutator_erase
: public Lang::CoreMutator
265 Mutator_erase( const char * name
)
266 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
270 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
272 args
.applyDefaults( callLoc
);
275 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
278 Kernel::ContRef cont
= evalState
->cont_
;
279 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
285 class Mutator_remove
: public Lang::CoreMutator
288 Mutator_remove( const char * name
)
289 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
291 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
294 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
296 args
.applyDefaults( callLoc
);
299 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
301 typedef const Lang::Symbol KeyType
;
302 RefCountPtr
< KeyType
> key
= Helpers::down_cast_MutatorArgument
< KeyType
>( state
, name_
, args
, 0, callLoc
);
304 state
->remove( key
->getKey( ) );
306 Kernel::ContRef cont
= evalState
->cont_
;
307 cont
->takeValue( Lang::THE_VOID
,
316 Kernel::WarmGroup2D::WarmGroup2D( )
317 : pile_( Lang::THE_NULL2D
)
320 Kernel::WarmGroup2D::~WarmGroup2D( )
324 WarmGroup2D_register_mutators( Lang::SystemFinalClass
* dstClass
)
326 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup2D
>( "erase" ) );
327 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup2D
>( "remove" ) );
330 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup2D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group2D" ), WarmGroup2D_register_mutators
) );
331 TYPEINFOIMPL_STATE( WarmGroup2D
);
335 Kernel::WarmGroup2D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
337 typedef const Lang::Drawable2D ArgType
;
338 RefCountPtr
< ArgType
> arg
= Helpers::down_cast
< ArgType
>( piece
, callLoc
);
341 /* For objects of user-defined type, we also check that the class inherits from Drawable.
343 typedef const Lang::Instance UserType
;
344 UserType
* obj
= dynamic_cast< UserType
* >( arg
.getPtr( ) );
347 if( ! obj
->getClass( )->method_isa( Lang::Drawable2D::TypeID
) )
349 throw Exceptions::TypeMismatch( callLoc
, "2D insertion", piece
->getTypeName( ), ArgType::staticTypeName( ) );
354 pile_
= RefCountPtr
< const Lang::Group2D
>( new Lang::GroupPair2D( arg
,
356 evalState
->dyn_
->getGraphicsState( ) ) );
357 Kernel::ContRef cont
= evalState
->cont_
;
358 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
363 Kernel::WarmGroup2D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
365 Kernel::ContRef cont
= evalState
->cont_
;
366 cont
->takeValue( pile_
,
371 Kernel::WarmGroup2D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
373 Kernel::ContRef cont
= evalState
->cont_
;
374 cont
->takeValue( pile_
,
379 Kernel::WarmGroup2D::erase( )
381 pile_
= Lang::THE_NULL2D
;
385 Kernel::WarmGroup2D::remove( Lang::Symbol::KeyType key
)
387 pile_
= pile_
->removeShallow( key
);
391 Kernel::WarmGroup2D::gcMark( Kernel::GCMarkedSet
& marked
)
393 const_cast< Lang::Group2D
* >( pile_
.getPtr( ) )->gcMark( marked
);
398 Kernel::WarmGroup3D::WarmGroup3D( )
399 : pile_( Lang::THE_NULL3D
)
402 Kernel::WarmGroup3D::~WarmGroup3D( )
406 WarmGroup3D_register_mutators( Lang::SystemFinalClass
* dstClass
)
408 dstClass
->registerMutator( new Kernel::Mutator_erase
< Kernel::WarmGroup3D
>( "erase" ) );
409 dstClass
->registerMutator( new Kernel::Mutator_remove
< Kernel::WarmGroup3D
>( "remove" ) );
412 RefCountPtr
< const Lang::Class
> Kernel::WarmGroup3D::TypeID( new Lang::SystemFinalClass( strrefdup( "#Group3D" ), WarmGroup3D_register_mutators
) );
413 TYPEINFOIMPL_STATE( WarmGroup3D
);
416 Kernel::WarmGroup3D::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
418 pile_
= RefCountPtr
< const Lang::Group3D
>( new Lang::GroupPair3D( Helpers::down_cast
< const Lang::Drawable3D
>( piece
, callLoc
),
420 evalState
->dyn_
->getGraphicsState( ) ) );
421 Kernel::ContRef cont
= evalState
->cont_
;
422 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
427 Kernel::WarmGroup3D::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
429 Kernel::ContRef cont
= evalState
->cont_
;
430 cont
->takeValue( pile_
,
435 Kernel::WarmGroup3D::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
437 Kernel::ContRef cont
= evalState
->cont_
;
438 cont
->takeValue( pile_
,
443 Kernel::WarmGroup3D::erase( )
445 pile_
= Lang::THE_NULL3D
;
449 Kernel::WarmGroup3D::remove( Lang::Symbol::KeyType key
)
451 pile_
= pile_
->removeShallow( key
);
455 Kernel::WarmGroup3D::gcMark( Kernel::GCMarkedSet
& marked
)
457 const_cast< Lang::Group3D
* >( pile_
.getPtr( ) )->gcMark( marked
);
461 Kernel::WarmGroupLights::WarmGroupLights( )
462 : pile_( Lang::THE_NULL_LIGHTS
)
465 Kernel::WarmGroupLights::~WarmGroupLights( )
468 RefCountPtr
< const Lang::Class
> Kernel::WarmGroupLights::TypeID( new Lang::SystemFinalClass( strrefdup( "#GroupLights" ) ) );
469 TYPEINFOIMPL_STATE( WarmGroupLights
);
472 Kernel::WarmGroupLights::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
474 pile_
= RefCountPtr
< const Lang::LightGroup
>( new Lang::LightPair( Helpers::down_cast
< const Lang::LightSource
>( piece
, callLoc
),
476 Kernel::ContRef cont
= evalState
->cont_
;
477 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
482 Kernel::WarmGroupLights::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
484 Kernel::ContRef cont
= evalState
->cont_
;
485 cont
->takeValue( pile_
,
490 Kernel::WarmGroupLights::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
492 Kernel::ContRef cont
= evalState
->cont_
;
493 cont
->takeValue( pile_
,
498 Kernel::WarmGroupLights::gcMark( Kernel::GCMarkedSet
& marked
)
500 const_cast< Lang::LightGroup
* >( pile_
.getPtr( ) )->gcMark( marked
);
504 Kernel::WarmZBuf::WarmZBuf( )
507 Kernel::WarmZBuf::~WarmZBuf( )
510 RefCountPtr
< const Lang::Class
> Kernel::WarmZBuf::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZBuf" ) ) );
511 TYPEINFOIMPL_STATE( WarmZBuf
);
514 Kernel::WarmZBuf::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
518 typedef const Lang::Drawable3D ArgType
;
519 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
522 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
524 catch( const char * ball
)
526 std::ostringstream oss
;
527 oss
<< "Conversion to polygon failed with: " << ball
;
528 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
530 Kernel::ContRef cont
= evalState
->cont_
;
531 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
535 catch( const NonLocalExit::NotThisType
& ball
)
537 /* Wrong type; never mind!.. but see below!
543 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
544 Kernel::ContRef cont
= evalState
->cont_
;
545 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
549 catch( const NonLocalExit::NotThisType
& ball
)
551 /* Wrong type; never mind!.. but see below!
557 typedef const Lang::LightGroup ArgType
;
558 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
560 while( ! lights
->isNull( ) )
562 typedef const Lang::LightPair PairType
;
563 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
564 lightPile_
->push_back( p
->car( ) );
568 Kernel::ContRef cont
= evalState
->cont_
;
569 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
573 catch( const NonLocalExit::NotThisType
& ball
)
575 /* Wrong type; never mind!.. but see below!
579 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
583 Kernel::WarmZBuf::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
585 Kernel::ContRef cont
= evalState
->cont_
;
586 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZBuf( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
591 Kernel::WarmZBuf::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
593 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-buffer state cannot be peeked." ) );
597 Kernel::WarmZBuf::gcMark( Kernel::GCMarkedSet
& marked
)
600 typedef typeof *pile_ ListType
;
601 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
603 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
607 // typedef typeof *strokePile_ ListType;
608 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
610 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
614 typedef typeof *lightPile_ ListType
;
615 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
617 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
623 Kernel::WarmZSorter::WarmZSorter( )
626 Kernel::WarmZSorter::~WarmZSorter( )
629 RefCountPtr
< const Lang::Class
> Kernel::WarmZSorter::TypeID( new Lang::SystemFinalClass( strrefdup( "#ZSorter" ) ) );
630 TYPEINFOIMPL_STATE( WarmZSorter
);
633 Kernel::WarmZSorter::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
637 typedef const Lang::Drawable3D ArgType
;
638 RefCountPtr
< ArgType
> drawable
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
641 drawable
->polygonize( pile_
.getPtr( ), strokePile_
.getPtr( ), evalState
->dyn_
, Lang::THE_3D_IDENTITY
, drawable
);
643 catch( const char * ball
)
645 std::ostringstream oss
;
646 oss
<< "Conversion to polygon failed with: " << ball
;
647 throw Exceptions::OutOfRange( callLoc
, strrefdup( oss
) );
649 Kernel::ContRef cont
= evalState
->cont_
;
650 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
654 catch( const NonLocalExit::NotThisType
& ball
)
656 /* Wrong type; never mind!.. but see below!
662 lightPile_
->push_back( Helpers::try_cast_CoreArgument
< const Lang::LightSource
>( piece
) );
663 Kernel::ContRef cont
= evalState
->cont_
;
664 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
668 catch( const NonLocalExit::NotThisType
& ball
)
670 /* Wrong type; never mind!.. but see below!
676 typedef const Lang::LightGroup ArgType
;
677 RefCountPtr
< ArgType
> lights
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
679 while( ! lights
->isNull( ) )
681 typedef const Lang::LightPair PairType
;
682 RefCountPtr
< PairType
> p
= lights
.down_cast
< PairType
>( );
683 lightPile_
->push_back( p
->car( ) );
687 Kernel::ContRef cont
= evalState
->cont_
;
688 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
692 catch( const NonLocalExit::NotThisType
& ball
)
694 /* Wrong type; never mind!.. but see below!
698 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Drawable3D::staticTypeName( ), Lang::LightSource::staticTypeName( ) ) );
702 Kernel::WarmZSorter::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
704 Kernel::ContRef cont
= evalState
->cont_
;
705 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ZSorter( pile_
, strokePile_
, lightPile_
, evalState
->dyn_
->getGraphicsState( ) ) ),
710 Kernel::WarmZSorter::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
712 throw Exceptions::MiscellaneousRequirement( strrefdup( "A z-sorter state cannot be peeked." ) );
716 Kernel::WarmZSorter::gcMark( Kernel::GCMarkedSet
& marked
)
719 typedef typeof *pile_ ListType
;
720 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
722 const_cast< Computation::PaintedPolygon3D
* >( i
->getPtr( ) )->gcMark( marked
);
726 // typedef typeof *strokePile_ ListType;
727 // for( ListType::const_iterator i = strokePile_->begin( ); i != strokePile_->end( ); ++i )
729 // const_cast< Computation::StrokedLine3D * >( i->getPtr( ) )->gcMark( marked );
733 typedef typeof *lightPile_ ListType
;
734 for( ListType::const_iterator i
= lightPile_
->begin( ); i
!= lightPile_
->end( ); ++i
)
736 const_cast< Lang::LightSource
* >( i
->getPtr( ) )->gcMark( marked
);
742 Kernel::WarmTimer::WarmTimer( )
745 int res
= getrusage( RUSAGE_SELF
, &ru
);
748 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
750 start_
= ru
.ru_utime
;
753 Kernel::WarmTimer::~WarmTimer( )
756 RefCountPtr
< const Lang::Class
> Kernel::WarmTimer::TypeID( new Lang::SystemFinalClass( strrefdup( "#Timer" ) ) );
757 TYPEINFOIMPL_STATE( WarmTimer
);
760 Kernel::WarmTimer::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
762 throw Exceptions::MiscellaneousRequirement( strrefdup( "A warm timer does not accept values. Please freeze to obtain the number of seconds since creation." ) );
766 Kernel::WarmTimer::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
769 int res
= getrusage( RUSAGE_SELF
, &ru
);
772 throw Exceptions::InternalError( strrefdup( "getrusage failed." ) );
774 timeval stop
= ru
.ru_utime
;
775 double time1
= start_
.tv_usec
/ 1000000.0 + start_
.tv_sec
;
776 double time2
= stop
.tv_usec
/ 1000000.0 + stop
.tv_sec
;
778 Kernel::ContRef cont
= evalState
->cont_
;
779 cont
->takeValue( Kernel::ValueRef( new Lang::Float( time2
- time1
) ),
784 Kernel::WarmTimer::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
787 int res
= getrusage( RUSAGE_SELF
, &ru
);
790 throw Exceptions::InternalError( strrefdup( "grtrusage failed." ) );
792 timeval stop
= ru
.ru_utime
;
793 double time1
= start_
.tv_usec
/ 1000000.0 + start_
.tv_sec
;
794 double time2
= stop
.tv_usec
/ 1000000.0 + stop
.tv_sec
;
796 Kernel::ContRef cont
= evalState
->cont_
;
797 cont
->takeValue( Kernel::ValueRef( new Lang::Float( time2
- time1
) ),
802 Kernel::WarmTimer::gcMark( Kernel::GCMarkedSet
& marked
)
806 Kernel::WarmText::WarmText( )
809 Kernel::WarmText::~WarmText( )
812 RefCountPtr
< const Lang::Class
> Kernel::WarmText::TypeID( new Lang::SystemFinalClass( strrefdup( "#Text" ) ) );
813 TYPEINFOIMPL_STATE( WarmText
);
816 Kernel::WarmText::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
820 typedef const Lang::TextOperation ArgType
;
821 pile_
->push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
822 Kernel::ContRef cont
= evalState
->cont_
;
823 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
827 catch( const NonLocalExit::NotThisType
& ball
)
829 /* Wrong type; never mind!.. but see below!
835 typedef const Lang::String ArgType
;
836 RefCountPtr
< ArgType
> str
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
837 Lang::KernedText
* text
= new Lang::KernedText( evalState
->dyn_
->getTextState( ), evalState
->dyn_
->getGraphicsState( ) );
838 text
->pushString( str
);
839 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( text
) );
840 Kernel::ContRef cont
= evalState
->cont_
;
841 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
845 catch( const NonLocalExit::NotThisType
& ball
)
847 /* Wrong type; never mind!.. but see below!
853 typedef const Lang::Transform2D ArgType
;
854 RefCountPtr
< ArgType
> tf
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
855 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextMoveto( tf
) ) );
856 Kernel::ContRef cont
= evalState
->cont_
;
857 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
861 catch( const NonLocalExit::NotThisType
& ball
)
863 /* Wrong type; never mind!.. but see below!
869 typedef const Lang::Coords2D ArgType
;
870 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
871 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( t
->x_
.get( ), t
->y_
.get( ) ) ) );
872 Kernel::ContRef cont
= evalState
->cont_
;
873 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
877 catch( const NonLocalExit::NotThisType
& ball
)
879 /* Wrong type; never mind!.. but see below!
885 typedef const Lang::FloatPair ArgType
;
886 RefCountPtr
< ArgType
> t
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
887 Concrete::Length sz
= evalState
->dyn_
->getTextState( )->size_
;
888 pile_
->push_back( RefCountPtr
< const Lang::TextOperation
>( new Lang::TextNewline( sz
* t
->x_
, sz
* t
->y_
) ) );
889 Kernel::ContRef cont
= evalState
->cont_
;
890 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
894 catch( const NonLocalExit::NotThisType
& ball
)
896 /* Wrong type; never mind!.. but see below!
900 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::TextOperation::staticTypeName( ), Lang::String::staticTypeName( ) ) );
904 Kernel::WarmText::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
906 if( pile_
->empty( ) )
908 Kernel::ContRef cont
= evalState
->cont_
;
909 cont
->takeValue( Lang::THE_NULL2D
,
914 Concrete::Length xmin
= Concrete::HUGE_LENGTH
;
915 Concrete::Length xmax
= -Concrete::HUGE_LENGTH
;
916 Concrete::Length ymin
= Concrete::HUGE_LENGTH
;
917 Concrete::Length ymax
= -Concrete::HUGE_LENGTH
;
920 Lang::Transform2D
textMatrix( 1, 0, 0, 1, 0, 0 );
921 Lang::Transform2D
textLineMatrix( 1, 0, 0, 1, 0, 0 );
922 typedef typeof *pile_ ListType
;
923 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
925 (*i
)->measure( & textMatrix
, & textLineMatrix
, & xmin
, & ymin
, & xmax
, & ymax
);
929 Lang::ElementaryPath2D
* bbox
= new Lang::ElementaryPath2D
;
931 if( xmin
< Concrete::HUGE_LENGTH
)
933 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymin
) );
934 bbox
->push_back( new Concrete::PathPoint2D( xmin
, ymax
) );
935 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymax
) );
936 bbox
->push_back( new Concrete::PathPoint2D( xmax
, ymin
) );
940 Kernel::ContRef cont
= evalState
->cont_
;
941 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Text( evalState
->dyn_
->getTextState( ),
943 RefCountPtr
< const Lang::ElementaryPath2D
>( bbox
) ) ),
948 Kernel::WarmText::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
950 throw Exceptions::MiscellaneousRequirement( strrefdup( "A text graphics state cannot be peeked." ) );
954 Kernel::WarmText::gcMark( Kernel::GCMarkedSet
& marked
)
956 typedef typeof *pile_ ListType
;
957 for( ListType::const_iterator i
= pile_
->begin( ); i
!= pile_
->end( ); ++i
)
959 const_cast< Lang::TextOperation
* >( i
->getPtr( ) )->gcMark( marked
);
964 Kernel::WarmType3Font::WarmType3Font( )
965 : metrics_( new FontMetrics::AFM( ) ), size_( -1 )
967 metrics_
->capHeight_
= std::numeric_limits
< double >::signaling_NaN( );
968 metrics_
->xHeight_
= std::numeric_limits
< double >::signaling_NaN( );
969 metrics_
->ascender_
= std::numeric_limits
< double >::signaling_NaN( );
970 metrics_
->descender_
= std::numeric_limits
< double >::signaling_NaN( );
971 metrics_
->leading_
= std::numeric_limits
< double >::signaling_NaN( );
972 metrics_
->stdHW_
= std::numeric_limits
< double >::signaling_NaN( );
973 metrics_
->stdVW_
= std::numeric_limits
< double >::signaling_NaN( );
974 metrics_
->fontBBoxXMin_
= 0;
975 metrics_
->fontBBoxXMax_
= -1;
977 horizontalMetrics_typed_
= new FontMetrics::SingleByte_WritingDirectionMetrics( );
978 metrics_
->horizontalMetrics_
= RefCountPtr
< FontMetrics::WritingDirectionMetrics
>( horizontalMetrics_typed_
);
979 horizontalMetrics_typed_
->underlinePosition_
= std::numeric_limits
< double >::signaling_NaN( );
980 horizontalMetrics_typed_
->underlineThickness_
= std::numeric_limits
< double >::signaling_NaN( );
981 horizontalMetrics_typed_
->italicAngleRadians_
= std::numeric_limits
< double >::signaling_NaN( );
984 Kernel::WarmType3Font::~WarmType3Font( )
987 RefCountPtr
< const Lang::Class
> Kernel::WarmType3Font::TypeID( new Lang::SystemFinalClass( strrefdup( "#Type3Font" ) ) );
988 TYPEINFOIMPL_STATE( WarmType3Font
);
991 Kernel::WarmType3Font::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
995 typedef const Lang::Type3Glyph ArgType
;
996 glyphs_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
997 Kernel::ContRef cont
= evalState
->cont_
;
998 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1002 catch( const NonLocalExit::NotThisType
& ball
)
1004 /* Wrong type; never mind!.. but see below!
1010 typedef const Lang::KernedText ArgType
;
1011 kernings_
.push_back( Helpers::try_cast_CoreArgument
< ArgType
>( piece
) );
1012 Kernel::ContRef cont
= evalState
->cont_
;
1013 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1017 catch( const NonLocalExit::NotThisType
& ball
)
1019 /* Wrong type; never mind!.. but see below!
1025 typedef const Lang::TaggedValue2D ArgType
;
1026 RefCountPtr
< ArgType
> taggedVal
= Helpers::try_cast_CoreArgument
< ArgType
>( piece
);
1028 RefCountPtr
< const char > tagMem
= Lang::Symbol::nameFromKey( taggedVal
->key( ) );
1029 const char * tag
= tagMem
.getPtr( );
1030 RefCountPtr
< const Lang::Value
> val
= taggedVal
->val( );
1032 if( strcmp( tag
, "size" ) == 0 )
1036 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1038 typedef const Lang::Length ValType
;
1039 size_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( );
1040 if( ! ( size_
> 0 ) )
1042 throw Exceptions::OutOfRange( callLoc
, "The size must be positive." );
1045 else if( strcmp( tag
, "FontName" ) == 0 )
1047 if( metrics_
->fontName_
!= NullPtr
< const char >( ) )
1049 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1051 typedef const Lang::Symbol ValType
;
1052 metrics_
->fontName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1054 else if( strcmp( tag
, "FullName" ) == 0 )
1056 if( metrics_
->fullName_
!= NullPtr
< const char >( ) )
1058 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1060 typedef const Lang::String ValType
;
1061 metrics_
->fullName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1063 else if( strcmp( tag
, "FamilyName" ) == 0 )
1065 if( metrics_
->familyName_
!= NullPtr
< const char >( ) )
1067 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1069 typedef const Lang::Symbol ValType
;
1070 metrics_
->familyName_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1072 else if( strcmp( tag
, "Weight" ) == 0 )
1076 typedef const Lang::Symbol ValType
;
1077 RefCountPtr
< const char > typedVal
= Helpers::try_cast_CoreArgument
< ValType
>( val
)->name( );
1078 if( metrics_
->weight_
!= NullPtr
< const char >( ) )
1080 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1082 static std::set
< const char *, charPtrLess
> legalStretchValues
;
1083 if( legalStretchValues
.empty( ) )
1085 initializeLegalStrechValues( & legalStretchValues
);
1087 if( legalStretchValues
.find( typedVal
.getPtr( ) ) == legalStretchValues
.end( ) )
1089 throw Exceptions::OutOfRange( callLoc
, "The 'Weight value is illegal. Please refer to the PDF specification." );
1091 metrics_
->weight_
= typedVal
;
1094 catch( const NonLocalExit::NotThisType
& ball
)
1096 /* Wrong type; never mind!.. but see below!
1102 typedef const Lang::Integer ValType
;
1103 RefCountPtr
< ValType
> casted_val
= Helpers::try_cast_CoreArgument
< ValType
>( val
);
1104 if( metrics_
->weightNumber_
> 0 )
1106 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1108 if( casted_val
->val_
% 100 != 0 )
1110 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be divisible by 100." );
1112 if( casted_val
->val_
< 100 || casted_val
->val_
> 900 )
1114 throw Exceptions::OutOfRange( callLoc
, "The 'Weight number must be in the range [ 100, 900 ]." );
1116 metrics_
->weightNumber_
= casted_val
->val_
;
1119 catch( const NonLocalExit::NotThisType
& ball
)
1121 /* Wrong type; never mind!.. but see below!
1125 throw Exceptions::TypeMismatch( callLoc
, val
->getTypeName( ), Helpers::typeSetString( Lang::String::staticTypeName( ), Lang::Integer::staticTypeName( ) ) );
1127 else if( strcmp( tag
, "Version" ) == 0 )
1129 if( metrics_
->version_
!= NullPtr
< const char >( ) )
1131 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1133 typedef const Lang::String ValType
;
1134 metrics_
->version_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1136 else if( strcmp( tag
, "Notice" ) == 0 )
1138 if( metrics_
->notice_
!= NullPtr
< const char >( ) )
1140 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1142 typedef const Lang::String ValType
;
1143 metrics_
->notice_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1145 else if( strcmp( tag
, "EncodingScheme" ) == 0 )
1147 if( metrics_
->encodingScheme_
!= NullPtr
< const char >( ) )
1149 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1151 typedef const Lang::Symbol ValType
;
1152 metrics_
->encodingScheme_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1154 else if( strcmp( tag
, "CharacterSet" ) == 0 )
1156 if( metrics_
->characterSet_
!= NullPtr
< const char >( ) )
1158 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1160 typedef const Lang::Symbol ValType
;
1161 metrics_
->characterSet_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->name( );
1163 else if( strcmp( tag
, "Comment" ) == 0 )
1165 typedef const Lang::String ValType
;
1166 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1167 metrics_
->comments_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1169 else if( strcmp( tag
, "CapHeight" ) == 0 )
1171 if( ! IS_NAN( metrics_
->capHeight_
) )
1173 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1175 if( ! ( size_
> 0 ) )
1177 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1179 typedef const Lang::Length ValType
;
1180 metrics_
->capHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1182 else if( strcmp( tag
, "XHeight" ) == 0 )
1184 if( ! IS_NAN( metrics_
->xHeight_
) )
1186 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1188 if( ! ( size_
> 0 ) )
1190 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1192 typedef const Lang::Length ValType
;
1193 metrics_
->xHeight_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1195 else if( strcmp( tag
, "Ascent" ) == 0 )
1197 if( ! IS_NAN( metrics_
->ascender_
) )
1199 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1201 if( ! ( size_
> 0 ) )
1203 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1205 typedef const Lang::Length ValType
;
1206 metrics_
->ascender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1208 else if( strcmp( tag
, "Descent" ) == 0 )
1210 if( ! IS_NAN( metrics_
->descender_
) )
1212 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1214 if( ! ( size_
> 0 ) )
1216 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1218 typedef const Lang::Length ValType
;
1219 metrics_
->descender_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1221 else if( strcmp( tag
, "Leading" ) == 0 )
1223 if( ! IS_NAN( metrics_
->leading_
) )
1225 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1227 if( ! ( size_
> 0 ) )
1229 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1231 typedef const Lang::Length ValType
;
1232 metrics_
->leading_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1234 else if( strcmp( tag
, "StemH" ) == 0 )
1236 if( ! IS_NAN( metrics_
->stdHW_
) )
1238 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1240 if( ! ( size_
> 0 ) )
1242 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1244 typedef const Lang::Length ValType
;
1245 metrics_
->stdHW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1247 else if( strcmp( tag
, "StemV" ) == 0 )
1249 if( ! IS_NAN( metrics_
->stdVW_
) )
1251 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1253 if( ! ( size_
> 0 ) )
1255 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1257 typedef const Lang::Length ValType
;
1258 metrics_
->stdVW_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1260 else if( strcmp( tag
, "FontBBox" ) == 0 )
1262 if( metrics_
->fontBBoxXMax_
>= metrics_
->fontBBoxXMin_
)
1264 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1266 if( ! ( size_
> 0 ) )
1268 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1270 typedef const Lang::ElementaryPath2D ValType
;
1271 RefCountPtr
< ValType
> casted_val
= Helpers::elementaryPathTry2D( val
);
1272 Concrete::Coords2D
llcorner( 0, 0 );
1273 Concrete::Coords2D
urcorner( 0, 0 );
1274 if( ! casted_val
->boundingRectangle( & llcorner
, & urcorner
) )
1276 throw Exceptions::OutOfRange( callLoc
, "The path was empty." );
1278 metrics_
->fontBBoxXMin_
= llcorner
.x_
/ size_
;
1279 metrics_
->fontBBoxYMin_
= llcorner
.y_
/ size_
;
1280 metrics_
->fontBBoxXMax_
= urcorner
.x_
/ size_
;
1281 metrics_
->fontBBoxYMax_
= urcorner
.y_
/ size_
;
1283 else if( strcmp( tag
, "UnderlinePosition" ) == 0 )
1285 if( ! IS_NAN( horizontalMetrics_typed_
->underlinePosition_
) )
1287 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1289 if( ! ( size_
> 0 ) )
1291 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1293 typedef const Lang::Length ValType
;
1294 horizontalMetrics_typed_
->underlinePosition_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1296 else if( strcmp( tag
, "UnderlineThickness" ) == 0 )
1298 if( ! IS_NAN( horizontalMetrics_typed_
->underlineThickness_
) )
1300 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1302 if( ! ( size_
> 0 ) )
1304 throw Exceptions::OutOfRange( callLoc
, "Please provide a value for 'size first." );
1306 typedef const Lang::Length ValType
;
1307 horizontalMetrics_typed_
->underlineThickness_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->get( ) / size_
;
1309 else if( strcmp( tag
, "ItalicAngle" ) == 0 )
1311 if( ! IS_NAN( horizontalMetrics_typed_
->italicAngleRadians_
) )
1313 throw Exceptions::MiscellaneousRequirement( "Multiply specified value." );
1315 typedef const Lang::Float ValType
;
1316 horizontalMetrics_typed_
->italicAngleRadians_
= Helpers::down_cast
< ValType
>( val
, callLoc
)->val_
;
1320 typedef const Lang::String ValType
;
1321 RefCountPtr
< ValType
> typedVal
= Helpers::down_cast
< ValType
>( val
, callLoc
);
1322 metrics_
->assortedGlobalInfo_
.push_back( FontMetrics::AFM::AssortedInfo( tagMem
, typedVal
->val_
) );
1326 Kernel::ContRef cont
= evalState
->cont_
;
1327 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1331 catch( const NonLocalExit::NotThisType
& ball
)
1333 /* Wrong type; never mind!.. but see below!
1337 throw Exceptions::TypeMismatch( callLoc
, piece
->getTypeName( ), Helpers::typeSetString( Lang::Type3Glyph::staticTypeName( ), Lang::KernedText::staticTypeName( ), Lang::TaggedValue2D::staticTypeName( ) ) );
1341 Kernel::WarmType3Font::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1343 if( glyphs_
.empty( ) )
1345 throw Exceptions::OutOfRange( callLoc
, "A font without glyphs?!" );
1347 if( ! ( size_
> 0 ) )
1349 throw Exceptions::OutOfRange( callLoc
, "Missing 'size." );
1351 if( strlen( metrics_
->fontName_
.getPtr( ) ) == 0 )
1353 throw Exceptions::OutOfRange( callLoc
, "Missing 'FontName." );
1355 if( metrics_
->weightNumber_
== 0 )
1357 metrics_
->weightNumber_
= 400;
1359 bool findBBox
= false;
1360 if( metrics_
->fontBBoxXMax_
< metrics_
->fontBBoxXMin_
)
1365 Concrete::ReciprocalLength invSize
= 1 / size_
;
1367 metrics_
->charCount_
= glyphs_
.size( );
1368 metrics_
->isCIDFont_
= false;
1370 size_t firstChar
= INT_MAX
;
1371 size_t lastChar
= 0;
1373 // In the first scan of the glyphs, only firstChar and lastChar are computed. The other tasks are performed in the later scan.
1374 typedef typeof glyphs_ ListType
;
1375 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1377 size_t code
= (*i
)->code( );
1380 firstChar
= std::min( firstChar
, code
);
1381 lastChar
= std::max( lastChar
, code
);
1386 RefCountPtr
< SimplePDF::PDF_Vector
> widths
;
1388 RefCountPtr
< SimplePDF::PDF_Object
> stdWidth
= SimplePDF::newFloat( 0 );
1389 widths
->vec
.resize( lastChar
- firstChar
+ 1, stdWidth
);
1391 RefCountPtr
< SimplePDF::PDF_Dictionary
> charProcs
;
1392 RefCountPtr
< SimplePDF::PDF_Resources
> resources
;
1393 // RefCountPtr< SimplePDF::PDF_Stream_out > toUnicode;
1395 horizontalMetrics_typed_
->charData_
.reserve( glyphs_
.size( ) );
1398 // This is the main loop over all glyphs.
1399 typedef typeof glyphs_ ListType
;
1400 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1402 size_t code
= (*i
)->code( );
1405 widths
->vec
[ code
- firstChar
] = SimplePDF::newFloat( (*i
)->widthX( ) );
1408 RefCountPtr
< SimplePDF::PDF_Stream_out
> glyphStream
;
1409 (*i
)->shipout( glyphStream
->data
, resources
);
1410 charProcs
->dic
[ (*i
)->name( ).getPtr( ) ] = SimplePDF::indirect( glyphStream
, & Kernel::theIndirectObjectCount
);
1412 size_t pos
= horizontalMetrics_typed_
->charData_
.size( );
1413 FontMetrics::CharacterMetrics
* glyphMetrics
= new FontMetrics::CharacterMetrics( pos
);
1414 (*i
)->setupMetric( glyphMetrics
, invSize
);
1415 horizontalMetrics_typed_
->charData_
.push_back( glyphMetrics
);
1416 horizontalMetrics_typed_
->nameMap_
[ (*i
)->name( ) ] = pos
;
1419 horizontalMetrics_typed_
->codeMap_
[ code
] = pos
;
1424 (*i
)->enlargeBBox( & metrics_
->fontBBoxXMin_
, & metrics_
->fontBBoxYMin_
, & metrics_
->fontBBoxXMax_
, & metrics_
->fontBBoxYMax_
);
1429 RefCountPtr
< SimplePDF::PDF_Vector
> fontBBox( new SimplePDF::PDF_Vector( metrics_
->fontBBoxXMin_
, metrics_
->fontBBoxYMin_
,
1430 metrics_
->fontBBoxXMax_
, metrics_
->fontBBoxYMax_
) );
1431 RefCountPtr
< SimplePDF::PDF_Dictionary
> fontDescriptor
;
1432 (*fontDescriptor
)[ "Type" ] = SimplePDF::newName( "FontDescriptor" );
1433 (*fontDescriptor
)[ "FontName" ] = SimplePDF::newName( metrics_
->fontName_
.getPtr( ) );
1434 if( metrics_
->familyName_
.getPtr( ) != NullPtr
< const char >( ) )
1436 (*fontDescriptor
)[ "FontFamily" ] = SimplePDF::newName( metrics_
->familyName_
.getPtr( ) );
1438 if( metrics_
->weight_
.getPtr( ) != NullPtr
< const char >( ) )
1440 // It has already been asserted that this value is legal.
1441 (*fontDescriptor
)[ "FontStretch" ] = SimplePDF::newName( metrics_
->weight_
.getPtr( ) );
1443 if( metrics_
->weightNumber_
> 0 )
1445 // It has already been asserted that this value is legal.
1446 (*fontDescriptor
)[ "FontWeight" ] = SimplePDF::newInt( metrics_
->weightNumber_
);
1448 (*fontDescriptor
)[ "Flags" ] = SimplePDF::newInt( (size_t)(1) << ( 6 - 1 ) ); // This is just the "Nonsymbolic" flag.
1449 (*fontDescriptor
)[ "FontBBox" ] = fontBBox
;
1450 if( ! IS_NAN( horizontalMetrics_typed_
->italicAngleRadians_
) )
1452 (*fontDescriptor
)[ "ItalicAngle" ] = SimplePDF::newFloat( ( 180 / M_PI
) * horizontalMetrics_typed_
->italicAngleRadians_
);
1456 throw Exceptions::OutOfRange( callLoc
, "Missing 'ItalicAngle." );
1458 if( ! IS_NAN( metrics_
->ascender_
) )
1460 (*fontDescriptor
)[ "Ascent" ] = SimplePDF::newFloat( metrics_
->ascender_
);
1462 if( ! IS_NAN( metrics_
->descender_
) )
1464 (*fontDescriptor
)[ "Descent" ] = SimplePDF::newFloat( metrics_
->descender_
);
1466 if( ! IS_NAN( metrics_
->leading_
) )
1468 (*fontDescriptor
)[ "Leading" ] = SimplePDF::newFloat( metrics_
->leading_
);
1470 if( ! IS_NAN( metrics_
->capHeight_
) )
1472 (*fontDescriptor
)[ "CapHeight" ] = SimplePDF::newFloat( metrics_
->capHeight_
);
1474 if( ! IS_NAN( metrics_
->xHeight_
) )
1476 (*fontDescriptor
)[ "XHeight" ] = SimplePDF::newFloat( metrics_
->xHeight_
);
1478 if( ! IS_NAN( metrics_
->stdHW_
) )
1480 (*fontDescriptor
)[ "StemH" ] = SimplePDF::newFloat( metrics_
->stdHW_
);
1482 if( ! IS_NAN( metrics_
->stdVW_
) )
1484 (*fontDescriptor
)[ "StemV" ] = SimplePDF::newFloat( metrics_
->stdVW_
);
1487 Concrete::Length
the1bp( 1 );
1489 RefCountPtr
< SimplePDF::PDF_Dictionary
> dic
;
1490 RefCountPtr
< SimplePDF::PDF_Object
> indirection
= SimplePDF::indirect( dic
, & Kernel::theIndirectObjectCount
);
1491 (*dic
)[ "Type" ] = SimplePDF::newName( "Font" );
1492 (*dic
)[ "Subtype" ] = SimplePDF::newName( "Type3" );
1493 (*dic
)[ "Encoding" ] = SimplePDF::newName( "MacRomanEncoding" );
1494 (*dic
)[ "FontBBox" ] = fontBBox
;
1495 (*dic
)[ "FontMatrix" ] = RefCountPtr
< SimplePDF::PDF_Vector
>( new SimplePDF::PDF_Vector( the1bp
* invSize
, 0, 0, the1bp
* invSize
, 0, 0 ) );
1496 (*dic
)[ "CharProcs" ] = charProcs
;
1497 (*dic
)[ "FirstChar" ] = SimplePDF::newInt( firstChar
);
1498 (*dic
)[ "LastChar" ] = SimplePDF::newInt( lastChar
);
1499 (*dic
)[ "Widths" ] = widths
;
1500 (*dic
)[ "FontDescriptor" ] = fontDescriptor
;
1501 (*dic
)[ "Resources" ] = SimplePDF::indirect( resources
, & Kernel::theIndirectObjectCount
);
1504 // static bool shown = false;
1507 // WARN_OR_THROW( Shapes::Exceptions::InternalError( "The ToUnicode CMap is not set up by Shapes.", true ) );
1511 // (*dic)[ "ToUnicode" ] = toUnicode;
1513 Kernel::ContRef cont
= evalState
->cont_
;
1514 cont
->takeValue( Kernel::ValueRef( new Lang::Type3Font( metrics_
->fontName_
,
1521 Kernel::WarmType3Font::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1523 throw Exceptions::MiscellaneousRequirement( strrefdup( "A type 3 font state cannot be peeked." ) );
1527 Kernel::WarmType3Font::gcMark( Kernel::GCMarkedSet
& marked
)
1530 typedef typeof kernings_ ListType
;
1531 for( ListType::const_iterator i
= kernings_
.begin( ); i
!= kernings_
.end( ); ++i
)
1533 const_cast< Lang::KernedText
* >( i
->getPtr( ) )->gcMark( marked
);
1537 typedef typeof glyphs_ ListType
;
1538 for( ListType::const_iterator i
= glyphs_
.begin( ); i
!= glyphs_
.end( ); ++i
)
1540 const_cast< Lang::Type3Glyph
* >( i
->getPtr( ) )->gcMark( marked
);
1547 Kernel::WarmType3Font::initializeLegalStrechValues( std::set
< const char *, charPtrLess
> * legalStretchValues
)
1549 legalStretchValues
->insert( "UltraCondensed" );
1550 legalStretchValues
->insert( "ExtraCondensed" );
1551 legalStretchValues
->insert( "Condensed" );
1552 legalStretchValues
->insert( "SemiCondensed" );
1553 legalStretchValues
->insert( "Normal" );
1554 legalStretchValues
->insert( "SemiExpanded" );
1555 legalStretchValues
->insert( "Expanded" );
1556 legalStretchValues
->insert( "ExtraExpanded" );
1557 legalStretchValues
->insert( "UltraExpanded" );
1561 Kernel::WarmRandomDevice::WarmRandomDevice( const char * deviceName
)
1562 : deviceName_( deviceName
)
1565 Kernel::WarmRandomDevice::~WarmRandomDevice( )
1568 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomDevice::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomDevice" ) ) );
1569 TYPEINFOIMPL_STATE( WarmRandomDevice
);
1572 Kernel::WarmRandomDevice::read( char * dst
, size_t sz
)
1574 if( ! idev_
.is_open( ) )
1576 idev_
.open( deviceName_
);
1577 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1579 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for input." ) ) );
1583 idev_
.read( dst
, sz
);
1587 Kernel::WarmRandomDevice::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
1589 if( ! odev_
.is_open( ) )
1591 odev_
.open( deviceName_
);
1592 if( ! odev_
.is_open( ) || ! odev_
.good( ) )
1594 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1598 piece
->show( odev_
);
1599 Kernel::ContRef cont
= evalState
->cont_
;
1600 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1605 Kernel::WarmRandomDevice::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1607 throw Exceptions::MiscellaneousRequirement( strrefdup( "The random device cannot be frozen." ) );
1611 Kernel::WarmRandomDevice::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1613 if( ! idev_
.is_open( ) )
1615 idev_
.open( deviceName_
);
1616 if( ! idev_
.is_open( ) || ! idev_
.good( ) )
1618 throw Exceptions::ExternalError( strrefdup( deviceName_
+ std::string( " could not be opened for output." ) ) );
1623 idev_
.read( reinterpret_cast< char * >( & tmp
), 1 );
1624 Kernel::ContRef cont
= evalState
->cont_
;
1625 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1630 Kernel::WarmRandomDevice::gcMark( Kernel::GCMarkedSet
& marked
)
1634 Kernel::WarmTime::WarmTime( )
1637 Kernel::WarmTime::~WarmTime( )
1640 RefCountPtr
< const Lang::Class
> Kernel::WarmTime::TypeID( new Lang::SystemFinalClass( strrefdup( "#Time" ) ) );
1641 TYPEINFOIMPL_STATE( WarmTime
);
1644 Kernel::WarmTime::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
1646 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time does not accept values." ) );
1650 Kernel::WarmTime::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1652 throw Exceptions::MiscellaneousRequirement( strrefdup( "The time cannot be frozen." ) );
1656 Kernel::WarmTime::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1658 time_t t
= time( 0 );
1659 Kernel::ContRef cont
= evalState
->cont_
;
1660 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ChronologicalTime( t
) ),
1665 Kernel::WarmTime::gcMark( Kernel::GCMarkedSet
& marked
)
1669 Kernel::WarmRandomState::WarmRandomState( char * state
)
1673 Kernel::WarmRandomState::~WarmRandomState( )
1675 delete state_
; // Let's hope this is not in use!
1678 RefCountPtr
< const Lang::Class
> Kernel::WarmRandomState::TypeID( new Lang::SystemFinalClass( strrefdup( "#RandomState" ) ) );
1679 TYPEINFOIMPL_STATE( WarmRandomState
);
1682 Kernel::WarmRandomState::setState( )
1688 Kernel::WarmRandomState::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
1690 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state does not accept values." ) );
1694 Kernel::WarmRandomState::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1696 throw Exceptions::MiscellaneousRequirement( strrefdup( "A random state cannot be frozen." ) );
1700 Kernel::WarmRandomState::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1703 long tmp
= random( );
1704 Kernel::ContRef cont
= evalState
->cont_
;
1705 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Integer( tmp
) ),
1710 Kernel::WarmRandomState::gcMark( Kernel::GCMarkedSet
& marked
)
1714 Kernel::WarmColorInterpolator::WarmColorInterpolator( )
1715 : hasKey_( false ), colorType_( Lang::ColorInterpolator::UNDEFINED
)
1718 Kernel::WarmColorInterpolator::~WarmColorInterpolator( )
1721 RefCountPtr
< const Lang::Class
> Kernel::WarmColorInterpolator::TypeID( new Lang::SystemFinalClass( strrefdup( "#ColorInterpolator" ) ) );
1722 TYPEINFOIMPL_STATE( WarmColorInterpolator
);
1725 Kernel::WarmColorInterpolator::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
1729 switch( colorType_
)
1731 case Lang::ColorInterpolator::UNDEFINED
:
1734 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1735 colorType_
= Lang::ColorInterpolator::RGB
;
1738 catch( const Exceptions::TypeMismatch
& )
1743 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1744 colorType_
= Lang::ColorInterpolator::GRAY
;
1747 catch( const Exceptions::TypeMismatch
& )
1752 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1753 colorType_
= Lang::ColorInterpolator::CMYK
;
1756 catch( const Exceptions::TypeMismatch
& )
1758 throw Exceptions::MiscellaneousRequirement( strrefdup( "Only colors can be passed to an interpolator." ) );
1760 case Lang::ColorInterpolator::RGB
:
1761 RGBcolor_
->push_back( Helpers::down_cast
< const Lang::RGB
>( piece
, callLoc
)->components( ) );
1764 case Lang::ColorInterpolator::GRAY
:
1765 graycolor_
->push_back( Helpers::down_cast
< const Lang::Gray
>( piece
, callLoc
)->components( ) );
1768 case Lang::ColorInterpolator::CMYK
:
1769 CMYKcolor_
->push_back( Helpers::down_cast
< const Lang::CMYK
>( piece
, callLoc
)->components( ) );
1775 typedef const Lang::Float ArgType
;
1776 double key
= Helpers::down_cast
< ArgType
>( piece
, callLoc
)->val_
;
1777 if( !key_
->empty( ) && key
< key_
->back( ) )
1779 throw Exceptions::MiscellaneousRequirement( strrefdup( "Keys must be added in nondecreasing order to an interpolator." ) );
1783 key_
->push_back( key
);
1787 hasKey_
= ! hasKey_
;
1789 Kernel::ContRef cont
= evalState
->cont_
;
1790 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
1795 Kernel::WarmColorInterpolator::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1797 if( key_
->empty( ) )
1799 throw Exceptions::MiscellaneousRequirement( strrefdup( "There are no colors that define the interpolation." ) );
1803 throw Exceptions::MiscellaneousRequirement( strrefdup( "Missing color for the last key." ) );
1806 Kernel::ContRef cont
= evalState
->cont_
;
1807 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::ColorInterpolator( key_
, RGBcolor_
, graycolor_
, CMYKcolor_
, colorType_
) ),
1812 Kernel::WarmColorInterpolator::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
1814 throw Exceptions::MiscellaneousRequirement( strrefdup( "An interpolator cannot be peeked." ) );
1818 Kernel::WarmColorInterpolator::gcMark( Kernel::GCMarkedSet
& marked
)
1827 class Mutator_vector_size
: public Lang::CoreMutator
1830 Mutator_vector_size( const char * name
)
1831 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1835 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1837 args
.applyDefaults( callLoc
);
1839 typedef Warm_vector StateType
;
1840 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1842 Kernel::ContRef cont
= evalState
->cont_
;
1843 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( state
->mem_
->size( ) ) ),
1848 class Mutator_vector_resize
: public Lang::CoreMutator
1851 Mutator_vector_resize( const char * name
)
1852 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1854 formals_
->appendEvaluatedCoreFormal( "size", Kernel::THE_SLOT_VARIABLE
);
1855 formals_
->appendEvaluatedCoreFormal( "fill", Kernel::THE_VOID_VARIABLE
);
1858 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1860 args
.applyDefaults( callLoc
);
1862 typedef Warm_vector StateType
;
1863 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1865 typedef const Lang::Integer IndexType
;
1866 IndexType::ValueType tmp
= Helpers::down_cast_MutatorArgument
< IndexType
>( state
, name_
, args
, 0, callLoc
)->val_
;
1869 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The size must be non-negative." );
1871 size_t newSize
= static_cast< size_t >( tmp
);
1873 if( newSize
< state
->mem_
->size( ) )
1875 while( newSize
< state
->mem_
->size( ) )
1877 state
->mem_
->pop_back( );
1882 state
->mem_
->reserve( newSize
);
1883 RefCountPtr
< const Lang::Value
> fill
= args
.getValue( 1 );
1884 while( newSize
> state
->mem_
->size( ) )
1886 state
->mem_
->push_back( fill
);
1890 Kernel::ContRef cont
= evalState
->cont_
;
1891 cont
->takeValue( Lang::THE_VOID
,
1896 class Mutator_vector_reserve
: public Lang::CoreMutator
1899 Mutator_vector_reserve( const char * name
)
1900 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1902 formals_
->appendEvaluatedCoreFormal( "size", Kernel::THE_SLOT_VARIABLE
);
1905 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1907 args
.applyDefaults( callLoc
);
1909 typedef Warm_vector StateType
;
1910 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1912 typedef const Lang::Integer IndexType
;
1913 IndexType::ValueType tmp
= Helpers::down_cast_MutatorArgument
< IndexType
>( state
, name_
, args
, 0, callLoc
)->val_
;
1916 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The size must be non-negative." );
1918 size_t newSize
= static_cast< size_t >( tmp
);
1920 state
->mem_
->reserve( newSize
);
1922 Kernel::ContRef cont
= evalState
->cont_
;
1923 cont
->takeValue( Lang::THE_VOID
,
1928 class Mutator_vector_set
: public Lang::CoreMutator
1931 Mutator_vector_set( const char * name
)
1932 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1934 formals_
->appendEvaluatedCoreFormal( "index", Kernel::THE_SLOT_VARIABLE
);
1935 formals_
->appendEvaluatedCoreFormal( "value", Kernel::THE_SLOT_VARIABLE
);
1938 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1940 args
.applyDefaults( callLoc
);
1942 typedef Warm_vector StateType
;
1943 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1945 typedef const Lang::Integer IndexType
;
1946 IndexType::ValueType tmp
= Helpers::down_cast_MutatorArgument
< IndexType
>( state
, name_
, args
, 0, callLoc
)->val_
;
1949 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The index must be non-negative." );
1951 size_t index
= static_cast< size_t >( tmp
);
1952 if( index
>= state
->mem_
->size( ) )
1954 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The index is out of range." );
1957 (*state
->mem_
)[ index
] = args
.getValue( 1 );
1959 Kernel::ContRef cont
= evalState
->cont_
;
1960 cont
->takeValue( Lang::THE_VOID
,
1965 class Mutator_vector_get
: public Lang::CoreMutator
1968 Mutator_vector_get( const char * name
)
1969 : CoreMutator( name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1971 formals_
->appendEvaluatedCoreFormal( "index", Kernel::THE_SLOT_VARIABLE
);
1974 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1976 args
.applyDefaults( callLoc
);
1978 typedef Warm_vector StateType
;
1979 StateType
* state
= Helpers::mutator_cast_self
< StateType
>( args
.getMutatorSelf( ) );
1981 typedef const Lang::Integer IndexType
;
1982 IndexType::ValueType tmp
= Helpers::down_cast_MutatorArgument
< IndexType
>( state
, name_
, args
, 0, callLoc
)->val_
;
1985 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The index must be non-negative." );
1987 size_t index
= static_cast< size_t >( tmp
);
1988 if( index
>= state
->mem_
->size( ) )
1990 throw Exceptions::CoreOutOfRange( new Interaction::MutatorLocation( state
, name_
), args
, 0, "The index is out of range." );
1993 Kernel::ContRef cont
= evalState
->cont_
;
1994 cont
->takeValue( (*state
->mem_
)[ index
],
2002 Kernel::Warm_vector::Warm_vector( )
2003 : mem_( new std::vector
< Kernel::ValueRef
> )
2006 Kernel::Warm_vector::~Warm_vector( )
2015 WarmVector_register_mutators( Lang::SystemFinalClass
* dstClass
)
2017 dstClass
->registerMutator( new Kernel::Mutator_vector_size( "size" ) );
2018 dstClass
->registerMutator( new Kernel::Mutator_vector_resize( "resize" ) );
2019 dstClass
->registerMutator( new Kernel::Mutator_vector_reserve( "reserve" ) );
2020 dstClass
->registerMutator( new Kernel::Mutator_vector_set( "set" ) );
2021 dstClass
->registerMutator( new Kernel::Mutator_vector_get( "get" ) );
2024 RefCountPtr
< const Lang::Class
> Kernel::Warm_vector::TypeID( new Lang::SystemFinalClass( strrefdup( "#Array" ), WarmVector_register_mutators
) );
2025 TYPEINFOIMPL_STATE( Warm_vector
);
2028 Kernel::Warm_vector::tackOnImpl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Value
> & piece
, const Ast::SourceLocation
& callLoc
)
2030 mem_
->push_back( piece
);
2031 Kernel::ContRef cont
= evalState
->cont_
;
2032 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
2037 Kernel::Warm_vector::freezeImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
2039 Kernel::ContRef cont
= evalState
->cont_
;
2040 cont
->takeValue( Kernel::ValueRef( new Lang::VectorFunction( mem_
) ),
2042 mem_
= 0; /* The VectorFunction owns the memory now. */
2046 Kernel::Warm_vector::peekImpl( Kernel::EvalState
* evalState
, const Ast::SourceLocation
& callLoc
)
2048 throw Exceptions::MiscellaneousRequirement( strrefdup( "An array state cannot be peeked. To inspect one entry at at time, use the <get> mutator." ) );
2052 Kernel::Warm_vector::gcMark( Kernel::GCMarkedSet
& marked
)
2057 Kernel::registerHot( Kernel::Environment
* env
)
2059 env
->initDefine( Lang::CANVAS_ID
, new Kernel::WarmGroup2D
);
2060 env
->initDefine( Lang::CATALOG_ID
, new Kernel::WarmCatalog
);
2061 env
->initDefine( Lang::THE_NAMESPACE_Shapes_IO
, "stdout", new Kernel::WarmOstream( std::cout
) );
2062 env
->initDefine( Lang::THE_NAMESPACE_Shapes_IO
, "stderr", new Kernel::WarmOstream( std::cerr
) );
2063 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Numeric_Random
, "randomdevice", new Kernel::WarmRandomDevice( "/dev/urandom" ) );
2064 env
->initDefine( Lang::THE_NAMESPACE_Shapes
, "time", new Kernel::WarmTime
);
2065 env
->initDefine( Lang::THE_NAMESPACE_Shapes
, "ignore", new Kernel::WarmIgnore
);
2067 env
->initDefine( Lang::THE_NAMESPACE_Shapes
, "newIgnore", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmIgnore
> ) );
2068 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Graphics
, "newGroup", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup2D
> ) );
2069 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "newGroup", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroup3D
> ) );
2070 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "newZBuf", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZBuf
> ) );
2071 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "newZSorter", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmZSorter
> ) );
2072 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Graphics3D
, "newLights", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmGroupLights
> ) );
2073 env
->initDefine( Lang::THE_NAMESPACE_Shapes_String
, "newString", Kernel::ValueRef( new Lang::HotDefault
< Kernel::Warm_ostringstream
> ) );
2074 env
->initDefine( Lang::THE_NAMESPACE_Shapes
, "newTimer", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmTimer
> ) );
2075 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Text
, "newText", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmText
> ) );
2076 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Text
, "newFont", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmType3Font
> ) );
2077 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Traits
, "newColorInterpolator", Kernel::ValueRef( new Lang::HotDefault
< Kernel::WarmColorInterpolator
> ) );
2078 env
->initDefine( Lang::THE_NAMESPACE_Shapes_Data
, "newArray", Kernel::ValueRef( new Lang::HotDefault
< Kernel::Warm_vector
> ) );