Ejemplo n.º 1
0
String CSSSupportsRule::cssText() const
{
    StringBuilder result;

    result.appendLiteral("@supports ");
    result.append(conditionText());
    result.appendLiteral(" {\n");
    appendCSSTextForItems(result);
    result.append('}');

    return result.toString();
}
Ejemplo n.º 2
0
bool SVGFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
{
  OBMol* pmol = dynamic_cast<OBMol*>(pOb);
  if(!pmol)
    return false;
  ostream &ofs = *pConv->GetOutStream();

  //Check for option for single mol in fixed size image
  const char* fixedpx = pConv->IsOption("P");
  if(!fixedpx)
    fixedpx= pConv->IsOption("px", OBConversion::GENOPTIONS);
  //If WriteMolecule called directly, e.g. from OBConversion::Write()
  //the default mode is a fixed image size of 200px square
  if(!fixedpx && !pConv->IsOption("svgwritechemobject"))
    fixedpx = "200";
  if(fixedpx)
  {
    _nmax = _nrows = _ncols = 1;
    pConv->AddOption("j");
    pConv->SetLast(true);
    pConv->SetOutputIndex(1);
  }

  //*** Coordinate generation ***
  //Generate coordinates only if no existing 2D coordinates
  if( (pConv->IsOption("y") || !pmol->Has2D(true)) && !pConv->IsOption("n") )
  {
    OBOp* pOp = OBOp::FindType("gen2D");
    if(!pOp)
    {
      obErrorLog.ThrowError("SVGFormat", "gen2D not found", obError, onceOnly);
      return false;
    }
    if(!pOp->Do(pmol))
    {
      obErrorLog.ThrowError("SVGFormat", string(pmol->GetTitle()) + "- Coordinate generation unsuccessful", obError);
      return false;
    }
  }
  if(!pmol->Has2D() && pmol->NumAtoms()>1)//allows 3D coordinates (if passed by -xn above)
  {
    string mes("Molecule ");
    mes += pmol->GetTitle();
    mes += " needs 2D coordinates to display in SVGformat";
    obErrorLog.ThrowError("SVGFormat", mes, obError);
    return false;
  }
  
  bool hasTable = (_nrows || _ncols);

  bool transparent=false;
  string background, bondcolor;
  const char* bg = pConv->IsOption("b");
  background = bg ? "black" : "white";
  bondcolor  = bg ? "white" : "black";
  if(bg && (!strcmp(bg, "none") || bg[0]=='0'))
  {
    transparent = true;
    bondcolor = "gray";
  }
  const char* bcol = pConv->IsOption("B");
  if(bcol && *bcol)
    bondcolor = bcol;
  if(bg && *bg)
    background = bg;
  
  if(pConv->GetOutputIndex()==1 || fixedpx)
  {
    //For the first molecule...
    if(hasTable)
    {
      //multiple molecules - use a table
      //Outer svg has viewbox for 0 0 100 100 or adjusted for table shape,
      //and no width or height - it uses the whole of its containing element.
      //Inner svg with width, height, x, y of table cell,
      //and viewbox to match molecule min and max x and y
      if(!pConv->IsOption("x"))
        ofs << "<?xml version=\"1.0\"?>\n";

      ofs << "<svg version=\"1.1\" id=\"topsvg\"\n"
             "xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
             "xmlns:cml=\"http://www.xml-cml.org/schema\" ";

      //*** Outer viewbox ***
      double vbwidth=100, vbheight=100;
      if (_nrows>_ncols)
        vbwidth = (100*_ncols)/_nrows;
      else if(_ncols>_nrows)
        vbheight = (100*_nrows)/_ncols;

      if(fixedpx)//fixed size image
        ofs << "x=\"0\" y=\"0\" width=\"" << fixedpx << "px\" height=\"" << fixedpx <<"px\" ";
      else
        ofs << "x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ";
      
      ofs << "viewBox=\"0 0 " << vbwidth << ' ' << vbheight << "\">\n";

      ofs << "<title>OBDepict</title>\n";
      // Draw the background unless transparent
      if(!transparent)
        ofs << "<rect x=\"0\" y=\"0\" width=\"" << vbwidth << "\" height=\"" << vbheight
            << "\" fill=\"" << background << "\"/>\n";
    }
  }

  //All mols
  double cellsize;
  if(hasTable)
  {
    //*** Parameter for inner svg ***
    int nc = _ncols ? _ncols : 1;
    int nr = (_nrows ? _nrows : 1);
    cellsize = 100. / std::max(nc, nr);
    int indx = pConv->GetOutputIndex() - 1;
    double innerX  = (indx % nc) * cellsize;
    double innerY  = (indx / nc) * cellsize;

    // Change the background in this cell if the condition in the first
    // parameter of  the -xh option is met. Use a default color if
    // the highlight color is not specified in the second parameter.
    const char* htxt = pConv->IsOption("h");
    if(htxt)
    {
      vector<string> vec;
      tokenize(vec, htxt);
      string highlight(vec.size()>1 ? vec[1] : "#f4f0ff");
      std::istringstream conditionText(vec[0]);
      if(OBDescriptor::FilterCompare(pOb, conditionText, false))
        //Still in outer <svg>, unfortunately
        ofs << "<rect x=\"" << innerX << "\" y=\"" << innerY
            << "\" width=\"" << cellsize << "\" height=\"" << cellsize
            << "\" fill=\"" << highlight << "\"/>\n";
    }

    //*** Write molecule name ***
    if(!pConv->IsOption("d"))
      ofs << "<text text-anchor=\"middle\" font-size=\"" << 0.06*cellsize << "\""
      << " fill =\"" << bondcolor << "\" font-family=\"sans-serif\"\n"
      << "x=\"" << innerX + cellsize * 0.5 << "\" y=\"" << innerY + cellsize - 2.0/nr << "\" >"
      << pmol->GetTitle() << "</text>\n";

    SVGPainter painter(*pConv->GetOutStream(), true, cellsize,cellsize,innerX,innerY);
    OBDepict depictor(&painter);

    if(!pConv->IsOption("C"))
      depictor.SetOption(OBDepict::drawTermC);// on by default
    if(pConv->IsOption("a"))
      depictor.SetOption(OBDepict::drawAllC);

    if(pConv->IsOption("A"))
    {
      AliasData::RevertToAliasForm(*pmol);
      depictor.SetAliasMode();
    }
    painter.SetFontFamily("sans-serif");
    painter.SetPenColor(OBColor(bondcolor));
    depictor.SetBondColor(bondcolor);
    if(pConv->IsOption("t"))
      painter.SetPenWidth(4);
    else
      painter.SetPenWidth(2);

    //No element-specific atom coloring if requested
    if(pConv->IsOption("u"))
      depictor.SetOption(OBDepict::bwAtoms);
    if(!pConv->IsOption("U"))
      depictor.SetOption(OBDepict::internalColor);
    if(pConv->IsOption("s"))
      depictor.SetOption(OBDepict::asymmetricDoubleBond);

    depictor.DrawMolecule(pmol);

    //Draw atom indices if requested
    if(pConv->IsOption("i"))
      depictor.AddAtomLabels(OBDepict::AtomIndex);

    //Embed CML of molecule if requested
    if(pConv->IsOption("e"))
      EmbedCML(pmol,pConv);
  }
  else //single molecule
  {
    //Nothing written until DrawMolecule call
    //Final </svg> written at the end of this block (painter destructor)
    //This leads to some code duplication.
    double factor = 1.0;
    SVGPainter painter(*pConv->GetOutStream(), false);
    OBDepict depictor(&painter);

    //Scale image by specifying the average bond length in pixels.
    const char* ppx = pConv->IsOption("p");
    if(!ppx)
      ppx= pConv->IsOption("px", OBConversion::GENOPTIONS);
    if(ppx)
    {
      double oldblen = depictor.GetBondLength();
      double newblen = atof(ppx);
      depictor.SetBondLength(newblen);
      factor = newblen / oldblen;
      //Scale bondspacing and font size by same factor
      depictor.SetBondSpacing(depictor.GetBondSpacing() * factor);
      depictor.SetFontSize((int)(depictor.GetFontSize() * factor));
    }

    if(pConv->IsOption("W"))
      depictor.SetOption(OBDepict::noWedgeHashGen);
    if(!pConv->IsOption("C"))
      depictor.SetOption(OBDepict::drawTermC);// on by default
    if(pConv->IsOption("a"))
      depictor.SetOption(OBDepict::drawAllC);

    if(pConv->IsOption("A"))
    {
      AliasData::RevertToAliasForm(*pmol);
      depictor.SetAliasMode();
    }

    painter.SetFontFamily("sans-serif");
    painter.SetPenColor(OBColor(bondcolor));
    depictor.SetBondColor(bondcolor);
    painter.SetFillColor(OBColor(background));
    if(pConv->IsOption("t"))
      painter.SetPenWidth(4);
    else
      painter.SetPenWidth(1);

    //No element-specific atom coloring if requested
    if(pConv->IsOption("u"))
      depictor.SetOption(OBDepict::bwAtoms);
    if(!pConv->IsOption("U"))
      depictor.SetOption(OBDepict::internalColor);
    if(pConv->IsOption("s"))
      depictor.SetOption(OBDepict::asymmetricDoubleBond);

    depictor.DrawMolecule(pmol);

    //Draw atom indices if requested
    if(pConv->IsOption("i"))
      depictor.AddAtomLabels(OBDepict::AtomIndex);


    //*** Write molecule name ***
    if(!pConv->IsOption("d"))
      ofs << "<text font-size=\"" << 18 * factor  << "\""
      << " fill =\"" << bondcolor << "\" font-family=\"sans-serif\"\n"
      << "x=\"" << 10 * factor << "\" y=\"" << 20 * factor << "\" >"
      << pmol->GetTitle() << "</text>\n";

    //*** Write page title name ***
    ofs << "<title>" << pmol->GetTitle() << " - OBDepict</title>\n";

    //Embed CML of molecule if requested
    if(pConv->IsOption("e"))
      EmbedCML(pmol,pConv);
  }

  if(hasTable && pConv->IsLast())
  {
    //Draw grid lines
    if(_nrows && _ncols && pConv->IsOption("l"))
    {
      for(int i=1; i<_nrows; ++i)
        ofs << " <line  stroke=\"gray\" stroke-width=\"0.1\" x1=\"0\" x2=\"100\""
            << " y1=\""  << i*cellsize << "\" y2=\""  << i*cellsize << "\"/>\n";
      for(int i=1; i<_ncols; ++i)
        ofs << " <line  stroke=\"gray\" stroke-width=\"0.1\" y1=\"0\" y2=\"100\""
            << " x1=\""  << i*cellsize << "\" x2=\""  << i*cellsize << "\"/>\n";
    }

    //Insert javascript for zooming and panning
    if(!pConv->IsOption("j"))
      EmbedScript(ofs);

    ofs << "</svg>\n" << endl;//Outer svg
  }
  return !fixedpx; // return false with fixed size image because only 1 mol
}
Ejemplo n.º 3
0
bool SVGFormat::WriteSVG(OBConversion* pConv, vector<OBBase*>& molecules)
{

  bool ret=true;

  //Check for option for single mol in fixed size image
  const char* fixedpx = pConv->IsOption("P");
  if(!fixedpx)
    fixedpx= pConv->IsOption("px", OBConversion::GENOPTIONS);
  //If WriteMolecule called directly, e.g. from OBConversion::Write()
  //the default mode is a fixed image size of 200px square
  if(!fixedpx && molecules.size()==1)
    fixedpx = "200";
  if(fixedpx)
  {
    _nmax = _nrows = _ncols = 1;
    pConv->AddOption("j");
  }

  ostream &ofs = *pConv->GetOutStream();

  bool hasTable = (_nrows>1) || (_ncols>1);

  bool transparent=false;
  string background, bondcolor;
  const char* bg = pConv->IsOption("b");
  background = bg ? "black" : "white";
  bondcolor  = bg ? "white" : "black";
  if(bg && (!strcmp(bg, "none") || bg[0]=='0'))
  {
    transparent = true;
    bondcolor = "gray";
  }
  const char* bcol = pConv->IsOption("B");
  if(bcol && *bcol)
    bondcolor = bcol;
  if(bg && *bg)
    background = bg;

  if(!pConv->IsOption("x"))
  ofs << "<?xml version=\"1.0\"?>\n";

  ofs << "<svg version=\"1.1\" id=\"topsvg\"\n"
         "xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
         "xmlns:cml=\"http://www.xml-cml.org/schema\" ";
  double vbwidth=100, vbheight=100;
  if (_nrows>_ncols)
    vbwidth = (100*_ncols)/_nrows;
  else if(_ncols>_nrows)
    vbheight = (100*_nrows)/_ncols;

  if(fixedpx)//fixed size image
    ofs << "x=\"0\" y=\"0\" width=\"" << fixedpx << "px\" height=\"" << fixedpx <<"px\" ";
  else
    ofs << "x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ";

  ofs << "viewBox=\"0 0 " << vbwidth << ' ' << vbheight << "\">\n";

  if (hasTable)
    ofs << "<title>Multiple Molecules - Open Babel Depiction</title>\n";
  else if(molecules.size() == 1)
    ofs << "<title>" << molecules[0]->GetTitle() << " - Open Babel Depiction</title>\n";

  // Draw the background unless transparent
  if(!transparent)
    ofs << "<rect x=\"0\" y=\"0\" width=\"" << vbwidth << "\" height=\"" << vbheight
        << "\" fill=\"" << background << "\"/>\n";

  unsigned opts = 0;
  if(pConv->IsOption("u"))
    opts |= OBDepict::bwAtoms;
  if(!pConv->IsOption("U"))
   opts |= OBDepict::internalColor;
  if(!pConv->IsOption("C"))
    opts |= OBDepict::drawTermC;// on by default
  if(pConv->IsOption("a"))
    opts |= OBDepict::drawAllC;
  if(pConv->IsOption("W"))
    opts |= OBDepict::noWedgeHashGen;
  if(pConv->IsOption("s"))
   opts |= OBDepict::asymmetricDoubleBond;
  if(pConv->IsOption("X"))
    opts |= OBDepict::allExplicit;

  bool balldepict = false;
  if(pConv->IsOption("S"))
    balldepict = true;

  double factor = 1.0;
  int nc = _ncols ? _ncols : 1;
  int nr = (_nrows ? _nrows : 1);
  double cellsize = 100. / std::max(nc, nr);

  stringstream molfs;
  std::set<ColorGradient> gradients;

  OBOp* pOp = OBOp::FindType("gen2D");
  if(!pOp)
  {
    obErrorLog.ThrowError("SVGFormat", "gen2D not found", obError, onceOnly);
    return false;
  }

  vector<OBBase*>::iterator iter;
  int indx = 0;
  for(iter=_objects.begin(); ret && iter!=_objects.end(); ++iter,++indx)
  {
    OBMol* pmol = dynamic_cast<OBMol*>(*iter);

    if (!pmol)
      continue;
    //*** Coordinate generation ***
    //Generate coordinates only if no existing 2D coordinates
    if( (pConv->IsOption("y") || !pmol->Has2D(true)) && !pConv->IsOption("n") )
    {
      if(!pOp->Do(pmol))
      {
        obErrorLog.ThrowError("SVGFormat", string(pmol->GetTitle()) + "- Coordinate generation unsuccessful", obError);
        return false;
      }
    }
    if(!pmol->Has2D() && pmol->NumAtoms()>1)//allows 3D coordinates (if passed by -xn above)
    {
      string mes("Molecule ");
      mes += pmol->GetTitle();
      mes += " needs 2D coordinates to display in SVGformat";
      obErrorLog.ThrowError("SVGFormat", mes, obError);
      return false;
    }
    double innerX = 0.0;
    double innerY = 0.0;
    if(hasTable)
    {
      //*** Parameter for inner svg ***
      innerX  = (indx % nc) * cellsize;
      innerY  = (indx / nc) * cellsize;

      // Change the background in this cell if the condition in the first
      // parameter of  the -xh option is met. Use a default color if
      // the highlight color is not specified in the second parameter.
      const char* htxt = pConv->IsOption("h");
      if(htxt)
      {
        vector<string> vec;
        tokenize(vec, htxt);
        string highlight(vec.size()>1 ? vec[1] : "#f4f0ff");
        std::istringstream conditionText(vec[0]);
        if(OBDescriptor::FilterCompare(*iter, conditionText, false))
          //Still in outer <svg>, unfortunately
          molfs << "<rect x=\"" << innerX << "\" y=\"" << innerY
              << "\" width=\"" << cellsize << "\" height=\"" << cellsize
              << "\" fill=\"" << highlight << "\"/>\n";
      }
    }

    SVGPainter painter(molfs, &gradients, true, cellsize, cellsize);
    OBDepict depictor(&painter, balldepict);

    depictor.SetOption(opts);

    if(pConv->IsOption("A"))
    {
      AliasData::RevertToAliasForm(*pmol);
      depictor.SetAliasMode();
    }
    painter.SetFontFamily("sans-serif");
    painter.SetPenColor(OBColor(bondcolor));
    depictor.SetBondColor(bondcolor);
    if(pConv->IsOption("t"))
      painter.SetPenWidth(4);
    else
      painter.SetPenWidth(2);

    molfs << "<g transform=\"translate(" << innerX << "," << innerY << ")\">\n";

    ret = depictor.DrawMolecule(pmol);


    //Draw atom indices if requested
    if(pConv->IsOption("i"))
      depictor.AddAtomLabels(OBDepict::AtomIndex);

    painter.EndCanvas();


    //Embed CML of molecule if requested
    if(pConv->IsOption("e"))
      EmbedCML(pmol, pConv, &molfs);

    molfs <<"</g>\n";

    //*** Write molecule name ***
    if(!pConv->IsOption("d"))
      if(hasTable)
        molfs << "<text text-anchor=\"middle\" font-size=\"" << 0.06*cellsize << "\""
        << " fill =\"" << bondcolor << "\" font-family=\"sans-serif\"\n"
        << "x=\"" << innerX + cellsize * 0.5 << "\" y=\"" << innerY + cellsize - 2.0/nr << "\" >"
        << pmol->GetTitle() << "</text>\n";
      else
        molfs << "<text font-size=\"" << 18 * factor  << "\""
        << " fill =\"" << bondcolor << "\" font-family=\"sans-serif\"\n"
        << "x=\"" << 10 * factor << "\" y=\"" << 20 * factor << "\" >"
        << pmol->GetTitle() << "</text>\n";
  }

  // finally write svg defs
  SVGPainter painter(ofs, &gradients, true, cellsize,cellsize);
  painter.WriteDefs();

  // and stream back all molecule data
  ofs << molfs.str();

  //Draw grid lines
  if(hasTable && pConv->IsOption("l"))
  {
    for(int i=1; i<_nrows; ++i)
      ofs << " <line  stroke=\"gray\" stroke-width=\"0.1\" x1=\"0\" x2=\"100\""
          << " y1=\""  << i*cellsize << "\" y2=\""  << i*cellsize << "\"/>\n";
    for(int i=1; i<_ncols; ++i)
      ofs << " <line  stroke=\"gray\" stroke-width=\"0.1\" y1=\"0\" y2=\"100\""
          << " x1=\""  << i*cellsize << "\" x2=\""  << i*cellsize << "\"/>\n";
  }

  //Insert javascript for zooming and panning
  if(!pConv->IsOption("j"))
    EmbedScript(ofs);

  ofs << "</svg>\n";
return ret;
}