Skip to content

Commit

Permalink
Added separate text support
Browse files Browse the repository at this point in the history
  • Loading branch information
rayzhuca committed Dec 18, 2023
1 parent 692e01d commit a0d3ac2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
64 changes: 55 additions & 9 deletions lib/src/middleware/export_svg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import 'dart:html';
import 'dart:svg' as svg;
import 'dart:svg';

import 'package:over_react/over_react.dart';
import 'package:redux/redux.dart';
import 'package:scadnano/src/middleware/system_clipboard.dart';
import 'package:scadnano/src/view/design_main_dna_sequence.dart';

import '../app.dart';
import '../state/app_state.dart';
Expand Down Expand Up @@ -45,11 +47,16 @@ export_svg_middleware(Store<AppState> store, dynamic action, NextDispatcher next
window.alert("No strands are selected, so there is nothing to export.\n"
"Please select some strands before choosing this option.");
} else {
var cloned_svg_element_with_style = get_cloned_svg_element_with_style(selected_elts);
var cloned_svg_element_with_style = get_cloned_svg_element_with_style(
selected_elts, store.state.ui_state.export_svg_text_separately);
_export_from_element(cloned_svg_element_with_style, 'selected');
}
} else
} else {
if (store.state.ui_state.export_svg_text_separately) {
elt = separate_if_svg_text(clone_and_apply_style(elt));
}
_export_from_element(elt, 'main');
}
}
if (action.type == actions.ExportSvgType.side || action.type == actions.ExportSvgType.both) {
var elt = document.getElementById("side-view-svg");
Expand All @@ -67,6 +74,37 @@ export_svg_middleware(Store<AppState> store, dynamic action, NextDispatcher next
}
}

// this directly modifies ele
Node separate_if_svg_text(Node ele) {
if (ele is TextElement && ele is SvgElement) {
double letterSpacing = double.tryParse(ele.getAttribute('letter-spacing') ?? "null");
if (letterSpacing != null) {
List<Element> children = [];
List<String> dna_seq = ele.text.split("");
double x = double.parse(ele.getAttribute('x'));
for (var i = 0; i < dna_seq.length; ++i) {
var child = clone_and_apply_style(ele)
..id = ele.id + '-n-${i}'
..text = dna_seq[i];
child.setAttribute('x', x.toString());
child.setAttribute('y', ele.getAttribute('y'));
child.setAttribute('dominant-baseline', 'text-top');
child.classes.add(DesignMainDNASequenceComponent.classname_dna_sequence);
children.add(child);
x += letterSpacing + DesignMainDNASequenceComponent.charWidth;
}
return SvgElement.tag("g")..children = children;
}
}
if (ele is Element) {
if (ele.hasChildNodes()) {
List<Node> nodes = ele.nodes.map(separate_if_svg_text).toList();
ele.nodes = nodes;
}
}
return ele;
}

List<Element> get_selected_strands(Store<AppState> store) {
var selected_strands = store.state.ui_state.selectables_store.selected_strands;
List<Element> selected_elts = [];
Expand All @@ -81,9 +119,12 @@ List<Element> get_selected_strands(Store<AppState> store) {
return selected_elts;
}

SvgSvgElement get_cloned_svg_element_with_style(List<Element> selected_elts) {
SvgSvgElement get_cloned_svg_element_with_style(List<Element> selected_elts, bool separate_text) {
var cloned_svg_element_with_style = SvgSvgElement()
..children = selected_elts.map(clone_and_apply_style).toList();
if (separate_text) {
selected_elts = selected_elts.map(separate_if_svg_text).map((x) => x as Element).toList();
}

// we can't get bbox without it being added to the DOM first
document.body.append(cloned_svg_element_with_style);
Expand Down Expand Up @@ -125,7 +166,7 @@ _export_svg(svg.SvgSvgElement svg_element, String filename_append) {
}

_copy_from_elements(List<Element> svg_elements) {
var cloned_svg_element_with_style = get_cloned_svg_element_with_style(svg_elements);
var cloned_svg_element_with_style = get_cloned_svg_element_with_style(svg_elements, false);
util.copy_svg_as_png(cloned_svg_element_with_style);
}

Expand Down Expand Up @@ -196,6 +237,7 @@ Element clone_and_apply_style(Element elt_orig) {
}

clone_and_apply_style_rec(Element elt_styled, Element elt_orig, {int depth = 0}) {
// print('elt_styled ${elt_styled.id} and elt_orig ${elt_orig.id}');
// Set<Element> children_styled_to_remove = {};
var tag_name = elt_styled.tagName;

Expand All @@ -208,7 +250,8 @@ clone_and_apply_style_rec(Element elt_styled, Element elt_orig, {int depth = 0})

if (relevant_styles.keys.contains(tag_name)) {
var style_def = elt_orig.getComputedStyle();

// print(
// 'id ${elt_styled.id} fill ${style_def.getPropertyValue("fill")} relevant_styles ${relevant_styles[tag_name]}');
//TODO: figure out how to remove nodes that aren't visible;
// getting error "Unsupported operation: Cannot setRange on filtered list" when removing children
// if (style_def.visibility == 'hidden') {
Expand All @@ -222,14 +265,17 @@ clone_and_apply_style_rec(Element elt_styled, Element elt_orig, {int depth = 0})
// correcting for this bug in InkScape that causes it to render hidden SVG objects:
// https://bugs.launchpad.net/inkscape/+bug/1577763
if (style_name == 'visibility' && style_value == 'hidden') {
style_strings.add('display: none');
// style_strings.add('display: none');
elt_styled.style.setProperty('display', 'none');
}
style_strings.add('${style_name}: ${style_value}');
elt_styled.style.setProperty(style_name, style_value);
// style_strings.add('${style_name}: ${style_value};');
}
}
var style_string = style_strings.join('; ') + ';';
// var style_string = style_strings.join(' ');

elt_styled.setAttribute("style", style_string);
// elt_styled.setAttribute("style", style_string);
// print(elt_styled.styleMap);

// print('${' ' * depth * 2} ${tag_name} ${elt_orig.classes.toList()} style: $style_string');
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/view/design_main_dna_sequence.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class DesignMainDNASequenceComponent extends UiComponent2<DesignMainDNASequenceP
}

static const classname_dna_sequence = 'dna-seq';
static const charWidth = 6.59375;

ReactElement _dna_sequence_on_domain(Domain domain) {
var seq_to_draw = domain.dna_sequence_deletions_insertions_to_spaces(
Expand Down Expand Up @@ -135,7 +136,6 @@ class DesignMainDNASequenceComponent extends UiComponent2<DesignMainDNASequenceP
}

var id = 'dna-${util.id_domain(domain)}';
double charWidth = 6.59375;

return (Dom.text()
..key = id
Expand Down

0 comments on commit a0d3ac2

Please sign in to comment.