add YED geometry convertation + separate cyb string module
This commit is contained in:
6
Makefile
6
Makefile
@@ -8,7 +8,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
TEST_TARGET := cyberiada_test
|
TEST_TARGET := cyberiada_test
|
||||||
LIB_SOURCES := cyberiadaml.c utf8enc.c cyb_types.c
|
LIB_SOURCES := cyberiadaml.c utf8enc.c cyb_types.c cyb_string.c
|
||||||
TEST_SOURCES := test.c
|
TEST_SOURCES := test.c
|
||||||
LIB_OBJECTS := $(patsubst %.c, %.o, $(LIB_SOURCES))
|
LIB_OBJECTS := $(patsubst %.c, %.o, $(LIB_SOURCES))
|
||||||
TEST_OBJECTS := $(patsubst %.c, %.o, $(TEST_SOURCES))
|
TEST_OBJECTS := $(patsubst %.c, %.o, $(TEST_SOURCES))
|
||||||
@@ -25,11 +25,11 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
INCLUDE := -I. -I/usr/include/libxml2
|
INCLUDE := -I. -I/usr/include/libxml2
|
||||||
LIBS := -L/usr/lib -lxml2
|
LIBS := -L/usr/lib -lxml2 -lm
|
||||||
TEST_LIBS := -L. -lcyberiadaml
|
TEST_LIBS := -L. -lcyberiadaml
|
||||||
|
|
||||||
$(LIB_TARGET): $(LIB_OBJECTS)
|
$(LIB_TARGET): $(LIB_OBJECTS)
|
||||||
ifeq ($(DYNAMIC), 1)
|
ifeq ($(DYNAMIC), yes)
|
||||||
gcc -shared $(LIBS) $(LIB_OBJECTS) -o $@
|
gcc -shared $(LIBS) $(LIB_OBJECTS) -o $@
|
||||||
else
|
else
|
||||||
ar rcs $@ $(LIB_OBJECTS)
|
ar rcs $@ $(LIB_OBJECTS)
|
||||||
|
|||||||
79
cyb_string.c
Normal file
79
cyb_string.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* The Cyberiada GraphML library implemention
|
||||||
|
*
|
||||||
|
* The string utilities
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 Alexey Fedoseev <aleksey@fedoseev.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "cyberiadaml.h"
|
||||||
|
#include "cyb_string.h"
|
||||||
|
|
||||||
|
int cyberiada_copy_string(char** target, size_t* size, const char* source)
|
||||||
|
{
|
||||||
|
char* target_str;
|
||||||
|
size_t strsize;
|
||||||
|
if (!source) {
|
||||||
|
*target = NULL;
|
||||||
|
*size = 0;
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
strsize = strlen(source);
|
||||||
|
if (strsize > MAX_STR_LEN - 1) {
|
||||||
|
strsize = MAX_STR_LEN - 1;
|
||||||
|
}
|
||||||
|
target_str = (char*)malloc(strsize + 1);
|
||||||
|
strncpy(target_str, source, strsize);
|
||||||
|
target_str[strsize] = 0;
|
||||||
|
*target = target_str;
|
||||||
|
if (size) {
|
||||||
|
*size = strsize;
|
||||||
|
}
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cyberiada_string_is_empty(const char* s)
|
||||||
|
{
|
||||||
|
while(*s) {
|
||||||
|
if (!isspace(*s)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cyberiada_string_trim(char* orig)
|
||||||
|
{
|
||||||
|
char* s;
|
||||||
|
if (!orig) return 1;
|
||||||
|
if (!*orig) return 0;
|
||||||
|
s = orig + strlen(orig) - 1;
|
||||||
|
while(s > orig) {
|
||||||
|
if (isspace(*s)) {
|
||||||
|
*s = 0;
|
||||||
|
s--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
44
cyb_string.h
Normal file
44
cyb_string.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* The Cyberiada GraphML library implemention
|
||||||
|
*
|
||||||
|
* The string utilities
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 Alexey Fedoseev <aleksey@fedoseev.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifndef __CYBERIADA_STRING_H
|
||||||
|
#define __CYBERIADA_STRING_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* The Cyberiada GraphML string utilities
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define MAX_STR_LEN 4096
|
||||||
|
|
||||||
|
int cyberiada_copy_string(char** target, size_t* size, const char* source);
|
||||||
|
int cyberiada_string_is_empty(const char* s);
|
||||||
|
int cyberiada_string_trim(char* orig);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
323
cyberiadaml.c
323
cyberiadaml.c
@@ -29,10 +29,12 @@
|
|||||||
#include <libxml/xmlwriter.h>
|
#include <libxml/xmlwriter.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "cyberiadaml.h"
|
#include "cyberiadaml.h"
|
||||||
#include "utf8enc.h"
|
#include "utf8enc.h"
|
||||||
#include "cyb_types.h"
|
#include "cyb_types.h"
|
||||||
|
#include "cyb_string.h"
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Cyberiada parser constants
|
* Cyberiada parser constants
|
||||||
@@ -170,7 +172,6 @@
|
|||||||
|
|
||||||
/* Misc. constants */
|
/* Misc. constants */
|
||||||
|
|
||||||
#define MAX_STR_LEN 4096
|
|
||||||
#define PSEUDO_NODE_SIZE 20
|
#define PSEUDO_NODE_SIZE 20
|
||||||
#define EMPTY_TITLE ""
|
#define EMPTY_TITLE ""
|
||||||
|
|
||||||
@@ -322,61 +323,6 @@ static GraphMLKey yed_graphml_keys[] = {
|
|||||||
};
|
};
|
||||||
static const size_t yed_graphml_keys_count = sizeof(yed_graphml_keys) / sizeof(GraphMLKey);
|
static const size_t yed_graphml_keys_count = sizeof(yed_graphml_keys) / sizeof(GraphMLKey);
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
|
||||||
* Utility functions
|
|
||||||
* ----------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
int cyberiada_copy_string(char** target, size_t* size, const char* source)
|
|
||||||
{
|
|
||||||
char* target_str;
|
|
||||||
size_t strsize;
|
|
||||||
if (!source) {
|
|
||||||
*target = NULL;
|
|
||||||
*size = 0;
|
|
||||||
return CYBERIADA_NO_ERROR;
|
|
||||||
}
|
|
||||||
strsize = strlen(source);
|
|
||||||
if (strsize > MAX_STR_LEN - 1) {
|
|
||||||
strsize = MAX_STR_LEN - 1;
|
|
||||||
}
|
|
||||||
target_str = (char*)malloc(strsize + 1);
|
|
||||||
strncpy(target_str, source, strsize);
|
|
||||||
target_str[strsize] = 0;
|
|
||||||
*target = target_str;
|
|
||||||
if (size) {
|
|
||||||
*size = strsize;
|
|
||||||
}
|
|
||||||
return CYBERIADA_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cyberiada_string_is_empty(const char* s)
|
|
||||||
{
|
|
||||||
while(*s) {
|
|
||||||
if (!isspace(*s)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cyberiada_string_trim(char* orig)
|
|
||||||
{
|
|
||||||
char* s;
|
|
||||||
if (!orig) return 1;
|
|
||||||
if (!*orig) return 0;
|
|
||||||
s = orig + strlen(orig) - 1;
|
|
||||||
while(s > orig) {
|
|
||||||
if (isspace(*s)) {
|
|
||||||
*s = 0;
|
|
||||||
s--;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Graph manipulation functions
|
* Graph manipulation functions
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
@@ -511,6 +457,13 @@ static CyberiadaPoint* cyberiada_copy_point(CyberiadaPoint* src)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cyberiada_update_point(CyberiadaPoint* p, float dx, float dy)
|
||||||
|
{
|
||||||
|
if (!p) return ;
|
||||||
|
p->x += dx;
|
||||||
|
p->y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
CyberiadaRect* cyberiada_new_rect(void)
|
CyberiadaRect* cyberiada_new_rect(void)
|
||||||
{
|
{
|
||||||
CyberiadaRect* r = (CyberiadaRect*)malloc(sizeof(CyberiadaRect));
|
CyberiadaRect* r = (CyberiadaRect*)malloc(sizeof(CyberiadaRect));
|
||||||
@@ -532,6 +485,13 @@ static CyberiadaRect* cyberiada_copy_rect(CyberiadaRect* src)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cyberiada_update_rect(CyberiadaRect* r, float dx, float dy)
|
||||||
|
{
|
||||||
|
if (!r) return ;
|
||||||
|
r->x += dx;
|
||||||
|
r->y += dy;
|
||||||
|
}
|
||||||
|
|
||||||
CyberiadaPolyline* cyberiada_new_polyline(void)
|
CyberiadaPolyline* cyberiada_new_polyline(void)
|
||||||
{
|
{
|
||||||
CyberiadaPolyline* pl = (CyberiadaPolyline*)malloc(sizeof(CyberiadaPolyline));
|
CyberiadaPolyline* pl = (CyberiadaPolyline*)malloc(sizeof(CyberiadaPolyline));
|
||||||
@@ -560,6 +520,15 @@ static CyberiadaPolyline* cyberiada_copy_polyline(CyberiadaPolyline* src)
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static void cyberiada_update_polyline(CyberiadaPolyline* pl, float dx, float dy)
|
||||||
|
{
|
||||||
|
if (!pl) return ;
|
||||||
|
do {
|
||||||
|
cyberiada_update_point(&(pl->point), dx, dy);
|
||||||
|
pl = pl->next;
|
||||||
|
} while (pl);
|
||||||
|
}*/
|
||||||
|
|
||||||
CyberiadaAction* cyberiada_new_action(CyberiadaActionType type,
|
CyberiadaAction* cyberiada_new_action(CyberiadaActionType type,
|
||||||
const char* trigger,
|
const char* trigger,
|
||||||
const char* guard,
|
const char* guard,
|
||||||
@@ -1440,8 +1409,242 @@ static int cyberiada_graphs_reconstruct_edges(CyberiadaDocument* doc, NamesList*
|
|||||||
}
|
}
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cyberiada_graphs_reconstruct_node_geometry_from_yed(CyberiadaNode* node, float parent_x, float parent_y)
|
||||||
|
{
|
||||||
|
float new_root_x;
|
||||||
|
float new_root_y;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (node->geometry_point) {
|
||||||
|
cyberiada_update_point(node->geometry_point, -parent_x, -parent_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->geometry_rect) {
|
||||||
|
new_root_x = node->geometry_rect->x;
|
||||||
|
new_root_y = node->geometry_rect->y;
|
||||||
|
|
||||||
|
cyberiada_update_rect(node->geometry_rect, -parent_x, -parent_y);
|
||||||
|
} else {
|
||||||
|
new_root_x = parent_x;
|
||||||
|
new_root_y = parent_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->children) {
|
||||||
|
cyberiada_graphs_reconstruct_node_geometry_from_yed(node->children, new_root_x, new_root_y);
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
return CYBERIADA_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
static int cyberiada_graphs_reconstruct_geometry_from_yed(CyberiadaDocument* doc)
|
static int cyberiada_graphs_reconstruct_geometry_from_yed(CyberiadaDocument* doc)
|
||||||
{
|
{
|
||||||
|
CyberiadaSM* sm;
|
||||||
|
CyberiadaNode* node;
|
||||||
|
CyberiadaEdge* edge;
|
||||||
|
CyberiadaPolyline* pl;
|
||||||
|
float from_x, from_y, to_x, to_y;
|
||||||
|
float src_from_x, src_from_y, src_to_x, src_to_y, tgt_from_x, tgt_from_y, tgt_to_x, tgt_to_y;
|
||||||
|
|
||||||
|
for (sm = doc->state_machines; sm; sm = sm->next) {
|
||||||
|
|
||||||
|
for (edge = sm->edges; edge; edge = edge->next) {
|
||||||
|
if (edge->source && (edge->source->geometry_rect || edge->source->geometry_point) &&
|
||||||
|
edge->target && (edge->target->geometry_rect || edge->target->geometry_point) &&
|
||||||
|
(edge->geometry_source_point ||
|
||||||
|
edge->geometry_target_point ||
|
||||||
|
edge->geometry_polyline ||
|
||||||
|
edge->geometry_label_point)) {
|
||||||
|
|
||||||
|
from_x = from_y = to_x = to_y = 0.0f;
|
||||||
|
if (edge->source->geometry_point) {
|
||||||
|
from_x += edge->source->geometry_point->x;
|
||||||
|
from_y += edge->source->geometry_point->y;
|
||||||
|
} else {
|
||||||
|
from_x += edge->source->geometry_rect->x + edge->source->geometry_rect->width / 2.0f;
|
||||||
|
from_y += edge->source->geometry_rect->y + edge->source->geometry_rect->height / 2.0f;
|
||||||
|
if (edge->geometry_source_point) {
|
||||||
|
from_x += edge->geometry_source_point->x;
|
||||||
|
from_y += edge->geometry_source_point->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (edge->target->geometry_point) {
|
||||||
|
to_x += edge->target->geometry_point->x;
|
||||||
|
to_y += edge->target->geometry_point->y;
|
||||||
|
} else {
|
||||||
|
to_x += edge->target->geometry_rect->x + edge->target->geometry_rect->width / 2.0f;
|
||||||
|
to_y += edge->target->geometry_rect->y + edge->target->geometry_rect->height / 2.0f;
|
||||||
|
if (edge->geometry_target_point) {
|
||||||
|
to_x += edge->geometry_target_point->x;
|
||||||
|
to_y += edge->geometry_target_point->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge->geometry_polyline) {
|
||||||
|
float first_p_x = edge->geometry_polyline->point.x;
|
||||||
|
float first_p_y = edge->geometry_polyline->point.y;
|
||||||
|
float last_p_x;
|
||||||
|
float last_p_y;
|
||||||
|
|
||||||
|
pl = edge->geometry_polyline;
|
||||||
|
while (pl->next) pl = pl->next;
|
||||||
|
last_p_x = pl->point.x;
|
||||||
|
last_p_y = pl->point.y;
|
||||||
|
|
||||||
|
src_from_x = from_x;
|
||||||
|
src_from_y = from_y;
|
||||||
|
src_to_x = first_p_x;
|
||||||
|
src_to_y = first_p_y;
|
||||||
|
tgt_from_x = last_p_x;
|
||||||
|
tgt_from_y = last_p_y;
|
||||||
|
tgt_to_x = to_x;
|
||||||
|
tgt_to_y = to_y;
|
||||||
|
} else {
|
||||||
|
src_from_x = tgt_from_x = from_x;
|
||||||
|
src_from_y = tgt_from_y = from_y;
|
||||||
|
src_to_x = tgt_to_x = to_x;
|
||||||
|
src_to_y = tgt_to_y = to_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DEBUG("edge (%f; %f) -> (%f; %f) and (%f; %f) -> (%f; %f)\n", */
|
||||||
|
/* src_from_x, src_from_y, src_to_x, src_to_y, */
|
||||||
|
/* tgt_from_x, tgt_from_y, tgt_to_x, tgt_to_y); */
|
||||||
|
|
||||||
|
if (edge->geometry_source_point) {
|
||||||
|
if (edge->source->geometry_point) {
|
||||||
|
if (src_from_x == src_to_x) {
|
||||||
|
edge->geometry_source_point->x = 0.0f;
|
||||||
|
if (src_from_y >= src_to_y) {
|
||||||
|
edge->geometry_source_point->y = -PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
} else {
|
||||||
|
edge->geometry_source_point->y = PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float alpha = (float)atan((src_from_y - src_to_y) / (src_to_x - src_from_x));
|
||||||
|
edge->geometry_source_point->x = (float)cos(alpha) * PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
edge->geometry_source_point->y = -(float)sin(alpha) * PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src_from_x == src_to_x) {
|
||||||
|
edge->geometry_source_point->x = edge->source->geometry_rect->width / 2.0f;
|
||||||
|
if (src_from_y >= src_to_y) {
|
||||||
|
edge->geometry_source_point->y = 0.0f;
|
||||||
|
} else {
|
||||||
|
edge->geometry_source_point->y = edge->source->geometry_rect->height;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float alpha = (float)atan((src_from_y - src_to_y) / (src_to_x - src_from_x));
|
||||||
|
if (src_to_x < src_from_x) alpha += (float)M_PI;
|
||||||
|
float alpha_g = 180.0f * alpha / (float)M_PI;
|
||||||
|
/* DEBUG("src alpha %f\n", alpha_g);*/
|
||||||
|
if (alpha_g < 0.0f) alpha_g += 360.0f;
|
||||||
|
if (alpha_g <= 45.0f || alpha_g > 315.0f) {
|
||||||
|
edge->geometry_source_point->x = edge->source->geometry_rect->width;
|
||||||
|
edge->geometry_source_point->y += (-(float)tan(alpha) * edge->source->geometry_rect->width +
|
||||||
|
edge->source->geometry_rect->height) / 2.0f;
|
||||||
|
} else if (alpha_g > 45.0f && alpha_g <= 135.0f) {
|
||||||
|
edge->geometry_source_point->x += ((float)tan(alpha) * edge->source->geometry_rect->height +
|
||||||
|
edge->source->geometry_rect->width) / 2.0f;
|
||||||
|
edge->geometry_source_point->y = 0.0f;
|
||||||
|
} else if (alpha_g > 135.0f && alpha_g <= 225.0f) {
|
||||||
|
edge->geometry_source_point->x = 0.0f;
|
||||||
|
edge->geometry_source_point->y += (-(float)tan(alpha) * edge->source->geometry_rect->width +
|
||||||
|
edge->source->geometry_rect->height) / 2.0f;
|
||||||
|
} else {
|
||||||
|
edge->geometry_source_point->x += (-(float)tan(alpha) * edge->source->geometry_rect->height +
|
||||||
|
edge->source->geometry_rect->width) / 2.0f;
|
||||||
|
edge->geometry_source_point->y = edge->source->geometry_rect->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge->geometry_source_point->x < 0) {
|
||||||
|
edge->geometry_source_point->x = 0.0f;
|
||||||
|
}
|
||||||
|
if (edge->geometry_source_point->x > edge->source->geometry_rect->width) {
|
||||||
|
edge->geometry_source_point->x = edge->source->geometry_rect->width;
|
||||||
|
}
|
||||||
|
if (edge->geometry_source_point->y < 0) {
|
||||||
|
edge->geometry_source_point->y = 0.0f;
|
||||||
|
}
|
||||||
|
if (edge->geometry_source_point->y > edge->source->geometry_rect->height) {
|
||||||
|
edge->geometry_source_point->y = edge->source->geometry_rect->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* DEBUG("sp: (%f; %f)\n", edge->geometry_source_point->x, edge->geometry_source_point->y); */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge->geometry_target_point) {
|
||||||
|
if (edge->target->geometry_point) {
|
||||||
|
if (tgt_from_x == tgt_to_x) {
|
||||||
|
edge->geometry_target_point->x = 0.0f;
|
||||||
|
if (tgt_from_y >= tgt_to_y) {
|
||||||
|
edge->geometry_target_point->y = PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
} else {
|
||||||
|
edge->geometry_target_point->y = -PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float alpha = (float)atan((tgt_from_y - tgt_to_y) / (tgt_to_x - tgt_from_x));
|
||||||
|
edge->geometry_target_point->x = (float)cos(alpha) * PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
edge->geometry_target_point->y = -(float)sin(alpha) * PSEUDO_NODE_SIZE / 2.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tgt_from_x == tgt_to_x) {
|
||||||
|
edge->geometry_target_point->x = edge->target->geometry_rect->width / 2.0f;
|
||||||
|
if (tgt_from_y >= tgt_to_y) {
|
||||||
|
edge->geometry_target_point->y = edge->target->geometry_rect->height;
|
||||||
|
} else {
|
||||||
|
edge->geometry_target_point->y = 0.0f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
float alpha = (float)atan((tgt_from_y - tgt_to_y) / (tgt_to_x - tgt_from_x));
|
||||||
|
if (tgt_to_x < tgt_from_x) alpha += (float)M_PI;
|
||||||
|
alpha += (float)M_PI; /* target = incoming edge */
|
||||||
|
float alpha_g = 180.0f * alpha / (float)M_PI;
|
||||||
|
/* DEBUG("tgt alpha %f\n", alpha_g);*/
|
||||||
|
if (alpha_g < 0.0f) alpha_g += 360.0f;
|
||||||
|
if (alpha_g <= 45.0f || alpha_g > 315.0f) {
|
||||||
|
edge->geometry_target_point->x = edge->target->geometry_rect->width;
|
||||||
|
edge->geometry_target_point->y += (-(float)tan(alpha) * edge->target->geometry_rect->width +
|
||||||
|
edge->target->geometry_rect->height) / 2.0f;
|
||||||
|
} else if (alpha_g > 45.0f && alpha_g <= 135.0f) {
|
||||||
|
edge->geometry_target_point->x += ((float)tan(alpha) * edge->target->geometry_rect->height +
|
||||||
|
edge->target->geometry_rect->width) / 2.0f;
|
||||||
|
edge->geometry_target_point->y = 0.0f;
|
||||||
|
} else if (alpha_g > 135.0f && alpha_g <= 225.0f) {
|
||||||
|
edge->geometry_target_point->x = 0.0f;
|
||||||
|
edge->geometry_target_point->y += (-(float)tan(alpha) * edge->target->geometry_rect->width +
|
||||||
|
edge->target->geometry_rect->height) / 2.0f;
|
||||||
|
} else {
|
||||||
|
edge->geometry_target_point->x += (-(float)tan(alpha) * edge->target->geometry_rect->height +
|
||||||
|
edge->target->geometry_rect->width) / 2.0f;
|
||||||
|
edge->geometry_target_point->y = edge->target->geometry_rect->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge->geometry_target_point->x < 0) {
|
||||||
|
edge->geometry_target_point->x = 0.0f;
|
||||||
|
}
|
||||||
|
if (edge->geometry_target_point->x > edge->target->geometry_rect->width) {
|
||||||
|
edge->geometry_target_point->x = edge->target->geometry_rect->width;
|
||||||
|
}
|
||||||
|
if (edge->geometry_target_point->y < 0) {
|
||||||
|
edge->geometry_target_point->y = 0.0f;
|
||||||
|
}
|
||||||
|
if (edge->geometry_target_point->y > edge->target->geometry_rect->height) {
|
||||||
|
edge->geometry_target_point->y = edge->target->geometry_rect->height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* DEBUG("tp: (%f; %f)\n", edge->geometry_target_point->x, edge->geometry_target_point->y); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (node = sm->nodes; node; node = node->next) {
|
||||||
|
cyberiada_graphs_reconstruct_node_geometry_from_yed(node, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CYBERIADA_NO_ERROR;
|
return CYBERIADA_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3306,9 +3509,6 @@ int cyberiada_read_sm_document(CyberiadaDocument* cyb_doc, const char* filename,
|
|||||||
/* DEBUG("reading format %d\n", format); */
|
/* DEBUG("reading format %d\n", format); */
|
||||||
if (format == cybxmlYED) {
|
if (format == cybxmlYED) {
|
||||||
res = cyberiada_decode_yed_xml(root, cyb_doc);
|
res = cyberiada_decode_yed_xml(root, cyb_doc);
|
||||||
if (res != CYBERIADA_NO_ERROR) {
|
|
||||||
cyberiada_graphs_reconstruct_geometry_from_yed(cyb_doc);
|
|
||||||
}
|
|
||||||
} else if (format == cybxmlCyberiada10) {
|
} else if (format == cybxmlCyberiada10) {
|
||||||
res = cyberiada_decode_cyberiada_xml(root, cyb_doc);
|
res = cyberiada_decode_cyberiada_xml(root, cyb_doc);
|
||||||
} else {
|
} else {
|
||||||
@@ -3335,6 +3535,11 @@ int cyberiada_read_sm_document(CyberiadaDocument* cyb_doc, const char* filename,
|
|||||||
filename);
|
filename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (format == cybxmlYED && res == CYBERIADA_NO_ERROR) {
|
||||||
|
cyberiada_graphs_reconstruct_geometry_from_yed(cyb_doc);
|
||||||
|
}
|
||||||
|
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
cyberiada_free_name_list(&nl);
|
cyberiada_free_name_list(&nl);
|
||||||
|
|||||||
Reference in New Issue
Block a user