summaryrefslogtreecommitdiffstats
path: root/src/file-update.cpp
diff options
context:
space:
mode:
authorMarc Jeanmougin <marc@jeanmougin.fr>2017-02-05 19:24:08 +0000
committerMarc Jeanmougin <marcjeanmougin@free.fr>2017-02-05 19:24:08 +0000
commit6947ff531840b67cafd4c7931e6b7bb9ceaf7d70 (patch)
treee648223cc925b2fbe62b7063262eed68f3463541 /src/file-update.cpp
parentadd missing header (diff)
downloadinkscape-6947ff531840b67cafd4c7931e6b7bb9ceaf7d70.tar.gz
inkscape-6947ff531840b67cafd4c7931e6b7bb9ceaf7d70.zip
forward-port from 0.92.x the line height conversion from <.92 to >=.92
Code written by su_v in python as an extension, ported to c++ by Mc, some fixes added by bryce. http://bazaar.launchpad.net/~inkscape.dev/inkscape/0.92.x/revision/15338 http://bazaar.launchpad.net/~inkscape.dev/inkscape/0.92.x/revision/15339 http://bazaar.launchpad.net/~inkscape.dev/inkscape/0.92.x/revision/15350 http://bazaar.launchpad.net/~inkscape.dev/inkscape/0.92.x/revision/15351 Option to disable it is called --no-convert-text-baseline-spacing The terminology "convert" is chosen as a jargon word to be used for all such legacy file conversions. The "--no-XXX" naming style is adopted from the convention used by other software such as GIMP. (bzr r15481)
Diffstat (limited to 'src/file-update.cpp')
-rw-r--r--src/file-update.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/file-update.cpp b/src/file-update.cpp
new file mode 100644
index 000000000..40a8bc834
--- /dev/null
+++ b/src/file-update.cpp
@@ -0,0 +1,173 @@
+/**
+ * @file-update
+ * Operations to bump files from the pre-0.92 era into the 0.92+ era
+ * (90dpi vs 96dpi, line height problems, and related bugs)
+ */
+/* Authors:
+ * Tavmjong Bah
+ * Marc Jeanmougin
+ * su_v
+ */
+#include "file.h"
+#include "sp-root.h"
+#include "sp-text.h"
+#include "sp-tspan.h"
+#include "sp-flowdiv.h"
+#include "sp-flowtext.h"
+#include "sp-object.h"
+#include "sp-item.h"
+#include "style.h"
+#include "document.h"
+#include <string>
+#include "text-editing.h"
+
+using namespace std;
+
+bool is_line(SPObject *i)
+{
+ if (!(i->getAttribute("sodipodi:role")))
+ return false;
+ return !strcmp(i->getAttribute("sodipodi:role"), "line");
+}
+
+
+void fix_blank_line(SPObject *o)
+{
+ if (SP_IS_TEXT(o))
+ ((SPText *)o)->rebuildLayout();
+ else if (SP_IS_FLOWTEXT(o))
+ ((SPFlowtext *)o)->rebuildLayout();
+
+ SPIFontSize fontsize = o->style->font_size;
+ SPILengthOrNormal lineheight = o->style->line_height;
+ vector<SPObject *> cl = o->childList(false);
+ bool beginning = true;
+ for (vector<SPObject *>::const_iterator ci = cl.begin(); ci != cl.end(); ++ci) {
+ SPObject *i = *ci;
+ if ((SP_IS_TSPAN(i) && is_line(i)) || SP_IS_FLOWPARA(i) || SP_IS_FLOWDIV(i)) {
+ if (sp_text_get_length((SPItem *)i) <= 1) { // empty line
+ Inkscape::Text::Layout::iterator pos = te_get_layout((SPItem*)(o))->charIndexToIterator(
+ ((SP_IS_FLOWPARA(i) || SP_IS_FLOWDIV(i))?0:((ci==cl.begin())?0:1)) + sp_text_get_length_upto(o,i) );
+ sp_te_insert((SPItem *)o, pos, "\u00a0"); //"\u00a0"
+ gchar *l = g_strdup_printf("%f", lineheight.value);
+ gchar *f = g_strdup_printf("%f", fontsize.value);
+ i->style->line_height.readIfUnset(l);
+ if (!beginning)
+ i->style->font_size.read(f);
+ else
+ i->style->font_size.readIfUnset(f);
+ g_free(l);
+ g_free(f);
+ } else {
+ beginning = false;
+ fontsize = i->style->font_size;
+ lineheight = o->style->line_height;
+ }
+ }
+ }
+}
+
+void fix_line_spacing(SPObject *o)
+{
+ SPILengthOrNormal lineheight = o->style->line_height;
+ bool inner = false;
+ vector<SPObject *> cl = o->childList(false);
+ for (vector<SPObject *>::const_iterator ci = cl.begin(); ci != cl.end(); ++ci) {
+ SPObject *i = *ci;
+ if ((SP_IS_TSPAN(i) && is_line(i)) || SP_IS_FLOWPARA(i) || SP_IS_FLOWDIV(i)) {
+ // if no line-height attribute, set it
+ gchar *l = g_strdup_printf("%f", lineheight.value);
+ i->style->line_height.readIfUnset(l);
+ g_free(l);
+ }
+ inner = true;
+ }
+ if (inner) {
+ if (SP_IS_TEXT(o)) {
+ o->style->line_height.read("0.00%");
+ } else {
+ o->style->line_height.read("0.01%");
+ }
+ }
+}
+
+void fix_font_name(SPObject *o)
+{
+ vector<SPObject *> cl = o->childList(false);
+ for (vector<SPObject *>::const_iterator ci = cl.begin(); ci != cl.end(); ++ci)
+ fix_font_name(*ci);
+ string prev = o->style->font_family.value ? o->style->font_family.value : o->style->font_family.value_default;
+ if (prev == "Sans")
+ o->style->font_family.read("sans-serif");
+ else if (prev == "Serif")
+ o->style->font_family.read("serif");
+ else if (prev == "Monospace")
+ o->style->font_family.read("monospace");
+}
+
+
+void fix_font_size(SPObject *o)
+{
+ SPIFontSize fontsize = o->style->font_size;
+ if (!fontsize.set)
+ return;
+ bool inner = false;
+ vector<SPObject *> cl = o->childList(false);
+ for (vector<SPObject *>::const_iterator ci = cl.begin(); ci != cl.end(); ++ci) {
+ SPObject *i = *ci;
+ fix_font_size(i);
+ if ((SP_IS_TSPAN(i) && is_line(i)) || SP_IS_FLOWPARA(i) || SP_IS_FLOWDIV(i)) {
+ inner = true;
+ gchar *s = g_strdup_printf("%f", fontsize.value);
+ if (fontsize.set)
+ i->style->font_size.readIfUnset(s);
+ g_free(s);
+ }
+ }
+ if (inner && (SP_IS_TEXT(o) || SP_IS_FLOWTEXT(o)))
+ o->style->font_size.clear();
+}
+
+
+
+// helper function
+void sp_file_text_run_recursive(void (*f)(SPObject *), SPObject *o)
+{
+ if (SP_IS_TEXT(o) || SP_IS_FLOWTEXT(o))
+ f(o);
+ else {
+ vector<SPObject *> cl = o->childList(false);
+ for (vector<SPObject *>::const_iterator ci = cl.begin(); ci != cl.end(); ++ci)
+ sp_file_text_run_recursive(f, *ci);
+ }
+}
+
+void fix_update(SPObject *o) {
+ o->style->write();
+ o->updateRepr();
+}
+
+void sp_file_convert_text_baseline_spacing(SPDocument *doc)
+{
+ sp_file_text_run_recursive(fix_blank_line, doc->getRoot());
+ sp_file_text_run_recursive(fix_line_spacing, doc->getRoot());
+ sp_file_text_run_recursive(fix_font_size, doc->getRoot());
+ sp_file_text_run_recursive(fix_update, doc->getRoot());
+}
+
+void sp_file_convert_font_name(SPDocument *doc)
+{
+ sp_file_text_run_recursive(fix_font_name, doc->getRoot());
+ sp_file_text_run_recursive(fix_update, doc->getRoot());
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :