1 // Copyright (c) 1996 James Clark
2 // See the file copying.txt for copying permission.
7 #include "Interpreter.h"
8 #include "InterpreterMessages.h"
12 #ifdef DSSSL_NAMESPACE
13 namespace DSSSL_NAMESPACE {
16 StyleStack::StyleStack()
21 void StyleStack::pushContinue(StyleObj *style,
22 const ProcessingMode::Rule *rule,
23 const NodePtr &nodePtr,
27 style->appendIter(iter);
29 const VarStyleObj *varStyle;
30 ConstPtr<InheritedC> spec(iter.next(varStyle));
33 size_t ind = spec->index();
34 if (ind >= inheritedCInfo_.size())
35 inheritedCInfo_.resize(ind + 1);
36 Ptr<InheritedCInfo> &info = inheritedCInfo_[ind];
37 if (!info.isNull() && info->valLevel == level_) {
39 ASSERT(info->rule != 0);
40 if (rule->compareSpecificity(*info->rule) == 0) {
41 mgr->setNextLocation(info->rule->location());
42 mgr->message(InterpreterMessages::ambiguousStyle,
43 StringMessageArg(info->spec->identifier()->name()),
50 popList_->list.push_back(ind);
51 info = new InheritedCInfo(spec, varStyle, level_, level_, rule, info);
56 void StyleStack::pushEnd(VM &vm, FOTBuilder &fotb)
58 const PopList *oldPopList = popList_->prev.pointer();
60 for (size_t i = 0; i < oldPopList->dependingList.size(); i++) {
61 size_t d = oldPopList->dependingList[i];
62 // d is the index of a characteristic that depends on the actual
63 // value of another characteritistic
64 if (inheritedCInfo_[d]->valLevel != level_) {
65 const Vector<size_t> &dependencies = inheritedCInfo_[d]->dependencies;
67 for (size_t j = 0; j < dependencies.size(); j++) {
68 const InheritedCInfo *p = inheritedCInfo_[dependencies[j]].pointer();
69 if (p && p->valLevel == level_) {
70 inheritedCInfo_[d] = new InheritedCInfo(inheritedCInfo_[d]->spec,
71 inheritedCInfo_[d]->style,
73 inheritedCInfo_[d]->specLevel,
74 inheritedCInfo_[d]->rule,
76 popList_->list.push_back(d);
81 // If it changed, then doing set() on the new value will add
82 // it to the dependingList for this level.
84 popList_->dependingList.push_back(d);
89 for (size_t i = 0; i < popList_->list.size(); i++) {
90 InheritedCInfo &info = *inheritedCInfo_[popList_->list[i]];
91 vm.specLevel = info.specLevel;
92 info.spec->set(vm, info.style, fotb, info.cachedValue, info.dependencies);
93 if (info.dependencies.size())
94 popList_->dependingList.push_back(popList_->list[i]);
99 void StyleStack::pop()
101 for (size_t i = 0; i < popList_->list.size(); i++) {
102 size_t ind = popList_->list[i];
103 ASSERT(inheritedCInfo_[ind]->valLevel == level_);
104 Ptr<InheritedCInfo> tem(inheritedCInfo_[ind]->prev);
105 inheritedCInfo_[ind] = tem;
108 Ptr<PopList> tem(popList_->prev);
112 ELObj *StyleStack::inherited(const ConstPtr<InheritedC> &ic, unsigned specLevel,
113 Interpreter &interp, Vector<size_t> &dependencies)
115 ASSERT(specLevel != unsigned(-1));
116 size_t ind = ic->index();
117 ConstPtr<InheritedC> spec;
118 const VarStyleObj *style = 0;
119 unsigned newSpecLevel = unsigned(-1);
120 if (ind >= inheritedCInfo_.size())
123 const InheritedCInfo *p = inheritedCInfo_[ind].pointer();
125 if (p->specLevel < specLevel)
127 p = p->prev.pointer();
132 if (p->cachedValue) {
133 // We can only use the cached value if none of the values
134 // we depended on changed since we computed it.
136 for (size_t i = 0; i < p->dependencies.size(); i++) {
137 size_t d = p->dependencies[i];
138 if (d < inheritedCInfo_.size()
139 && inheritedCInfo_[d]->valLevel > p->valLevel) {
145 return p->cachedValue;
149 newSpecLevel = p->specLevel;
153 vm.styleStack = this;
154 vm.specLevel = newSpecLevel;
155 return spec->value(vm, style, dependencies);
158 ELObj *StyleStack::actual(const ConstPtr<InheritedC> &ic, const Location &loc,
159 Interpreter &interp, Vector<size_t> &dependencies)
161 size_t ind = ic->index();
162 for (size_t i = 0; i < dependencies.size(); i++) {
163 if (dependencies[i] == ind) {
164 interp.setNextLocation(loc);
165 interp.message(InterpreterMessages::actualLoop,
166 StringMessageArg(ic->identifier()->name()));
167 return interp.makeError();
170 dependencies.push_back(ind);
171 ConstPtr<InheritedC> spec;
172 const VarStyleObj *style = 0;
173 if (ind >= inheritedCInfo_.size())
176 const InheritedCInfo *p = inheritedCInfo_[ind].pointer();
179 else if (p->cachedValue) {
180 const Vector<size_t> &dep = p->dependencies;
181 for (size_t i = 0; i < dep.size(); i++)
182 dependencies.push_back(dep[i]);
183 return p->cachedValue;
191 vm.styleStack = this;
192 vm.specLevel = level_;
193 return spec->value(vm, style, dependencies);
196 void StyleStack::trace(Collector &c) const
198 for (size_t i = 0; i < inheritedCInfo_.size(); i++) {
199 for (const InheritedCInfo *p = inheritedCInfo_[i].pointer();
201 p = p->prev.pointer()) {
203 c.trace(p->cachedValue);
208 InheritedCInfo::InheritedCInfo(const ConstPtr<InheritedC> &sp,
209 const VarStyleObj *so,
212 const ProcessingMode::Rule *r,
213 const Ptr<InheritedCInfo> &p)
214 : spec(sp), style(so), valLevel(vl), specLevel(sl), rule(r), prev(p), cachedValue(0)
218 StyleObj *StyleObj::asStyle()
223 VarStyleObj::VarStyleObj(const ConstPtr<StyleSpec> &styleSpec, StyleObj *use, ELObj **display,
225 : styleSpec_(styleSpec), use_(use), display_(display), node_(node)
230 VarStyleObj::~VarStyleObj()
235 void VarStyleObj::traceSubObjects(Collector &c) const
239 for (ELObj **pp = display_; *pp; pp++)
243 void VarStyleObj::appendIterForce(StyleObjIter &iter) const
245 if (styleSpec_->forceSpecs.size())
246 iter.append(&styleSpec_->forceSpecs, this);
249 void VarStyleObj::appendIterNormal(StyleObjIter &iter) const
251 if (styleSpec_->specs.size())
252 iter.append(&styleSpec_->specs, this);
254 use_->appendIter(iter);
257 void VarStyleObj::appendIter(StyleObjIter &iter) const
259 VarStyleObj::appendIterForce(iter);
260 VarStyleObj::appendIterNormal(iter);
263 OverriddenStyleObj::OverriddenStyleObj(BasicStyleObj *basic, StyleObj *override)
264 : basic_(basic), override_(override)
269 void OverriddenStyleObj::traceSubObjects(Collector &c) const
275 void OverriddenStyleObj::appendIter(StyleObjIter &iter) const
277 basic_->appendIterForce(iter);
278 override_->appendIter(iter);
279 basic_->appendIterNormal(iter);
282 MergeStyleObj::MergeStyleObj()
287 void MergeStyleObj::append(StyleObj *obj)
289 styles_.push_back(obj);
292 void MergeStyleObj::appendIter(StyleObjIter &iter) const
294 for (size_t i = 0; i < styles_.size(); i++)
295 styles_[i]->appendIter(iter);
298 void MergeStyleObj::traceSubObjects(Collector &c) const
300 for (size_t i = 0; i < styles_.size(); i++)
304 ColorObj *ColorObj::asColor()
309 DeviceRGBColorObj::DeviceRGBColorObj(unsigned char red, unsigned char green,
313 color_.green = green;
317 void DeviceRGBColorObj::set(FOTBuilder &fotb) const
319 fotb.setColor(color_);
322 void DeviceRGBColorObj::setBackground(FOTBuilder &fotb) const
324 fotb.setBackgroundColor(color_);
327 ColorSpaceObj *ColorSpaceObj::asColorSpace()
332 // invert a 3x3 matrix A. result is returned in B
333 // both must be arrays of length 9.
335 invert(double *A, double *B)
337 B[0] = (A[4]*A[8] - A[5]*A[7]);
338 B[3] = - (A[3]*A[8] - A[5]*A[6]);
339 B[6] = (A[3]*A[7] - A[4]*A[6]);
340 B[1] = - (A[1]*A[8] - A[2]*A[7]);
341 B[4] = (A[0]*A[8] - A[2]*A[6]);
342 B[7] = - (A[0]*A[7] - A[1]*A[6]);
343 B[2] = (A[1]*A[5] - A[2]*A[4]);
344 B[5] = - (A[0]*A[5] - A[2]*A[3]);
345 B[8] = (A[0]*A[4] - A[1]*A[3]);
346 double det = A[0]*B[0] + A[1]*B[3] + A[2]*B[6];
350 B[0] /= det; B[1] /= det; B[2] /= det;
351 B[3] /= det; B[4] /= det; B[5] /= det;
352 B[6] /= det; B[7] /= det; B[8] /= det;
356 FIXME make color handling more flexible:
357 * pass different color types to backends
358 * move the conversion code to a separate
359 class ColorConverter, which could then
360 be used by backends to do the needed
362 * make phosphors settable
363 * make highlight color for KX settable
364 * whitepoint correction, making the device
365 whitepoint/blackpoint settable
367 for the formulas used here, see:
368 * Computer Graphics, Principles and Practice, Second Edition,
369 Foley, van Damme, Hughes,
371 * Principles of Color Technology, Second Edition,
372 Fred W. Billmeyer, Jr. and Max Saltzman,
373 John Wiley & Sons, Inc., 1981
376 CIEXYZColorSpaceObj::CIEXYZColorSpaceObj(const double *wp, const double *bp)
378 xyzData_ = new XYZData;
379 for (int i = 0; i < 3; i++)
380 xyzData_->white_[i] = wp[i];
381 double tmp = wp[0] + 15*wp[1] + 3*wp[2];
382 xyzData_->white_u = 4*wp[0]/tmp;
383 xyzData_->white_v = 9*wp[1]/tmp;
385 // from the color faq
386 double xr = .64; double yr = .33;
387 double xg = .30; double yg = .60;
388 double xb = .15; double yb = .06;
390 U[0] = xr; U[1] = xg; U[2] = xb;
391 U[3] = yr; U[4] = yg; U[5] = yb;
392 U[6] = 1.0 - xr - yr; U[7] = 1.0 - xg - yg; U[8] = 1.0 - xb - yb;
396 for (int i = 0; i < 3; i++)
397 C[i] = Uinv[3*i]*wp[0] + Uinv[3*i+1]*wp[1] + Uinv[3*i+2]*wp[2];
399 Minv[0] = U[0]*C[0]; Minv[1] = U[1]*C[1]; Minv[2] = U[2]*C[2];
400 Minv[3] = U[3]*C[0]; Minv[4] = U[4]*C[1]; Minv[5] = U[5]*C[2];
401 Minv[6] = U[6]*C[0]; Minv[7] = U[7]*C[1]; Minv[8] = U[8]*C[2];
402 invert(Minv, xyzData_->M_);
405 CIEXYZColorSpaceObj::~CIEXYZColorSpaceObj()
410 ELObj *CIEXYZColorSpaceObj::makeColor (const double *h, Interpreter &interp)
413 for (int i = 0; i < 3; i++)
414 c[i] = (unsigned char) ((xyzData_->M_[3*i]*h[0]
415 + xyzData_->M_[3*i+1]*h[1]
416 + xyzData_->M_[3*i+2]*h[2])*255.0 + .5);
418 return new (interp) DeviceRGBColorObj(c[0], c[1], c[2]);
421 CIELUVColorSpaceObj::CIELUVColorSpaceObj(const double *wp, const double *bp, const double *r)
422 : CIEXYZColorSpaceObj(wp, bp)
424 luvData_ = new LUVData;
425 for (int i = 0; i < 6; i++)
426 luvData_->range_[i] = r ? r[i] : ((i % 2) ? 1.0 : .0);
429 CIELUVColorSpaceObj::~CIELUVColorSpaceObj()
434 ELObj *CIELUVColorSpaceObj::makeColor(int argc, ELObj **argv,
435 Interpreter &interp, const Location &loc)
438 return new (interp) DeviceRGBColorObj(0, 0, 0);
440 interp.setNextLocation(loc);
441 interp.message(InterpreterMessages::colorArgCount,
442 StringMessageArg(interp.makeStringC("CIE LUV")));
443 return interp.makeError();
446 for (int i = 0; i < 3; i++) {
447 if (!argv[i]->realValue(d[i])) {
448 interp.setNextLocation(loc);
449 interp.message(InterpreterMessages::colorArgType,
450 StringMessageArg(interp.makeStringC("CIE LUV")));
451 return interp.makeError();
453 if (d[i] < luvData_->range_[2*i] || d[i] > luvData_->range_[2*i+1]) {
454 interp.setNextLocation(loc);
455 interp.message(InterpreterMessages::colorArgRange,
456 StringMessageArg(interp.makeStringC("CIE LUV")));
457 return interp.makeError();
463 h[0] = h[1] = h[2] = 0.0;
465 if (d[0] <= 7.996968)
468 h[1] = (d[0] + 16.0) / 116.0;
469 h[1] = h[1] * h[1] * h[1];
471 double uu = d[1] / (13.0 * d[0]) + xyzData_->white_u;
472 double vv = d[2] / (13.0 * d[0]) + xyzData_->white_v;
473 double tmp = 9.0 * h[1] / vv;
474 h[0] = uu * tmp / 4.0;
475 h[2] = (tmp - 15.0 * h[1] - h[0]) / 3.0;
478 return CIEXYZColorSpaceObj::makeColor(h, interp);
481 CIELABColorSpaceObj::CIELABColorSpaceObj(const double *wp, const double *bp, const double *r)
482 : CIEXYZColorSpaceObj(wp, bp)
484 labData_ = new LABData;
486 for (int i = 0; i < 6; i++)
487 labData_->range_[i] = r[i];
489 labData_->range_[0] = .0;
490 labData_->range_[1] = 100.0;
491 labData_->range_[2] = .0;
492 labData_->range_[3] = 1.0;
493 labData_->range_[4] = .0;
494 labData_->range_[5] = 1.0;
498 CIELABColorSpaceObj::~CIELABColorSpaceObj()
503 ELObj *CIELABColorSpaceObj::makeColor(int argc, ELObj **argv,
504 Interpreter &interp, const Location &loc)
507 return new (interp) DeviceRGBColorObj(0, 0, 0);
509 interp.setNextLocation(loc);
510 interp.message(InterpreterMessages::colorArgCount,
511 StringMessageArg(interp.makeStringC("CIE LAB")));
512 return interp.makeError();
515 for (int i = 0; i < 3; i++) {
516 if (!argv[i]->realValue(d[i])) {
517 interp.setNextLocation(loc);
518 interp.message(InterpreterMessages::colorArgType,
519 StringMessageArg(interp.makeStringC("CIE LAB")));
520 return interp.makeError();
522 if (d[i] < labData_->range_[2*i] || d[i] > labData_->range_[2*i+1]) {
523 interp.setNextLocation(loc);
524 interp.message(InterpreterMessages::colorArgRange,
525 StringMessageArg(interp.makeStringC("CIE LAB")));
526 return interp.makeError();
532 double tmp = (d[0] + 16.0) / 116.0;
533 h[1] = tmp * tmp * tmp;
534 if (h[1] < 0.008856) {
535 tmp = d[0] / 9.03292;
536 h[0] = xyzData_->white_[0] * ((d[1] / 3893.5) + tmp);
538 h[2] = xyzData_->white_[2] * (tmp - (d[2] / 1557.4));
540 double tmp2 = tmp + (d[1] / 5.0);
541 h[0] = xyzData_->white_[0] * tmp2 * tmp2 * tmp2;
542 tmp2 = tmp - (d[2] / 2.0);
543 h[2] = xyzData_->white_[2] * tmp2 * tmp2 * tmp2;
546 return CIEXYZColorSpaceObj::makeColor(h, interp);
549 CIEABCColorSpaceObj::CIEABCColorSpaceObj(const double *wp, const double *bp,
550 const double *rabc, FunctionObj **dabc, const double *mabc,
551 const double *rlmn, FunctionObj **dlmn, const double *mlmn)
552 : CIEXYZColorSpaceObj(wp, bp)
554 abcData_ = new ABCData;
556 for (i = 0; i < 6; i++)
557 abcData_->rangeAbc_[i] = rabc ? rabc[i] : ((i % 2) ? 1.0 : 0.0);
558 for (i = 0; i < 3; i++)
559 abcData_->decodeAbc_[i] = dabc ? dabc[i] : 0;
560 for (i = 0; i < 9; i++)
561 abcData_->matrixAbc_[i] = mabc ? mabc[i] : ((i % 4) ? 0.0 : 1.0);
562 for (i = 0; i < 6; i++)
563 abcData_->rangeLmn_[i] = rlmn ? rlmn[i] : ((i % 2) ? 1.0 : 0.0);
564 for (i = 0; i < 3; i++)
565 abcData_->decodeLmn_[i] = dlmn ? dlmn[i] : 0;
566 for (i = 0; i < 9; i++)
567 abcData_->matrixLmn_[i] = mlmn ? mlmn[i] : ((i % 4) ? 0.0 : 1.0);
570 CIEABCColorSpaceObj::~CIEABCColorSpaceObj()
575 void CIEABCColorSpaceObj::traceSubObjects(Collector &c) const
577 for (int i = 0; i < 3; i++)
578 if (abcData_->decodeAbc_[i])
579 c.trace(abcData_->decodeAbc_[i]);
580 for (int i = 0; i < 3; i++)
581 if (abcData_->decodeLmn_[i])
582 c.trace(abcData_->decodeLmn_[i]);
587 bool applyFunc(Interpreter &interp, FunctionObj *f, double &d)
590 insns[1] = f->makeCallInsn(1, interp, Location(), InsnPtr());
591 insns[0] = InsnPtr(new ConstantInsn(new (interp) RealObj(d),insns[1]));
593 ELObj *res = vm.eval(insns[0].pointer());
594 if (!res || !res->realValue(d))
599 ELObj *CIEABCColorSpaceObj::makeColor(int argc, ELObj **argv,
600 Interpreter &interp, const Location &loc)
603 return new (interp) DeviceRGBColorObj(0, 0, 0);
605 interp.setNextLocation(loc);
606 interp.message(InterpreterMessages::colorArgCount,
607 StringMessageArg(interp.makeStringC("CIE Based ABC")));
608 return interp.makeError();
611 for (int i = 0; i < 3; i++) {
612 if (!argv[i]->realValue(d[i])) {
613 interp.setNextLocation(loc);
614 interp.message(InterpreterMessages::colorArgType,
615 StringMessageArg(interp.makeStringC("CIE Based ABC")));
616 return interp.makeError();
618 if (d[i] < abcData_->rangeAbc_[2*i] || d[i] > abcData_->rangeAbc_[2*i+1]) {
619 interp.setNextLocation(loc);
620 interp.message(InterpreterMessages::colorArgRange,
621 StringMessageArg(interp.makeStringC("CIE Based ABC")));
622 return interp.makeError();
624 if (abcData_->decodeAbc_[i] && !applyFunc(interp, abcData_->decodeAbc_[i], d[i])) {
625 interp.setNextLocation(loc);
626 interp.message(InterpreterMessages::colorProcResType,
627 StringMessageArg(interp.makeStringC("CIE Based ABC")));
628 return interp.makeError();
632 for (int i = 0; i < 3; i++) {
633 l[i] = abcData_->matrixAbc_[i]*d[0]
634 + abcData_->matrixAbc_[3+i]*d[1]
635 + abcData_->matrixAbc_[6+i]*d[2];
636 if (l[i] < abcData_->rangeLmn_[2*i] || l[i] > abcData_->rangeLmn_[2*i+1]) {
637 interp.setNextLocation(loc);
638 interp.message(InterpreterMessages::colorArgRange,
639 StringMessageArg(interp.makeStringC("CIE Based ABC")));
640 return interp.makeError();
642 if (abcData_->decodeLmn_[i] && !applyFunc(interp, abcData_->decodeLmn_[i], l[i])) {
643 interp.setNextLocation(loc);
644 interp.message(InterpreterMessages::colorProcResType,
645 StringMessageArg(interp.makeStringC("CIE Based ABC")));
646 return interp.makeError();
650 for (int i = 0; i < 3; i++)
651 h[i] = abcData_->matrixLmn_[i]*l[0]
652 + abcData_->matrixLmn_[3+i]*l[1]
653 + abcData_->matrixLmn_[6+i]*l[2];
655 return CIEXYZColorSpaceObj::makeColor(h, interp);
658 CIEAColorSpaceObj::CIEAColorSpaceObj(const double *wp, const double *bp,
659 const double *ra, FunctionObj *da, const double *ma,
660 const double *rlmn, FunctionObj **dlmn, const double *mlmn)
661 : CIEXYZColorSpaceObj(wp, bp)
665 for (i = 0; i < 2; i++)
666 aData_->rangeA_[i] = ra ? ra[i] : ((i % 2) ? 1.0 : 0.0);
667 aData_->decodeA_ = da ? da : 0;
668 for (i = 0; i < 3; i++)
669 aData_->matrixA_[i] = ma ? ma[i] : 1.0;
670 for (i = 0; i < 6; i++)
671 aData_->rangeLmn_[i] = rlmn ? rlmn[i] : ((i % 2) ? 1.0 : 0.0);
672 for (i = 0; i < 3; i++)
673 aData_->decodeLmn_[i] = dlmn ? dlmn[i] : 0;
674 for (i = 0; i < 9; i++)
675 aData_->matrixLmn_[i] = mlmn ? mlmn[i] : ((i % 4) ? 0.0 : 1.0);
678 CIEAColorSpaceObj::~CIEAColorSpaceObj()
683 void CIEAColorSpaceObj::traceSubObjects(Collector &c) const
685 if (aData_->decodeA_)
686 c.trace(aData_->decodeA_);
687 for (int i = 0; i < 3; i++)
688 if (aData_->decodeLmn_[i])
689 c.trace(aData_->decodeLmn_[i]);
692 ELObj *CIEAColorSpaceObj::makeColor(int argc, ELObj **argv,
693 Interpreter &interp, const Location &loc)
696 return new (interp) DeviceRGBColorObj(0, 0, 0);
698 interp.setNextLocation(loc);
699 interp.message(InterpreterMessages::colorArgCount,
700 StringMessageArg(interp.makeStringC("CIE Based A")));
701 return interp.makeError();
704 if (!argv[0]->realValue(d)) {
705 interp.setNextLocation(loc);
706 interp.message(InterpreterMessages::colorArgType,
707 StringMessageArg(interp.makeStringC("CIE Based A")));
708 return interp.makeError();
710 if (d < aData_->rangeA_[0] || d > aData_->rangeA_[1]) {
711 interp.setNextLocation(loc);
712 interp.message(InterpreterMessages::colorArgRange,
713 StringMessageArg(interp.makeStringC("CIE Based A")));
714 return interp.makeError();
716 if (aData_->decodeA_ && !applyFunc(interp, aData_->decodeA_, d)) {
717 interp.setNextLocation(loc);
718 interp.message(InterpreterMessages::colorProcResType,
719 StringMessageArg(interp.makeStringC("CIE Based A")));
720 return interp.makeError();
723 for (int i = 0; i < 3; i++) {
724 l[i] = aData_->matrixA_[i]*d;
725 if (l[i] < aData_->rangeLmn_[2*i] || l[i] > aData_->rangeLmn_[2*i+1]) {
726 interp.setNextLocation(loc);
727 interp.message(InterpreterMessages::colorArgRange,
728 StringMessageArg(interp.makeStringC("CIE Based A")));
729 return interp.makeError();
731 if (aData_->decodeLmn_[i] && !applyFunc(interp, aData_->decodeLmn_[i], l[i])) {
732 interp.setNextLocation(loc);
733 interp.message(InterpreterMessages::colorProcResType,
734 StringMessageArg(interp.makeStringC("CIE Based A")));
735 return interp.makeError();
739 for (int i = 0; i < 3; i++) {
740 h[i] = aData_->matrixLmn_[i]*l[0]
741 + aData_->matrixLmn_[3+i]*l[1]
742 + aData_->matrixLmn_[6+i]*l[2];
744 return CIEXYZColorSpaceObj::makeColor(h, interp);
747 ELObj *DeviceRGBColorSpaceObj::makeColor(int argc, ELObj **argv,
748 Interpreter &interp, const Location &loc)
751 return new (interp) DeviceRGBColorObj(0, 0, 0);
753 interp.setNextLocation(loc);
754 interp.message(InterpreterMessages::colorArgCount,
755 StringMessageArg(interp.makeStringC("Device RGB")));
756 return interp.makeError();
759 for (int i = 0; i < 3; i++) {
761 if (!argv[i]->realValue(d)) {
762 interp.setNextLocation(loc);
763 interp.message(InterpreterMessages::colorArgType,
764 StringMessageArg(interp.makeStringC("Device RGB")));
765 return interp.makeError();
767 if (d < 0.0 || d > 1.0) {
768 interp.setNextLocation(loc);
769 interp.message(InterpreterMessages::colorArgRange,
770 StringMessageArg(interp.makeStringC("Device RGB")));
771 return interp.makeError();
773 c[i] = (unsigned char)(d*255.0 + .5);
775 return new (interp) DeviceRGBColorObj(c[0], c[1], c[2]);
778 ELObj *DeviceGrayColorSpaceObj::makeColor(int argc, ELObj **argv,
779 Interpreter &interp, const Location &loc)
782 return new (interp) DeviceRGBColorObj(0, 0, 0);
784 interp.setNextLocation(loc);
785 interp.message(InterpreterMessages::colorArgCount,
786 StringMessageArg(interp.makeStringC("Device Gray")));
787 return interp.makeError();
791 if (!argv[0]->realValue(d)) {
792 interp.setNextLocation(loc);
793 interp.message(InterpreterMessages::colorArgType,
794 StringMessageArg(interp.makeStringC("Device Gray")));
795 return interp.makeError();
797 if (d < 0.0 || d > 1.0) {
798 interp.setNextLocation(loc);
799 interp.message(InterpreterMessages::colorArgRange,
800 StringMessageArg(interp.makeStringC("Device Gray")));
801 return interp.makeError();
803 c = (unsigned char)(d*255.0 + .5);
804 return new (interp) DeviceRGBColorObj(c, c, c);
807 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
809 ELObj *DeviceCMYKColorSpaceObj::makeColor(int argc, ELObj **argv,
810 Interpreter &interp, const Location &loc)
813 return new (interp) DeviceRGBColorObj(0, 0, 0);
815 interp.setNextLocation(loc);
816 interp.message(InterpreterMessages::colorArgCount,
817 StringMessageArg(interp.makeStringC("Device CMYK")));
818 return interp.makeError();
821 for (int i = 0; i < 4; i++) {
822 if (!argv[i]->realValue(d[i])) {
823 interp.setNextLocation(loc);
824 interp.message(InterpreterMessages::colorArgType,
825 StringMessageArg(interp.makeStringC("Device CMYK")));
826 return interp.makeError();
828 if (d[i] < 0.0 || d[i] > 1.0) {
829 interp.setNextLocation(loc);
830 interp.message(InterpreterMessages::colorArgRange,
831 StringMessageArg(interp.makeStringC("Device CMYK")));
832 return interp.makeError();
836 for (int i = 0; i < 3; i++)
837 c[i] = (unsigned char)((1 - MIN(1, d[i] + d[3]))*255.0 + .5);
838 return new (interp) DeviceRGBColorObj(c[0], c[1], c[2]);
841 ELObj *DeviceKXColorSpaceObj::makeColor(int argc, ELObj **argv,
842 Interpreter &interp, const Location &loc)
845 return new (interp) DeviceRGBColorObj(0, 0, 0);
847 interp.setNextLocation(loc);
848 interp.message(InterpreterMessages::colorArgCount,
849 StringMessageArg(interp.makeStringC("Device KX")));
850 return interp.makeError();
853 for (int i = 0; i < 2; i++) {
854 if (!argv[i]->realValue(d[i])) {
855 interp.setNextLocation(loc);
856 interp.message(InterpreterMessages::colorArgType,
857 StringMessageArg(interp.makeStringC("Device KX")));
858 return interp.makeError();
860 if (d[i] < 0.0 || d[i] > 1.0) {
861 interp.setNextLocation(loc);
862 interp.message(InterpreterMessages::colorArgRange,
863 StringMessageArg(interp.makeStringC("Device KX")));
864 return interp.makeError();
868 c = (unsigned char)((1 - MIN(1, d[0] + d[1]))*255.0 + .5);
869 return new (interp) DeviceRGBColorObj(c, c, c);
872 VarInheritedC::VarInheritedC(const ConstPtr<InheritedC> &ic,
873 const InsnPtr &code, const Location &loc)
874 : InheritedC(ic->identifier(), ic->index()), inheritedC_(ic), code_(code), loc_(loc)
878 void VarInheritedC::set(VM &vm, const VarStyleObj *style, FOTBuilder &fotb,
879 ELObj *&cacheObj, Vector<size_t> &dependencies) const
882 EvalContext::CurrentNodeSetter cns(style->node(), 0, vm);
883 vm.actualDependencies = &dependencies;
884 cacheObj = vm.eval(code_.pointer(), style->display());
885 ASSERT(cacheObj != 0);
886 vm.actualDependencies = 0;
888 if (!vm.interp->isError(cacheObj)) {
889 ConstPtr<InheritedC> c(inheritedC_->make(cacheObj, loc_, *vm.interp));
891 c->set(vm, 0, fotb, cacheObj, dependencies);
895 ConstPtr<InheritedC> VarInheritedC::make(ELObj *obj, const Location &loc, Interpreter &interp)
898 return inheritedC_->make(obj, loc, interp);
901 ELObj *VarInheritedC::value(VM &vm, const VarStyleObj *style,
902 Vector<size_t> &dependencies) const
904 EvalContext::CurrentNodeSetter cns(style->node(), 0, vm);
905 vm.actualDependencies = &dependencies;
906 return vm.eval(code_.pointer(), style->display());
909 StyleObjIter::StyleObjIter()
914 void StyleObjIter::append(const Vector<ConstPtr<InheritedC> > *v, const VarStyleObj *obj)
916 styleVec_.push_back(obj);
920 ConstPtr<InheritedC> StyleObjIter::next(const VarStyleObj *&style)
922 for (; vi_ < vecs_.size(); vi_++, i_ = 0) {
923 if (i_ < vecs_[vi_]->size()) {
924 style = styleVec_[vi_];
925 return (*vecs_[vi_])[i_++];
928 return ConstPtr<InheritedC>();
931 StyleSpec::StyleSpec(Vector<ConstPtr<InheritedC> > &fs, Vector<ConstPtr<InheritedC> > &s)
937 #ifdef DSSSL_NAMESPACE