diff options
| author | Marc Jeanmougin <marc@jeanmougin.fr> | 2017-02-05 19:24:08 +0000 |
|---|---|---|
| committer | Marc Jeanmougin <marcjeanmougin@free.fr> | 2017-02-05 19:24:08 +0000 |
| commit | 6947ff531840b67cafd4c7931e6b7bb9ceaf7d70 (patch) | |
| tree | e648223cc925b2fbe62b7063262eed68f3463541 | |
| parent | add missing header (diff) | |
| download | inkscape-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)
| -rw-r--r-- | inkscape.pod | 10 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/document.cpp | 14 | ||||
| -rw-r--r-- | src/document.h | 18 | ||||
| -rw-r--r-- | src/file-update.cpp | 173 | ||||
| -rw-r--r-- | src/file.h | 3 | ||||
| -rw-r--r-- | src/main.cpp | 9 |
7 files changed, 224 insertions, 4 deletions
diff --git a/inkscape.pod b/inkscape.pod index 451e690f8..a8369f28a 100644 --- a/inkscape.pod +++ b/inkscape.pod @@ -63,6 +63,7 @@ options: -z, --without-gui --vacuum-defs + --no-convert-text-baseline-spacing --g-fatal-warnings @@ -342,6 +343,15 @@ Remove all unused items from the <lt>defs<gt> section of the SVG file. If this option is invoked in conjunction with --export-plain-svg, only the exported file will be affected. If it is used alone, the specified file will be modified in place. +=item B<--no-convert-text-baseline-spacing> + +Do not automatically fix text baselines in legacy (pre-0.92) files on +opening. Inkscape 0.92 adopts the CSS standard definition for the +'line-height' property, which differs from past versions. By default, +the line height values in files created prior to Inkscape 0.92 will be +adjusted on loading to preserve the intended text layout. This command +line option will skip that adjustment. + =item B<-z>, B<--without-gui> Do not open the GUI (on Unix, do not use X server); only process the files from console. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47aa02ef1..bb45ffa4a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -200,6 +200,7 @@ set(inkscape_SRC event-log.cpp extract-uri.cpp file.cpp + file-update.cpp filter-chemistry.cpp filter-enums.cpp gc-anchored.cpp diff --git a/src/document.cpp b/src/document.cpp index 57208582a..b69508751 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -49,6 +49,7 @@ #include "display/drawing.h" #include "document-private.h" #include "document-undo.h" +#include "file.h" #include "id-clash.h" #include "inkscape.h" #include "inkscape-version.h" @@ -71,7 +72,7 @@ using Inkscape::Util::unit_table; // since we want it to happen when there are no more updates. #define SP_DOCUMENT_REROUTING_PRIORITY (G_PRIORITY_HIGH_IDLE - 1) - +bool sp_no_convert_text_baseline_spacing = false; static gint sp_document_idle_handler(gpointer data); static gint sp_document_rerouting_handler(gpointer data); @@ -452,6 +453,17 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc, )); document->oldSignalsConnected = true; + /** Fix baseline spacing (pre-92 files) **/ + if ( (!sp_no_convert_text_baseline_spacing) + && sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) { + sp_file_convert_text_baseline_spacing(document); + } + + /** Fix font names in legacy documents (pre-92 files) **/ + if ( sp_version_inside_range( document->root->version.inkscape, 0, 1, 0, 92 ) ) { + sp_file_convert_font_name(document); + } + return document; } diff --git a/src/document.h b/src/document.h index 49bde1897..142eb5000 100644 --- a/src/document.h +++ b/src/document.h @@ -30,6 +30,24 @@ #include <set> #include <deque> +// This variable is introduced with 0.92.1 +// with the introduction of automatic fix +// for files detected to have been created +// with previous versions to have a similar +// look in 0.92+. +extern bool sp_no_convert_text_baseline_spacing; + + + +// This variable is introduced with 0.92.1 +// with the introduction of automatic fix +// for files detected to have been created +// with previous versions to have a similar +// look in 0.92+. +extern bool sp_do_not_fix_pre_92; + + + namespace Avoid { class Router; } 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 : diff --git a/src/file.h b/src/file.h index 4ffbc8ec0..2fc4ea910 100644 --- a/src/file.h +++ b/src/file.h @@ -203,7 +203,8 @@ void sp_file_print (Gtk::Window& parentWindow); * clean unused defs out of file */ void sp_file_vacuum (SPDocument *doc); - +void sp_file_convert_text_baseline_spacing(SPDocument *doc); +void sp_file_convert_font_name(SPDocument *doc); #endif // SEEN_SP_FILE_H diff --git a/src/main.cpp b/src/main.cpp index 605c1207e..47cf43456 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -166,6 +166,7 @@ enum { SP_ARG_SHELL, SP_ARG_VERSION, SP_ARG_VACUUM_DEFS, + SP_ARG_NO_CONVERT_TEXT_BASELINE_SPACING, #ifdef WITH_DBUS SP_ARG_DBUS_LISTEN, SP_ARG_DBUS_NAME, @@ -235,7 +236,6 @@ static gchar *sp_xverbs_yaml_utf8 = NULL; static gchar *sp_xverbs_yaml = NULL; #endif // WITH_YAML - /** * Reset variables to default values. */ @@ -274,6 +274,7 @@ static void resetCommandlineGlobals() { sp_query_all = FALSE; sp_query_id = NULL; sp_vacuum_defs = FALSE; + sp_no_convert_text_baseline_spacing = FALSE; #ifdef WITH_DBUS sp_dbus_listen = FALSE; sp_dbus_name = NULL; @@ -525,6 +526,11 @@ struct poptOption options[] = { N_("Start Inkscape in interactive shell mode."), NULL}, + {"no-convert-text-baseline-spacing", 0, + POPT_ARG_NONE, &sp_no_convert_text_baseline_spacing, SP_ARG_NO_CONVERT_TEXT_BASELINE_SPACING, + N_("Do not fix legacy (pre-0.92) files' text baseline spacing on opening."), + NULL}, + POPT_AUTOHELP POPT_TABLEEND }; @@ -1636,7 +1642,6 @@ static int sp_do_export_png(SPDocument *doc) return retcode; } - /** * Perform a PDF/PS/EPS export * |
