+string const InsetGraphics::toDocbookLength(LyXLength const & len) const
+{
+ ostringstream result;
+ switch (len.unit()) {
+ case LyXLength::SP: // Scaled point (65536sp = 1pt) TeX's smallest unit.
+ result << len.value() * 65536.0 * 72 / 72.27 << "pt";
+ break;
+ case LyXLength::PT: // Point = 1/72.27in = 0.351mm
+ result << len.value() * 72 / 72.27 << "pt";
+ break;
+ case LyXLength::BP: // Big point (72bp = 1in), also PostScript point
+ result << len.value() << "pt";
+ break;
+ case LyXLength::DD: // Didot point = 1/72 of a French inch, = 0.376mm
+ result << len.value() * 0.376 << "mm";
+ break;
+ case LyXLength::MM: // Millimeter = 2.845pt
+ result << len.value() << "mm";
+ break;
+ case LyXLength::PC: // Pica = 12pt = 4.218mm
+ result << len.value() << "pc";
+ break;
+ case LyXLength::CC: // Cicero = 12dd = 4.531mm
+ result << len.value() * 4.531 << "mm";
+ break;
+ case LyXLength::CM: // Centimeter = 10mm = 2.371pc
+ result << len.value() << "cm";
+ break;
+ case LyXLength::IN: // Inch = 25.4mm = 72.27pt = 6.022pc
+ result << len.value() << "in";
+ break;
+ case LyXLength::EX: // Height of a small "x" for the current font.
+ // Obviously we have to compromise here. Any better ratio than 1.5 ?
+ result << len.value() / 1.5 << "em";
+ break;
+ case LyXLength::EM: // Width of capital "M" in current font.
+ result << len.value() << "em";
+ break;
+ case LyXLength::MU: // Math unit (18mu = 1em) for positioning in math mode
+ result << len.value() * 18 << "em";
+ break;
+ case LyXLength::PTW: // Percent of TextWidth
+ case LyXLength::PCW: // Percent of ColumnWidth
+ case LyXLength::PPW: // Percent of PageWidth
+ case LyXLength::PLW: // Percent of LineWidth
+ case LyXLength::PTH: // Percent of TextHeight
+ case LyXLength::PPH: // Percent of Paper
+ // Sigh, this will go wrong.
+ result << len.value() << "%";
+ break;
+ default:
+ result << len.asString();
+ break;
+ }
+ return result.str();
+}
+
+string const InsetGraphics::createDocBookAttributes() const
+{
+ // Calculate the options part of the command, we must do it to a string
+ // stream since we copied the code from createLatexParams() ;-)
+
+ // FIXME: av: need to translate spec -> Docbook XSL spec (http://www.sagehill.net/docbookxsl/ImageSizing.html)
+ // Right now it only works with my version of db2latex :-)
+
+ ostringstream options;
+ double const scl = convert<double>(params().scale);
+ if (!params().scale.empty() && !float_equal(scl, 0.0, 0.05)) {
+ if (!float_equal(scl, 100.0, 0.05))
+ options << " scale=\""
+ << static_cast<int>( (scl) + 0.5 )
+ << "\" ";
+ } else {
+ if (!params().width.zero()) {
+ options << " width=\"" << toDocbookLength(params().width) << "\" ";
+ }
+ if (!params().height.zero()) {
+ options << " depth=\"" << toDocbookLength(params().height) << "\" ";
+ }
+ if (params().keepAspectRatio) {
+ // This will be irrelevant unless both width and height are set
+ options << "scalefit=\"1\" ";
+ }
+ }
+
+
+ if (!params().special.empty())
+ options << params().special << " ";
+
+ string opts = options.str();
+ // trailing blanks are ok ...
+ return opts;
+}
+
+
+namespace {
+
+enum CopyStatus {
+ SUCCESS,
+ FAILURE,
+ IDENTICAL_PATHS,
+ IDENTICAL_CONTENTS
+};
+
+
+std::pair<CopyStatus, string> const
+copyFileIfNeeded(string const & file_in, string const & file_out)
+{
+ BOOST_ASSERT(AbsolutePath(file_in));
+ BOOST_ASSERT(AbsolutePath(file_out));
+
+ unsigned long const checksum_in = support::sum(file_in);
+ unsigned long const checksum_out = support::sum(file_out);
+
+ if (checksum_in == checksum_out)
+ // Nothing to do...
+ return std::make_pair(IDENTICAL_CONTENTS, file_out);
+
+ Mover const & mover = movers(formats.getFormatFromFile(file_in));
+ bool const success = mover.copy(file_in, file_out);
+ if (!success) {
+ lyxerr[Debug::GRAPHICS]
+ << support::bformat(_("Could not copy the file\n%1$s\n"
+ "into the temporary directory."),
+ file_in)
+ << std::endl;
+ }
+
+ CopyStatus status = success ? SUCCESS : FAILURE;
+ return std::make_pair(status, file_out);
+}
+
+
+std::pair<CopyStatus, string> const
+copyToDirIfNeeded(string const & file_in, string const & dir, bool zipped)
+{
+ using support::rtrim;
+
+ BOOST_ASSERT(AbsolutePath(file_in));
+
+ string const only_path = support::OnlyPath(file_in);
+ if (rtrim(support::OnlyPath(file_in) , "/") == rtrim(dir, "/"))
+ return std::make_pair(IDENTICAL_PATHS, file_in);
+
+ string mangled = FileName(file_in).mangledFilename();
+ if (zipped) {
+ // We need to change _eps.gz to .eps.gz. The mangled name is
+ // still unique because of the counter in mangledFilename().
+ // We can't just call mangledFilename() with the zip
+ // extension removed, because base.eps and base.eps.gz may
+ // have different content but would get the same mangled
+ // name in this case.
+ string const base = RemoveExtension(unzippedFileName(file_in));
+ string::size_type const ext_len = file_in.length() - base.length();
+ mangled[mangled.length() - ext_len] = '.';
+ }
+ string const file_out = support::MakeAbsPath(mangled, dir);
+
+ return copyFileIfNeeded(file_in, file_out);
+}
+
+
+string const stripExtension(string const & file)
+{
+ // Remove the extension so the LaTeX will use whatever
+ // is appropriate (when there are several versions in
+ // different formats)
+ // This works only if the filename contains no dots besides
+ // the just removed one. We can fool here by replacing all
+ // dots with a macro whose definition is just a dot ;-)
+ return subst(RemoveExtension(file), ".", "\\lyxdot ");
+}
+
+
+string const stripExtensionIfPossible(string const & file, string const & to)