git.s-ol.nu inkscape / livecoding
wip: create SVGs from Janet tables s-ol 3 years ago
4 changed file(s) with 105 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
3535 return janet_wrap_nil();
3636 }
3737
38 SPCSSAttr *get_css(Janet table) {
39 JanetKV const *kv = NULL;
40 SPCSSAttr *css = sp_repr_css_attr_new();
41 JanetDictView style = janet_getdictionary(&table, 0);
42 while ((kv = janet_dictionary_next(style.kvs, style.cap, kv))) {
43 if (!janet_checktype(kv->key, JANET_KEYWORD)) {
44 janet_panic(":style keys have to be keywords");
45 }
46 if (!janet_checktype(kv->value, JANET_STRING)) {
47 janet_panic(":style values have to be strings");
48 }
49 char const *key = (char const *)janet_unwrap_keyword(kv->key);
50 char const *value = (char const *)janet_unwrap_string(kv->value);
51 sp_repr_css_set_property(css, key, value);
52 }
53
54 return css;
55 }
56
57 Inkscape::XML::Node *get_node(int32_t argc, Janet *argv) {
58 janet_fixarity(argc, 2);
59 char const *element = (char const *)janet_unwrap_keyword(argv[0]);
60 JanetDictView attrs = janet_getdictionary(argv, 1);
61
62 Inkscape::XML::Node *repr = ctx().createElement(element);
63
64 g_message("+ new node '%s'", element);
65
66 JanetKV const *kv = NULL;
67 while ((kv = janet_dictionary_next(attrs.kvs, attrs.cap, kv))) {
68 if (!janet_checktype(kv->key, JANET_KEYWORD)) {
69 janet_panic("attribute keys have to be keywords");
70 }
71 char const *key = (char const *)janet_unwrap_keyword(kv->key);
72
73 switch (janet_type(kv->value)) {
74 case JANET_NUMBER:
75 g_message(" setting '%s' = %f", key, janet_unwrap_number(kv->value));
76 sp_repr_set_svg_double(repr, key, janet_unwrap_number(kv->value));
77 break;
78 case JANET_STRING:
79 g_message(" setting '%s' = '%s'", key, janet_unwrap_string(kv->value));
80 repr->setAttribute(key, (gchar const *)janet_unwrap_string(kv->value));
81 break;
82 case JANET_STRUCT:
83 case JANET_TABLE: {
84 if (strcmp(key, "style") != 0) {
85 janet_panic("struct/table values are only allowed for :style");
86 }
87
88 Glib::ustring css_str;
89 SPCSSAttr *css = get_css(kv->value);
90 sp_repr_css_write_string(css, css_str);
91 sp_repr_css_attr_unref(css);
92 repr->setAttribute("style", css_str.c_str());
93 g_message(" setting '%s' = '%s'", key, css_str.c_str());
94 break;
95 }
96 default:
97 janet_panic("unsupported value type in attributes dict!");
98 break;
99 }
100 }
101
102 return repr;
103 }
104
105 extern "C" Janet cfun_draw_doc(int32_t argc, Janet *argv) {
106 char const *id = janet_getcstring(argv, 0);
107 ctx().draw_doc(id, get_node(argc - 1, argv + 1));
108 g_message("+ draw_doc id=%s", id);
109 return argv[0];
110 }
111
112 extern "C" Janet cfun_draw_ui(int32_t argc, Janet *argv) {
113 char const *id = janet_getcstring(argv, 0);
114 ctx().draw_ui(id, get_node(argc - 1, argv + 1));
115 g_message("+ draw_ui id=%s", id);
116 return argv[0];
117 }
118
38119 const JanetReg it_cfuns[] = {
39120 {
40121 "input/point", cfun_input_point,
51132 "(input/arrow id from to)\n\nMake a modifiable arrow between from and to\n"
52133 "This function mutates from and to."
53134 },
135 {
136 "draw/doc", cfun_draw_doc,
137 "(draw/doc id elem [attrs])\n\nDraw an SVG element to the document layer"
138 },
139 {
140 "draw/ui", cfun_draw_ui,
141 "(draw/ui id elem [attrs])\n\nDraw an SVG element to the UI layer"
142 },
54143 {NULL, NULL, NULL}
55144 };
56145
5151 }
5252 }
5353
54
55 Inkscape::XML::Node *Context::createElement(gchar const *element) {
56 SPDocument *doc = desktop->getDocument();
57 Inkscape::XML::Document *xml_doc = doc->getReprDoc();
58
59 Inkscape::XML::Node *repr = xml_doc->createElement("svg:rect");
60 return repr;
61 }
62
5463 Inkscape::XML::Node *Context::make_rect(Geom::Rect const &rect, SPCSSAttr *css) {
5564 SPDocument *doc = desktop->getDocument();
5665 Inkscape::XML::Document *xml_doc = doc->getReprDoc();
282291 Inkscape::GC::release(rdoc);
283292
284293 ui_root = SP_ITEM(desktop->currentLayer()->appendChildRepr(rui));
285 ui_root->doWriteTransform(ui2doc(), nullptr, true);
294 doc_root->updateRepr();
286295 Inkscape::GC::release(rui);
287296 }
288297
289298 void Context::finish_frame() {
290299 doc_root->updateRepr();
291 ui_root->updateRepr();
300 ui_root->doWriteTransform(ui2doc(), nullptr, true);
292301 _mouse.finish_frame();
293302 }
294303
295304 void Context::load_script(Glib::ustring const &path) {
296305 g_message("loading script %s", path.c_str());
297 _script = nullptr;
298306
299307 try {
300308 _script.reset(new Script(env, path));
3535 Context(SPDesktop *desktop);
3636 ~Context();
3737
38 Inkscape::XML::Node *createElement(gchar const *element);
3839 Inkscape::XML::Node *make_rect(Geom::Rect const &rect, SPCSSAttr *css = nullptr);
3940 Inkscape::XML::Node *make_line(Geom::Point const &p1, Geom::Point const &p2, SPCSSAttr *css = nullptr);
4041 Inkscape::XML::Node *make_path(Glib::ustring d, Geom::Point const &pos = Geom::Point(), SPCSSAttr *css = nullptr);
2626 void Script::frame() {
2727 if (function) {
2828 Janet result;
29 janet_pcall(function, 0, NULL, &result, NULL);
29 JanetSignal status = janet_pcall(function, 0, NULL, &result, NULL);
30 if (status == JANET_SIGNAL_ERROR && janet_checktype(result, JANET_STRING)) {
31 g_message("error executing Janet Script: %s", (gchar const *)janet_unwrap_string(result));
32 }
3033 }
3134 }
3235