Skip to content

Commit

Permalink
Merge pull request #776 from epam/render_all_styles
Browse files Browse the repository at this point in the history
core: render2d: text renderer fixes, UTF-8 support, subscript/superscript, all arrows styles, fix for #355
  • Loading branch information
even1024 authored Jul 29, 2022
2 parents 29c6907 + 82f092b commit 3b0d987
Show file tree
Hide file tree
Showing 8 changed files with 563 additions and 116 deletions.
30 changes: 20 additions & 10 deletions core/indigo-core/molecule/ket_commons.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@
namespace indigo
{
const double KETDefaultFontSize = 13;
const double KETFontScaleFactor = 58;
const double KETFontScaleFactor = 47;

struct hashFunction
struct compareFunction
{
size_t operator()(const std::pair<int, bool>& x) const
bool operator()(const std::pair<int, bool>& a, const std::pair<int, bool>& b) const
{
return x.first ^ x.second;
return a.second == b.second ? a.first < b.first : a.second < b.second;
}
};

using FONT_STYLE_SET = std::unordered_set<std::pair<int, bool>, hashFunction>;
using FONT_STYLE_SET = std::set<std::pair<int, bool>, compareFunction>;

constexpr std::uint32_t string_hash(char const* s, std::size_t count)
{
Expand Down Expand Up @@ -183,7 +183,7 @@ namespace indigo
static const std::uint32_t CID = "KET reaction arrow"_hash;
enum
{
EOpenAngle,
EOpenAngle = 2,
EFilledTriangle,
EFilledBow,
EDashedOpenAngle,
Expand All @@ -194,17 +194,23 @@ namespace indigo
EEquilibriumOpenAngle,
EUnbalancedEquilibriumFilledHalfBow,
EUnbalancedEquilibriumLargeFilledHalfBow,
EUnbalancedEquilibriumFilleHalfTriangle
EUnbalancedEquilibriumFilleHalfTriangle,
EEllipticalArcFilledBow,
EEllipticalArcFilledTriangle,
EEllipticalArcOpenAngle,
EEllipticalArcOpenHalfAngle,
};

KETReactionArrow(int arrow_type, const Vec2f& begin, const Vec2f& end) : MetaObject(CID), _arrow_type(arrow_type), _begin(begin), _end(end){};
KETReactionArrow(int arrow_type, const Vec2f& begin, const Vec2f& end, float height = 0)
: MetaObject(CID), _arrow_type(arrow_type), _begin(begin), _end(end), _height(height){};

MetaObject* clone() const override
{
return new KETReactionArrow(_arrow_type, _begin, _end);
return new KETReactionArrow(_arrow_type, _begin, _end, _height);
}

int _arrow_type;
float _height;
Vec2f _begin;
Vec2f _end;
};
Expand Down Expand Up @@ -257,7 +263,11 @@ namespace indigo
ARROW_EQUILIBRIUM_OPEN_ANGLE,
ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_BOW,
ARROW_UNBALANCED_EQUILIBRIUM_LARGE_FILLED_HALF_BOW,
ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_TRIANGLE
ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_TRIANGLE,
ARROW_ELLIPTICAL_ARC_FILLED_BOW,
ARROW_ELLIPTICAL_ARC_FILLED_TRIANGLE,
ARROW_ELLIPTICAL_ARC_OPEN_ANGLE,
ARROW_ELLIPTICAL_ARC_OPEN_HALF_ANGLE
};

enum
Expand Down
21 changes: 16 additions & 5 deletions core/indigo-core/molecule/src/molecule_json_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,11 @@ void MoleculeJsonLoader::loadMetaObjects(rapidjson::Value& meta_objects, MetaDat
{"equilibrium-open-angle", ReactionComponent::ARROW_EQUILIBRIUM_OPEN_ANGLE},
{"unbalanced-equilibrium-filled-half-bow", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_FILLED_HALF_BOW},
{"unbalanced-equilibrium-large-filled-half-bow", ReactionComponent::ARROW_UNBALANCED_EQUILIBRIUM_LARGE_FILLED_HALF_BOW},
{"unbalanced-equilibrium-filled-half-triangle", ReactionComponent::ARROW_BOTH_ENDS_FILLED_TRIANGLE}};
{"unbalanced-equilibrium-filled-half-triangle", ReactionComponent::ARROW_BOTH_ENDS_FILLED_TRIANGLE},
{"elliptical-arc-arrow-filled-bow", ReactionComponent::ARROW_ELLIPTICAL_ARC_FILLED_BOW},
{"elliptical-arc-arrow-filled-triangle", ReactionComponent::ARROW_ELLIPTICAL_ARC_FILLED_TRIANGLE},
{"elliptical-arc-arrow-open-angle", ReactionComponent::ARROW_ELLIPTICAL_ARC_OPEN_ANGLE},
{"elliptical-arc-arrow-open-half-angle", ReactionComponent::ARROW_ELLIPTICAL_ARC_OPEN_HALF_ANGLE}};

