in core/indigo-core/molecule/src/molecule_json_saver.cpp [1806:2080]
void MoleculeJsonSaver::saveMetaData(JsonWriter& writer, MetaDataStorage& meta)
{
static const std::unordered_map<int, std::string> _arrow_type2string = {
{ReactionComponent::ARROW_BASIC, "open-angle"},
{ReactionComponent::ARROW_FILLED_TRIANGLE, "filled-triangle"},
{ReactionComponent::ARROW_FILLED_BOW, "filled-bow"},
{ReactionComponent::ARROW_DASHED, "dashed-open-angle"},
{ReactionComponent::ARROW_FAILED, "failed"},
{ReactionComponent::ARROW_BOTH_ENDS_FILLED_TRIANGLE, "both-ends-filled-triangle"},
{ReactionComponent::ARROW_EQUILIBRIUM_FILLED_HALF_BOW, "equilibrium-filled-half-bow"},
{ReactionComponent::ARROW_EQUILIBRIUM_FILLED_TRIANGLE, "equilibrium-filled-triangle"},
{ReactionComponent::ARROW_EQUILIBRIUM_OPEN_ANGLE, "equilibrium-open-angle"},
{ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_BOW, "unbalanced-equilibrium-filled-half-bow"},
{ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_LARGE_FILLED_HALF_BOW, "unbalanced-equilibrium-large-filled-half-bow"},
{ReactionComponent::ARROW_BOTH_ENDS_FILLED_TRIANGLE, "unbalanced-equilibrium-filled-half-triangle"},
{ReactionComponent::ARROW_RETROSYNTHETIC, "retrosynthetic"}};
const auto& meta_objects = meta.metaData();
for (int meta_index = 0; meta_index < meta_objects.size(); ++meta_index)
{
auto pobj = meta_objects[meta_index];
switch (pobj->_class_id)
{
case ReactionArrowObject::CID: {
ReactionArrowObject& ar = (ReactionArrowObject&)(*pobj);
writer.StartObject();
writer.Key("type");
writer.String("arrow");
writer.Key("data");
writer.StartObject();
// arrow mode
writer.Key("mode");
std::string arrow_mode = "open-angle";
auto at_it = _arrow_type2string.find(ar.getArrowType());
if (at_it != _arrow_type2string.end())
arrow_mode = at_it->second.c_str();
writer.String(arrow_mode.c_str());
// arrow coordinates
writer.Key("pos");
writer.StartArray();
writer.StartObject();
writer.Key("x");
writeFloat(writer, ar.getTail().x);
writer.Key("y");
writeFloat(writer, ar.getTail().y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.StartObject();
writer.Key("x");
writeFloat(writer, ar.getHead().x);
writer.Key("y");
writeFloat(writer, ar.getHead().y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.EndArray(); // arrow coordinates
writer.EndObject(); // end data
writer.EndObject(); // end node
}
break;
case ReactionMultitailArrowObject::CID: {
ReactionMultitailArrowObject& ar = (ReactionMultitailArrowObject&)(*pobj);
writer.StartObject();
writer.Key("type");
writer.String("multi-tailed-arrow");
writer.Key("data");
writer.StartObject();
writer.Key("head");
writer.StartObject();
writer.Key("position");
writer.StartObject();
writer.Key("x");
writeFloat(writer, ar.getHead().x);
writer.Key("y");
writeFloat(writer, ar.getHead().y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.EndObject();
writer.Key("spine");
writer.StartObject();
writer.Key("pos");
writer.StartArray();
writer.StartObject();
writer.Key("x");
writeFloat(writer, ar.getSpineBegin().x);
writer.Key("y");
writeFloat(writer, ar.getSpineBegin().y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.StartObject();
writer.Key("x");
writeFloat(writer, ar.getSpineEnd().x);
writer.Key("y");
writeFloat(writer, ar.getSpineEnd().y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.EndArray();
writer.EndObject();
writer.Key("tails");
writer.StartObject();
writer.Key("pos");
writer.StartArray();
for (auto& t : ar.getTails())
{
writer.StartObject();
writer.Key("x");
writeFloat(writer, t.x);
writer.Key("y");
writeFloat(writer, t.y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
}
writer.EndArray();
writer.EndObject();
writer.Key("zOrder");
writer.Int(0);
writer.EndObject();
writer.EndObject();
}
break;
case ReactionPlusObject::CID: {
ReactionPlusObject& rp = (ReactionPlusObject&)(*pobj);
writer.StartObject();
writer.Key("type");
writer.String("plus");
writer.Key("location");
writer.StartArray();
writeFloat(writer, rp.getPos().x);
writeFloat(writer, rp.getPos().y);
writer.Double(0);
writer.EndArray();
writer.EndObject();
}
break;
case SimpleGraphicsObject::CID: {
auto simple_obj = (SimpleGraphicsObject*)pobj;
writer.StartObject();
writer.Key("type");
writer.String("simpleObject");
writer.Key("data");
writer.StartObject();
writer.Key("mode");
switch (simple_obj->_mode)
{
case SimpleGraphicsObject::EEllipse:
writer.String("ellipse");
break;
case SimpleGraphicsObject::ERectangle:
writer.String("rectangle");
break;
case SimpleGraphicsObject::ELine:
writer.String("line");
break;
}
writer.Key("pos");
writer.StartArray();
auto& coords = simple_obj->_coordinates;
// point1
writer.StartObject();
writer.Key("x");
writeFloat(writer, coords.first.x);
writer.Key("y");
writeFloat(writer, coords.first.y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
// point2
writer.StartObject();
writer.Key("x");
writeFloat(writer, coords.second.x);
writer.Key("y");
writeFloat(writer, coords.second.y);
writer.Key("z");
writer.Double(0);
writer.EndObject();
writer.EndArray();
// end data
writer.EndObject();
// end node
writer.EndObject();
break;
}
case SimpleTextObject::CID: {
auto simple_obj = (SimpleTextObject*)pobj;
writer.StartObject();
writer.Key("type");
writer.String("text");
writer.Key("data");
writer.StartObject();
writer.Key("content");
writer.String(simple_obj->_content.c_str());
writer.Key("position");
writePos(writer, simple_obj->_pos);
writer.Key("pos");
writer.StartArray();
Vec2f pos_bbox(simple_obj->_pos.x, simple_obj->_pos.y);
writePos(writer, pos_bbox);
pos_bbox.y -= simple_obj->_size.y;
writePos(writer, pos_bbox);
pos_bbox.x += simple_obj->_size.x;
writePos(writer, pos_bbox);
pos_bbox.y += simple_obj->_size.y;
writePos(writer, pos_bbox);
writer.EndArray();
writer.EndObject(); // end data
writer.EndObject(); // end node
break;
}
case EmbeddedImageObject::CID: {
auto image_obj = static_cast<const EmbeddedImageObject*>(pobj);
auto& bbox = image_obj->getBoundingBox();
writer.StartObject(); // start node
writer.Key("type");
writer.String("image");
writer.Key("format");
switch (image_obj->getFormat())
{
case EmbeddedImageObject::EKETPNG:
writer.String(KImagePNG);
break;
case EmbeddedImageObject::EKETSVG:
writer.String(KImageSVG);
break;
default:
throw Exception("Bad image format: %d", image_obj->getFormat());
}
writer.Key("boundingBox");
writer.StartObject(); // start bbox
writer.Key("x");
writeFloat(writer, bbox.left());
writer.Key("y");
writeFloat(writer, bbox.top());
writer.Key("z");
writer.Double(0);
writer.Key("width");
writeFloat(writer, bbox.width());
writer.Key("height");
writeFloat(writer, bbox.height());
writer.EndObject(); // end bbox
writer.Key("data");
writer.String(image_obj->getBase64().c_str());
writer.EndObject(); // end node
break;
}
}
}
}