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_Ast_decls.h"
22 #include "Shapes_Kernel_decls.h"
23 #include "Shapes_Lang_decls.h"
24 #include "Shapes_Lang_decls.h"
28 #include "environment.h"
29 #include "statetypes.h"
30 #include "elementarylength.h"
31 #include "concretecolors.h"
32 #include "elementarycoords.h"
33 #include "fontmetrics.h"
47 class Font
: public Lang::NoOperatorOverloadValue
50 static std::map
< RefCountPtr
< const char >, RefCountPtr
< SimplePDF::PDF_Object
>, charRefPtrLess
> theFontResourceMap_
;
51 static std::map
< RefCountPtr
< const char >, RefCountPtr
< const FontMetrics::BaseFont
>, charRefPtrLess
> theFontMetricsMap_
;
52 static std::list
< std::string
> theFontMetricsSearchPath_
;
55 static void push_backFontMetricsPath( const std::string
& path
);
56 static std::string
searchGlyphList( );
57 static std::string
searchCharacterEncoding( const char * encodingName
);
59 static std::string
searchFontMetrics( RefCountPtr
< const char > fontName
);
60 RefCountPtr
< const char > fontName_
;
61 mutable RefCountPtr
< SimplePDF::PDF_Object
> resource_
;
62 mutable RefCountPtr
< const FontMetrics::BaseFont
> metrics_
;
64 Font( const RefCountPtr
< const char > fontName
, RefCountPtr
< SimplePDF::PDF_Object
> & resource
, RefCountPtr
< const FontMetrics::BaseFont
> metrics
= NullPtr
< const FontMetrics::BaseFont
>( ) );
65 Font( const RefCountPtr
< const char > builtInFontName
); // It is important that this is not used with fonts that aren't built in.
67 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
68 const RefCountPtr
< SimplePDF::PDF_Object
> & resource( ) const;
69 RefCountPtr
< const char > fontName( ) const;
70 RefCountPtr
< const FontMetrics::BaseFont
> metrics( ) const;
74 class TextRenderingMode
: public Lang::NoOperatorOverloadValue
77 typedef enum { FILL
= 0, STROKE
, FILLSTROKE
, INVISIBLE
, FILLCLIP
, STROKECLIP
, FILLSTROKECLIP
, CLIP
, UNDEFINED
} ValueType
;
79 TextRenderingMode( const ValueType
& mode
);
80 TextRenderingMode( bool fill
, bool stroke
, bool clip
);
81 virtual ~TextRenderingMode( );
82 virtual void gcMark( Kernel::GCMarkedSet
& marked
){ };
85 static ValueType
clipMode( ValueType mode
);
88 class TextOperation
: public Lang::NoOperatorOverloadValue
92 virtual ~TextOperation( );
94 virtual void shipout( std::ostream
& os
, Kernel::PageContentStates
* pdfState
, const Lang::Transform2D
& tf
, bool clip
= false ) const = 0;
95 virtual void measure( Lang::Transform2D
* textMatrix
, Lang::Transform2D
* textLineMatrix
, Concrete::Length
* xmin
, Concrete::Length
* ymin
, Concrete::Length
* xmax
, Concrete::Length
* ymax
) const = 0;
100 class KernedText
: public Lang::TextOperation
102 RefCountPtr
< const Kernel::TextState
> textState_
;
103 RefCountPtr
< const Kernel::GraphicsState
> metaState_
;
105 // The representation is a bit artificial to be efficient: NullPtr objects in
106 // strings_ mark where kerning values are to be taken from kernings_. Hence,
107 // The number of NullPtr objects in strings_ must match the length of kernings_.
108 std::list
< RefCountPtr
< const Lang::String
> > strings_
;
109 std::list
< double > kernings_
;
112 KernedText( const RefCountPtr
< const Kernel::TextState
> & textState
, const RefCountPtr
< const Kernel::GraphicsState
> & metaState
);
113 KernedText( const RefCountPtr
< const Kernel::TextState
> & textState
, const RefCountPtr
< const Kernel::GraphicsState
> & metaState
, const RefCountPtr
< const Lang::String
> & str
);
114 virtual ~KernedText( );
115 virtual Kernel::VariableHandle
getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const;
116 void pushString( const RefCountPtr
< const Lang::String
> & str
);
117 void pushKerning( double kerning
);
119 virtual void show( std::ostream
& os
) const;
120 virtual void shipout( std::ostream
& os
, Kernel::PageContentStates
* pdfState
, const Lang::Transform2D
& tf
, bool clip
) const;
121 virtual void measure( Lang::Transform2D
* textMatrix
, Lang::Transform2D
* textLineMatrix
, Concrete::Length
* xmin
, Concrete::Length
* ymin
, Concrete::Length
* xmax
, Concrete::Length
* ymax
) const;
123 void push( Lang::KernedText
* dst
) const;
125 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
128 RefCountPtr
< const Lang::SingleList
> makeList( ) const;
129 static RefCountPtr
< const Lang::String
> oneMacRomanToUTF8( const char c
);
132 class TextNewline
: public Lang::TextOperation
134 Concrete::Coords2D t_
;
136 TextNewline( const Concrete::Length tx
, const Concrete::Length ty
);
137 virtual ~TextNewline( );
139 virtual void show( std::ostream
& os
) const;
140 virtual void shipout( std::ostream
& os
, Kernel::PageContentStates
* pdfState
, const Lang::Transform2D
& tf
, bool clip
) const;
141 virtual void measure( Lang::Transform2D
* textMatrix
, Lang::Transform2D
* textLineMatrix
, Concrete::Length
* xmin
, Concrete::Length
* ymin
, Concrete::Length
* xmax
, Concrete::Length
* ymax
) const;
143 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
146 class TextMoveto
: public Lang::TextOperation
148 RefCountPtr
< const Lang::Transform2D
> tf_
;
150 TextMoveto( const RefCountPtr
< const Lang::Transform2D
> & tf
);
151 virtual ~TextMoveto( );
153 virtual void show( std::ostream
& os
) const;
154 virtual void shipout( std::ostream
& os
, Kernel::PageContentStates
* pdfState
, const Lang::Transform2D
& tf
, bool clip
) const;
155 virtual void measure( Lang::Transform2D
* textMatrix
, Lang::Transform2D
* textLineMatrix
, Concrete::Length
* xmin
, Concrete::Length
* ymin
, Concrete::Length
* xmax
, Concrete::Length
* ymax
) const;
157 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
165 class CharacterSpacingBinding
: public DynamicBindings
167 const Ast::DynamicBindingExpression
* bindingExpr_
;
168 Concrete::Length spacing_
;
172 CharacterSpacingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Concrete::Length spacing
);
173 CharacterSpacingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const double r
);
174 virtual ~CharacterSpacingBinding( );
175 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
176 virtual void show( std::ostream
& os
) const;
177 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
180 class WordSpacingBinding
: public DynamicBindings
182 const Ast::DynamicBindingExpression
* bindingExpr_
;
183 Concrete::Length spacing_
;
187 WordSpacingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Concrete::Length spacing
);
188 WordSpacingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const double r
);
189 virtual ~WordSpacingBinding( );
190 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
191 virtual void show( std::ostream
& os
) const;
192 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
195 class HorizontalScalingBinding
: public DynamicBindings
197 const Ast::DynamicBindingExpression
* bindingExpr_
;
201 HorizontalScalingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const double scaling
);
202 virtual ~HorizontalScalingBinding( );
203 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
204 virtual void show( std::ostream
& os
) const;
205 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
208 class LeadingBinding
: public DynamicBindings
210 const Ast::DynamicBindingExpression
* bindingExpr_
;
211 Concrete::Length ty_
;
215 LeadingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Concrete::Length ty
);
216 LeadingBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const double r
);
217 virtual ~LeadingBinding( );
218 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
219 virtual void show( std::ostream
& os
) const;
220 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
223 class FontBinding
: public DynamicBindings
225 const Ast::DynamicBindingExpression
* bindingExpr_
;
226 RefCountPtr
< const Lang::Font
> font_
;
229 FontBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const RefCountPtr
< const Lang::Font
> & font
);
230 virtual ~FontBinding( );
231 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
232 virtual void show( std::ostream
& os
) const;
233 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
236 class TextSizeBinding
: public DynamicBindings
238 const Ast::DynamicBindingExpression
* bindingExpr_
;
239 Concrete::Length size_
;
242 TextSizeBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Concrete::Length size
);
243 virtual ~TextSizeBinding( );
244 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
245 virtual void show( std::ostream
& os
) const;
246 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
249 class TextRenderingModeBinding
: public DynamicBindings
251 const Ast::DynamicBindingExpression
* bindingExpr_
;
252 Lang::TextRenderingMode::ValueType mode_
;
255 TextRenderingModeBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Lang::TextRenderingMode::ValueType mode
);
256 virtual ~TextRenderingModeBinding( );
257 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
258 virtual void show( std::ostream
& os
) const;
259 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
262 class TextRiseBinding
: public DynamicBindings
264 const Ast::DynamicBindingExpression
* bindingExpr_
;
265 Concrete::Length ty_
;
269 TextRiseBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const Concrete::Length ty
);
270 TextRiseBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const double r
);
271 virtual ~TextRiseBinding( );
272 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
273 virtual void show( std::ostream
& os
) const;
274 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
277 class TextKnockoutBinding
: public DynamicBindings
279 const Ast::DynamicBindingExpression
* bindingExpr_
;
283 TextKnockoutBinding( const char * id
, const Ast::DynamicBindingExpression
* bindingExpr
, const bool knockout
);
284 virtual ~TextKnockoutBinding( );
285 virtual void bind( MapType
& bindings
, Kernel::SystemDynamicVariables
** sysBindings
) const;
286 virtual void show( std::ostream
& os
) const;
287 virtual void gcMark( Kernel::GCMarkedSet
& marked
);
295 class CharacterSpacingDynamicVariableProperties
: public Kernel::DynamicVariableProperties
298 CharacterSpacingDynamicVariableProperties( const char * name
);
299 virtual ~CharacterSpacingDynamicVariableProperties( );
300 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
301 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
304 class WordSpacingDynamicVariableProperties
: public Kernel::DynamicVariableProperties
307 WordSpacingDynamicVariableProperties( const char * name
);
308 virtual ~WordSpacingDynamicVariableProperties( );
309 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
310 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
313 class HorizontalScalingDynamicVariableProperties
: public Kernel::DynamicVariableProperties
316 HorizontalScalingDynamicVariableProperties( const char * name
);
317 virtual ~HorizontalScalingDynamicVariableProperties( );
318 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
319 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
322 class LeadingDynamicVariableProperties
: public Kernel::DynamicVariableProperties
325 LeadingDynamicVariableProperties( const char * name
);
326 virtual ~LeadingDynamicVariableProperties( );
327 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
328 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
331 class FontDynamicVariableProperties
: public Kernel::DynamicVariableProperties
334 FontDynamicVariableProperties( const char * name
);
335 virtual ~FontDynamicVariableProperties( );
336 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
337 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
340 class TextSizeDynamicVariableProperties
: public Kernel::DynamicVariableProperties
343 TextSizeDynamicVariableProperties( const char * name
);
344 virtual ~TextSizeDynamicVariableProperties( );
345 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
346 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
349 class TextRenderingModeDynamicVariableProperties
: public Kernel::DynamicVariableProperties
352 TextRenderingModeDynamicVariableProperties( const char * name
);
353 virtual ~TextRenderingModeDynamicVariableProperties( );
354 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
355 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
358 class TextRiseDynamicVariableProperties
: public Kernel::DynamicVariableProperties
361 TextRiseDynamicVariableProperties( const char * name
);
362 virtual ~TextRiseDynamicVariableProperties( );
363 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
364 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
367 class TextKnockoutDynamicVariableProperties
: public Kernel::DynamicVariableProperties
370 TextKnockoutDynamicVariableProperties( const char * name
);
371 virtual ~TextKnockoutDynamicVariableProperties( );
372 virtual Kernel::VariableHandle
fetch( const Kernel::PassedDyn
& dyn
) const;
373 virtual void makeBinding( Kernel::VariableHandle val
, const Ast::DynamicBindingExpression
* bindingExpr
, Kernel::EvalState
* evalState
) const;
379 static const char RELATIVE_LEADING
= 0x01;
380 static const char RELATIVE_RISE
= 0x02;
381 static const char RELATIVE_CHARACTER_SPACING
= 0x04;
382 static const char RELATIVE_WORD_SPACING
= 0x08;
384 unsigned char relativeFlags_
;
387 static const char KNOCKOUT_FLAG_BIT
= 0x01;
388 static const char KNOCKOUT_UNDEFINED_BIT
= 0x02;
390 Concrete::Length characterSpacing_
; // Use NaN for undefined.
391 Concrete::Length wordSpacing_
; // Use NaN for undefined.
392 double horizontalScaling_
; // Use NaN for undefined.
394 Concrete::Length leading_
; // Use NaN for undefined. Offtype in case leadingIsRelative_.
395 Concrete::Length rise_
; // Use NaN for undefined. Offtype in case riseIsRelative_.
397 RefCountPtr
< const Lang::Font
> font_
; // Use NullPtr for undefined.
398 Concrete::Length size_
; // Use NaN for undefined.
399 Lang::TextRenderingMode::ValueType mode_
; // Use UNDEFINED for undefined.
400 char knockout_
; // Set the bit KNOCKOUT_UNDEFINED for undefined.
403 explicit TextState( const Kernel::TextState
& orig
); // explicit, since reference counting shall be used in most cases
404 TextState( const Kernel::TextState
& newValues
, const Kernel::TextState
& oldValues
);
405 TextState( bool setDefaults
);
408 void setLeading( const Concrete::Length leading
);
409 void setLeading( const double relativeLeading
);
410 bool hasLeading( ) const;
411 inline bool leadingIsRelative( ) const;
412 Concrete::Length
leadingConcrete( ) const;
413 RefCountPtr
< const Lang::Value
> leading( ) const;
415 void setRise( const Concrete::Length rise
);
416 void setRise( const double relativeRise
);
417 bool hasRise( ) const;
418 bool riseIsRelative( ) const;
419 Concrete::Length
riseConcrete( ) const;
420 RefCountPtr
< const Lang::Value
> rise( ) const;
422 void setCharacterSpacing( const Concrete::Length spacing
);
423 void setCharacterSpacing( const double relativeSpacing
);
424 bool hasCharacterSpacing( ) const;
425 bool characterSpacingIsRelative( ) const;
426 Concrete::Length
characterSpacingConcrete( ) const;
427 RefCountPtr
< const Lang::Value
> characterSpacing( ) const;
429 void setWordSpacing( const Concrete::Length spacing
);
430 void setWordSpacing( const double relativeSpacing
);
431 bool hasWordSpacing( ) const;
432 bool wordSpacingIsRelative( ) const;
433 Concrete::Length
wordSpacingConcrete( ) const;
434 RefCountPtr
< const Lang::Value
> wordSpacing( ) const;
436 bool synchKnockout( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
437 bool synchAssertKnockout( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool clip
, bool force
= false );
439 void print( std::ostream
& os
, const std::string
& indentation
) const;
442 static std::map
< bool, RefCountPtr
< SimplePDF::PDF_Object
> > knockoutNameMap_
;
444 bool synchCharacterSpacing( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
445 bool synchWordSpacing( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
446 bool synchHorizontalScaling( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
447 bool synchLeading( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
448 bool synchFontAndSize( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
449 bool synchMode( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool clip
, bool force
= false );
450 bool synchRise( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool force
= false );
452 void assertKnockout( const Kernel::TextState
* ref
);
454 bool synchButKnockout( std::ostream
& os
, const Kernel::TextState
* ref
, SimplePDF::PDF_Resources
* resources
, bool clip
, bool force
= false );