if (meta_objects.IsArray())
{
Expand Down Expand Up @@ -1099,17 +1103,24 @@ void MoleculeJsonLoader::loadMetaObjects(rapidjson::Value& meta_objects, MetaDat
}
else if (node_type == "arrow")
{
const rapidjson::Value& arrow_begin = mobj["data"]["pos"][0];
const rapidjson::Value& arrow_end = mobj["data"]["pos"][1];
std::string mode = mobj["data"]["mode"].GetString();
auto& mobj_data = mobj["data"];
const rapidjson::Value& arrow_begin = mobj_data["pos"][0];
const rapidjson::Value& arrow_end = mobj_data["pos"][1];
std::string mode = mobj_data["mode"].GetString();
int arrow_type = ReactionComponent::ARROW_BASIC;
auto arrow_type_it = arrow_string2type.find(mode);
if (arrow_type_it != arrow_string2type.end())
arrow_type = arrow_type_it->second;

Vec2f arr_begin(arrow_begin["x"].GetFloat(), arrow_begin["y"].GetFloat());
Vec2f arr_end(arrow_end["x"].GetFloat(), arrow_end["y"].GetFloat());
meta_interface.addMetaObject(new KETReactionArrow(arrow_type, arr_begin, arr_end));
if (mobj_data.HasMember("height"))
{
auto height = mobj_data["height"].GetFloat();
meta_interface.addMetaObject(new KETReactionArrow(arrow_type, arr_begin, arr_end, height));
}
else
meta_interface.addMetaObject(new KETReactionArrow(arrow_type, arr_begin, arr_end));
}
else if (node_type == "plus")
{
Expand Down
38 changes: 25 additions & 13 deletions core/indigo-core/reaction/src/reaction_auto_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,17 @@ void ReactionAutoLoader::_loadReaction(BaseReaction& reaction, bool query)

{
long long pos = _scanner->tell();
_scanner->skipSpace();
bool hasbom = false;
if (_scanner->length() >= 3)
{
unsigned char bom[3];
_scanner->readCharsFix(3, (char*)bom);
if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF)
hasbom = true;
else
_scanner->seek(pos, SEEK_SET);
}

if (_scanner->lookNext() == '{')
{
if (_scanner->findWord("arrow"))
Expand All @@ -189,21 +199,23 @@ void ReactionAutoLoader::_loadReaction(BaseReaction& reaction, bool query)
Array<char> buf;
_scanner->readAll(buf);
buf.push(0);
unsigned char* ptr = (unsigned char*)buf.ptr();
// skip utf8 BOM
if (hasbom)
ptr += 3;
Document data;
if (data.Parse(buf.ptr()).HasParseError())
throw Error("Error at parsing JSON: %s", buf.ptr());
if (data.HasMember("root") && data["root"].HasMember("nodes"))
if (!data.Parse((char*)ptr).HasParseError())
{
ReactionJsonLoader loader(data);
loader.stereochemistry_options = stereochemistry_options;
loader.ignore_noncritical_query_features = ignore_noncritical_query_features;
loader.treat_x_as_pseudoatom = treat_x_as_pseudoatom;
loader.ignore_no_chiral_flag = ignore_no_chiral_flag;

loader.loadReaction(reaction);
if (data.HasMember("root") && data["root"].HasMember("nodes"))
{
ReactionJsonLoader loader(data);
loader.stereochemistry_options = stereochemistry_options;
loader.ignore_noncritical_query_features = ignore_noncritical_query_features;
loader.treat_x_as_pseudoatom = treat_x_as_pseudoatom;
loader.ignore_no_chiral_flag = ignore_no_chiral_flag;
loader.loadReaction(reaction);
}
}
else
throw Error("Ketcher's JSON has no root node");
return;
}
}
Expand Down
14 changes: 14 additions & 0 deletions core/render2d/render_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace indigo
void removeStoredTransform();
void drawRectangle(const Vec2f& v1, const Vec2f& sz);
void drawEllipse(const Vec2f& v1, const Vec2f& v2);
void drawHalfEllipse(const Vec2f& v1, const Vec2f& v2, const float height, const bool is_negative = false);

void drawItemBackground(const RenderItem& item);
void drawTextItemText(const TextItem& ti, bool idle);
void drawTextItemText(const TextItem& ti, const Vec3f& color, bool idle);
Expand All @@ -75,6 +77,7 @@ namespace indigo
void fillCircle(const Vec2f& center, const float r);
void drawArc(const Vec2f& center, const float r, const float a0, const float a1);
void drawPoly(const Array<Vec2f>& v);
double getFontExtentHeight();
void setFontSize(double fontSize);
void setTextItemSize(TextItem& ti);
void setTextItemSize(TextItem& ti, const Vec2f& c);
Expand All @@ -97,6 +100,17 @@ namespace indigo
void drawPlus(const Vec2f& pos, const float linewidth, const float size);
void drawEquality(const Vec2f& pos, const float linewidth, const float size, const float interval);
void drawArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawCustomArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const bool is_bow = false,
const bool is_failed = false);
void drawDashedArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawBothEndsArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize);
void drawEllipticalArrow(const Vec2f& p1, const Vec2f& p2, const float width, const float headwidth, const float headsize, const float height,
int arrow_type);
void drawArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize, bool is_bow = false);
void drawHalfArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize);

void drawTriangleArrowHeader(const Vec2f& v, const Vec2f& dir, const float width, const float headwidth, const float headsize);

float highlightedBondLineWidth() const;
float currentLineWidth() const;
void setHighlight();
Expand Down
5 changes: 2 additions & 3 deletions core/render2d/render_item_aux.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,13 @@ namespace indigo
void _drawRIfThen(bool idle);
void _drawText(bool idle);
void _drawText(TextItem& ti, bool idle);
void _drawTextCentered(TextItem& ti, const Vec2f& sz, bool idle);

void _drawMeta(bool idle);
void _drawPlus();
void _drawArrow();
void _drawArrow(const KETReactionArrow& ar);
void _renderIdle();
void _renderSimpleObject(const KETSimpleObject& simple);
void _getLineExtents(const KETTextObject::KETTextLine& tl, Vec2f& sz);
float _getMaxHeight(const KETTextObject::KETTextLine& tl);
};

} // namespace indigo
Expand Down
Loading

0 comments on commit 3b0d987

Please sign in to comment.