Skip to content

Commit

Permalink
additional image formats
Browse files Browse the repository at this point in the history
  • Loading branch information
jjallaire committed May 6, 2011
1 parent b931288 commit d637ee0
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 63 deletions.
16 changes: 9 additions & 7 deletions src/cpp/r/include/r/session/RGraphics.hpp
Expand Up @@ -56,6 +56,11 @@ struct DisplayState
int plotCount;
};

extern const char * const kPngFormat;
extern const char * const kJpegFormat;
extern const char * const kTiffFormat;
extern const char * const kBmpFormat;

class Display
{
public:
Expand All @@ -70,13 +75,10 @@ class Display
virtual core::Error removePlot(int index) = 0;

// actions on active plot
virtual core::Error savePlotAsPng(const core::FilePath& filePath,
int widthPx,
int heightPx) = 0;

virtual core::Error savePlotAsPdf(const core::FilePath& filePath,
int widthPx,
int heightPx) = 0;
virtual core::Error savePlotAsImage(const core::FilePath& filePath,
const std::string& format,
int widthPx,
int heightPx) = 0;

virtual core::Error savePlotAsPdf(const core::FilePath& filePath,
double widthInches,
Expand Down
65 changes: 51 additions & 14 deletions src/cpp/r/session/graphics/RGraphicsPlotManager.cpp
Expand Up @@ -39,6 +39,11 @@ namespace r {
namespace session {
namespace graphics {

const char * const kPngFormat = "png";
const char * const kJpegFormat = "jpeg";
const char * const kBmpFormat = "bmp";
const char * const kTiffFormat = "tiff";


// satisfy r::session::graphics::Display singleton
Display& display()
Expand Down Expand Up @@ -229,24 +234,56 @@ Error PlotManager::savePlotAsFile(const std::string& deviceCreationCode)
boost::bind(r::exec::executeString, deviceCreationCode));
}

Error PlotManager::savePlotAsPng(const FilePath& filePath,
int widthPx,
int heightPx)
Error PlotManager::savePlotAsImage(const FilePath& filePath,
const std::string& format,
int widthPx,
int heightPx)
{
return savePlotAsFile(boost::bind(file_device::create,
widthPx,
heightPx,
filePath));
if (format == kPngFormat)
{
return savePlotAsFile(boost::bind(file_device::create,
widthPx,
heightPx,
filePath));
}
else if (format == kBmpFormat || format == kJpegFormat || format == kTiffFormat)
{
return savePlotAsBitmapFile(format, widthPx, heightPx, filePath);
}
else
{
return systemError(boost::system::errc::invalid_argument, ERROR_LOCATION);
}
}


Error PlotManager::savePlotAsPdf(const core::FilePath& filePath,
int widthPx,
int heightPx)
Error PlotManager::savePlotAsBitmapFile(const std::string& bitmapFileType,
int width,
int height,
const FilePath& targetPath)
{
double widthInches = (double)widthPx / 72.0;
double heightInches = (double)heightPx / 72.0;
return savePlotAsPdf(filePath, widthInches, heightInches);
// optional format specific extra params
std::string extraParams;

// add extra quality parameter for jpegs
if (bitmapFileType == kJpegFormat)
extraParams = ", quality = 100";

#ifdef __APPLE__
extraParams += ", type = \"quartz\"";
#endif

// generate code for creating bitmap file device
boost::format fmt(
"{ require(grDevices, quietly=TRUE); "
" %1%(filename=\"%2%\", width=%3%, height=%4%, pointsize = 16 %5%); }");
std::string deviceCreationCode = boost::str(fmt % bitmapFileType %
targetPath %
width %
height %
extraParams);

// save the file
return savePlotAsFile(deviceCreationCode);
}

Error PlotManager::savePlotAsPdf(const FilePath& filePath,
Expand Down
22 changes: 11 additions & 11 deletions src/cpp/r/session/graphics/RGraphicsPlotManager.hpp
Expand Up @@ -72,13 +72,10 @@ class PlotManager : boost::noncopyable, public r::session::graphics::Display
virtual core::Error removePlot(int index);

// actions on active plot
virtual core::Error savePlotAsPng(const core::FilePath& filePath,
int widthPx,
int heightPx);

virtual core::Error savePlotAsPdf(const core::FilePath& filePath,
int widthPx,
int heightPx);
virtual core::Error savePlotAsImage(const core::FilePath& filePath,
const std::string& format,
int widthPx,
int heightPx);

virtual core::Error savePlotAsPdf(const core::FilePath& filePath,
double widthInches,
Expand Down Expand Up @@ -134,10 +131,13 @@ class PlotManager : boost::noncopyable, public r::session::graphics::Display
core::Error savePlotAsFile(const boost::function<core::Error()>&
deviceCreationFunction);
core::Error savePlotAsFile(const std::string& fileDeviceCreationCode);
core::Error savePlotAsFile(const std::string& fileType,
int width,
int height,
const core::FilePath& targetPath);

core::Error savePlotAsBitmapFile(const std::string& bitmapFileType,
int width,
int height,
const core::FilePath& targetPath);



// error helpers
core::Error plotIndexError(int index, const core::ErrorLocation& location)
Expand Down
59 changes: 32 additions & 27 deletions src/cpp/session/modules/SessionPlots.cpp
Expand Up @@ -112,9 +112,11 @@ Error exportPlot(const json::JsonRpcRequest& request,
FilePath plotPath = module_context::resolveAliasedPath(path);

// save plot
return r::session::graphics::display().savePlotAsPng(plotPath,
width,
height);
using namespace r::session::graphics;
return r::session::graphics::display().savePlotAsImage(plotPath,
kPngFormat,
width,
height);
}

Error savePlotAs(const json::JsonRpcRequest& request,
Expand All @@ -137,18 +139,7 @@ Error savePlotAs(const json::JsonRpcRequest& request,
// save plot
using namespace r::session::graphics;
Display& display = r::session::graphics::display();
if (format == "png")
{
return display.savePlotAsPng(plotPath, width, height);
}
else if (format == "pdf")
{
return display.savePlotAsPdf(plotPath, width, height);
}
else
{
return Error(json::errc::ParamInvalid, ERROR_LOCATION);
}
return display.savePlotAsImage(plotPath, format, width, height);
}

bool hasStem(const FilePath& filePath, const std::string& stem)
Expand All @@ -175,19 +166,23 @@ Error getPlotExportContext(const json::JsonRpcRequest& request,
json::Array formats;

// base formats
formats.push_back(plotExportFormat("PNG", "png"));
formats.push_back(plotExportFormat("PDF", "pdf"));
using namespace r::session::graphics;
formats.push_back(plotExportFormat("PNG", kPngFormat));
formats.push_back(plotExportFormat("JPEG", kJpegFormat));
formats.push_back(plotExportFormat("TIFF", kTiffFormat));
formats.push_back(plotExportFormat("BMP", kBmpFormat));
/*
#ifndef _WIN32
formats.push_back(plotExportFormat("SVG", "svg"));
#endif
formats.push_back(plotExportFormat("Postscript", "ps"));
#if _WIN32
formats.push_back(plotExportFormat("Metafile", "emf"));
#endif
#ifndef _WIN32
formats.push_back(plotExportFormat("SVG", "svg"));
#endif
formats.push_back(plotExportFormat("JPEG", "jpeg"));
formats.push_back(plotExportFormat("TIFF", "tiff"));
formats.push_back(plotExportFormat("BMP", "bmp"));
*/


/*
formats.push_back(plotExportFormat("XFig", "fix"));
formats.push_back(plotExportFormat("PicTeX", "tex"));
*/
Expand Down Expand Up @@ -219,7 +214,10 @@ Error getPlotExportContext(const json::JsonRpcRequest& request,
break;

// update stem and search again
stem = "Rplot" + boost::lexical_cast<std::string>(++i);
boost::format fmt("Rplot%1%");
stem = boost::str(fmt % boost::io::group(std::setfill('0'),
std::setw(3),
++i));
}
contextJson["filename"] = stem;

Expand Down Expand Up @@ -307,7 +305,7 @@ void handleZoomRequest(const http::Request& request, http::Response* pResponse)
templateStream <<
"<html>"
"<head>"
"<title>RStudio Plot</title>"
"<title>Plot Zoom</title>"
"<script type=\"text/javascript\">"

"window.timerPending = false;"
Expand Down Expand Up @@ -358,8 +356,12 @@ void handleZoomPngRequest(const http::Request& request,
return ;

// generate the file
using namespace r::session::graphics;
FilePath imagePath = module_context::tempFile("plot", "png");
Error saveError = graphics::display().savePlotAsPng(imagePath, width, height);
Error saveError = graphics::display().savePlotAsImage(imagePath,
kPngFormat,
width,
height);
if (saveError)
{
pResponse->setError(http::status::InternalServerError,
Expand Down Expand Up @@ -411,7 +413,10 @@ void handlePngRequest(const http::Request& request,
// generate the image
using namespace r::session;
FilePath imagePath = module_context::tempFile("plot", "png");
Error error = graphics::display().savePlotAsPng(imagePath, width, height);
Error error = graphics::display().savePlotAsImage(imagePath,
graphics::kPngFormat,
width,
height);
if (error)
{
pResponse->setError(http::status::InternalServerError,
Expand Down
@@ -1,6 +1,5 @@
package org.rstudio.studio.client.workbench.views.plots.ui.export;

import org.rstudio.core.client.Debug;
import org.rstudio.core.client.files.FileSystemItem;
import org.rstudio.core.client.widget.Operation;
import org.rstudio.core.client.widget.OperationWithInput;
Expand Down
Expand Up @@ -25,9 +25,8 @@
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;

// TODO: specify pdf in pixels
// TODO: use Rplot001 as the syntax for names
// TODO: we don't check for plot stem in the actual target dir
// TODO: rename PlotExportContext to SaveAsContext ??
// TODO: view after saving

public class SavePlotAsTargetEditor extends Composite implements CanFocus
Expand All @@ -54,7 +53,7 @@ public SavePlotAsTargetEditor(String defaultFormat,
for (int i=0; i<formats.length(); i++)
{
PlotExportFormat format = formats.get(i);
if (format.getName().equals(defaultFormat))
if (format.getExtension().equals(defaultFormat))
selectedIndex = i;
imageFormatListBox_.addItem(format.getName(), format.getExtension());
}
Expand Down

0 comments on commit d637ee0

Please sign in to comment.