commit ea81faa911fc2561a017eb36c3a3d0bbe5b86756
Author: Enrico Forestieri <for...@lyx.org>
Date:   Sun Jun 24 20:06:40 2018 +0200

    Fix bug #11180
    
    When a raster image with an advertised pixel density different
    from 72 dpi is included in a latex file, the output image dimensions
    are scaled by the ratio 72/pixel_density. Hence, if a clipping
    bounding box is specified, it has to be scaled by the same ratio,
    otherwise the images will be clipped differently on screen and output.
    Here we use the extractbb command (present in any TeX distribution)
    to ask about the output dimensions of the image as dictated by the
    pixel density and compute the scaling ratio by the knowledge of the
    actual dimensions. If, for whatever reason, extractbb is not found,
    everything goes as before, because the clipping bounding box will
    simply not be corrected.
    
    (cherry picked from commit 380f34a11485c41d812695dc4279b24a5ed5cc07)
---
 src/insets/InsetGraphics.cpp |   77 +++++++++++++++++++++++++++++++++++++++--
 src/insets/InsetGraphics.h   |    2 +
 status.23x                   |    2 +
 3 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp
index a46d3fb..c1d9822 100644
--- a/src/insets/InsetGraphics.cpp
+++ b/src/insets/InsetGraphics.cpp
@@ -74,6 +74,10 @@ TODO
 #include "frontends/alert.h"
 #include "frontends/Application.h"
 
+#include "graphics/GraphicsCache.h"
+#include "graphics/GraphicsCacheItem.h"
+#include "graphics/GraphicsImage.h"
+
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
@@ -83,8 +87,11 @@ TODO
 #include "support/lyxlib.h"
 #include "support/lstrings.h"
 #include "support/os.h"
+#include "support/qstring_helpers.h"
 #include "support/Systemcall.h"
 
+#include <QProcess>
+
 #include <algorithm>
 #include <sstream>
 #include <tuple>
@@ -304,6 +311,66 @@ void InsetGraphics::read(Lexer & lex)
 }
 
 
+void InsetGraphics::outBoundingBox(graphics::BoundingBox & bbox) const
+{
+       if (bbox.empty())
+               return;
+
+       FileName const file(params().filename.absFileName());
+
+       // No correction is necessary for a postscript image
+       bool const zipped = theFormats().isZippedFile(file);
+       FileName const unzipped_file = zipped ? unzipFile(file) : file;
+       string const format = theFormats().getFormatFromFile(unzipped_file);
+       if (zipped)
+               unzipped_file.removeFile();
+       if (Formats::isPostScriptFileFormat(format))
+               return;
+
+       // Get the actual image dimensions in pixels
+       int width = 0;
+       int height = 0;
+       graphics::Cache & gc = graphics::Cache::get();
+       if (gc.inCache(file)) {
+               graphics::Image const * image = gc.item(file)->image();
+               if (image) {
+                       width  = image->width();
+                       height = image->height();
+               }
+       }
+       if (width == 0 || height == 0)
+               return;
+
+       // Use extractbb to find the dimensions in the typeset output
+       QProcess extractbb;
+       extractbb.start("extractbb", QStringList() << "-O" << 
toqstr(file.absFileName()));
+       if (!extractbb.waitForStarted() || !extractbb.waitForFinished()) {
+               LYXERR0("Cannot read output bounding box of " << file);
+               return;
+       }
+
+       string const result = extractbb.readAll().constData();
+       size_t i = result.find("%%BoundingBox:");
+       if (i == string::npos) {
+               LYXERR0("Cannot find output bounding box of " << file);
+               return;
+       }
+
+       string const bb = result.substr(i);
+       int out_width = convert<int>(token(bb, ' ', 3));
+       int out_height = convert<int>(token(bb, ' ', 4));
+
+       // Compute the scaling ratio and correct the bounding box
+       double scalex = out_width / double(width);
+       double scaley = out_height / double(height);
+
+       bbox.xl.value(scalex * bbox.xl.value());
+       bbox.xr.value(scalex * bbox.xr.value());
+       bbox.yb.value(scaley * bbox.yb.value());
+       bbox.yt.value(scaley * bbox.yt.value());
+}
+
+
 string InsetGraphics::createLatexOptions(bool const ps) const
 {
        // Calculate the options part of the command, we must do it to a string
@@ -311,11 +378,13 @@ string InsetGraphics::createLatexOptions(bool const ps) 
const
        // before writing it to the output stream.
        ostringstream options;
        if (!params().bbox.empty()) {
+               graphics::BoundingBox out_bbox = params().bbox;
+               outBoundingBox(out_bbox);
                string const key = ps ? "bb=" : "viewport=";
-               options << key << params().bbox.xl.asLatexString() << ' '
-                       << params().bbox.yb.asLatexString() << ' '
-                       << params().bbox.xr.asLatexString() << ' '
-                       << params().bbox.yt.asLatexString() << ',';
+               options << key << out_bbox.xl.asLatexString() << ' '
+                       << out_bbox.yb.asLatexString() << ' '
+                       << out_bbox.xr.asLatexString() << ' '
+                       << out_bbox.yt.asLatexString() << ',';
        }
        if (params().draft)
            options << "draft,";
diff --git a/src/insets/InsetGraphics.h b/src/insets/InsetGraphics.h
index 58b28ab..27f9cf1 100644
--- a/src/insets/InsetGraphics.h
+++ b/src/insets/InsetGraphics.h
@@ -113,6 +113,8 @@ private:
        Inset * clone() const;
        /// Get the status message, depends on the image loading status.
        std::string statusMessage() const;
+       /// Get the output bounding box accounting for raster formats.
+       void outBoundingBox(graphics::BoundingBox &) const;
        /// Create the options for the latex command.
        std::string createLatexOptions(bool const ps) const;
        /// Create length values for docbook export.
diff --git a/status.23x b/status.23x
index 14a978a..d0cf002 100644
--- a/status.23x
+++ b/status.23x
@@ -153,6 +153,8 @@ What's new
 
 - Don't step counters in deleted material (bug 11135).
 
+- Fix display of raster graphics with viewports (bug 11180).
+
 
 * INTERNALS
 

Reply via email to