From 6947ff531840b67cafd4c7931e6b7bb9ceaf7d70 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 5 Feb 2017 20:24:08 +0100 Subject: 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) --- src/file-update.cpp | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 src/file-update.cpp (limited to 'src/file-update.cpp') 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 +#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 cl = o->childList(false); + bool beginning = true; + for (vector::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 cl = o->childList(false); + for (vector::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 cl = o->childList(false); + for (vector::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 cl = o->childList(false); + for (vector::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 cl = o->childList(false); + for (vector::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 : -- cgit v1.2.3