python-package/kotlin-bridge/lets_plot_kotlin_bridge.c (165 lines of code) (raw):

/* Copyright (c) 2019. JetBrains s.r.o. Use of this source code is governed by the MIT license that can be found in the LICENSE file. */ #include <Python.h> #include "liblets_plot_python_extension_api.h" #define __ liblets_plot_python_extension_symbols()-> #define T_(name) liblets_plot_python_extension_kref_org_jetbrains_letsPlot_pythonExtension_interop_ ## name // Note, that as we cache this in the global, and Kotlin/Native object references // are currently thread local, we make this global a TLS variable. #ifdef _MSC_VER #define TLSVAR __declspec(thread) #else #define TLSVAR __thread #endif // Deprecated: replaced by get_display_html_for_raw_spec() with default parameters /* static PyObject* generate_html(PyObject* self, PyObject* rawPlotSpecDict) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); // Create empty dict for sizing options (will default to notebookCell sizing) PyObject* emptySizingOptions = PyDict_New(); // Call generateDisplayHtmlForRawSpec with default parameters // dynamicScriptLoading=1 (true), forceImmediateRender=0 (false), responsive=0 (false) PyObject* html = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateDisplayHtmlForRawSpec( reprGen, rawPlotSpecDict, emptySizingOptions, 1, // dynamicScriptLoading = true 0, // forceImmediateRender = false 0 // responsive = false ); Py_DECREF(emptySizingOptions); return html; } */ static PyObject* export_svg(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); PyObject *rawPlotSpecDict; float width; float height; const char* unit; if (!PyArg_ParseTuple(args, "Offs", &rawPlotSpecDict, &width, &height, &unit)) { PyErr_SetString(PyExc_TypeError, "export_svg: failed to parse arguments"); return NULL; } //printf("export_svg: width=%f, height=%f, unit=%s\n", width, height, unit); PyObject* svg = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateSvg(reprGen, rawPlotSpecDict, width, height, unit); return svg; } static PyObject* export_png(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); PyObject *rawPlotSpecDict; float width; float height; const char* unit; int dpi; float scale; if (!PyArg_ParseTuple(args, "Offsif", &rawPlotSpecDict, &width, &height, &unit, &dpi, &scale)) { PyErr_SetString(PyExc_TypeError, "export_png: failed to parse arguments"); return NULL; } //printf("export_png: width=%f, height=%f, unit=%s, dpi=%d, scale=%f\n", width, height, unit, dpi, scale); PyObject* imageData = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.exportPng(reprGen, rawPlotSpecDict, width, height, unit, dpi, scale); return imageData; // base64 encoded PNG } static PyObject* export_mvg(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); PyObject *rawPlotSpecDict; float width; float height; const char* unit; int dpi; float scale; if (!PyArg_ParseTuple(args, "Offsif", &rawPlotSpecDict, &width, &height, &unit, &dpi, &scale)) { PyErr_SetString(PyExc_TypeError, "export_mvg: failed to parse arguments"); return NULL; } //printf("export_mvg: width=%f, height=%f, unit=%s, dpi=%d, scale=%f\n", width, height, unit, dpi, scale); PyObject* mvg = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.exportMvg(reprGen, rawPlotSpecDict, width, height, unit, dpi, scale); return mvg; } static PyObject* export_html(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); // parse arguments PyObject *rawPlotSpecDict; const char *scriptUrl; int iframe; // 0 - false, 1 - true PyArg_ParseTuple(args, "Osp", &rawPlotSpecDict, &scriptUrl, &iframe); PyObject* html = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateExportHtml(reprGen, rawPlotSpecDict, (void*)scriptUrl, iframe); return html; } static PyObject* get_static_configure_html(PyObject* self, PyObject* scriptUrl) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); if (!PyUnicode_Check(scriptUrl)) { PyErr_SetString(PyExc_TypeError, "string argument expected"); return NULL; } const char* scriptUrlStr = PyUnicode_AsUTF8(scriptUrl); PyObject* html = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateStaticConfigureHtml(reprGen, (void*)scriptUrlStr); return html; } static PyObject* get_display_html_for_raw_spec(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); PyObject *plotSpecDict; PyObject *sizingOptionsDict; int dynamicScriptLoading; int forceImmediateRender; int responsive; int height100pct; PyArg_ParseTuple(args, "OOpppp", &plotSpecDict, &sizingOptionsDict, &dynamicScriptLoading, &forceImmediateRender, &responsive, &height100pct ); PyObject* html = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateDisplayHtmlForRawSpec( reprGen, plotSpecDict, sizingOptionsDict, dynamicScriptLoading, forceImmediateRender, responsive, height100pct ); return html; } static PyObject* get_static_html_page_for_raw_spec(PyObject* self, PyObject* args) { T_(PlotReprGenerator) reprGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator._instance(); PyObject *plotSpecDict; const char *scriptUrl; PyObject *sizingOptionsDict; int dynamicScriptLoading; int forceImmediateRender; int responsive; int height100pct; PyArg_ParseTuple(args, "OsOpppp", &plotSpecDict, &scriptUrl, &sizingOptionsDict, &dynamicScriptLoading, &forceImmediateRender, &responsive, &height100pct ); PyObject* html = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.PlotReprGenerator.generateStaticHtmlPageForRawSpec( reprGen, plotSpecDict, (void*)scriptUrl, sizingOptionsDict, dynamicScriptLoading, forceImmediateRender, responsive, height100pct ); return html; } static PyObject* get_palette_from_color_scale_spec(PyObject* self, PyObject* args) { T_(ColorScalePaletteGenerator) paletteGen = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.ColorScalePaletteGenerator._instance(); PyObject *scaleSpecDict; int n; if (!PyArg_ParseTuple(args, "Oi", &scaleSpecDict, &n)) { PyErr_SetString(PyExc_TypeError, "get_palette_from_color_scale_spec: failed to parse arguments"); return NULL; } PyObject* palette = __ kotlin.root.org.jetbrains.letsPlot.pythonExtension.interop.ColorScalePaletteGenerator.generatePalette(paletteGen, scaleSpecDict, n); return palette; } static PyMethodDef module_methods[] = { // { "generate_html", (PyCFunction)generate_html, METH_O, "Generates HTML and JS sufficient for buidling of interactive plot." }, // Deprecated: use get_display_html_for_raw_spec { "export_svg", (PyCFunction)export_svg, METH_VARARGS, "Generates SVG representing plot." }, { "export_html", (PyCFunction)export_html, METH_VARARGS, "Generates HTML page showing plot." }, { "export_mvg", (PyCFunction)export_mvg, METH_VARARGS, "Generates MVG string representing plot. For internal use." }, { "export_png", (PyCFunction)export_png, METH_VARARGS, "Generates Base64-encoded PNG string representing plot." }, { "get_static_configure_html", (PyCFunction)get_static_configure_html, METH_O, "Generates static HTML configuration." }, { "get_display_html_for_raw_spec", (PyCFunction)get_display_html_for_raw_spec, METH_VARARGS, "Generates display HTML for raw plot spec." }, { "get_static_html_page_for_raw_spec", (PyCFunction)get_static_html_page_for_raw_spec, METH_VARARGS, "Generates static HTML page for raw plot spec." }, { "get_palette_from_color_scale_spec", (PyCFunction)get_palette_from_color_scale_spec, METH_VARARGS, "Generates color palette for a scale." }, { NULL } }; static struct PyModuleDef module_def = { PyModuleDef_HEAD_INIT, "lets_plot_kotlin_bridge", NULL, -1, // m_size: -1 => module does not support sub-interpreters, has global state module_methods, NULL, // m_slots: using single-phase initialization NULL, // m_traverse NULL, // m_clear NULL // m_free }; PyMODINIT_FUNC PyInit_lets_plot_kotlin_bridge(void) { PyObject *module = PyModule_Create(&module_def); return module; }