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 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
25 #include "shapesexceptions.h"
27 #include "simplepdfi.h"
28 #include "simplepdfo.h"
31 #include "multipage.h"
32 #include "charconverters.h"
33 #include "pagecontentstates.h"
34 #include "texlabelmanager.h"
35 #include "autoonoff.h"
36 #include "timetypes.h"
46 using namespace Shapes
;
54 class Core_tag
: public Lang::CoreFunction
57 Core_tag( const char * title
)
58 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
60 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
61 formals_
->appendEvaluatedCoreFormal( "obj", Kernel::THE_SLOT_VARIABLE
);
62 formals_
->appendEvaluatedCoreFormal( "transform", Kernel::THE_TRUE_VARIABLE
); // this argument means "transform if applicable"
63 formals_
->appendEvaluatedCoreFormal( "draw", Kernel::THE_TRUE_VARIABLE
); // this argument means "draw if applicable"
67 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
69 args
.applyDefaults( );
71 typedef const Lang::Symbol KeyType
;
72 RefCountPtr
< KeyType
> key
= Helpers::down_cast_CoreArgument
< KeyType
>( title_
, args
, 0, callLoc
);
73 bool tryTransform
= Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( title_
, args
, 2, callLoc
)->val_
;
74 bool tryDraw
= Helpers::down_cast_CoreArgument
< const Lang::Boolean
>( title_
, args
, 3, callLoc
)->val_
;
76 if( tryDraw
&& ! tryTransform
)
78 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "A tagged object which does not transform cannot be drawn." );
87 typedef const Lang::Drawable2D ArgType
;
89 RefCountPtr
< ArgType
> obj
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
91 Kernel::ContRef cont
= evalState
->cont_
;
92 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::TaggedDrawable2D( key
, obj
) ),
96 catch( const NonLocalExit::NotThisType
& ball
)
98 // Never mind, see below
103 typedef const Lang::Drawable3D ArgType
;
105 RefCountPtr
< ArgType
> obj
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
107 Kernel::ContRef cont
= evalState
->cont_
;
108 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::TaggedDrawable3D( key
, obj
) ),
112 catch( const NonLocalExit::NotThisType
& ball
)
114 // Never mind, see below
122 typedef const Lang::Geometric2D ArgType
;
124 RefCountPtr
< ArgType
> obj
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
126 Kernel::ContRef cont
= evalState
->cont_
;
127 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::TaggedGeometric2D( key
, obj
) ),
131 catch( const NonLocalExit::NotThisType
& ball
)
133 // Never mind, see below
138 typedef const Lang::Geometric3D ArgType
;
140 RefCountPtr
< ArgType
> obj
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( argsi
) );
142 Kernel::ContRef cont
= evalState
->cont_
;
143 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::TaggedGeometric3D( key
, obj
) ),
147 catch( const NonLocalExit::NotThisType
& ball
)
149 // Never mind, see below
154 // As a last resort, we tag any value.
155 // We return a Drawable2D. Use immerse to make it 3D.
156 Kernel::ContRef cont
= evalState
->cont_
;
157 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::TaggedValue2D( key
, args
.getValue( argsi
) ) ),
163 // This function is in this file just because it i so related to Core_tag.
164 class Core_find
: public Lang::CoreFunction
167 Core_find( const char * title
)
168 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
170 formals_
->appendEvaluatedCoreFormal( "container", Kernel::THE_SLOT_VARIABLE
);
171 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
175 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
177 args
.applyDefaults( );
179 typedef const Lang::Symbol KeyType
;
180 RefCountPtr
< KeyType
> key
= Helpers::down_cast_CoreArgument
< KeyType
>( title_
, args
, 1, callLoc
);
186 typedef const Lang::Drawable2D ContainerType
;
188 RefCountPtr
< ContainerType
> container
= Helpers::try_cast_CoreArgument
< ContainerType
>( args
.getValue( argsi
) );
190 if( ! container
->findOneTag( evalState
, key
->getKey( ), Lang::THE_2D_IDENTITY
) )
192 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "Key not found." );
196 catch( const NonLocalExit::NotThisType
& ball
)
198 // Never mind, see below
203 typedef const Lang::Drawable3D ContainerType
;
205 RefCountPtr
< ContainerType
> container
= Helpers::try_cast_CoreArgument
< ContainerType
>( args
.getValue( argsi
) );
207 if( ! container
->findOneTag( evalState
, key
->getKey( ), Lang::THE_3D_IDENTITY
) )
209 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "Key not found." );
213 catch( const NonLocalExit::NotThisType
& ball
)
215 // Never mind, see below
218 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, argsi
, Helpers::typeSetString( Lang::Drawable2D::staticTypeName( ), Lang::Drawable3D::staticTypeName( ) ) );
222 // This function is in this file just because it i so related to Core_tag.
223 class Core_findall
: public Lang::CoreFunction
226 Core_findall( const char * title
)
227 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
229 formals_
->appendEvaluatedCoreFormal( "container", Kernel::THE_SLOT_VARIABLE
);
230 formals_
->appendEvaluatedCoreFormal( "key", Kernel::THE_SLOT_VARIABLE
);
234 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
236 args
.applyDefaults( );
238 typedef const Lang::Symbol KeyType
;
239 RefCountPtr
< KeyType
> key
= Helpers::down_cast_CoreArgument
< KeyType
>( title_
, args
, 1, callLoc
);
245 typedef const Lang::Drawable2D ContainerType
;
247 RefCountPtr
< ContainerType
> container
= Helpers::try_cast_CoreArgument
< ContainerType
>( args
.getValue( argsi
) );
249 std::vector
< Kernel::ValueRef
> * dst
= new std::vector
< Kernel::ValueRef
>;
250 container
->findTags( dst
, evalState
->dyn_
, key
->getKey( ), Lang::THE_2D_IDENTITY
);
252 Kernel::ContRef cont
= evalState
->cont_
;
253 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::VectorFunction( dst
) ),
257 catch( const NonLocalExit::NotThisType
& ball
)
259 // Never mind, see below
264 typedef const Lang::Drawable3D ContainerType
;
266 RefCountPtr
< ContainerType
> container
= Helpers::try_cast_CoreArgument
< ContainerType
>( args
.getValue( argsi
) );
268 std::vector
< Kernel::ValueRef
> * dst
= new std::vector
< Kernel::ValueRef
>;
269 container
->findTags( dst
, evalState
->dyn_
, key
->getKey( ), Lang::THE_3D_IDENTITY
);
271 Kernel::ContRef cont
= evalState
->cont_
;
272 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::VectorFunction( dst
) ),
276 catch( const NonLocalExit::NotThisType
& ball
)
278 // Never mind, see below
281 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, argsi
, Helpers::typeSetString( Lang::Drawable2D::staticTypeName( ), Lang::Drawable3D::staticTypeName( ) ) );
285 class Core_phong
: public Lang::CoreFunction
288 Core_phong( const char * title
) : CoreFunction( title
) { }
290 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
292 const size_t ARITY
= 1;
293 CHECK_ARITY( args
, ARITY
, title_
);
295 typedef const Lang::Float ArgType
;
296 double exponent
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
)->val_
;
299 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The Phong exponent should be greater than 0." );
302 Kernel::ContRef cont
= evalState
->cont_
;
303 cont
->takeValue( Kernel::ValueRef( new Lang::SpecularReflectionTerm( 1., exponent
) ),
308 class Core_cons
: public Lang::CoreFunction
311 Core_cons( const char * title
)
312 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), false ) )
314 formals_
->appendEvaluatedCoreFormal( "car", Kernel::THE_SLOT_VARIABLE
);
315 formals_
->appendEvaluatedCoreFormal( "cdr", Kernel::THE_SLOT_VARIABLE
);
318 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
320 const size_t ARITY
= 2;
321 CHECK_ARITY( args
, ARITY
, title_
);
323 Kernel::ContRef cont
= evalState
->cont_
;
324 cont
->takeValue( Kernel::ValueRef( new Lang::ConsPair( args
.getHandle( 0 ),
325 args
.getHandle( 1 ) ) ),
330 class Core_list
: public Lang::CoreFunction
333 Core_list( const char * title
) : CoreFunction( title
) { }
335 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
337 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
338 if( ! args
.empty( ) )
340 for( size_t i
= args
.size( ) - 1; ; --i
)
342 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( args
.getHandle( i
), res
) );
350 Kernel::ContRef cont
= evalState
->cont_
;
351 cont
->takeValue( res
,
356 class Core_unlist
: public Lang::CoreFunction
358 Kernel::UnnamedStructureFactory argListFactory_
;
360 Core_unlist( const char * title
) : CoreFunction( title
) { }
362 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
364 const size_t ARITY
= 1;
365 CHECK_ARITY( args
, ARITY
, title_
);
367 typedef const Lang::SingleList ArgType
;
369 Kernel::ContRef cont
= evalState
->cont_
;
370 cont
->takeValue( argListFactory_
.build( Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
) ),
375 class Core_isnull
: public Lang::CoreFunction
378 Core_isnull( const char * title
) : CoreFunction( title
) { }
380 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
382 const size_t ARITY
= 1;
383 CHECK_ARITY( args
, ARITY
, title_
);
385 RefCountPtr
< const Lang::Value
> aUntyped
= args
.getValue( 0 );
387 Kernel::ContRef cont
= evalState
->cont_
;
388 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::Boolean( dynamic_cast< const Lang::SingleListNull
* >( args
.getValue( 0 ).getPtr( ) ) != 0 ) ),
393 class Core_range
: public Lang::CoreFunction
396 Core_range( const char * title
)
397 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
399 formals_
->appendEvaluatedCoreFormal( "begin", Kernel::THE_VOID_VARIABLE
);
400 formals_
->appendEvaluatedCoreFormal( "end", Kernel::THE_VOID_VARIABLE
);
401 formals_
->appendEvaluatedCoreFormal( "step", Kernel::THE_VOID_VARIABLE
);
402 formals_
->appendEvaluatedCoreFormal( "count", Kernel::THE_VOID_VARIABLE
);
405 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
407 typedef const Lang::Integer CountType
;
409 args
.applyDefaults( );
413 typedef const Lang::Integer ArgType
;
415 RefCountPtr
< ArgType
> beginPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ), true );
416 RefCountPtr
< ArgType
> endPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 1 ), true );
417 if( beginPtr
== NullPtr
< ArgType
>( ) && endPtr
== NullPtr
< ArgType
>( ) )
419 throw Exceptions::CoreRequirement( "At least one of the arguments <begin> and <end> must be provided.", title_
, callLoc
);
421 RefCountPtr
< ArgType
> stepPtr
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 2, callLoc
, true );
422 RefCountPtr
< CountType
> countPtr
= Helpers::down_cast_CoreArgument
< CountType
>( title_
, args
, 3, callLoc
, true );
424 if( beginPtr
!= NullPtr
< ArgType
>( ) && endPtr
!= NullPtr
< ArgType
>( ) &&
425 stepPtr
!= NullPtr
< ArgType
>( ) && countPtr
!= NullPtr
< CountType
>( ) )
427 throw Exceptions::CoreRequirement( "At least one of the arguments must be omitted.", title_
, callLoc
);
430 ArgType::ValueType begin
= 0;
431 ArgType::ValueType end
= -1;
432 ArgType::ValueType step
= 1;
433 if( beginPtr
== NullPtr
< ArgType
>( ) )
435 if( stepPtr
!= NullPtr
< ArgType
>( ) )
437 step
= stepPtr
->val_
;
439 if( countPtr
== NullPtr
< CountType
>( ) )
441 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of integers when <begin> is omitted.", title_
, callLoc
);
443 if( countPtr
->val_
< 2 )
445 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
448 begin
= end
- step
* ( countPtr
->val_
- 1 );
450 else if( endPtr
== NullPtr
< ArgType
>( ) )
452 if( stepPtr
!= NullPtr
< ArgType
>( ) )
454 step
= stepPtr
->val_
;
456 if( countPtr
== NullPtr
< CountType
>( ) )
458 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of integers when <end> is omitted.", title_
, callLoc
);
460 if( countPtr
->val_
< 2 )
462 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
464 begin
= beginPtr
->val_
;
465 end
= begin
+ step
* ( countPtr
->val_
- 1 );
469 if( countPtr
!= NullPtr
< CountType
>( ) )
471 throw Exceptions::CoreRequirement( "It is an error to provide the <count> arguments when constructing a range of integers from <begin> to <end>.", title_
, args
.getLoc( 3 ) );
474 begin
= beginPtr
->val_
;
476 if( stepPtr
!= NullPtr
< ArgType
>( ) )
478 step
= stepPtr
->val_
;
482 std::list
< ArgType::ValueType
> tmp
;
484 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
487 for( ArgType::ValueType x
= begin
; x
<= end
; x
+= step
)
494 for( ArgType::ValueType x
= begin
; x
>= end
; x
+= step
)
501 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "Step size must not be zero." );
504 while( ! tmp
.empty( ) )
506 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( Helpers::newValHandle( new Lang::Integer( tmp
.back( ) ) ),
511 Kernel::ContRef cont
= evalState
->cont_
;
512 cont
->takeValue( res
,
516 catch( const NonLocalExit::NotThisType
& ball
)
518 // Never mind, see below
523 typedef const Lang::Float ArgType
;
525 RefCountPtr
< ArgType
> beginPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ), true );
526 RefCountPtr
< ArgType
> endPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 1 ), true );
527 if( beginPtr
== NullPtr
< ArgType
>( ) && endPtr
== NullPtr
< ArgType
>( ) )
529 throw Exceptions::CoreRequirement( "At least one of the arguments <begin> and <end> must be provided.", title_
, callLoc
);
531 RefCountPtr
< ArgType
> stepPtr
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 2, callLoc
, true );
532 RefCountPtr
< CountType
> countPtr
= Helpers::down_cast_CoreArgument
< CountType
>( title_
, args
, 3, callLoc
, true );
534 if( beginPtr
!= NullPtr
< ArgType
>( ) && endPtr
!= NullPtr
< ArgType
>( ) &&
535 stepPtr
!= NullPtr
< ArgType
>( ) && countPtr
!= NullPtr
< CountType
>( ) )
537 throw Exceptions::CoreRequirement( "At least one of the arguments must be omitted.", title_
, callLoc
);
543 bool appendEnd
= false;
544 if( beginPtr
== NullPtr
< ArgType
>( ) )
546 if( stepPtr
== NullPtr
< ArgType
>( ) )
548 throw Exceptions::CoreRequirement( "The <step> must be provided when constructing a range of floats when <begin> is omitted.", title_
, callLoc
);
550 if( countPtr
== NullPtr
< CountType
>( ) )
552 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of floats when <begin> is omitted.", title_
, callLoc
);
554 if( countPtr
->val_
< 2 )
556 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
559 step
= stepPtr
->val_
;
560 begin
= end
- step
* ( countPtr
->val_
- 1 );
564 else if( endPtr
== NullPtr
< ArgType
>( ) )
566 if( stepPtr
== NullPtr
< ArgType
>( ) )
568 throw Exceptions::CoreRequirement( "The <step> must be provided when constructing a range of floats when <end> is omitted.", title_
, callLoc
);
570 if( countPtr
== NullPtr
< CountType
>( ) )
572 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of floats when <end> is omitted.", title_
, callLoc
);
574 if( countPtr
->val_
< 2 )
576 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
578 begin
= beginPtr
->val_
;
579 step
= stepPtr
->val_
;
580 end
= begin
+ step
* ( countPtr
->val_
- 0.5 );
584 // When we reach here, we know that at most one of <step> and <count> is provided.
585 if( stepPtr
!= NullPtr
< ArgType
>( ) )
587 begin
= beginPtr
->val_
;
589 step
= stepPtr
->val_
;
591 else if( countPtr
!= NullPtr
< CountType
>( ) )
593 if( countPtr
->val_
< 2 )
595 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The number of elements must be at least 2." );
597 begin
= beginPtr
->val_
;
599 step
= ( end
- begin
) / ( countPtr
->val_
- 1 );
605 begin
= beginPtr
->val_
;
610 std::list
< double > tmp
;
612 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
615 for( double x
= begin
; x
< end
; x
+= step
)
622 for( double x
= begin
; x
> end
; x
+= step
)
629 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "Step size must not be zero." );
633 tmp
.push_back( endPtr
->val_
);
636 while( ! tmp
.empty( ) )
638 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( Helpers::newValHandle( new Lang::Float( tmp
.back( ) ) ),
643 Kernel::ContRef cont
= evalState
->cont_
;
644 cont
->takeValue( res
,
648 catch( const NonLocalExit::NotThisType
& ball
)
650 // Never mind, see below
655 typedef const Lang::Length ArgType
;
657 RefCountPtr
< ArgType
> beginPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ), true );
658 RefCountPtr
< ArgType
> endPtr
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 1 ), true );
659 if( beginPtr
== NullPtr
< ArgType
>( ) && endPtr
== NullPtr
< ArgType
>( ) )
661 throw Exceptions::CoreRequirement( "At least one of the arguments <begin> and <end> must be provided.", title_
, callLoc
);
663 RefCountPtr
< ArgType
> stepPtr
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 2, callLoc
, true );
664 RefCountPtr
< CountType
> countPtr
= Helpers::down_cast_CoreArgument
< CountType
>( title_
, args
, 3, callLoc
, true );
666 if( beginPtr
!= NullPtr
< ArgType
>( ) && endPtr
!= NullPtr
< ArgType
>( ) &&
667 stepPtr
!= NullPtr
< ArgType
>( ) && countPtr
!= NullPtr
< CountType
>( ) )
669 throw Exceptions::CoreRequirement( "At least one of the arguments must be omitted.", title_
, callLoc
);
675 bool appendEnd
= false;
676 if( beginPtr
== NullPtr
< ArgType
>( ) )
678 if( stepPtr
== NullPtr
< ArgType
>( ) )
680 throw Exceptions::CoreRequirement( "The <step> must be provided when constructing a range of lengths when <begin> is omitted.", title_
, callLoc
);
682 if( countPtr
== NullPtr
< CountType
>( ) )
684 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of lengths when <begin> is omitted.", title_
, callLoc
);
686 if( countPtr
->val_
< 2 )
688 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
690 end
= endPtr
->getScalar( );
691 step
= stepPtr
->getScalar( );
692 begin
= end
- step
* ( countPtr
->val_
- 1 );
696 else if( endPtr
== NullPtr
< ArgType
>( ) )
698 if( stepPtr
== NullPtr
< ArgType
>( ) )
700 throw Exceptions::CoreRequirement( "The <step> must be provided when constructing a range of lengths when <end> is omitted.", title_
, callLoc
);
702 if( countPtr
== NullPtr
< CountType
>( ) )
704 throw Exceptions::CoreRequirement( "The <count> must be provided when constructing a range of lengths when <end> is omitted.", title_
, callLoc
);
706 if( countPtr
->val_
< 2 )
708 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The <count> must be at least 2." );
710 begin
= beginPtr
->getScalar( );
711 step
= stepPtr
->getScalar( );
712 end
= begin
+ step
* ( countPtr
->val_
- 0.5 );
716 if( stepPtr
== NullPtr
< ArgType
>( ) && countPtr
== NullPtr
< CountType
>( ) )
718 throw Exceptions::CoreRequirement( "Either of the <step> and <count> arguments must be provided when constructing a range of lengths from <begin> to <end>.", title_
, callLoc
);
720 // When we reach here, we know that exactly one of <step> and <count> is provided.
721 if( stepPtr
!= NullPtr
< ArgType
>( ) )
723 begin
= beginPtr
->getScalar( );
724 end
= endPtr
->getScalar( );
725 step
= stepPtr
->getScalar( );
729 begin
= beginPtr
->getScalar( );
730 end
= endPtr
->getScalar( );
731 // We know countPtr is not null here.
732 if( countPtr
->val_
< 2 )
734 throw Exceptions::CoreOutOfRange( title_
, args
, 3, "The number of elements must be at least 2." );
736 step
= ( end
- begin
) / ( countPtr
->val_
- 1 );
743 std::list
< double > tmp
;
745 RefCountPtr
< const Lang::SingleList
> res
= Lang::THE_CONS_NULL
;
748 for( double x
= begin
; x
< end
; x
+= step
)
755 for( double x
= begin
; x
> end
; x
+= step
)
762 throw Exceptions::CoreOutOfRange( title_
, args
, 2, "Step size must not be zero." );
766 tmp
.push_back( endPtr
->getScalar( ) );
769 while( ! tmp
.empty( ) )
771 res
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( Helpers::newValHandle( new Lang::Length( tmp
.back( ) ) ),
776 Kernel::ContRef cont
= evalState
->cont_
;
777 cont
->takeValue( res
,
781 catch( const NonLocalExit::NotThisType
& ball
)
783 // Never mind, see below
786 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Integer::staticTypeName( ), Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
790 class Core_affinetransform
: public Lang::CoreFunction
793 Core_affinetransform( const char * title
) : CoreFunction( title
) { }
795 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
797 const size_t ARITY
= 3;
798 CHECK_ARITY( args
, ARITY
, title_
);
800 typedef const Lang::FloatPair ArgType0
;
801 typedef const Lang::FloatPair ArgType1
;
802 typedef const Lang::Coords2D ArgType2
;
804 RefCountPtr
< ArgType0
> argx
= Helpers::down_cast_CoreArgument
< ArgType0
>( title_
, args
, 0, callLoc
);
805 RefCountPtr
< ArgType1
> argy
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, 1, callLoc
);
806 RefCountPtr
< ArgType2
> arg1
= Helpers::down_cast_CoreArgument
< ArgType2
>( title_
, args
, 2, callLoc
);
808 Kernel::ContRef cont
= evalState
->cont_
;
809 cont
->takeValue( Kernel::ValueRef( new Lang::Transform2D( argx
->x_
, argx
->y_
, argy
->x_
, argy
->y_
, arg1
->x_
.get( ), arg1
->y_
.get( ) ) ),
814 class Core_affinetransform3D
: public Lang::CoreFunction
817 Core_affinetransform3D( const char * title
) : CoreFunction( title
) { }
819 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
821 const size_t ARITY
= 4;
822 CHECK_ARITY( args
, ARITY
, title_
);
824 typedef const Lang::FloatTriple ArgType0
;
825 typedef const Lang::FloatTriple ArgType1
;
826 typedef const Lang::FloatTriple ArgType2
;
827 typedef const Lang::Coords3D ArgType3
;
829 RefCountPtr
< ArgType0
> argx
= Helpers::down_cast_CoreArgument
< ArgType0
>( title_
, args
, 0, callLoc
);
830 RefCountPtr
< ArgType1
> argy
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, 1, callLoc
);
831 RefCountPtr
< ArgType2
> argz
= Helpers::down_cast_CoreArgument
< ArgType2
>( title_
, args
, 2, callLoc
);
832 RefCountPtr
< ArgType3
> arg1
= Helpers::down_cast_CoreArgument
< ArgType3
>( title_
, args
, 3, callLoc
);
834 Kernel::ContRef cont
= evalState
->cont_
;
835 cont
->takeValue( Kernel::ValueRef( new Lang::Transform3D( argx
->x_
, argx
->y_
, argx
->z_
,
836 argy
->x_
, argy
->y_
, argy
->z_
,
837 argz
->x_
, argz
->y_
, argz
->z_
,
838 arg1
->x_
.get( ), arg1
->y_
.get( ), arg1
->z_
.get( ) ) ),
843 class Core_shift
: public Lang::CoreFunction
846 Core_shift( const char * title
) : CoreFunction( title
) { }
848 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
850 const size_t ARITY
= 1;
851 CHECK_ARITY( args
, ARITY
, title_
);
853 Kernel::ContRef cont
= evalState
->cont_
;
858 typedef const Lang::Coords2D ArgType1
;
859 RefCountPtr
< ArgType1
> arg1
= Helpers::try_cast_CoreArgument
< ArgType1
>( args
.getValue( i
) );
860 cont
->takeValue( Kernel::ValueRef( new Lang::Transform2D( 1, 0, 0, 1, arg1
->x_
.get( ), arg1
->y_
.get( ) ) ),
864 catch( const NonLocalExit::NotThisType
& ball
)
866 // Never mind, see below
871 typedef const Lang::Coords3D ArgType1
;
872 RefCountPtr
< ArgType1
> arg1
= Helpers::try_cast_CoreArgument
< ArgType1
>( args
.getValue( i
) );
873 cont
->takeValue( Kernel::ValueRef( new Lang::Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, arg1
->x_
.get( ), arg1
->y_
.get( ), arg1
->z_
.get( ) ) ),
877 catch( const NonLocalExit::NotThisType
& ball
)
879 // Never mind, see below
882 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, i
, Helpers::typeSetString( Lang::Coords2D::staticTypeName( ), Lang::Coords3D::staticTypeName( ) ) );
886 class Core_rotate
: public Lang::CoreFunction
889 Core_rotate( const char * title
)
890 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
892 formals_
->appendEvaluatedCoreFormal( "angle", Kernel::THE_SLOT_VARIABLE
);
895 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
897 args
.applyDefaults( );
901 typedef const Lang::Float ArgType1
;
902 RefCountPtr
< ArgType1
> arg1
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, i
, callLoc
);
904 double c
= cos( arg1
->val_
);
905 double s
= sin( arg1
->val_
);
906 Kernel::ContRef cont
= evalState
->cont_
;
907 cont
->takeValue( Kernel::ValueRef( new Lang::Transform2D( c
, s
, -s
, c
, 0, 0 ) ),
912 class Core_rotate3d
: public Lang::CoreFunction
915 Core_rotate3d( const char * title
)
916 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
918 formals_
->appendEvaluatedCoreFormal( "dir", Kernel::THE_SLOT_VARIABLE
);
919 formals_
->appendEvaluatedCoreFormal( "angle", Kernel::THE_SLOT_VARIABLE
);
922 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
924 args
.applyDefaults( );
928 typedef const Lang::FloatTriple ArgType1
;
929 RefCountPtr
< ArgType1
> dir
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, i
, callLoc
);
930 if( dir
->x_
== 0 && dir
->y_
== 0 && dir
->z_
== 0 )
932 throw Exceptions::CoreOutOfRange( title_
, args
, i
, "The rotation direction is degenerate, that is (0,0,0)." );
937 typedef const Lang::Float ArgType2
;
938 RefCountPtr
< ArgType2
> angle
= Helpers::down_cast_CoreArgument
< ArgType2
>( title_
, args
, i
, callLoc
);
940 double r
= sqrt( dir
->x_
* dir
->x_
+ dir
->y_
* dir
->y_
+ dir
->z_
* dir
->z_
);
941 double x
= dir
->x_
/ r
;
942 double y
= dir
->y_
/ r
;
943 double z
= dir
->z_
/ r
;
947 double c
= cos( angle
->val_
);
948 double s
= sin( angle
->val_
);
949 Kernel::ContRef cont
= evalState
->cont_
;
950 cont
->takeValue( Kernel::ValueRef( new Lang::Transform3D( x2
+(y2
+z2
)*c
, x
*y
*(1-c
)+z
*s
, x
*z
*(1-c
)-y
*s
,
951 x
*y
*(1-c
)-z
*s
, y2
+(x2
+z2
)*c
, y
*z
*(1-c
)+x
*s
,
952 x
*z
*(1-c
)+y
*s
, y
*z
*(1-c
)-x
*s
, z2
+(x2
+y2
)*c
,
958 class Core_scale
: public Lang::CoreFunction
961 Core_scale( const char * title
)
962 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
964 Kernel::VariableHandle
one( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Float( 1 ) ) ) );
966 formals_
->appendEvaluatedCoreFormal( "r", one
);
967 formals_
->appendEvaluatedCoreFormal( "x", one
);
968 formals_
->appendEvaluatedCoreFormal( "y", one
);
971 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
973 args
.applyDefaults( );
975 typedef const Lang::Float ArgType
;
976 RefCountPtr
< ArgType
> argr
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
977 RefCountPtr
< ArgType
> argx
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 1, callLoc
);
978 RefCountPtr
< ArgType
> argy
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 2, callLoc
);
980 Kernel::ContRef cont
= evalState
->cont_
;
981 cont
->takeValue( Kernel::ValueRef( new Lang::Transform2D( argr
->val_
* argx
->val_
, 0,
982 0, argr
->val_
* argy
->val_
,
988 class Core_scale3d
: public Lang::CoreFunction
991 Core_scale3d( const char * title
)
992 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
994 Kernel::VariableHandle
one( new Kernel::Variable( RefCountPtr
< const Lang::Value
>( new Lang::Float( 1 ) ) ) );
996 formals_
->appendEvaluatedCoreFormal( "r", one
);
997 formals_
->appendEvaluatedCoreFormal( "x", one
);
998 formals_
->appendEvaluatedCoreFormal( "y", one
);
999 formals_
->appendEvaluatedCoreFormal( "z", one
);
1002 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1004 args
.applyDefaults( );
1006 typedef const Lang::Float ArgType
;
1007 RefCountPtr
< ArgType
> argr
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
1008 RefCountPtr
< ArgType
> argx
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 1, callLoc
);
1009 RefCountPtr
< ArgType
> argy
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 2, callLoc
);
1010 RefCountPtr
< ArgType
> argz
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 3, callLoc
);
1012 Kernel::ContRef cont
= evalState
->cont_
;
1013 cont
->takeValue( Kernel::ValueRef( new Lang::Transform3D( argr
->val_
* argx
->val_
, 0, 0,
1014 0, argr
->val_
* argy
->val_
, 0,
1015 0, 0, argr
->val_
* argz
->val_
,
1021 class Core_inverse
: public Lang::CoreFunction
1024 Core_inverse( const char * title
) : CoreFunction( title
) { }
1026 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1028 const size_t ARITY
= 1;
1029 CHECK_ARITY( args
, ARITY
, title_
);
1032 typedef const Lang::Transform2D ArgType
;
1033 ArgType
* tf
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1036 double det
= tf
->xx_
* tf
->yy_
- tf
->xy_
* tf
->yx_
;
1037 if( fabs( det
) < Computation::SINGULAR_TRANSFORM_LIMIT
)
1039 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "Singular transforms cannot be inverted." );
1041 double idet
= 1 / det
;
1042 double ixx
= idet
* tf
->yy_
;
1043 double ixy
= - idet
* tf
->xy_
;
1044 double iyx
= - idet
* tf
->yx_
;
1045 double iyy
= idet
* tf
->xx_
;
1046 Kernel::ContRef cont
= evalState
->cont_
;
1047 cont
->takeValue( Kernel::ValueRef( new Lang::Transform2D( ixx
, iyx
,
1049 -( ixx
* tf
->xt_
+ ixy
* tf
->yt_
), -( iyx
* tf
->xt_
+ iyy
* tf
->yt_
) ) ),
1056 typedef const Lang::Transform3D ArgType
;
1057 ArgType
* tf
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1061 tf
->xx_
* ( tf
->yy_
* tf
->zz_
- tf
->yz_
* tf
->zy_
)
1062 - tf
->xy_
* ( tf
->yx_
* tf
->zz_
- tf
->yz_
* tf
->zx_
)
1063 + tf
->xz_
* ( tf
->yx_
* tf
->zy_
- tf
->yy_
* tf
->zx_
);
1064 if( fabs( det
) < Computation::SINGULAR_TRANSFORM_LIMIT
)
1066 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "Singular transforms cannot be inverted." );
1068 double idet
= 1 / det
;
1069 double ixx
= idet
* ( tf
->yy_
* tf
->zz_
- tf
->yz_
* tf
->zy_
);
1070 double ixy
= - idet
* ( tf
->xy_
* tf
->zz_
- tf
->xz_
* tf
->zy_
);
1071 double ixz
= idet
* ( tf
->xy_
* tf
->yz_
- tf
->xz_
* tf
->yy_
);
1072 double iyx
= - idet
* ( tf
->yx_
* tf
->zz_
- tf
->yz_
* tf
->zx_
);
1073 double iyy
= idet
* ( tf
->xx_
* tf
->zz_
- tf
->xz_
* tf
->zx_
);
1074 double iyz
= - idet
* ( tf
->xx_
* tf
->yz_
- tf
->xz_
* tf
->yx_
);
1075 double izx
= idet
* ( tf
->yx_
* tf
->zy_
- tf
->yy_
* tf
->zx_
);
1076 double izy
= - idet
* ( tf
->xx_
* tf
->zy_
- tf
->xy_
* tf
->zx_
);
1077 double izz
= idet
* ( tf
->xx_
* tf
->yy_
- tf
->xy_
* tf
->yx_
);
1078 Kernel::ContRef cont
= evalState
->cont_
;
1079 cont
->takeValue( Kernel::ValueRef( new Lang::Transform3D( ixx
, iyx
, izx
,
1082 -( ixx
* tf
->xt_
+ ixy
* tf
->yt_
+ ixz
* tf
->zt_
),
1083 -( iyx
* tf
->xt_
+ iyy
* tf
->yt_
+ iyz
* tf
->zt_
),
1084 -( izx
* tf
->xt_
+ izy
* tf
->yt_
+ izz
* tf
->zt_
) ) ),
1090 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Transform2D::staticTypeName( ), Lang::Transform3D::staticTypeName( ) ) );
1094 class Core_formxo
: public Lang::CoreFunction
1097 Core_formxo( const char * title
) : CoreFunction( title
) { }
1099 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1101 const size_t ARITY
= 1;
1102 CHECK_ARITY( args
, ARITY
, title_
);
1104 typedef const Lang::Drawable2D ArgType
;
1105 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
1107 RefCountPtr
< const Lang::ElementaryPath2D
> theBBox
= arg
->bbox( Lang::Drawable2D::BOUNDING
);
1108 Concrete::Coords2D
llcorner( 0, 0 );
1109 Concrete::Coords2D
urcorner( 0, 0 );
1110 if( ! theBBox
->boundingRectangle( & llcorner
, & urcorner
) )
1112 std::string
strTitle( title_
);
1113 throw Exceptions::InternalError( strrefdup( strTitle
+ ": The object has no bounding box!" ) );
1117 RefCountPtr
< SimplePDF::PDF_Stream_out
> form
;
1118 RefCountPtr
< SimplePDF::PDF_Object
> indirection
= SimplePDF::indirect( form
, & Kernel::theIndirectObjectCount
);
1120 RefCountPtr
< SimplePDF::PDF_Resources
> resources
;
1121 (*form
)[ "Resources" ] = SimplePDF::indirect( resources
, & Kernel::theIndirectObjectCount
);
1123 (*form
)[ "Subtype" ] = SimplePDF::newName( "Form" );
1124 (*form
)[ "FormType" ] = SimplePDF::newInt( 1 );
1125 (*form
)[ "BBox" ] = RefCountPtr
< SimplePDF::PDF_Vector
>( new SimplePDF::PDF_Vector( llcorner
.x_
.offtype
< 1, 0 >( ), llcorner
.y_
.offtype
< 1, 0 >( ),
1126 urcorner
.x_
.offtype
< 1, 0 >( ), urcorner
.y_
.offtype
< 1, 0 >( ) ) );
1128 /* There's a possibility of adding a transformation matrix entry in the dictionary here, but it is not used, not even
1129 * for transformed drawables.
1131 // (*markForm)[ "Matrix" ] = RefCountPtr<PDF_Object>( new PDF_Vector( 1, 0, 0, 1, -30, -30 ) );
1133 Kernel::PageContentStates
pdfState( resources
);
1134 arg
->shipout( form
->data
, & pdfState
, Lang::Transform2D( 1, 0, 0, 1, 0, 0 ) );
1137 Lang::XObject
* res
= new Lang::XObject( indirection
,
1139 res
->setDebugStr( "user form" );
1140 Kernel::ContRef cont
= evalState
->cont_
;
1141 cont
->takeValue( Kernel::ValueRef( res
),
1146 class Core_transparencygroup
: public Lang::CoreFunction
1149 Core_transparencygroup( const char * title
)
1150 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1152 formals_
->appendEvaluatedCoreFormal( "content", Kernel::THE_SLOT_VARIABLE
);
1153 formals_
->appendEvaluatedCoreFormal( "isolated", Kernel::THE_FALSE_VARIABLE
);
1154 formals_
->appendEvaluatedCoreFormal( "knockout", Kernel::THE_FALSE_VARIABLE
);
1157 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1159 args
.applyDefaults( );
1161 typedef const Lang::Group2D ArgType0
;
1162 typedef const Lang::Boolean ArgType1
;
1163 typedef const Lang::Boolean ArgType2
;
1164 RefCountPtr
< ArgType0
> content
= Helpers::down_cast_CoreArgument
< ArgType0
>( title_
, args
, 0, callLoc
);
1165 RefCountPtr
< ArgType1
> isolated
= Helpers::down_cast_CoreArgument
< ArgType1
>( title_
, args
, 1, callLoc
);
1166 RefCountPtr
< ArgType2
> knockout
= Helpers::down_cast_CoreArgument
< ArgType2
>( title_
, args
, 2, callLoc
);
1168 RefCountPtr
< const Lang::ColorSpace
> blendSpace
= evalState
->dyn_
->getBlendSpace( );
1170 Kernel::ContRef cont
= evalState
->cont_
;
1171 cont
->takeValue( Helpers::newTransparencyGroup( content
, isolated
->val_
, knockout
->val_
, blendSpace
),
1176 class Core_vector
: public Lang::CoreFunction
1179 Core_vector( const char * title
) : CoreFunction( title
) { }
1181 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1183 std::vector
< RefCountPtr
< const Lang::Value
> > * res
= new std::vector
< RefCountPtr
< const Lang::Value
> >;
1184 res
->reserve( args
.size( ) );
1186 for( size_t i
= 0; i
!= args
.size( ); ++i
)
1188 res
->push_back( args
.getValue( i
) );
1191 Kernel::ContRef cont
= evalState
->cont_
;
1192 cont
->takeValue( Kernel::ValueRef( new Lang::VectorFunction( res
) ),
1197 class Core_interpolate
: public Lang::CoreFunction
1200 Core_interpolate( const char * title
)
1201 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1203 formals_
->appendEvaluatedCoreFormal( "function", Kernel::THE_SLOT_VARIABLE
);
1204 formals_
->appendEvaluatedCoreFormal( "domain", Kernel::THE_SLOT_VARIABLE
);
1205 formals_
->appendEvaluatedCoreFormal( "size", Kernel::THE_SLOT_VARIABLE
);
1206 formals_
->appendEvaluatedCoreFormal( "range", Kernel::THE_SLOT_VARIABLE
);
1207 formals_
->appendEvaluatedCoreFormal( "encode", Kernel::THE_VOID_VARIABLE
);
1208 formals_
->appendEvaluatedCoreFormal( "decode", Kernel::THE_VOID_VARIABLE
);
1211 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1213 args
.applyDefaults( );
1215 throw Exceptions::NotImplemented( "Core_interpolate::call" );
1219 class Core_importPDFpages
: public Lang::CoreFunction
1222 Core_importPDFpages( const char * title
) : CoreFunction( title
) { }
1224 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1226 const size_t ARITY
= 1;
1227 CHECK_ARITY( args
, ARITY
, title_
);
1229 typedef const Lang::String ArgType
;
1230 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( title_
, args
, 0, callLoc
);
1232 RefCountPtr
< std::ifstream
> iFile( new std::ifstream( arg
->val_
.getPtr( ) ) );
1233 if( ! iFile
->good( ) )
1235 std::ostringstream msg
;
1236 msg
<< "Failed to open file for input: " << arg
->val_
.getPtr( ) ;
1237 throw Exceptions::CoreOutOfRange( title_
, args
, 0, strrefdup( msg
) );
1239 RefCountPtr
< SimplePDF::PDF_in
> pdfi( new SimplePDF::PDF_in( iFile
) );
1241 RefCountPtr
< const std::vector
< RefCountPtr
< const Lang::XObject
> > > typedRes
= RefCountPtr
< const std::vector
< RefCountPtr
< const Lang::XObject
> > >( NullPtr
< std::vector
< RefCountPtr
< const Lang::XObject
> > >( ) );
1244 typedRes
= Kernel::thePDFImporter
.addPagesAsXObjects( pdfi
);
1246 catch( const char * ball
)
1248 throw Exceptions::InternalError( strrefdup( ( std::string( "An error occurred while importing " ) + arg
->val_
.getPtr( ) + ": " + ball
).c_str( ) ) );
1251 std::vector
< RefCountPtr
< const Lang::Value
> > * untypedRes
= new std::vector
< RefCountPtr
< const Lang::Value
> >;
1252 untypedRes
->reserve( typedRes
->size( ) );
1253 typedef typeof *typedRes ListType
;
1254 for( ListType::const_iterator i
= typedRes
->begin( ); i
!= typedRes
->end( ); ++i
)
1256 untypedRes
->push_back( *i
);
1259 Kernel::ContRef cont
= evalState
->cont_
;
1260 cont
->takeValue( Kernel::ValueRef( new Lang::VectorFunction( untypedRes
) ),
1265 namespace Implementation
1268 svg_path_strtod( const char ** src
)
1270 const char * start
= *src
;
1272 double res
= strtod( start
, & endp
);
1276 for( ; *start
== ' '; ++start
)
1278 throw std::string( start
, strchr( start
, ' ' ) - start
);
1283 class Core_svg_path
: public Lang::CoreFunction
1286 Core_svg_path( const char * title
)
1287 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1289 formals_
->appendEvaluatedCoreFormal( "d", Kernel::THE_SLOT_VARIABLE
);
1290 formals_
->appendEvaluatedCoreFormal( "xunit", Helpers::newValHandle( new Lang::Length( Concrete::Length( 1 ) ) ) );
1291 formals_
->appendEvaluatedCoreFormal( "yunit", Helpers::newValHandle( new Lang::Length( Concrete::Length( 1 ) ) ) );
1292 formals_
->appendEvaluatedCoreFormal( "multi", Kernel::THE_VOID_VARIABLE
);
1293 formals_
->appendEvaluatedCoreFormal( "singletons", Kernel::THE_TRUE_VARIABLE
);
1296 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1298 args
.applyDefaults( );
1301 typedef const Lang::String StrType
;
1302 RefCountPtr
< StrType
> arg
= Helpers::down_cast_CoreArgument
< StrType
>( title_
, args
, argsi
, callLoc
);
1304 typedef const Lang::Length ScaleType
;
1306 Concrete::Length dx
= Helpers::down_cast_CoreArgument
< ScaleType
>( title_
, args
, argsi
, callLoc
)->get( );
1308 Concrete::Length dy
= Helpers::down_cast_CoreArgument
< ScaleType
>( title_
, args
, argsi
, callLoc
)->get( );
1310 typedef const Lang::Boolean FlagType
;
1312 RefCountPtr
< FlagType
> multi
= Helpers::down_cast_CoreArgument
< FlagType
>( title_
, args
, argsi
, callLoc
, true );
1314 bool singletons
= Helpers::down_cast_CoreArgument
< FlagType
>( title_
, args
, argsi
, callLoc
)->val_
;
1316 RefCountPtr
< char > buf
= RefCountPtr
< char >( new char[ 2 * strlen( arg
->val_
.getPtr( ) + 1 ) ] );
1318 /* Get rid of any whitespace that isn't a plain space, and make sure every number is terminated by whitespace.
1320 char * dst
= buf
.getPtr( );
1321 for( const char * src
= arg
->val_
.getPtr( ); *src
!= '\0'; ++src
, ++dst
)
1331 if( ( 'A' <= *src
&& *src
<= 'Z' ) || ( 'a' <= *src
&& *src
<= 'z' ) )
1333 /* Insert whitespace before command to ensure command is not immediately following number.
1345 RefCountPtr
< Lang::MultiPath2D
> multiPath
= RefCountPtr
< Lang::MultiPath2D
>( new Lang::MultiPath2D
);
1346 RefCountPtr
< Lang::ElementaryPath2D
> elemPath
= RefCountPtr
< Lang::ElementaryPath2D
>( NullPtr
< Lang::ElementaryPath2D
>( ) );
1351 Concrete::PathPoint2D
originPathPoint( new Concrete::Coords2D( 0, 0 ) );
1352 Concrete::PathPoint2D
* first
= & originPathPoint
;
1353 Concrete::PathPoint2D
* last
= & originPathPoint
;
1354 const char * srcEnd
= buf
.getPtr( ) + strlen( buf
.getPtr( ) );
1355 for( const char * src
= buf
.getPtr( ); src
< srcEnd
; ++src
)
1357 for( ; *src
== ' '; ++src
)
1391 throw Exceptions::CoreOutOfRange( title_
, args
, 0, strrefdup( std::string( "SVG path command not compatible with cubic splines: " ) + *src
) );
1398 if( elemPath
!= NullPtr
< Lang::ElementaryPath2D
>( ) && ( singletons
|| elemPath
->duration( ) >= 1 ) )
1400 multiPath
->push_back( elemPath
);
1402 Concrete::Length x
= dx
* Implementation::svg_path_strtod( & src
);
1403 Concrete::Length y
= - dy
* Implementation::svg_path_strtod( & src
);
1404 first
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, y
) );
1406 elemPath
= RefCountPtr
< Lang::ElementaryPath2D
>( new Lang::ElementaryPath2D
);
1407 elemPath
->push_back( last
);
1413 if( elemPath
!= NullPtr
< Lang::ElementaryPath2D
>( ) && ( singletons
|| elemPath
->duration( ) >= 1 ) )
1415 multiPath
->push_back( elemPath
);
1417 Concrete::Length x
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1418 Concrete::Length y
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1419 first
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, y
) );
1421 elemPath
= RefCountPtr
< Lang::ElementaryPath2D
>( new Lang::ElementaryPath2D
);
1422 elemPath
->push_back( last
);
1440 Concrete::Length x
= dx
* Implementation::svg_path_strtod( & src
);
1441 Concrete::Length y
= - dy
* Implementation::svg_path_strtod( & src
);
1442 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, y
) );
1443 elemPath
->push_back( last
);
1448 Concrete::Length x
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1449 Concrete::Length y
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1450 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, y
) );
1451 elemPath
->push_back( last
);
1456 Concrete::Length x
= dx
* Implementation::svg_path_strtod( & src
);
1457 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, last
->mid_
->y_
) );
1458 elemPath
->push_back( last
);
1463 Concrete::Length x
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1464 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x
, last
->mid_
->y_
) );
1465 elemPath
->push_back( last
);
1470 Concrete::Length y
= - dy
* Implementation::svg_path_strtod( & src
);
1471 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( last
->mid_
->x_
, y
) );
1472 elemPath
->push_back( last
);
1477 Concrete::Length y
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1478 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( last
->mid_
->x_
, y
) );
1479 elemPath
->push_back( last
);
1484 Concrete::Length x1
= dx
* Implementation::svg_path_strtod( & src
);
1485 Concrete::Length y1
= - dy
* Implementation::svg_path_strtod( & src
);
1486 Concrete::Length x2
= dx
* Implementation::svg_path_strtod( & src
);
1487 Concrete::Length y2
= - dy
* Implementation::svg_path_strtod( & src
);
1488 Concrete::Length x3
= dx
* Implementation::svg_path_strtod( & src
);
1489 Concrete::Length y3
= - dy
* Implementation::svg_path_strtod( & src
);
1490 last
->front_
= new Concrete::Coords2D( x1
, y1
);
1491 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x3
, y3
) );
1492 last
->rear_
= new Concrete::Coords2D( x2
, y2
);
1493 elemPath
->push_back( last
);
1498 Concrete::Length x1
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1499 Concrete::Length y1
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1500 Concrete::Length x2
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1501 Concrete::Length y2
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1502 Concrete::Length x3
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1503 Concrete::Length y3
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1504 last
->front_
= new Concrete::Coords2D( x1
, y1
);
1505 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x3
, y3
) );
1506 last
->rear_
= new Concrete::Coords2D( x2
, y2
);
1507 elemPath
->push_back( last
);
1512 Concrete::Length x2
= dx
* Implementation::svg_path_strtod( & src
);
1513 Concrete::Length y2
= - dy
* Implementation::svg_path_strtod( & src
);
1514 Concrete::Length x3
= dx
* Implementation::svg_path_strtod( & src
);
1515 Concrete::Length y3
= - dy
* Implementation::svg_path_strtod( & src
);
1516 last
->front_
= new Concrete::Coords2D( 2 * *(last
->mid_
) - *(last
->rear_
) );
1517 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x3
, y3
) );
1518 last
->rear_
= new Concrete::Coords2D( x2
, y2
);
1519 elemPath
->push_back( last
);
1524 Concrete::Length x2
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1525 Concrete::Length y2
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1526 Concrete::Length x3
= last
->mid_
->x_
+ dx
* Implementation::svg_path_strtod( & src
);
1527 Concrete::Length y3
= last
->mid_
->y_
- dy
* Implementation::svg_path_strtod( & src
);
1528 last
->front_
= new Concrete::Coords2D( 2 * *(last
->mid_
) - *(last
->rear_
) );
1529 last
= new Concrete::PathPoint2D( new Concrete::Coords2D( x3
, y3
) );
1530 last
->rear_
= new Concrete::Coords2D( x2
, y2
);
1531 elemPath
->push_back( last
);
1535 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "Malformed SVG path string (failed to initialize command character)." );
1538 throw Exceptions::InternalError( "While reading SVG path string: Command character out of range." );
1543 catch( const std::string
& badNumber
)
1545 throw Exceptions::CoreOutOfRange( title_
, args
, 0, strrefdup( std::string( "Ill-formed number: " ) + badNumber
) );
1548 if( elemPath
!= NullPtr
< Lang::ElementaryPath2D
>( ) && ( singletons
|| elemPath
->duration( ) >= 1 ) )
1550 multiPath
->push_back( RefCountPtr
< const Lang::Path2D
>( elemPath
) );
1553 if( multiPath
->size( ) == 0 )
1555 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "No path was produced." );
1557 if( multiPath
->size( ) == 1 )
1559 Kernel::ContRef cont
= evalState
->cont_
;
1560 if( multi
!= NullPtr
< FlagType
>( ) && multi
->val_
)
1562 cont
->takeValue( Kernel::ValueRef( multiPath
),
1567 cont
->takeValue( Kernel::ValueRef( multiPath
->front( ) ),
1573 if( multi
!= NullPtr
< FlagType
>( ) && ! multi
->val_
)
1575 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "More than one sub-path conflicts with false for <multi>." );
1577 Kernel::ContRef cont
= evalState
->cont_
;
1578 cont
->takeValue( Kernel::ValueRef( multiPath
),
1584 class Core_sprintf
: public Lang::CoreFunction
1587 Core_sprintf( const char * title
) : CoreFunction( title
) { }
1589 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1593 throw Exceptions::CoreArityMismatch( title_
, 1, args
.size( ) );
1595 typedef typeof args ArgListType
;
1597 typedef const Lang::String Arg1Type
;
1598 RefCountPtr
< Arg1Type
> arg1
= Helpers::down_cast_CoreArgument
< Arg1Type
>( title_
, args
, i
, callLoc
);
1600 /* snprintf( 0, 0, ... ) does not seem to work properly on some systems.
1601 * Therefore, I resort to the use of a dummy string, and "n = 1".
1606 switch( args
.size( ) )
1610 size_t sz
= snprintf( dummy
, 1, arg1
->val_
.getPtr( ), 0 ); /* The final 0 is just a dummy argument that makes the compiler relax. */
1611 res
= new char[ sz
+ 1 ];
1612 status
= sprintf( res
, arg1
->val_
.getPtr( ), 0 ); /* The final 0 is just a dummy argument that makes the compiler relax. */
1619 typedef const Lang::String Arg2Type
;
1620 Arg2Type
* arg2
= dynamic_cast< Arg2Type
* >( args
.getValue( i
).getPtr( ) );
1623 size_t sz
= snprintf( dummy
, 1, arg1
->val_
.getPtr( ), arg2
->val_
.getPtr( ) );
1624 res
= new char[ sz
+ 1 ];
1625 status
= sprintf( res
, arg1
->val_
.getPtr( ), arg2
->val_
.getPtr( ) );
1630 typedef const Lang::Float Arg2Type
;
1631 Arg2Type
* arg2
= dynamic_cast< Arg2Type
* >( args
.getValue( i
).getPtr( ) );
1634 size_t sz
= snprintf( dummy
, 1, arg1
->val_
.getPtr( ), arg2
->val_
);
1635 res
= new char[ sz
+ 1 ];
1636 status
= sprintf( res
, arg1
->val_
.getPtr( ), arg2
->val_
);
1641 typedef const Lang::Integer Arg2Type
;
1642 Arg2Type
* arg2
= dynamic_cast< Arg2Type
* >( args
.getValue( i
).getPtr( ) );
1645 size_t sz
= snprintf( dummy
, 1, arg1
->val_
.getPtr( ), arg2
->val_
);
1646 res
= new char[ sz
+ 1 ];
1647 status
= sprintf( res
, arg1
->val_
.getPtr( ), arg2
->val_
);
1652 typedef const Lang::ChronologicalTime Arg2Type
;
1653 Arg2Type
* arg2
= dynamic_cast< Arg2Type
* >( args
.getValue( i
).getPtr( ) );
1656 const char * fmt
= arg1
->val_
.getPtr( );
1657 const struct tm
* tmp
= arg2
->temporary_localtime( );
1658 size_t sz
= strlen( fmt
) * 2;
1659 res
= new char[ sz
];
1660 while( strftime( res
, sz
, fmt
, tmp
) == 0 )
1664 res
= new char[ sz
];
1666 status
= 0; // Here, I'd like to check some error condition instead...
1670 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, i
, Interaction::SEVERAL_TYPES
);
1674 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The number of arguments is out of the implemented range." );
1679 throw Exceptions::InternalError( "Failed to assign to res in sprintf." );
1684 std::ostringstream oss
;
1685 oss
<< "Call to library routine returned negative value indicating an error: " << status
<< ".";
1686 throw Exceptions::CoreOutOfRange( title_
, args
, 0, strrefdup( oss
) );
1689 Kernel::ContRef cont
= evalState
->cont_
;
1690 cont
->takeValue( Kernel::ValueRef( new Lang::String( res
, false ) ),
1695 class Core_strftime
: public Lang::CoreFunction
1698 Core_strftime( const char * title
) : CoreFunction( title
) { }
1700 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1702 const size_t ARITY
= 0;
1703 CHECK_ARITY( args
, ARITY
, title_
);
1708 timeInfo
= localtime( & t
);
1709 std::ostringstream res
;
1710 res
<< timeInfo
->tm_hour
<< ":" << timeInfo
->tm_min
<< ":" << timeInfo
->tm_sec
;
1712 Kernel::ContRef cont
= evalState
->cont_
;
1713 cont
->takeValue( Kernel::ValueRef( new Lang::String( strrefdup( res
) ) ),
1718 class Core_ambient_light
: public Lang::CoreFunction
1721 Core_ambient_light( const char * title
)
1722 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1724 formals_
->appendEvaluatedCoreFormal( "color", Kernel::THE_SLOT_VARIABLE
);
1727 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1729 args
.applyDefaults( );
1732 typedef const Lang::Gray ArgType
;
1733 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1736 Kernel::ContRef cont
= evalState
->cont_
;
1737 cont
->takeValue( Kernel::ValueRef( new Lang::AmbientLightGray( col
->components( ) ) ),
1744 typedef const Lang::RGB ArgType
;
1745 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1748 Kernel::ContRef cont
= evalState
->cont_
;
1749 cont
->takeValue( Kernel::ValueRef( new Lang::AmbientLightRGB( col
->components( ) ) ),
1755 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
1759 class Core_specular_light
: public Lang::CoreFunction
1762 Core_specular_light( const char * title
)
1763 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1765 formals_
->appendEvaluatedCoreFormal( "color", Kernel::THE_SLOT_VARIABLE
);
1766 formals_
->appendEvaluatedCoreFormal( "radius", Helpers::newValHandle( new Lang::Length( HUGE_VAL
) ) );
1767 formals_
->appendEvaluatedCoreFormal( "shadows", Kernel::THE_FALSE_VARIABLE
);
1770 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1772 args
.applyDefaults( );
1774 typedef const Lang::Length RadiusType
;
1775 RefCountPtr
< RadiusType
> radius
= Helpers::down_cast_CoreArgument
< RadiusType
>( title_
, args
, 1, callLoc
);
1776 typedef const Lang::Boolean ShadowsType
;
1777 RefCountPtr
< ShadowsType
> shadows
= Helpers::down_cast_CoreArgument
< ShadowsType
>( title_
, args
, 2, callLoc
);
1780 typedef const Lang::Gray ArgType
;
1781 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1784 Kernel::ContRef cont
= evalState
->cont_
;
1785 cont
->takeValue( Kernel::ValueRef( new Lang::SpecularLightGray( Concrete::Coords3D( 0, 0, 0 ),
1795 typedef const Lang::RGB ArgType
;
1796 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1799 Kernel::ContRef cont
= evalState
->cont_
;
1800 cont
->takeValue( Kernel::ValueRef( new Lang::SpecularLightRGB( Concrete::Coords3D( 0, 0, 0 ),
1809 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
1813 class Core_distant_light
: public Lang::CoreFunction
1816 Core_distant_light( const char * title
)
1817 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1819 formals_
->appendEvaluatedCoreFormal( "color", Kernel::THE_SLOT_VARIABLE
);
1820 formals_
->appendEvaluatedCoreFormal( "shadows", Kernel::THE_FALSE_VARIABLE
);
1823 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1825 args
.applyDefaults( );
1827 typedef const Lang::Boolean ShadowsType
;
1828 RefCountPtr
< ShadowsType
> shadows
= Helpers::down_cast_CoreArgument
< ShadowsType
>( title_
, args
, 1, callLoc
);
1831 typedef const Lang::Gray ArgType
;
1832 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1835 Kernel::ContRef cont
= evalState
->cont_
;
1836 cont
->takeValue( Kernel::ValueRef( new Lang::DistantLightGray( Concrete::UnitFloatTriple( 0., 0., -1. ),
1845 typedef const Lang::RGB ArgType
;
1846 ArgType
* col
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1849 Kernel::ContRef cont
= evalState
->cont_
;
1850 cont
->takeValue( Kernel::ValueRef( new Lang::DistantLightRGB( Concrete::UnitFloatTriple( 0., 0., -1. ),
1858 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, 0, Helpers::typeSetString( Lang::Gray::staticTypeName( ), Lang::RGB::staticTypeName( ) ) );
1862 class Core_textrenderingmode
: public Lang::CoreFunction
1865 Core_textrenderingmode( const char * title
)
1866 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
1868 formals_
->appendEvaluatedCoreFormal( "fill", Kernel::THE_FALSE_VARIABLE
);
1869 formals_
->appendEvaluatedCoreFormal( "stroke", Kernel::THE_FALSE_VARIABLE
);
1872 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1874 args
.applyDefaults( );
1876 typedef const Lang::Boolean FlagType
;
1877 RefCountPtr
< FlagType
> fill
= Helpers::down_cast_CoreArgument
< FlagType
>( title_
, args
, 0, callLoc
);
1878 RefCountPtr
< FlagType
> stroke
= Helpers::down_cast_CoreArgument
< FlagType
>( title_
, args
, 1, callLoc
);
1880 Kernel::ContRef cont
= evalState
->cont_
;
1881 cont
->takeValue( Kernel::ValueRef( new Lang::TextRenderingMode( fill
->val_
, stroke
->val_
, false ) ),
1886 class Core_manualkern
: public Lang::CoreFunction
1889 Core_manualkern( const char * title
) : CoreFunction( title
) { }
1891 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1893 // Note that res is _not_ yet const. We use a RefCountPtr to take care of memory deallocation in case some argument has the wrong type and
1894 // the result is not used.
1895 RefCountPtr
< Lang::KernedText
> res( new Lang::KernedText( evalState
->dyn_
->getTextState( ), evalState
->dyn_
->getGraphicsState( ) ) );
1897 for( size_t i
= 0; i
!= args
.size( ); ++i
)
1901 typedef const Lang::String ArgType
;
1902 res
->pushString( Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( i
) ) );
1905 catch( const NonLocalExit::NotThisType
& ball
)
1907 // Never mind, see below
1912 typedef const Lang::Float ArgType
;
1913 res
->pushKerning( Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( i
) )->val_
);
1916 catch( const NonLocalExit::NotThisType
& ball
)
1918 // Never mind, see below
1923 typedef const Lang::KernedText ArgType
;
1924 Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( i
) )->push( res
.getPtr( ) );
1927 catch( const NonLocalExit::NotThisType
& ball
)
1929 // Never mind, see below
1932 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, i
, Helpers::typeSetString( Lang::String::staticTypeName( ), Lang::Float::staticTypeName( ), Lang::KernedText::staticTypeName( ) ) );
1935 Kernel::ContRef cont
= evalState
->cont_
;
1936 cont
->takeValue( res
,
1941 class Core_automatickern
: public Lang::CoreFunction
1944 Core_automatickern( const char * title
) : CoreFunction( title
) { }
1946 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1948 iconv_t converter
= Helpers::requireUTF8ToMacRomanConverter( );
1949 iconv_t backconverter
= Helpers::requireMacRomanToUTF8Converter( );
1951 RefCountPtr
< const FontMetrics::BaseFont
> metrics
= evalState
->dyn_
->getTextState( )->font_
->metrics( );
1952 if( metrics
->horizontalMetrics_
== NullPtr
< FontMetrics::WritingDirectionMetrics
>( ) )
1954 throw Exceptions::FontMetricsError( evalState
->dyn_
->getTextState( )->font_
->fontName( ), strrefdup( "No horizontal metrics defined." ) );
1957 // Note that res is _not_ yet const. We use a RefCountPtr to take care of memory deallocation in case some argument has the wrong type and
1958 // the result is not used.
1959 RefCountPtr
< Lang::KernedText
> res( new Lang::KernedText( evalState
->dyn_
->getTextState( ), evalState
->dyn_
->getGraphicsState( ) ) );
1961 std::ostringstream pendingChars
;
1962 unsigned char prevChar
= 0;
1963 double pendingKerning
= 0;
1965 size_t backbufSize
= 5;
1966 char * backbuf
= new char[ backbufSize
];
1967 DeleteOnExit
< char > bufDeleter( backbuf
);
1969 for( size_t i
= 0; i
!= args
.size( ); ++i
)
1973 typedef const Lang::String ArgType
;
1974 RefCountPtr
< ArgType
> str
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( i
) );
1976 const char * inbuf
= str
->val_
.getPtr( );
1978 size_t bufSize
= strlen( inbuf
) + 1;
1979 char * buf
= new char[ bufSize
];
1980 DeleteOnExit
< char > bufDeleter( buf
);
1982 char * outbuf
= buf
;
1983 size_t inbytesleft
= bufSize
- 1;
1984 size_t outbytesleft
= bufSize
- 1;
1985 // The ICONV_CAST macro is defined in config.h.
1986 size_t count
= iconv( converter
,
1987 ICONV_CAST( & inbuf
), & inbytesleft
,
1988 & outbuf
, & outbytesleft
);
1989 if( count
== (size_t)(-1) )
1991 if( errno
== EILSEQ
)
1993 throw Exceptions::MiscellaneousRequirement( "It is suspected that one of the UFT-8 characters used in showed text has no MacRoman representation." );
1995 else if( errno
== EINVAL
)
1997 throw Exceptions::MiscellaneousRequirement( "It is suspected that showed text ended with an incomplete multibyte character." );
1999 else if( errno
== E2BIG
)
2001 throw Exceptions::InternalError( "The buffer allocated for UTF-8 to MacRoman conversion was too small." );
2005 std::ostringstream msg
;
2006 msg
<< "iconv failed with an unrecognized error code: " << errno
;
2007 throw Exceptions::InternalError( strrefdup( msg
) );
2011 for( const char * src
= buf
; *src
!= '\0'; ++src
)
2013 unsigned char currentChar
= *reinterpret_cast< const unsigned char * >( src
);
2014 double currentKerning
= pendingKerning
- metrics
->getHorizontalKernPairXByCode( prevChar
, currentChar
);
2015 prevChar
= currentChar
;
2017 if( currentKerning
!= 0 )
2019 if( ! pendingChars
.str( ).empty( ) )
2021 res
->pushString( RefCountPtr
< const Lang::String
>( new Lang::String( strrefdup( pendingChars
) ) ) );
2022 pendingChars
.str( "" );
2024 res
->pushKerning( currentKerning
);
2027 // Copy the current (multibyte) character to the character queue
2029 const char * inbuf
= src
;
2030 char * outbuf
= backbuf
;
2031 size_t inbytesleft
= 1;
2032 size_t outbytesleft
= backbufSize
;
2033 // The ICONV_CAST macro is defined in config.h.
2034 size_t count
= iconv( backconverter
,
2035 ICONV_CAST( & inbuf
), & inbytesleft
,
2036 & outbuf
, & outbytesleft
);
2037 if( count
== (size_t)(-1) )
2039 if( errno
== EILSEQ
)
2041 throw Exceptions::ExternalError( "A character converted from UTF-8 could not be converted back to UFT-8." );
2043 else if( errno
== EINVAL
)
2045 throw Exceptions::ExternalError( "A character converted from UTF-8 was deemed incomplete." );
2047 else if( errno
== E2BIG
)
2049 throw Exceptions::InternalError( "The buffer allocated for conversion of a single character back to UTF-8 was too small." );
2053 std::ostringstream msg
;
2054 msg
<< "iconv failed with an unrecognized error code: " << errno
;
2055 throw Exceptions::InternalError( strrefdup( msg
) );
2059 pendingChars
<< backbuf
;
2064 catch( const NonLocalExit::NotThisType
& ball
)
2066 // Never mind, see below
2071 typedef const Lang::Float ArgType
;
2072 pendingKerning
+= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( i
) )->val_
;
2075 catch( const NonLocalExit::NotThisType
& ball
)
2077 // Never mind, see below
2080 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, i
, Helpers::typeSetString( Lang::String::staticTypeName( ), Lang::Float::staticTypeName( ) ) );
2083 if( ! pendingChars
.str( ).empty( ) )
2085 res
->pushString( RefCountPtr
< const Lang::String
>( new Lang::String( strrefdup( pendingChars
) ) ) );
2086 pendingChars
.str( "" );
2089 Kernel::ContRef cont
= evalState
->cont_
;
2090 cont
->takeValue( res
,
2095 class Core_newrandom
: public Lang::CoreFunction
2098 Core_newrandom( const char * title
)
2099 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
2101 formals_
->appendEvaluatedCoreFormal( "seed", Kernel::THE_SLOT_VARIABLE
);
2102 formals_
->appendEvaluatedCoreFormal( "size", Helpers::newValHandle( new Lang::Integer( 32 ) ) );
2105 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
2107 args
.applyDefaults( );
2109 typedef const Lang::Integer SizeType
;
2110 Lang::Integer::ValueType sz
= Helpers::down_cast_CoreArgument
< SizeType
>( title_
, args
, 1, callLoc
)->val_
;
2113 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "The size must be at least 8." );
2117 throw Exceptions::CoreOutOfRange( title_
, args
, 1, "The size must at most 256." );
2124 typedef const Lang::ChronologicalTime SeedType
;
2126 RefCountPtr
< SeedType
> seed
= Helpers::try_cast_CoreArgument
< SeedType
>( args
.getValue( argsi
) );
2128 Kernel::ContRef cont
= evalState
->cont_
;
2129 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::HotRandomSeed( sz
, seed
->val( ) ) ),
2133 catch( const NonLocalExit::NotThisType
& ball
)
2135 // Never mind, see below
2140 typedef const Lang::Integer SeedType
;
2142 RefCountPtr
< SeedType
> seed
= Helpers::try_cast_CoreArgument
< SeedType
>( args
.getValue( argsi
) );
2144 Kernel::ContRef cont
= evalState
->cont_
;
2145 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::HotRandomSeed( sz
, seed
->val_
) ),
2149 catch( const NonLocalExit::NotThisType
& ball
)
2151 // Never mind, see below
2154 throw Exceptions::CoreTypeMismatch( callLoc
, title_
, args
, argsi
, Helpers::typeSetString( Lang::Integer::staticTypeName( ), Lang::ChronologicalTime::staticTypeName( ) ) );
2158 class Core_devrandom
: public Lang::CoreFunction
2161 Core_devrandom( const char * title
)
2162 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
2164 formals_
->appendCoreStateFormal( "device" );
2165 formals_
->appendEvaluatedCoreFormal( "size", Helpers::newValHandle( new Lang::Integer( 32 ) ) );
2168 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
2170 args
.applyDefaults( );
2172 typedef const Lang::Integer SizeType
;
2173 Lang::Integer::ValueType sz
= Helpers::down_cast_CoreArgument
< SizeType
>( title_
, args
, 0, callLoc
)->val_
;
2176 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The size must be at least 8." );
2180 throw Exceptions::CoreOutOfRange( title_
, args
, 0, "The size must at most 256." );
2183 typedef Kernel::WarmRandomDevice GeneratorType
;
2184 GeneratorType
* gen
= Helpers::down_cast_CoreState
< GeneratorType
>( title_
, args
, 0, callLoc
);
2186 Kernel::ContRef cont
= evalState
->cont_
;
2187 cont
->takeValue( RefCountPtr
< const Lang::Value
>( new Lang::HotRandomSeed( static_cast< size_t >( sz
), gen
) ),
2192 class Core_destination
: public Lang::CoreFunction
2195 Core_destination( const char * title
)
2196 : CoreFunction( title
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( title
), true ) )
2198 formals_
->appendEvaluatedCoreFormal( "remote", Kernel::THE_FALSE_VARIABLE
);
2199 formals_
->appendEvaluatedCoreFormal( "name", Kernel::THE_VOID_VARIABLE
);
2200 formals_
->appendEvaluatedCoreFormal( "level", Kernel::THE_VOID_VARIABLE
);
2201 formals_
->appendEvaluatedCoreFormal( "text", Kernel::THE_VOID_VARIABLE
);
2202 formals_
->appendEvaluatedCoreFormal( "open", Kernel::THE_FALSE_VARIABLE
);
2203 formals_
->appendEvaluatedCoreFormal( "bold", Kernel::THE_FALSE_VARIABLE
);
2204 formals_
->appendEvaluatedCoreFormal( "italic", Kernel::THE_FALSE_VARIABLE
);
2205 formals_
->appendEvaluatedCoreFormal( "color", Helpers::newValHandle( new Lang::RGB( Concrete::RGB( 0, 0, 0 ) ) ) );
2206 formals_
->appendEvaluatedCoreFormal( "sides", Kernel::THE_VOID_VARIABLE
);
2207 formals_
->appendEvaluatedCoreFormal( "target", Kernel::THE_VOID_VARIABLE
);
2208 formals_
->appendEvaluatedCoreFormal( "fittobbox", Kernel::THE_VOID_VARIABLE
);
2209 formals_
->appendEvaluatedCoreFormal( "zoom", Kernel::THE_VOID_VARIABLE
);
2210 formals_
->appendEvaluatedCoreFormal( "transform", Kernel::THE_TRUE_VARIABLE
);
2213 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
2215 args
.applyDefaults( );
2218 const size_t remove_i
= argsi
;
2219 typedef const Lang::Boolean RemoteType
;
2220 bool remote
= Helpers::down_cast_CoreArgument
< RemoteType
>( title_
, args
, argsi
, callLoc
)->val_
;
2223 typedef const Lang::String NameType
;
2224 RefCountPtr
< NameType
> nameVal
= Helpers::down_cast_CoreArgument
< NameType
>( title_
, args
, argsi
, callLoc
, true );
2225 RefCountPtr
< const char > name
= RefCountPtr
< const char >( NullPtr
< const char >( ) );
2226 if( nameVal
!= NullPtr
< NameType
>( ) )
2228 const SimplePDF::PDF_Version::Version STRINGDESTS_VERSION
= SimplePDF::PDF_Version::PDF_1_2
;
2229 if( Kernel::the_PDF_version
.greaterOrEqual( STRINGDESTS_VERSION
) )
2231 name
= nameVal
->val_
;
2235 Kernel::the_PDF_version
.message( STRINGDESTS_VERSION
, "The naming of a destination was ignored." );
2236 // Note that this will leave name being null, and hence generate further errors if remote_.
2239 if( nameVal
== NullPtr
< NameType
>( ) ) // Note why this is not an else clause!
2243 throw Exceptions::CoreOutOfRange( title_
, args
, remove_i
, "The destination cannot be remote if no name is given." );
2248 const size_t outlineLevel_i
= argsi
;
2249 typedef const Lang::Integer OutlineLevelType
;
2250 RefCountPtr
< OutlineLevelType
> levelVal
= Helpers::down_cast_CoreArgument
< OutlineLevelType
>( title_
, args
, argsi
, callLoc
, true );
2251 int outlineLevel
= -1; // This will remain negative only if the level is not present.
2252 if( levelVal
!= NullPtr
< OutlineLevelType
>( ) )
2254 outlineLevel
= levelVal
->val_
;
2255 if( outlineLevel
< 0 )
2257 throw Exceptions::CoreOutOfRange( title_
, args
, argsi
, "The outline level must be non-negative." );
2262 typedef const Lang::String OutlineTextType
;
2263 RefCountPtr
< OutlineTextType
> textVal
= Helpers::down_cast_CoreArgument
< OutlineTextType
>( title_
, args
, argsi
, callLoc
, true );
2264 RefCountPtr
< const char > outlineText
= RefCountPtr
< const char >( NullPtr
< const char >( ) );
2265 if( textVal
!= NullPtr
< OutlineTextType
>( ) )
2267 outlineText
= textVal
->val_
;
2271 if( outlineLevel
>= 0 )
2273 throw Exceptions::CoreOutOfRange( title_
, args
, outlineLevel_i
, "Without an outline text, it is not allowed to make an outline item." );
2278 typedef const Lang::Boolean OutlineOpenType
;
2279 bool outlineOpen
= Helpers::down_cast_CoreArgument
< OutlineOpenType
>( title_
, args
, argsi
, callLoc
)->val_
;
2282 typedef const Lang::Boolean OutlineBoldType
;
2283 bool outlineBold
= Helpers::down_cast_CoreArgument
< OutlineBoldType
>( title_
, args
, argsi
, callLoc
)->val_
;
2286 typedef const Lang::Boolean OutlineItalicType
;
2287 bool outlineItalic
= Helpers::down_cast_CoreArgument
< OutlineItalicType
>( title_
, args
, argsi
, callLoc
)->val_
;
2290 typedef const Lang::RGB OutlineColorType
;
2291 Concrete::RGB outlineColor
= Helpers::down_cast_CoreArgument
< OutlineColorType
>( title_
, args
, argsi
, callLoc
)->components( );
2294 const size_t sidesMode_i
= argsi
;
2295 typedef const Lang::Symbol SidesModeType
;
2296 RefCountPtr
< SidesModeType
> sidesVal
= Helpers::down_cast_CoreArgument
< SidesModeType
>( title_
, args
, argsi
, callLoc
, true );
2299 const size_t target_i
= argsi
;
2300 typedef const Lang::Drawable2D TargetType
;
2301 RefCountPtr
< TargetType
> target
= Helpers::down_cast_CoreArgument
< TargetType
>( title_
, args
, argsi
, callLoc
, true );
2303 Lang::DocumentDestination::Sides sides
= Lang::DocumentDestination::PAGE
; // Defaults to false, unless a target is given.
2304 if( target
!= NullPtr
< TargetType
>( ) )
2306 sides
= Lang::DocumentDestination::TOPLEFT
;
2309 throw Exceptions::CoreOutOfRange( title_
, args
, target_i
, "The target can not be specified for remote destinations." );
2312 static Lang::Symbol
SIDES_TopLeft( "topleft" );
2313 static Lang::Symbol
SIDES_Page( "page" );
2314 static Lang::Symbol
SIDES_Top( "top" );
2315 static Lang::Symbol
SIDES_Left( "left" );
2316 static Lang::Symbol
SIDES_Rectangle( "rectangle" );
2317 if( sidesVal
!= NullPtr
< SidesModeType
>( ) )
2319 if( *sidesVal
== SIDES_TopLeft
)
2321 sides
= Lang::DocumentDestination::TOPLEFT
;
2323 else if( *sidesVal
== SIDES_Page
)
2325 if( target
!= NullPtr
< TargetType
>( ) )
2327 throw Exceptions::CoreOutOfRange( title_
, args
, sidesMode_i
, "The sides mode cannot be page when a target object is present." );
2329 sides
= Lang::DocumentDestination::PAGE
;
2331 else if( *sidesVal
== SIDES_Top
)
2333 sides
= Lang::DocumentDestination::TOP
;
2335 else if( *sidesVal
== SIDES_Left
)
2337 sides
= Lang::DocumentDestination::LEFT
;
2339 else if( *sidesVal
== SIDES_Rectangle
)
2341 sides
= Lang::DocumentDestination::RECTANGLE
;
2345 std::ostringstream oss
;
2346 oss
<< "Valid sides modes are the symbols { "
2347 << SIDES_TopLeft
.name( ).getPtr( ) << ", "
2348 << SIDES_Page
.name( ).getPtr( ) << ", "
2349 << SIDES_Top
.name( ).getPtr( ) << ", "
2350 << SIDES_Left
.name( ).getPtr( ) << ", "
2351 << SIDES_Rectangle
.name( ).getPtr( )
2353 throw Exceptions::CoreOutOfRange( title_
, args
, sidesMode_i
, strrefdup( oss
) );
2358 typedef const Lang::Boolean FitToType
;
2359 RefCountPtr
< FitToType
> fittobboxVal
= Helpers::down_cast_CoreArgument
< FitToType
>( title_
, args
, argsi
, callLoc
, true );
2360 bool fittobbox
= false;
2361 if( fittobboxVal
!= NullPtr
< FitToType
>( ) )
2363 if( remote
|| sides
== Lang::DocumentDestination::TOPLEFT
|| sides
== Lang::DocumentDestination::RECTANGLE
)
2365 throw Exceptions::CoreOutOfRange( title_
, args
, argsi
, "The fit-to-bbox flag cannot be specified in this mode." );
2367 fittobbox
= fittobboxVal
->val_
;
2371 typedef const Lang::Float ZoomType
;
2372 RefCountPtr
< ZoomType
> zoomVal
= Helpers::down_cast_CoreArgument
< ZoomType
>( title_
, args
, argsi
, callLoc
, true );
2373 double zoom
= 0; // This will remain zero only if the zoom argument is not specified.
2374 if( zoomVal
!= NullPtr
< ZoomType
>( ) )
2376 if( remote
|| sides
!= Lang::DocumentDestination::TOPLEFT
)
2378 throw Exceptions::CoreOutOfRange( title_
, args
, argsi
, "The zoom can only be specified when using the top-left sides." );
2380 zoom
= zoomVal
->val_
;
2383 throw Exceptions::CoreOutOfRange( title_
, args
, argsi
, "The zoom value must be positive." );
2388 typedef const Lang::Boolean DoTransformType
;
2389 bool doTransform
= Helpers::down_cast_CoreArgument
< DoTransformType
>( title_
, args
, argsi
, callLoc
)->val_
;
2391 Kernel::ContRef cont
= evalState
->cont_
;
2394 RefCountPtr
< const Lang::DocumentDestination
>
2395 taggedObj( new Lang::DocumentDestination( remote
, name
, outlineLevel
,
2396 outlineText
, outlineOpen
, outlineBold
, outlineItalic
, outlineColor
) );
2397 cont
->takeValue( RefCountPtr
< const Lang::Value
>
2398 ( new Lang::TaggedValue2D( Kernel::THE_NAVIGATION_SYMBOL
, taggedObj
) ),
2403 RefCountPtr
< const Lang::DocumentDestination
>
2404 taggedObj( new Lang::DocumentDestination( name
, outlineLevel
,
2405 outlineText
, outlineOpen
, outlineBold
, outlineItalic
, outlineColor
,
2406 sides
, target
, fittobbox
, zoom
) );
2409 cont
->takeValue( RefCountPtr
< const Lang::Value
>
2410 ( new Lang::TaggedGeometric2D( Kernel::THE_NAVIGATION_SYMBOL
, taggedObj
) ),
2415 cont
->takeValue( RefCountPtr
< const Lang::Value
>
2416 ( new Lang::TaggedValue2D( Kernel::THE_NAVIGATION_SYMBOL
, taggedObj
) ),
2428 Kernel::registerCore_construct( Kernel::Environment
* env
)
2430 env
->initDefineCoreFunction( new Lang::Core_cons( "cons" ) );
2431 env
->initDefineCoreFunction( new Lang::Core_list( "list" ) );
2432 env
->initDefineCoreFunction( new Lang::Core_unlist( "unlist" ) );
2433 env
->initDefineCoreFunction( new Lang::Core_isnull( "null?" ) );
2434 env
->initDefineCoreFunction( new Lang::Core_range( "range" ) );
2435 env
->initDefineCoreFunction( new Lang::Core_affinetransform( "affinetransform" ) );
2436 env
->initDefineCoreFunction( new Lang::Core_shift( "shift" ) );
2437 env
->initDefineCoreFunction( new Lang::Core_rotate( "rotate" ) );
2438 env
->initDefineCoreFunction( new Lang::Core_rotate3d( "rotate3D" ) );
2439 env
->initDefineCoreFunction( new Lang::Core_scale( "scale" ) );
2440 env
->initDefineCoreFunction( new Lang::Core_scale3d( "scale3D" ) );
2441 env
->initDefineCoreFunction( new Lang::Core_affinetransform3D( "affinetransform3D" ) );
2442 env
->initDefineCoreFunction( new Lang::Core_inverse( "inverse" ) );
2444 env
->initDefineCoreFunction( new Lang::Core_formxo( "formxo" ) );
2445 env
->initDefineCoreFunction( new Lang::Core_transparencygroup( "tgroup" ) );
2447 env
->initDefineCoreFunction( new Lang::Core_tag( "tag" ) );
2448 env
->initDefineCoreFunction( new Lang::Core_find( "find" ) );
2449 env
->initDefineCoreFunction( new Lang::Core_findall( "findall" ) );
2451 env
->initDefineCoreFunction( new Lang::Core_ambient_light( "ambient_light" ) );
2452 env
->initDefineCoreFunction( new Lang::Core_specular_light( "specular_light" ) );
2453 env
->initDefineCoreFunction( new Lang::Core_distant_light( "distant_light" ) );
2454 env
->initDefineCoreFunction( new Lang::Core_phong( "phong" ) );
2456 env
->initDefineCoreFunction( new Lang::Core_vector( "vector" ) );
2457 env
->initDefineCoreFunction( new Lang::Core_importPDFpages( "import" ) );
2459 env
->initDefineCoreFunction( new Lang::Core_svg_path( "svg_path" ) );
2461 env
->initDefineCoreFunction( new Lang::Core_sprintf( "sprintf" ) );
2462 env
->initDefineCoreFunction( new Lang::Core_strftime( "strftime" ) );
2464 env
->initDefineCoreFunction( new Lang::Core_newrandom( "newRandom" ) );
2465 env
->initDefineCoreFunction( new Lang::Core_devrandom( "devRandom" ) );
2467 env
->initDefineCoreFunction( new Lang::Core_destination( "destination" ) );
2469 env
->initDefineCoreFunction( new Lang::Core_textrenderingmode( "textmode" ) );
2470 env
->initDefineCoreFunction( new Lang::Core_manualkern( "kerning" ) );
2471 env
->initDefineCoreFunction( new Lang::Core_automatickern( "kern" ) );