/***** * drawfill.cc * Andy Hammerlindl 2002/06/06 * * Stores a cyclic path that will outline a filled shape in a picture. *****/ #include "drawfill.h" namespace camp { void drawAxialShade::palette(psfile *out) { pentype.convert(); penb.convert(); colorspace=(ColorSpace) max(pentype.colorspace(),penb.colorspace()); switch(colorspace) { case RGB: { if (pentype.grayscale()) pentype.greytorgb(); else if (penb.grayscale()) penb.greytorgb(); break; } case CMYK: { if (pentype.grayscale()) pentype.greytocmyk(); else if (penb.grayscale()) penb.greytocmyk(); if (pentype.rgb()) pentype.rgbtocmyk(); else if (penb.rgb()) penb.rgbtocmyk(); break; } default: break; } out->gsave(); } bool drawFill::draw(psfile *out) { if(pentype.invisible() || empty()) return true; palette(out); writepath(out); fill(out); return true; } drawElement *drawFill::transformed(const transform& t) { return new drawFill(transpath(t),stroke,transpen(t)); } drawElement *drawLatticeShade::transformed(const transform& t) { return new drawLatticeShade(transpath(t),stroke,pentype,pens,t*T); } drawElement *drawAxialShade::transformed(const transform& t) { pair A=t*a, B=t*b; return new drawAxialShade(transpath(t),stroke,pentype,A,penb,B); } drawElement *drawRadialShade::transformed(const transform& t) { pair A=t*a, B=t*b; double RA=length(t*(a+ra)-A); double RB=length(t*(b+rb)-B); return new drawRadialShade(transpath(t),stroke,pentype,A,RA,penb,B,RB); } drawElement *drawGouraudShade::transformed(const transform& t) { size_t size=vertices.size(); vm::array *Vertices=new vm::array(size); for(size_t i=0; i < size; i++) (*Vertices)[i]=t*vm::read(vertices,i); return new drawGouraudShade(transpath(t),stroke,pentype,pens,*Vertices,edges); } drawElement *drawTensorShade::transformed(const transform& t) { size_t size=boundaries.size(); size_t zsize=z.size(); vm::array *Boundaries=new vm::array(size); vm::array *Z=new vm::array(zsize); for(size_t i=0; i < size; i++) (*Boundaries)[i]=vm::read(boundaries,i).transformed(t); for(size_t i=0; i < zsize; i++) { vm::array *zi=vm::read(z,i); size_t zisize=checkArray(zi); vm::array *Zi=new vm::array(zisize); (*Z)[i]=Zi; for(size_t j=0; j < zisize; j++) (*Zi)[j]=t*vm::read(zi,j); } return new drawTensorShade(transpath(t),stroke,pentype,pens,*Boundaries,*Z); } bool drawFunctionShade::write(texfile *out, const bbox& box) { if(empty()) return true; ColorSpace colorspace=pentype.colorspace(); size_t ncomponents=ColorComponents[colorspace]; out->verbatim("\\pdfobj stream attr {/FunctionType 4"); out->verbatim("/Domain [0 1 0 1]"); out->verbatim("/Range ["); for(size_t i=0; i < ncomponents; ++i) out->verbatim("0 1 "); out->verbatim("]}{{"); out->verbatimline(shader); out->verbatimline("}}%"); out->verbatimline("\\edef\\lastobj{\\the\\pdflastobj}\\pdfrefobj\\lastobj"); out->verbatim("\\setbox\\ASYbox=\\hbox to "); double Hoffset=out->hoffset(); double hoffset=(bpath.Max().getx()-Hoffset)*ps2tex; out->write(hoffset); out->verbatim("pt {"); out->verbatim("\\vbox to "); out->write((box.top-box.bottom)*ps2tex); out->verbatimline("pt {\\vfil%"); out->gsave(); out->beginspecial(); out->beginraw(); writeshiftedpath(out); if(stroke) strokepath(out); out->endclip(pentype); out->verbatimline("/Sh sh"); out->endraw(); out->endspecial(); out->grestore(); out->verbatimline("}\\hfil}%"); out->verbatimline("\\pdfxform resources {"); out->verbatimline("/Shading << /Sh << /ShadingType 1"); out->verbatim("/Matrix ["); out->write(shift(pair(-Hoffset,-box.bottom))*matrix(bpath.Min(),bpath.Max())); out->verbatimline("]"); out->verbatim("/Domain [0 1 0 1]"); out->verbatim("/ColorSpace /Device"); out->verbatimline(ColorDeviceSuffix[colorspace]); out->verbatimline("/Function \\lastobj\\space 0 R >> >>}\\ASYbox"); out->verbatimline("\\pdfrefxform\\the\\pdflastxform"); out->verbatim("\\kern"); out->write(-hoffset); out->verbatimline("pt%"); return true; } drawElement *drawFunctionShade::transformed(const transform& t) { return new drawFunctionShade(transpath(t),stroke,pentype,shader); } } // namespace camp