People ask in regular intervals on the users list how it is possible to get included graphics converted to pdf format rather than png for pdflatex export, because that results in higher quality output and/or smaller file size. See also http://bugzilla.lyx.org/show_bug.cgi?id=2868
This patch fixes this problem by replacing the hardcoded pdf conversion for ps and eps with a format flag that tells whether a format can contain vector graphics. All image formats that can contain vector graphics are then converted to pdf instead of png. This will go into trunk if I get no objections. An 1.4 backport is possible (and desirable IMHO), but changes of course the preferences file format. Georg Log: Fix bug 2868 * src/insets/insetgraphics.C (findTargetFormat): return pdf for vector graphics * src/format.h (Flags): new enum describing format flags (flags_): new member variable for format flags (vectorFormat): new, tell whether a format can contain vector graphics * src/format.C: adjust to flags changes * src/frontends/qt[34]/QPrefsDialog.C (QPrefsDialog::QPrefsDialog): handle new vector flag (QPrefsDialog::switch_format): ditto (QPrefsDialog::updateFormatsButtons): ditto (QPrefsDialog::new_format): ditto (QPrefsDialog::modify_format): ditto * src/frontends/qt3/ui/QPrefFileformatsModule.ui * src/frontends/qt4/ui/QPrefFileformatsUi.ui (vectorCB): new checkbox for vector flag * src/lyxrc.C (LyXRC::read): read vector flag (LyXRC::write): write vector flag * lib/doc/Customization.lyx: document format flags * lib/configure.py (checkFormatEntries): Add vector flag to some formats
Index: src/insets/insetgraphics.C =================================================================== --- src/insets/insetgraphics.C (Revision 15186) +++ src/insets/insetgraphics.C (Arbeitskopie) @@ -126,11 +126,12 @@ string findTargetFormat(string const & f // Are we using latex or pdflatex? if (runparams.flavor == OutputParams::PDFLATEX) { lyxerr[Debug::GRAPHICS] << "findTargetFormat: PDF mode" << endl; - // Convert postscript to pdf - if (format == "eps" || format == "ps") + Format const * const f = formats.getFormat(format); + // Convert vector graphics to pdf + if (f && f->vectorFormat()) return "pdf"; // pdflatex can use jpeg, png and pdf directly - if (format == "jpg" || format == "pdf") + if (format == "jpg") return format; // Convert everything else to png return "png"; Index: src/format.C =================================================================== --- src/format.C (Revision 15186) +++ src/format.C (Arbeitskopie) @@ -93,9 +93,9 @@ bool operator<(Format const & a, Format Format::Format(string const & n, string const & e, string const & p, string const & s, string const & v, string const & ed, - bool d) + int flags) : name_(n), extension_(e), prettyname_(p), shortcut_(s), viewer_(v), - editor_(ed), document_(d) + editor_(ed), flags_(flags) {} @@ -209,24 +209,25 @@ int Formats::getNumber(string const & na void Formats::add(string const & name) { if (!getFormat(name)) - add(name, name, name, string(), string(), string(), true); + add(name, name, name, string(), string(), string(), + Format::document); } void Formats::add(string const & name, string const & extension, string const & prettyname, string const & shortcut, - string const & viewer, string const & editor, bool document) + string const & viewer, string const & editor, + int flags) { FormatList::iterator it = find_if(formatlist.begin(), formatlist.end(), FormatNamesEqual(name)); if (it == formatlist.end()) formatlist.push_back(Format(name, extension, prettyname, - shortcut, viewer, editor, - document)); + shortcut, viewer, editor, flags)); else *it = Format(name, extension, prettyname, shortcut, viewer, - editor, document); + editor, flags); } Index: src/frontends/qt3/QPrefsDialog.C =================================================================== --- src/frontends/qt3/QPrefsDialog.C (Revision 15186) +++ src/frontends/qt3/QPrefsDialog.C (Arbeitskopie) @@ -188,6 +188,7 @@ QPrefsDialog::QPrefsDialog(QPrefs * form connect(fileformatsModule->viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed())); connect(fileformatsModule->editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed())); connect(fileformatsModule->documentCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed())); + connect(fileformatsModule->vectorCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed())); connect(convertersModule->converterNewPB, SIGNAL(clicked()), this, SLOT(new_converter())); connect(convertersModule->converterRemovePB, SIGNAL(clicked()), this, SLOT(remove_converter())); @@ -735,6 +736,7 @@ void QPrefsDialog::switch_format(int nr) fileformatsModule->viewerED->setText(toqstr(f.viewer())); fileformatsModule->editorED->setText(toqstr(f.editor())); fileformatsModule->documentCB->setChecked(f.documentFormat()); + fileformatsModule->vectorCB->setChecked(f.vectorFormat()); fileformatsModule->formatRemovePB->setEnabled( !form_->converters().formatIsUsed(f.name())); @@ -777,6 +779,7 @@ void QPrefsDialog::updateFormatsButtons( string const old_viewer(f.viewer()); string const old_editor(f.editor()); bool const old_document(f.documentFormat()); + bool const old_vector(f.vectorFormat()); string const new_pretty(fromqstr(gui_name)); string const new_shortcut(fromqstr(fileformatsModule->shortcutED->text())); @@ -784,10 +787,12 @@ void QPrefsDialog::updateFormatsButtons( string const new_viewer(fromqstr(fileformatsModule->viewerED->text())); string const new_editor(fromqstr(fileformatsModule->editorED->text())); bool const new_document(fileformatsModule->documentCB->isChecked()); + bool const new_vector(fileformatsModule->vectorCB->isChecked()); bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut) || (old_extension != new_extension) || (old_viewer != new_viewer) - || (old_editor != new_editor)) || old_document != new_document; + || old_editor != new_editor || old_document != new_document + || old_vector != new_vector); fileformatsModule->formatModifyPB->setEnabled( valid && known && modified && !known_otherwise); @@ -804,10 +809,14 @@ void QPrefsDialog::new_format() string const shortcut = fromqstr(fileformatsModule->shortcutED->text()); string const viewer = fromqstr(fileformatsModule->viewerED->text()); string const editor = fromqstr(fileformatsModule->editorED->text()); - bool const document = fileformatsModule->documentCB->isChecked(); + int flags = Format::none; + if (fileformatsModule->documentCB->isChecked()) + flags |= Format::document; + if (fileformatsModule->vectorCB->isChecked()) + flags |= Format::vector; form_->formats().add(name, extension, prettyname, shortcut, viewer, - editor, document); + editor, flags); form_->formats().sort(); updateFormats(); fileformatsModule->formatsLB->setCurrentItem(form_->formats().getNumber(name)); @@ -835,10 +844,14 @@ void QPrefsDialog::modify_format() string const shortcut = fromqstr(fileformatsModule->shortcutED->text()); string const viewer = fromqstr(fileformatsModule->viewerED->text()); string const editor = fromqstr(fileformatsModule->editorED->text()); - bool const document = fileformatsModule->documentCB->isChecked(); + int flags = Format::none; + if (fileformatsModule->documentCB->isChecked()) + flags |= Format::document; + if (fileformatsModule->vectorCB->isChecked()) + flags |= Format::vector; form_->formats().add(name, extension, prettyname, shortcut, viewer, - editor, document); + editor, flags); form_->formats().sort(); fileformatsModule->formatsLB->setUpdatesEnabled(false); Index: src/frontends/qt3/ui/QPrefFileformatsModule.ui =================================================================== --- src/frontends/qt3/ui/QPrefFileformatsModule.ui (Revision 15186) +++ src/frontends/qt3/ui/QPrefFileformatsModule.ui (Arbeitskopie) @@ -60,6 +60,17 @@ <string>Tell whether this format is a document format. A document can not be exported to or viewed in a non-document format.</string> </property> </widget> + <widget class="QCheckBox" row="7" column="1"> + <property name="name"> + <cstring>vectorCB</cstring> + </property> + <property name="text"> + <string>Vector graphi&cs format</string> + </property> + <property name="toolTip" stdset="0"> + <string>Tell whether this format can contain vector graphics.</string> + </property> + </widget> <widget class="QLineEdit" row="2" column="1"> <property name="name"> <cstring>shortcutED</cstring> @@ -336,6 +347,7 @@ <tabstop>viewerED</tabstop> <tabstop>editorED</tabstop> <tabstop>documentCB</tabstop> + <tabstop>vectorCB</tabstop> </tabstops> <includes> <include location="global" impldecl="in implementation">config.h</include> Index: src/frontends/qt4/QPrefsDialog.C =================================================================== --- src/frontends/qt4/QPrefsDialog.C (Revision 15186) +++ src/frontends/qt4/QPrefsDialog.C (Arbeitskopie) @@ -1293,6 +1293,7 @@ PrefFileformats::PrefFileformats(QPrefs connect(viewerED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed())); connect(editorED, SIGNAL(textChanged(const QString&)), this, SLOT(fileformat_changed())); connect(documentCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed())); + connect(vectorCB, SIGNAL(toggled(bool)), this, SLOT(fileformat_changed())); connect(formatNewPB, SIGNAL(clicked()), this, SIGNAL(changed())); connect(formatRemovePB, SIGNAL(clicked()), @@ -1356,6 +1357,7 @@ void PrefFileformats::switch_format(int viewerED->setText(toqstr(f.viewer())); editorED->setText(toqstr(f.editor())); documentCB->setChecked((f.documentFormat())); + vectorCB->setChecked((f.vectorFormat())); formatRemovePB->setEnabled( !form_->converters().formatIsUsed(f.name())); @@ -1398,6 +1400,7 @@ void PrefFileformats::updateButtons() string const old_viewer(f.viewer()); string const old_editor(f.editor()); bool const old_document(f.documentFormat()); + bool const old_vector(f.vectorFormat()); string const new_pretty(fromqstr(gui_name)); string const new_shortcut(fromqstr(shortcutED->text())); @@ -1405,10 +1408,12 @@ void PrefFileformats::updateButtons() string const new_viewer(fromqstr(viewerED->text())); string const new_editor(fromqstr(editorED->text())); bool const new_document(documentCB->isChecked()); + bool const new_vector(vectorCB->isChecked()); bool modified = ((old_pretty != new_pretty) || (old_shortcut != new_shortcut) || (old_extension != new_extension) || (old_viewer != new_viewer) - || (old_editor != new_editor) || old_document != new_document); + || old_editor != new_editor || old_document != new_document + || old_vector != new_vector); formatModifyPB->setEnabled( valid && known && modified && !known_otherwise); @@ -1429,10 +1434,14 @@ void PrefFileformats::new_format() string const shortcut = fromqstr(shortcutED->text()); string const viewer = fromqstr(viewerED->text()); string const editor = fromqstr(editorED->text()); - bool const document = documentCB->isChecked(); + int flags = Format::none; + if (documentCB->isChecked()) + flags |= Format::document; + if (vectorCB->isChecked()) + flags |= Format::vector; form_->formats().add(name, extension, prettyname, shortcut, viewer, - editor, document); + editor, flags); form_->formats().sort(); update(); @@ -1464,10 +1473,14 @@ void PrefFileformats::modify_format() string const shortcut = fromqstr(shortcutED->text()); string const viewer = fromqstr(viewerED->text()); string const editor = fromqstr(editorED->text()); - bool const document = documentCB->isChecked(); + int flags = Format::none; + if (documentCB->isChecked()) + flags |= Format::document; + if (vectorCB->isChecked()) + flags |= Format::vector; form_->formats().add(name, extension, prettyname, shortcut, viewer, - editor, document); + editor, flags); form_->formats().sort(); formatsLW->setUpdatesEnabled(false); Index: src/frontends/qt4/ui/QPrefFileformatsUi.ui =================================================================== --- src/frontends/qt4/ui/QPrefFileformatsUi.ui (Revision 15186) +++ src/frontends/qt4/ui/QPrefFileformatsUi.ui (Arbeitskopie) @@ -180,6 +180,19 @@ </property> </widget> </item> + <item row="7" column="0" > + <widget class="QCheckBox" name="vectorCB" > + <property name="enabled" > + <bool>true</bool> + </property> + <property name="toolTip" > + <string>Tell whether this format can contain vector graphics.</string> + </property> + <property name="text" > + <string>Vector graphi&cs format</string> + </property> + </widget> + </item> </layout> </item> <item row="4" column="0" > @@ -240,6 +253,7 @@ <tabstop>viewerED</tabstop> <tabstop>editorED</tabstop> <tabstop>documentCB</tabstop> + <tabstop>vectorCB</tabstop> <tabstop>formatNewPB</tabstop> <tabstop>formatModifyPB</tabstop> <tabstop>formatRemovePB</tabstop> Index: src/format.h =================================================================== --- src/format.h (Revision 15186) +++ src/format.h (Arbeitskopie) @@ -21,10 +21,20 @@ class Buffer; class Format { public: + /// Flags for some format properties + enum Flags { + none = 0, + /// Set if this format is a document format (as opposed to + /// e.g. image formats). + /// Some formats are both (e.g. pdf), they have this flag set. + document = 1, + /// Set if this format can contain vector graphics. + vector = 2, + }; /// Format(std::string const & n, std::string const & e, std::string const & p, std::string const & s, std::string const & v, std::string const & ed, - bool ex); + int); /// bool dummy() const; /// Tell whether this format is a child format. @@ -66,7 +76,11 @@ public: } /// bool documentFormat() const { - return document_; + return flags_ & document; + } + /// + bool vectorFormat() const { + return flags_ & vector; } private: /// Internal name. Needs to be unique. @@ -87,14 +101,14 @@ private: std::string viewer_; /// Editor for this format. \sa viewer_. std::string editor_; - /// Is this format a document format? (as opposed to e.g. image formats) - /// Some formats are both (e.g. pdf), they have this flag set. - bool document_; + /// + int flags_; }; bool operator<(Format const & a, Format const & b); + /// class Formats { public: @@ -126,7 +140,7 @@ public: void add(std::string const & name, std::string const & extension, std::string const & prettyname, std::string const & shortcut, std::string const & viewer, std::string const & editor, - bool document); + int flags); /// void erase(std::string const & name); /// Index: src/lyxrc.C =================================================================== --- src/lyxrc.C (Revision 15186) +++ src/lyxrc.C (Arbeitskopie) @@ -49,7 +49,6 @@ using lyx::support::expandPath; using lyx::support::getEnv; using lyx::support::libFileSearch; using lyx::support::token; -using lyx::support::tokenPos; using std::cout; using std::endl; @@ -1083,9 +1082,6 @@ int LyXRC::read(LyXLex & lexrc) viewer = lexrc.getString(); if (lexrc.next()) editor = lexrc.getString(); - // The only supported flag for now is "document". - // More flags could be added in the future. - // Therefore we use tokenPos below to read the flag. string flags; // Hack to ensure compatibility with versions older // than 1.5.0 @@ -1101,13 +1097,19 @@ int LyXRC::read(LyXLex & lexrc) flags.erase(); } } - bool const document = - (tokenPos(flags, ',', "document") >= 0); - if (!flags.empty() && flags != "document") - lyxerr << "Ignoring flags other than " - "`document' in `" << flags - << "' for format `" << format << "'." - << endl; + int flgs = Format::none; + while (!flags.empty()) { + string flag; + flags = lyx::support::split(flags, flag, ','); + if (flag == "document") + flgs |= Format::document; + else if (flag == "vector") + flgs |= Format::vector; + else + lyxerr << "Ignoring unknown flag `" + << flag << "' for format `" + << format << "'." << endl; + } if (prettyname.empty()) { if (converters.formatIsUsed(format)) { lyxerr << "Can't delete format " @@ -1117,7 +1119,7 @@ int LyXRC::read(LyXLex & lexrc) } } else { formats.add(format, extension, prettyname, - shortcut, viewer, editor, document); + shortcut, viewer, editor, flgs); } break; } @@ -2017,15 +2019,20 @@ void LyXRC::write(ostream & os, bool ign format->shortcut() != cit->shortcut() || format->viewer() != cit->viewer() || format->editor() != cit->editor() || - format->documentFormat() != cit->documentFormat()) { + format->documentFormat() != cit->documentFormat() || + format->vectorFormat() != cit->vectorFormat()) { os << "\\format \"" << cit->name() << "\" \"" << cit->extension() << "\" \"" << cit->prettyname() << "\" \"" << cit->shortcut() << "\" \"" << cit->viewer() << "\" \"" << cit->editor() << "\" \""; + std::vector<string> flags; if (cit->documentFormat()) - os << "document"; + flags.push_back("document"); + if (cit->vectorFormat()) + flags.push_back("vector"); + os << lyx::support::getStringFromVector(flags); os << "\"\n"; } } Index: lib/doc/Customization.lyx =================================================================== --- lib/doc/Customization.lyx (Revision 15186) +++ lib/doc/Customization.lyx (Arbeitskopie) @@ -1791,8 +1791,9 @@ P references:Conversion \family default dialog. - This does currently only work in the Windows® port of LyX, but it is planned - to implement this feature on all other ports that can support it, too. + This does currently only work in the Windows® and Mac OS X ports of LyX, + but it is planned to implement this feature on all other ports that can + support it, too. \end_layout \begin_layout Standard @@ -1848,6 +1849,110 @@ For example, the file may reference othe directory and may modify it in the process. \end_layout +\begin_layout Standard +Sometimes LyX needs to know a bit more about the properties of a format. + These bits can be specified with flags. + Currently there are two of them: +\end_layout + +\begin_layout Standard +The +\family typewriter +document +\family default + flag tells LyX that a format is suitable for document export. + If this flag is set for a format, and if a suitable conversion route exists, + then the format will appear in the +\family sans +\bar under +F +\bar default +ile\SpecialChar \menuseparator + +\bar under +E +\bar default +xport +\family default + menu. + The format will also appear in the +\family sans +\bar under +V +\bar default +iew +\family default + menu if it has a viewer associated to it. + Pure image formats (e.g.\InsetSpace ~ + +\family typewriter +png +\family default +) do not have this flag set, formats that can both represent images and + documents (e.g.\InsetSpace ~ + +\family typewriter +pdf +\family default +) do have it set. +\end_layout + +\begin_layout Standard +The +\family typewriter +vector +\family default + flag tells LyX whether a format can contain vector graphics. + This information is used to determine the target format of included graphics + for +\family typewriter +pdflatex +\family default + export. + Included graphics may need to be converted to either +\family typewriter +pdf +\family default +, +\family typewriter +png +\family default + or +\family typewriter +jpg +\family default +, since +\family typewriter +pdflatex +\family default + can not handle other image formats. + If an included graphic is not already in +\family typewriter +pdf +\family default +, +\family typewriter +png +\family default + or +\family typewriter +jpg +\family default + format it is converted to +\family typewriter +pdf +\family default + if the +\family typewriter +vector +\family default + flag of the format is set, and otherwise to +\family typewriter +png +\family default +. +\end_layout + \begin_layout Section BibTeX and makeindex \end_layout Index: lib/configure.py =================================================================== --- lib/configure.py (Revision 15186) +++ lib/configure.py (Arbeitskopie) @@ -220,13 +220,13 @@ def checkLatex(): def checkFormatEntries(): ''' Check all formats (\Format entries) ''' checkViewer('a Tgif viewer and editor', ['tgif'], - rc_entry = [r'\Format tgif obj Tgif "" "%%" "%%" ""']) + rc_entry = [r'\Format tgif obj Tgif "" "%%" "%%" "vector"']) # checkViewer('a FIG viewer and editor', ['xfig'], - rc_entry = [r'\Format fig fig FIG "" "%%" "%%" ""']) + rc_entry = [r'\Format fig fig FIG "" "%%" "%%" "vector"']) # checkViewer('a Grace viewer and editor', ['xmgrace'], - rc_entry = [r'\Format agr agr Grace "" "%%" "%%" ""']) + rc_entry = [r'\Format agr agr Grace "" "%%" "%%" "vector"']) # checkViewer('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'], rc_entry = [r'\Format fen fen FEN "" "%%" "%%" ""']) @@ -266,22 +266,22 @@ def checkFormatEntries(): #checkProg('a Postscript interpreter', ['gs'], # rc_entry = [ r'\ps_command "%%"' ]) checkViewer('a Postscript previewer', ['gv', 'ghostview -swap', 'kghostview'], - rc_entry = [r'''\Format eps eps EPS "" "%%" "" "" -\Format ps ps Postscript t "%%" "" "document"''']) + rc_entry = [r'''\Format eps eps EPS "" "%%" "" "vector" +\Format ps ps Postscript t "%%" "" "document,vector"''']) # checkViewer('a PDF previewer', ['acrobat', 'acroread', 'gv', 'ghostview', \ 'xpdf', 'kpdf', 'kghostview'], - rc_entry = [r'''\Format pdf pdf "PDF (ps2pdf)" P "%%" "" "document" -\Format pdf2 pdf "PDF (pdflatex)" F "%%" "" "document" -\Format pdf3 pdf "PDF (dvipdfm)" m "%%" "" "document"''']) + rc_entry = [r'''\Format pdf pdf "PDF (ps2pdf)" P "%%" "" "document,vector" +\Format pdf2 pdf "PDF (pdflatex)" F "%%" "" "document,vector" +\Format pdf3 pdf "PDF (dvipdfm)" m "%%" "" "document,vector"''']) # checkViewer('a DVI previewer', ['xdvi', 'kdvi'], - rc_entry = [r'\Format dvi dvi DVI D "%%" "" "document"']) + rc_entry = [r'\Format dvi dvi DVI D "%%" "" "document,vector"']) if ((os.name == 'nt' or sys.platform == 'cygwin') and checkProg('DVI to DTL converter', ['dv2dt']) != ['', ''] and checkProg('DTL to DVI converter', ['dt2dv']) != ['', '']): # Windows only: DraftDVI - addToRC(r'\Format dvi2 dvi DraftDVI "" "" "document"') + addToRC(r'\Format dvi2 dvi DraftDVI "" "" "document,vector"') # checkViewer('a HTML previewer', ['mozilla file://$$p$$i', 'netscape'], rc_entry = [r'\Format html html HTML H "%%" "" "document"']) @@ -295,10 +295,10 @@ def checkFormatEntries(): \Format pdftex pdftex_t PDFTEX "" "" "" "" \Format program "" Program "" "" "" "" \Format pstex pstex_t PSTEX "" "" "" "" -\Format rtf rtf "Rich Text Format" "" "" "" "document" -\Format sxw sxw "OpenOffice.Org Writer" O "" "" "document" -\Format wmf wmf "Windows Meta File" "" "" "" "" -\Format word doc "MS Word" W "" "" "document" +\Format rtf rtf "Rich Text Format" "" "" "" "document,vector" +\Format sxw sxw "OpenOffice.Org Writer" O "" "" "document,vector" +\Format wmf wmf "Windows Meta File" "" "" "" "vector" +\Format word doc "MS Word" W "" "" "document,vector" \Format wordhtml html "MS Word (HTML)" "" "" "" "document" ''')