Logo Search packages:      
Sourcecode: sam2p version File versions

void Rule::writeTTE ( GenBuffer::Writable out,
GenBuffer::Writable outpal,
GenBuffer::Writable outstream,
char const *  template_,
Rule::OutputRule *  or_,
Image::SampledInfo *  sf,
stream_writer_t  stream_writer,
char const *const *  strings = (char**)NULLP 
) [static]

Writes a PS/PDF file to `out' according to `template_': substitutes actual image (pixel) data from `sf->getImg()', and substitutes image metadata from `sf'. `outstream' should be a prepared stream (top of chain of Encode filters). See a .tte file for an example template.

Definition at line 771 of file rule.cpp.

References Image::Sampled::cs2devcs(), Image::Sampled::getBpc(), Image::Sampled::getCpp(), Image::Sampled::getCs(), Image::Sampled::getHeadp(), Image::Sampled::getHt(), Image::Sampled::getRlen(), Image::Sampled::getRowbeg(), Image::Sampled::getTy(), Image::Sampled::getWd(), Error::sev(), Image::Sampled::TY_INDEXED, and GenBuffer::Writable::vi_write().

Referenced by writeTTM(), and writeTTT().

                                                                                                                          {
  unsigned int i, j;
  register char const*p;
  char *r;
  Image::Sampled *img=sf->getImg();
  param_assert(template_!=(const char*)NULLP);
  p=template_;
  bool nzp, scp;
  SimBuffer::B scf;
  while (1) {  
    assert(template_==p);
    while (*p!='`' && *p!='\0') p++; /* '`' is the escape character */
    if (p!=template_) out.vi_write(template_, p-template_);
    if (*p++=='\0') break;
    switch (*p++) {
     case '\0':
      p--; /* fall through */
     case '`':
      out.vi_write("`", 1); break;
     case '#': /* number of non-transparent colors of /Indexed*, /Transparent* */
      out << sf->getNncols(); break;
     case 'p': /* 3*(number of non-transparent colors of /Indexed*, /Transparent*) */
      out << (3*sf->getNncols()); break;
     case 'P': /* number of palette bytes (including the transparent color) */
      out << img->getRowbeg()-img->getHeadp(); break;
     case '0': case '1': case '2': /* arbitrary, user-defined string */
      param_assert(strings!=(char const*const*)NULLP);
      out << strings[p[-1]-'0']; break;
     case 'C': /* PDF /Procset entries */
      if (or_->cache.isIndexed()) out << "/ImageI";
      else if (or_->cache.isGray()) out << "/ImageB";
      else out << "/ImageC"; /* SF_Rgb*, SF_Asis etc. */
      break;
     case 'i': /* PS image or colorimage operator */
      out << (or_->cache.isGray() ? "image"
            : or_->cache.SampleFormat==Image::SF_Mask || or_->cache.SampleFormat==Image::SF_Indexed1 ? "imagemask"
            : "false 3 colorimage");
      break;
     case 'I': /* PS warning for usage of colorimage operator */
       // if (!or_->cache.isGray()) out << "% PSLC required\n";
       if (!or_->cache.isGray() && !or_->cache.isTransparentM()) out << "%%Extensions: CMYK\n";
       break;
#if 0
     case "p:invalid": /* optional predictor specification */
      { unsigned char pred=or_->cache.Predictor;
             if (pred== 2) out << "/Predictor 2";  /* TIFF predictor */
        else if (pred>=10) out << "/Predictor 10"; /* any PNG predictor */
      }
#endif
     case 'w': /* image width, decimal */
      out << img->getWd();
      break;
     case 'h': /* image height, decimal */
      out << img->getHt();
      break;
     case '?': /* a divisor of rlen*height near 4096 */
      if (sf->getImgs()!=NULLP) { /* /Transparent+ */
        out << near_div(sf->getImgs()[0]->getRlen(), img->getHt());
        /* Dat: `img->getHt()*sf->getNncols()' would be wrong */
      } else {
        out << near_div(img->getRlen(), img->getHt());
      }
      break;
     case 'B': /* Clean7Bits or Binary; Sun Jun 23 18:55:35 CEST 2002 */
      out << (or_->cache.isPDF() ? (or_->cache.isBinSB() ? "%\307\354\217\242\n" : "")
                                 : (or_->cache.isBinSB() ? "Binary" : "Clean7Bit"));
      break;
     case 'b': /* image bpc, decimal */
      /* added "true"|"false" for sam2p-0.39 at Sun Sep 22 17:49:25 CEST 2002 */
      if (or_->cache.SampleFormat==Image::SF_Mask) out << "false";
      else if (or_->cache.SampleFormat==Image::SF_Indexed1) out << "true";
      else out << (unsigned)img->getBpc();
      break;
     case 'c': /* image cpp, decimal */
      out << (unsigned)img->getCpp();
      break;
     case 'd': /* device-specific color-space name */
      out << Image::Sampled::cs2devcs(img->getCs());
      break;
     case 't': /* closefile specification in PostScript */
      if (or_->cache.Compression!=or_->cache.CO_None) out << " F closefile";
      if (or_->cache.TransferEncoding!=or_->cache.TE_Binary) out << " T closefile";
      break;
     case 'T': /* TransferEncoding specification in PostScript */
      or_->appendTransferSpec(out);
      break;
     case 'F': /* decoding filter specification in PostScript */
      or_->appendDecoderSpec(out);
      break;
     case 'O': /* 0..1 /Decode values */
      i=1;
      emit_Decode:
      j=img->getCpp(); 
      out << "0 " << i;
      while (j--!=1) out << " 0 " << i;
      break;
     case 'D': /* 0..1 /Decode values for indexed, 0..max-1 for others */
      i=(or_->cache.isIndexed())?(1<<img->getBpc())-1:1;
      goto emit_Decode;
     case 'S': /* image data stream */
      stream_writer(outpal, outstream, sf);
      break;
     case 'g': /* PDF 0..1 RGB triplet of the 0th palette color */
      assert(img->getTy()==img->TY_INDEXED);
      r=img->getHeadp();
      goto appG;
     case 'G': /* PDF 0..1 RGB triplet of the 1st palette color */
      assert(img->getTy()==img->TY_INDEXED);
      r=img->getHeadp()+3;
     appG:
      div255(out, (unsigned char)r[0]); out << ' ';
      div255(out, (unsigned char)r[1]); out << ' ';
      div255(out, (unsigned char)r[2]);
      break;
     case 'r': /* PS 0..1 RGB triplet of the 0th palette color */
      assert(img->getTy()==img->TY_INDEXED);
      r=img->getHeadp();
      out << (unsigned)(unsigned char)r[0] << " 255 div "
          << (unsigned)(unsigned char)r[1] << " 255 div "
          << (unsigned)(unsigned char)r[2] << " 255 div";
      break;
     case 'R': /* PS code for setting up bg and fg colors for an imagemask */
      /* formerly: PS 0..1 RGB triplet of the 1st palette color */
      /* changed at Sun Sep 22 18:02:41 CEST 2002 */
      if (or_->cache.SampleFormat==Image::SF_Mask || or_->cache.SampleFormat==Image::SF_Indexed1) {
        assert(img->getTy()==img->TY_INDEXED);
        r=img->getHeadp();
        out << (unsigned)(unsigned char)r[0] << " 255 div " /* 0th palette color */
            << (unsigned)(unsigned char)r[1] << " 255 div "
            << (unsigned)(unsigned char)r[2] << " 255 div setrgbcolor\n";
        if (or_->cache.SampleFormat==Image::SF_Indexed1) {
          out << "0 0 moveto\n"
              << img->getWd() << " 0 lineto\n0 "
              << img->getHt() << " rlineto\n-"
              << img->getWd() << " 0 rlineto\nclosepath fill\n"
              << (unsigned)(unsigned char)r[3] << " 255 div " /* 1st palette color */
              << (unsigned)(unsigned char)r[4] << " 255 div "
              << (unsigned)(unsigned char)r[5] << " 255 div\nsetrgbcolor\n";
        }
      }
      break;
     case 'E': /* EPS header for unscaled PS files */
      if (or_->cacheHints.Scale==or_->cacheHints.SC_None) out << " EPSF-3.0";
      break;
     case 'X': /* BoundingBox for EPS, MediaBox for PDF */
      if (or_->cache.isPDF()) {
        // out << "0 0 ";
        out << "0 ";
        goto do_bbox;
      } else if (or_->cacheHints.Scale==or_->cacheHints.SC_None) {
        /* It is no point to start the BoundingBox of EPS files at
         * (LeftMargin,BottomMargin). The effect would be the same as
         * specifying no margins at all.  Our choice is better: the
         * BoundingBox contains the image and the margins too.
         */
        // out << "%%BoundingBox: 0 0 ";
        out << "%%BoundingBox: 0 ";
       do_bbox:
        // out << MiniPS::RVALUE(or_->cacheHints.LowerMargin) << ';'; /* SUXX: this would put `1 72 mul' */
        // out << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << ';'; /* SUXX: this would put `1 72 mul' */
        MiniPS::dumpAdd3(out, MiniPS::Qinteger(0), MiniPS::Qinteger(0), MiniPS::Qinteger(0), or_->cacheHints.LowerMargin, or_->cacheHints.BottomMargin, 1);
        out << ' ';
        MiniPS::dumpAdd3(out, or_->cacheHints.ImageDPI, MiniPS::Qinteger(img->getWd()),
          or_->cacheHints.LeftMargin, or_->cacheHints.RightMargin, MiniPS::Qinteger(0), 2);
        out << ' ';
        MiniPS::dumpAdd3(out, or_->cacheHints.ImageDPI, MiniPS::Qinteger(img->getHt()),
          or_->cacheHints.TopMargin, or_->cacheHints.LowerMargin, MiniPS::Qinteger(0), 2);
        if (!or_->cache.isPDF()) out << '\n';
      }
      break;
     case 's': /* scaling to a full PostScript page or translation for PDF and EPS */
      nzp=!(MiniPS::isZero(or_->cacheHints.LowerMargin)
         && MiniPS::isZero(or_->cacheHints.TopMargin));
      scp=!MiniPS::isEq(or_->cacheHints.ImageDPI, 72);
      
      if (or_->cache.isPDF()) {
        SimBuffer::B scf;
        if (scp) MiniPS::dumpScale(scf, or_->cacheHints.ImageDPI);
            else scf << 'x';
        if (nzp || scp) out << " " << scf << " 0 0 " << scf << " " << MiniPS::RVALUE(or_->cacheHints.LeftMargin)
                            << ' ' << MiniPS::RVALUE(or_->cacheHints.LowerMargin)
                     << " cm"; /* translate */
      } else switch (or_->cacheHints.Scale) {
       case Rule::CacheHints::SC_None:
        if (nzp) out << '\n' << MiniPS::RVALUE(or_->cacheHints.LeftMargin)
                     << ' '  << MiniPS::RVALUE(or_->cacheHints.LowerMargin)
                     << " translate";
        if (scp) {
          MiniPS::dumpScale(scf, or_->cacheHints.ImageDPI);
          out << '\n' << scf << " dup scale";
        }
        break;
       case Rule::CacheHints::SC_OK:
        /* from pshack/big.ps */
        out <<"\n6 dict begin currentpagedevice/PageSize get dup 0 get\n " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.RightMargin) << " sub/w exch\n"
               " def 1 get " << MiniPS::RVALUE(or_->cacheHints.TopMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " sub/h exch\n"
               " def/x " << img->getWd() << " def/y " << img->getHt() <<  " def " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " translate x h\n"
               " mul y w mul gt{w x 0 h y w mul x div sub 2 div}{h y w x h mul y div sub 2 div\n"
               " 0}ifelse translate div dup scale\nend";
        break;
       case Rule::CacheHints::SC_RotateOK:
        /* from pshack/big.ps */
        out <<"\n6 dict begin currentpagedevice/PageSize get dup 0 get\n " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.RightMargin) << " sub/w exch\n"
               " def 1 get " << MiniPS::RVALUE(or_->cacheHints.TopMargin) << " sub " << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << " sub/h exch\n"
               " def/x " << img->getWd() << " def/y " << img->getHt() <<  " def " << MiniPS::RVALUE(or_->cacheHints.LeftMargin) << ' ' << MiniPS::RVALUE(or_->cacheHints.BottomMargin) << "/b y h mul x\n"
               " w mul gt def b{w y}{h x}ifelse div/c x h mul y w mul gt def c{w x}{h y}ifelse\n"
               " div gt{h add translate -90 rotate b{w y h x w mul y div sub 2 div 0}{h\n"
               " x 0 w y h mul x div sub 2 div}}{translate c{w x 0 h y w mul x div sub 2 div}{h\n"
               " y w x h mul y div sub 2 div 0}}ifelse ifelse translate div dup scale\nend";
        break;
      }
      break;
     default:
      Error::sev(Error::EERROR) << "writeTTE: unknown escape: " << (char)p[-1] << (Error*)0;
    }
    template_=p;
  }
}


Generated by  Doxygen 1.6.0   Back to index