Initial commit
[profile/ivi/openjade.git] / style / ELObj.h
1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
3
4 #ifndef ELObj_INCLUDED
5 #define ELObj_INCLUDED 1
6
7 #include "types.h"
8 #include "Collector.h"
9 #include "OutputCharStream.h"
10 #include "Boolean.h"
11 #include "Location.h"
12 #include "Node.h"
13 #include "FOTBuilder.h"
14 #include <string.h>
15
16 #ifdef DSSSL_NAMESPACE
17 namespace DSSSL_NAMESPACE {
18 #endif
19
20 class Interpreter;
21 class EvalContext;
22
23 class Unit;
24 class PairObj;
25 class FunctionObj;
26 class SymbolObj;
27 class KeywordObj;
28 class BoxObj;
29 class StringObj;
30 class SosofoObj;
31 class AppendSosofoObj;
32 class ColorObj;
33 class ColorSpaceObj;
34 class StyleObj;
35 class AddressObj;
36 class NodeListObj;
37 class NamedNodeListObj;
38 class Identifier;
39 class LengthSpec;
40 class DisplaySpaceObj;
41 class InlineSpaceObj;
42 class GlyphSubstTableObj;
43 class VectorObj;
44 class LanguageObj;
45
46 class ELObj : public Collector::Object {
47 public:
48   ELObj();
49   void *operator new(size_t, Collector &c) {
50     return c.allocateObject(0);
51   }
52 #ifdef SP_HAVE_PLACEMENT_OPERATOR_DELETE
53 private:
54   void operator delete(void *p) { }
55 public:
56   void operator delete(void *p, Collector &c) {
57     c.unallocateObject(p);
58   }
59 #endif
60   virtual bool isNil() const;
61   virtual bool isList() const;
62   virtual bool isTrue() const;
63   virtual PairObj *asPair();
64   virtual SymbolObj *asSymbol();
65   virtual KeywordObj *asKeyword();
66   virtual FunctionObj *asFunction();
67   virtual SosofoObj *asSosofo();
68   virtual AppendSosofoObj *asAppendSosofo();
69   virtual ColorObj *asColor();
70   virtual ColorSpaceObj *asColorSpace();
71   virtual StyleObj *asStyle();
72   virtual AddressObj *asAddress();
73   virtual DisplaySpaceObj *asDisplaySpace();
74   virtual InlineSpaceObj *asInlineSpace();
75   virtual GlyphSubstTableObj *asGlyphSubstTable();
76   virtual NodeListObj *asNodeList();
77   virtual NamedNodeListObj *asNamedNodeList();
78   virtual StringObj *convertToString(); // either symbol or string
79   virtual BoxObj *asBox();
80   virtual VectorObj *asVector();
81   virtual LanguageObj *asLanguage();
82   virtual bool charValue(Char &);
83   virtual bool stringData(const Char *&, size_t &);
84   virtual void print(Interpreter &, OutputCharStream &);
85   virtual void print(Interpreter &, OutputCharStream &, unsigned);
86   virtual bool exactIntegerValue(long &);
87   virtual bool realValue(double &);
88   virtual bool inexactRealValue(double &);
89   virtual bool lengthValue(long &);
90   virtual const FOTBuilder::GlyphId *glyphId() const;
91   virtual const LengthSpec *lengthSpec() const;
92   enum QuantityType {
93     noQuantity,
94     longQuantity,
95     doubleQuantity
96     };
97   virtual QuantityType quantityValue(long &, double &, int &);
98   virtual ELObj *resolveQuantities(bool force, Interpreter &,
99                                    const Location &);
100   virtual bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
101   static bool equal(ELObj &, ELObj &);
102   // Note that in DSSSL2 unlike Scheme eqv? for lists and strings is the same
103   // as equal?.  Only for vectors do they differ.
104   static bool eqv(ELObj &, ELObj &);
105 protected:
106   // This checks for equality of *distinct* objects.
107   virtual bool isEqual(ELObj &);
108   // This checks for equivalence of *distinct* objects.
109   virtual bool isEquiv(ELObj &);
110 };
111
112 class ErrorObj : public ELObj {
113 public:
114   void print(Interpreter &, OutputCharStream &);
115 private:
116   ErrorObj();
117   friend class Interpreter;
118 };
119
120 class UnspecifiedObj : public ELObj {
121 public:
122   void print(Interpreter &, OutputCharStream &);
123 private:
124   UnspecifiedObj();
125   friend class Interpreter;
126 };
127
128 class NilObj : public ELObj {
129 public:
130   bool isNil() const;
131   bool isList() const;
132   void print(Interpreter &, OutputCharStream &);
133 private:
134   NilObj();
135   friend class Interpreter;
136 };
137
138 class TrueObj : public ELObj {
139 public:
140   void print(Interpreter &, OutputCharStream &);
141 private:
142   TrueObj();
143   friend class Interpreter;
144 };
145
146 class FalseObj : public ELObj {
147 public:
148   void print(Interpreter &, OutputCharStream &);
149   bool isTrue() const;
150 private:
151   FalseObj();
152   friend class Interpreter;
153 };
154
155 class StringObj;
156 class CharObj;
157
158 class SymbolObj : public ELObj {
159 public:
160   void print(Interpreter &, OutputCharStream &);
161   SymbolObj *asSymbol();
162   StringObj *convertToString();
163   StringObj *name() const;
164   void traceSubObjects(Collector &) const;
165   FOTBuilder::Symbol cValue() const;
166   void setCValue(FOTBuilder::Symbol);
167   static const StringC &key(const SymbolObj &);
168 private:
169   SymbolObj(StringObj *);
170   StringObj *name_;
171   FOTBuilder::Symbol cValue_;
172   friend class Interpreter;
173 };
174
175 class Identifier;
176
177 class KeywordObj : public ELObj {
178 public:
179   void print(Interpreter &, OutputCharStream &);
180   KeywordObj *asKeyword();
181   const Identifier *identifier() const;
182   bool isEqual(ELObj &);
183 private:
184   KeywordObj(const Identifier *);
185   const Identifier *ident_;
186 friend class Interpreter;
187 };
188
189 class PairObj : public ELObj {
190 public:
191   PairObj(ELObj *car, ELObj *cdr);
192   ELObj *car();
193   ELObj *cdr();
194   void setCar(ELObj *);
195   void setCdr(ELObj *);
196   PairObj *asPair();
197   bool isList() const;
198   void print(Interpreter &, OutputCharStream &);
199   void traceSubObjects(Collector &) const;
200   ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
201   bool isEqual(ELObj &);
202   bool isEquiv(ELObj &);
203 private:
204   ELObj *car_;
205   ELObj *cdr_;
206 };
207
208 class VectorObj : public ELObj, public Vector<ELObj *> {
209 public:
210   void *operator new(size_t, Collector &c) {
211     return c.allocateObject(1);
212   }
213   VectorObj();
214   VectorObj(Vector<ELObj *> &v);
215   void traceSubObjects(Collector &) const;
216   VectorObj *asVector();
217   bool isEqual(ELObj &);
218   bool isEquiv(ELObj &);
219   void print(Interpreter &, OutputCharStream &);
220   ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
221 };
222
223 class CharObj : public ELObj {
224 public:
225   Char ch();
226   void print(Interpreter &, OutputCharStream &);
227   void display(Interpreter &, OutputCharStream &) const;
228   bool isEqual(ELObj &);
229   bool charValue(Char &);
230 private:
231   CharObj(Char);
232   Char ch_;
233   friend class Interpreter;
234 };
235
236 class StringObj : public ELObj, public StringC {
237 public:
238   void *operator new(size_t, Collector &c) {
239     return c.allocateObject(1);
240   }
241   StringObj();
242   StringObj(const StringC &str);
243   StringObj(const Char *, size_t);
244   void print(Interpreter &, OutputCharStream &);
245   StringObj *convertToString();
246   bool stringData(const Char *&, size_t &);
247   bool isEqual(ELObj &);
248 };
249
250 class IntegerObj : public ELObj {
251 public:
252   void print(Interpreter &, OutputCharStream &);
253   void print(Interpreter &, OutputCharStream &, unsigned);
254   bool exactIntegerValue(long &);
255   bool realValue(double &);
256   QuantityType quantityValue(long &, double &, int &);
257   bool isEqual(ELObj &);
258 private:
259   friend class Interpreter;
260   IntegerObj();
261   IntegerObj(long);
262   long n_;
263 };
264
265 class RealObj : public ELObj {
266 public:
267   RealObj(double);
268   bool realValue(double &);
269   bool inexactRealValue(double &);
270   QuantityType quantityValue(long &, double &, int &);
271   bool isEqual(ELObj &);
272   void print(Interpreter &, OutputCharStream &);
273 private:
274   double n_;
275 };
276
277 class LengthObj : public ELObj {
278 public:
279   LengthObj(long units);
280   bool lengthValue(long &);
281   QuantityType quantityValue(long &, double &, int &);
282   void print(Interpreter &, OutputCharStream &);
283   bool isEqual(ELObj &);
284 private:
285   long n_;
286 };
287
288 class QuantityObj : public ELObj {
289 public:
290   QuantityObj(double, int);
291   QuantityType quantityValue(long &, double &, int &);
292   void print(Interpreter &, OutputCharStream &);
293   bool isEqual(ELObj &);
294   bool realValue(double &);
295   bool inexactRealValue(double &);
296 private:
297   // This is in units per inch.
298   double val_;
299   int dim_;
300 };
301
302 class LengthSpec {
303 public:
304   enum Unknown { displaySize = 1, tableUnit };
305   LengthSpec();
306   LengthSpec(double);
307   LengthSpec(Unknown, double);
308   void operator+=(const LengthSpec &);
309   void operator+=(double d) { val_[0] += d; }
310   void operator-=(const LengthSpec &);
311   void operator-=(double d) { val_[0] -= d; }
312   void operator*=(double);
313   void operator/=(double);
314   bool convert(FOTBuilder::LengthSpec &) const;
315   bool convert(FOTBuilder::TableLengthSpec &) const;
316 private:
317   enum { nVals = 3 };
318   double val_[nVals];
319 };
320
321 class LengthSpecObj : public ELObj {
322 public:
323   void *operator new(size_t, Collector &c) {
324     return c.allocateObject(1);
325   }
326   LengthSpecObj(const LengthSpec &);
327   const LengthSpec *lengthSpec() const;
328 private:
329   Owner<LengthSpec> lengthSpec_;
330 };
331
332 class DisplaySpaceObj : public ELObj {
333 public:
334   void *operator new(size_t, Collector &c) {
335     return c.allocateObject(1);
336   }
337   DisplaySpaceObj(const FOTBuilder::DisplaySpace &);
338   const FOTBuilder::DisplaySpace &displaySpace() const;
339   DisplaySpaceObj *asDisplaySpace();
340 private:
341   Owner<FOTBuilder::DisplaySpace> displaySpace_;
342 };
343
344 class InlineSpaceObj : public ELObj {
345 public:
346   void *operator new(size_t, Collector &c) {
347     return c.allocateObject(1);
348   }
349   InlineSpaceObj(const FOTBuilder::InlineSpace &);
350   const FOTBuilder::InlineSpace &inlineSpace() const;
351   InlineSpaceObj *asInlineSpace();
352 private:
353   Owner<FOTBuilder::InlineSpace> inlineSpace_;
354 };
355
356 class UnresolvedQuantityObj : public ELObj {
357 public:
358   UnresolvedQuantityObj(double, Unit *, int);
359   ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
360 private:
361   double val_;
362   Unit *unit_;
363   int unitExp_;
364 };
365
366 class UnresolvedLengthObj : public ELObj {
367 public:
368   UnresolvedLengthObj(long val, int valExp, Unit *);
369   ELObj *resolveQuantities(bool force, Interpreter &, const Location &);
370 private:
371   long val_;
372   Unit *unit_;
373   int valExp_;
374 };
375
376 class GlyphIdObj : public ELObj {
377 public:
378   GlyphIdObj(const FOTBuilder::GlyphId &);
379   const FOTBuilder::GlyphId *glyphId() const;
380   bool isEqual(ELObj &);
381 private:
382   FOTBuilder::GlyphId glyphId_;
383 };
384
385 class GlyphSubstTableObj : public ELObj {
386 public:
387   void *operator new(size_t, Collector &c) {
388     return c.allocateObject(1);
389   }
390   GlyphSubstTableObj(const ConstPtr<FOTBuilder::GlyphSubstTable> &);
391   GlyphSubstTableObj *asGlyphSubstTable();
392   const ConstPtr<FOTBuilder::GlyphSubstTable> &glyphSubstTable() const;
393 private:
394   ConstPtr<FOTBuilder::GlyphSubstTable> table_;
395 };
396
397 class AddressObj : public ELObj {
398 public:
399   void *operator new(size_t, Collector &c) {
400     return c.allocateObject(1);
401   }
402   AddressObj(FOTBuilder::Address::Type,
403              const NodePtr & = NodePtr(),
404              const StringC & = StringC(),
405              const StringC & = StringC(),
406              const StringC & = StringC());
407   AddressObj *asAddress();
408   const FOTBuilder::Address &address() const;
409 private:
410   Owner<FOTBuilder::Address> address_;
411 };
412
413 class NodeListObj : public ELObj {
414 public:
415   NodeListObj *asNodeList();
416   bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
417   virtual NodePtr nodeListFirst(EvalContext &, Interpreter &) = 0;
418   virtual NodeListObj *nodeListRest(EvalContext &, Interpreter &) = 0;
419   virtual NodeListObj *nodeListNoOrder(Collector &);
420   // If this node contains all the node in the chunk of the first node, then
421   // this *may* return the node list containing the nodes following the chunk;
422   // If so chunk, will be set to 1.  Otherwise return nodeListRest() and set
423   // chunk to 0.  If charChunk() returns a string of length n, then
424   // the chunk of the node is the node together with the n - 1 following siblings;
425   // otherwise the chunk of the node is the node itself.
426   virtual NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &chunk);
427   virtual NodePtr nodeListRef(long, EvalContext &, Interpreter &);
428   virtual NodeListObj *nodeListReverse(EvalContext &, Interpreter &);
429   virtual long nodeListLength(EvalContext &, Interpreter &);
430   virtual bool suppressError();
431 };
432
433 class NamedNodeListObj : public NodeListObj {
434 public:
435   NamedNodeListObj *asNamedNodeList();
436   virtual NodePtr namedNode(const Char *, size_t) = 0;
437   virtual bool nodeName(const NodePtr &, GroveString &) = 0;
438   virtual size_t normalize(Char *, size_t) = 0;
439 };
440
441 class NodePtrNodeListObj : public NodeListObj {
442 public:
443   void *operator new(size_t, Collector &c) {
444     return c.allocateObject(1);
445   }
446   NodePtrNodeListObj();
447   NodePtrNodeListObj(const NodePtr &);
448   NodePtr nodeListFirst(EvalContext &, Interpreter &);
449   NodeListObj *nodeListRest(EvalContext &, Interpreter &);
450   bool optSingletonNodeList(EvalContext &, Interpreter &, NodePtr &);
451   bool chunkComplete();
452 private:
453   // Null for no node.
454   NodePtr node_;
455 };
456
457 class NodeListPtrNodeListObj : public NodeListObj {
458 public:
459   void *operator new(size_t, Collector &c) {
460     return c.allocateObject(1);
461   }
462   NodeListPtrNodeListObj(const NodeListPtr &);
463   NodePtr nodeListFirst(EvalContext &, Interpreter &);
464   NodeListObj *nodeListRest(EvalContext &, Interpreter &);
465   NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &);
466   NodePtr nodeListRef(long, EvalContext &, Interpreter &);
467 private:
468   // never null
469   NodeListPtr nodeList_;
470 };
471
472 class NamedNodeListPtrNodeListObj : public NamedNodeListObj {
473 public:
474   void *operator new(size_t, Collector &c) {
475     return c.allocateObject(1);
476   }
477   NamedNodeListPtrNodeListObj(const NamedNodeListPtr &);
478   NodePtr nodeListFirst(EvalContext &, Interpreter &);
479   NodeListObj *nodeListRest(EvalContext &, Interpreter &);
480   NodePtr namedNode(const Char *, size_t);
481   bool nodeName(const NodePtr &, GroveString &);
482   size_t normalize(Char *, size_t);
483   NodeListObj *nodeListNoOrder(Collector &);
484 private:
485   NamedNodeListPtr namedNodeList_;
486   // cached node list, null if not yet computed
487   NodeListPtr nodeList_;
488 };
489
490 class PairNodeListObj : public NodeListObj {
491 public:
492   PairNodeListObj(NodeListObj *, NodeListObj *);
493   NodePtr nodeListFirst(EvalContext &, Interpreter &);
494   NodeListObj *nodeListRest(EvalContext &, Interpreter &);
495   NodeListObj *nodeListChunkRest(EvalContext &, Interpreter &, bool &);
496   void traceSubObjects(Collector &) const;
497 private:
498   NodeListObj *head_; // may be null
499   NodeListObj *tail_;
500 };
501
502 inline
503 bool ELObj::equal(ELObj &obj1, ELObj &obj2)
504 {
505   return &obj1 == &obj2 || obj1.isEqual(obj2);
506 }
507     
508 inline
509 bool ELObj::eqv(ELObj &obj1, ELObj &obj2)
510 {
511   return &obj1 == &obj2 || obj1.isEquiv(obj2);
512 }
513
514 inline
515 ELObj *PairObj::car()
516 {
517   return car_;
518 }
519
520 inline
521 ELObj *PairObj::cdr()
522 {
523   return cdr_;
524 }
525
526 inline
527 void PairObj::setCar(ELObj *car)
528 {
529   car_ = car;
530 }
531
532 inline
533 void PairObj::setCdr(ELObj *cdr)
534 {
535   cdr_ = cdr;
536 }
537
538 inline
539 StringObj *SymbolObj::name() const
540 {
541   return name_;
542 }
543
544 inline
545 FOTBuilder::Symbol SymbolObj::cValue() const
546 {
547   return cValue_;
548 }
549
550 inline
551 void SymbolObj::setCValue(FOTBuilder::Symbol sym)
552 {
553   cValue_ = sym;
554 }
555
556 inline
557 Char CharObj::ch()
558 {
559   return ch_;
560 }
561
562 inline
563 const StringC &SymbolObj::key(const SymbolObj &sym)
564 {
565   return *sym.name();
566 }
567
568 inline
569 const Identifier *KeywordObj::identifier() const
570 {
571   return ident_;
572 }
573
574 inline
575 const FOTBuilder::Address &AddressObj::address() const
576 {
577   return *address_;
578 }
579
580 inline
581 const ConstPtr<FOTBuilder::GlyphSubstTable> &
582 GlyphSubstTableObj::glyphSubstTable() const
583 {
584   return table_;
585 }
586
587 #ifdef DSSSL_NAMESPACE
588 }
589 #endif
590
591 #endif /* not ELObj_INCLUDED */