diff --git a/cyberiadaml.c b/cyberiadaml.c index 0de527a..2ddc65b 100644 --- a/cyberiadaml.c +++ b/cyberiadaml.c @@ -3207,15 +3207,19 @@ static int cyberiada_process_decode_sm_document(CyberiadaDocument* cyb_doc, xmlD ERROR("error: cannot reconstruct graph edges' identifier\n"); break; } - + if (res == CYBERIADA_NO_ERROR) { if (flags & CYBERIADA_FLAG_SKIP_GEOMETRY) { cyberiada_clean_document_geometry(cyb_doc); - } else { + } else if (cyberiada_document_has_geometry(cyb_doc) || + flags & CYBERIADA_FLAG_RECONSTRUCT_GEOMETRY) { cyberiada_import_document_geometry(cyb_doc, flags, format); + } else { + /* document has no geometry */ + cyb_doc->geometry_format = cybCoordNone; + cyb_doc->edge_geom_format = cybEdgeNone; } } - } while(0); cyberiada_free_name_list(&nl); @@ -4437,12 +4441,12 @@ static int cyberiada_process_encode_sm_document(CyberiadaDocument* doc, xmlTextW } } - if (CYBERIADA_FLAG_ABSOLUTE_GEOMETRY | - CYBERIADA_FLAG_LEFTTOP_LOCAL_GEOMETRY | - CYBERIADA_FLAG_CENTER_LOCAL_GEOMETRY | - CYBERIADA_FLAG_LEFTTOP_BORDER_EDGE_GEOMETRY | - CYBERIADA_FLAG_CENTER_BORDER_EDGE_GEOMETRY | - CYBERIADA_FLAG_CENTER_EDGE_GEOMETRY) { + if (flags & (CYBERIADA_FLAG_ABSOLUTE_GEOMETRY | + CYBERIADA_FLAG_LEFTTOP_LOCAL_GEOMETRY | + CYBERIADA_FLAG_CENTER_LOCAL_GEOMETRY | + CYBERIADA_FLAG_LEFTTOP_BORDER_EDGE_GEOMETRY | + CYBERIADA_FLAG_CENTER_BORDER_EDGE_GEOMETRY | + CYBERIADA_FLAG_CENTER_EDGE_GEOMETRY)) { ERROR("Geometry flags (abs, left-top, center) & edge geometry flags are not allowed for export\n"); return CYBERIADA_BAD_PARAMETER; @@ -4551,7 +4555,7 @@ int cyberiada_encode_sm_document(CyberiadaDocument* doc, char** buffer, size_t* return CYBERIADA_XML_ERROR; } - res = cyberiada_process_encode_sm_document(doc, writer, format, flags); + res = cyberiada_process_encode_sm_document(doc, writer, format, flags); if (res == CYBERIADA_NO_ERROR) { size_t size = xml_buffer->use; diff --git a/cyberiadaml.h b/cyberiadaml.h index 049ff27..0cc14bd 100644 --- a/cyberiadaml.h +++ b/cyberiadaml.h @@ -368,6 +368,9 @@ typedef enum { /* Free the SM polyline structure in memory */ int cyberiada_destroy_polyline(CyberiadaPolyline* polyline); + /* Check the presence of the SM document geometry, return 1 if there is any geometry object available */ + int cyberiada_document_has_geometry(CyberiadaDocument* doc); + /* Change the SM document geometry format and convert the SMs geometry data */ int cyberiada_convert_document_geometry(CyberiadaDocument* doc, CyberiadaGeometryCoordFormat new_format, diff --git a/geometry.c b/geometry.c index 5c85d58..e1c2aff 100644 --- a/geometry.c +++ b/geometry.c @@ -1136,7 +1136,7 @@ int cyberiada_import_document_geometry(CyberiadaDocument* doc, bounding_rect->x = bounding_rect->y = bounding_rect->width = bounding_rect->height = 0.0; cyberiada_build_bounding_rect(sm->nodes, bounding_rect, old_format); sm->bounding_rect = bounding_rect; - } + } cyberiada_convert_node_geometry(sm->nodes, sm->bounding_rect, old_format, new_format); @@ -1188,6 +1188,8 @@ int cyberiada_export_document_geometry(CyberiadaDocument* doc, if (flags & CYBERIADA_FLAG_RECONSTRUCT_GEOMETRY) { cyberiada_reconstruct_document_geometry(doc); + } else if (!cyberiada_document_has_geometry(doc)) { + return CYBERIADA_NO_ERROR; } if (flags & CYBERIADA_FLAG_ROUND_GEOMETRY) { @@ -1195,8 +1197,10 @@ int cyberiada_export_document_geometry(CyberiadaDocument* doc, } for (sm = doc->state_machines; sm; sm = sm->next) { - cyberiada_convert_node_geometry(sm->nodes, sm->bounding_rect, - doc->geometry_format, to_format); + if (sm->bounding_rect) { + cyberiada_convert_node_geometry(sm->nodes, sm->bounding_rect, + doc->geometry_format, to_format); + } if (sm->edges) { cyberiada_convert_edge_geometry(sm->edges, doc->geometry_format, to_format, @@ -1204,6 +1208,58 @@ int cyberiada_export_document_geometry(CyberiadaDocument* doc, } } - return CYBERIADA_NO_ERROR; + return CYBERIADA_NO_ERROR; } +static int cyberiada_node_has_geometry(CyberiadaNode* node) +{ + while (node) { + if (node->geometry_point) { + return 1; + } + if (node->geometry_rect) { + return 1; + } + if (node->children) { + int found = cyberiada_node_has_geometry(node->children); + if (found) { + return 1; + } + } + node = node->next; + } + return 0; +} + +int cyberiada_document_has_geometry(CyberiadaDocument* doc) +{ + CyberiadaSM* sm; + CyberiadaEdge* edge; + + if (!doc) { + return 0; + } + + for (sm = doc->state_machines; sm; sm = sm->next) { + if (cyberiada_node_has_geometry(sm->nodes)) { + return 1; + } + edge = sm->edges; + while (edge) { + if (edge->geometry_polyline) { + return 1; + } + if (edge->geometry_source_point) { + return 1; + } + if (edge->geometry_target_point) { + return 1; + } + if (edge->geometry_label_point) { + return 1; + } + edge = edge->next; + } + } + return 0; +} diff --git a/geometry.h b/geometry.h index 9b40336..8865d5b 100644 --- a/geometry.h +++ b/geometry.h @@ -51,6 +51,7 @@ extern "C" { int flags, CyberiadaXMLFormat file_format); int cyberiada_export_document_geometry(CyberiadaDocument* doc, int flags, CyberiadaXMLFormat file_format); + int cyberiada_document_has_geometry(CyberiadaDocument* doc); #ifdef __cplusplus }