diff options
author | fmalita <fmalita@chromium.org> | 2015-01-30 09:03:29 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-30 09:03:29 -0800 |
commit | 93957f4e8087774f35e2d1c3ff38ec7da306551d (patch) | |
tree | d66948ba458530c4484aad664f491b9f9c4feced | |
parent | 1872ad0fe97d8e90446ee619b273de87e9b8c1fa (diff) |
Initial SVG backend stubbing
This adds SkSVGDevice and a small utility for converting SKP files to SVG (skp2svg).
R=reed@google.com,jcgregorio@google.com
BUG=skia:3368
Review URL: https://codereview.chromium.org/892533002
-rw-r--r-- | experimental/svg/SkSVGDevice.cpp | 187 | ||||
-rw-r--r-- | experimental/svg/SkSVGDevice.h | 72 | ||||
-rw-r--r-- | experimental/svg/skp2svg.cpp | 70 | ||||
-rw-r--r-- | gyp/tools.gyp | 21 |
4 files changed, 350 insertions, 0 deletions
diff --git a/experimental/svg/SkSVGDevice.cpp b/experimental/svg/SkSVGDevice.cpp new file mode 100644 index 0000000000..4a662e7b94 --- /dev/null +++ b/experimental/svg/SkSVGDevice.cpp @@ -0,0 +1,187 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkSVGDevice.h" + +#include "SkBitmap.h" +#include "SkDraw.h" +#include "SkPaint.h" +#include "SkParsePath.h" +#include "SkStream.h" +#include "SkXMLWriter.h" + +namespace { + +class AutoElement { +public: + AutoElement(const char name[], SkXMLWriter* writer) + : fWriter(writer) { + fWriter->startElement(name); + } + + ~AutoElement() { + fWriter->endElement(); + } + +private: + SkXMLWriter* fWriter; +}; + +} + +SkBaseDevice* SkSVGDevice::Create(const SkISize& size, SkWStream* wstream) { + if (!SkToBool(wstream)) { + return NULL; + } + + return SkNEW_ARGS(SkSVGDevice, (size, wstream)); +} + +SkSVGDevice::SkSVGDevice(const SkISize& size, SkWStream* wstream) + : fWriter(SkNEW_ARGS(SkXMLStreamWriter, (wstream))) { + + fLegacyBitmap.setInfo(SkImageInfo::MakeUnknown(size.width(), size.height())); + + fWriter->writeHeader(); + fWriter->startElement("svg"); + fWriter->addAttribute("xmlns", "http://www.w3.org/2000/svg"); + fWriter->addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + fWriter->addS32Attribute("width", size.width()); + fWriter->addS32Attribute("height", size.height()); +} + +SkSVGDevice::~SkSVGDevice() { + fWriter->endElement(); + fWriter->flush(); + SkDELETE(fWriter); +} + +SkImageInfo SkSVGDevice::imageInfo() const { + return fLegacyBitmap.info(); +} + +const SkBitmap& SkSVGDevice::onAccessBitmap() { + return fLegacyBitmap; +} + +void SkSVGDevice::addPaint(const SkPaint& paint) { + SkColor color = paint.getColor(); + SkString colorStr; + colorStr.appendf("rgb(%u,%u,%u)", SkColorGetR(color), SkColorGetG(color), SkColorGetB(color)); + + SkPaint::Style style = paint.getStyle(); + if (style == SkPaint::kFill_Style || style == SkPaint::kStrokeAndFill_Style) { + fWriter->addAttribute("fill", colorStr.c_str()); + } else { + fWriter->addAttribute("fill", "none"); + } + + if (style == SkPaint::kStroke_Style || style == SkPaint::kStrokeAndFill_Style) { + fWriter->addAttribute("stroke", colorStr.c_str()); + fWriter->addScalarAttribute("stroke-width", paint.getStrokeWidth()); + } else { + fWriter->addAttribute("stroke", "none"); + } +} + +void SkSVGDevice::addTransform(const SkMatrix &t) { + if (t.isIdentity()) { + return; + } + + SkString tstr; + tstr.appendf("matrix(%g %g %g %g %g %g)", + SkScalarToFloat(t.getScaleX()), SkScalarToFloat(t.getSkewY()), + SkScalarToFloat(t.getSkewX()), SkScalarToFloat(t.getScaleY()), + SkScalarToFloat(t.getTranslateX()), SkScalarToFloat(t.getTranslateY())); + fWriter->addAttribute("transform", tstr.c_str()); +} + +void SkSVGDevice::drawPaint(const SkDraw&, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, + const SkPoint[], const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) { + AutoElement elem("rect", fWriter); + + fWriter->addScalarAttribute("x", r.fLeft); + fWriter->addScalarAttribute("y", r.fTop); + fWriter->addScalarAttribute("width", r.width()); + fWriter->addScalarAttribute("height", r.height()); + + this->addPaint(paint); + this->addTransform(*draw.fMatrix); +} + +void SkSVGDevice::drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint, + const SkMatrix* prePathMatrix, bool pathIsMutable) { + AutoElement elem("path", fWriter); + + SkString pathStr; + SkParsePath::ToSVGString(path, &pathStr); + fWriter->addAttribute("d", pathStr.c_str()); + + this->addPaint(paint); + this->addTransform(*draw.fMatrix); +} + +void SkSVGDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, + const SkMatrix& matrix, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, + int x, int y, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, + const SkRect& dst, const SkPaint& paint, + SkCanvas::DrawBitmapRectFlags flags) { + // todo +} + +void SkSVGDevice::drawText(const SkDraw&, const void* text, size_t len, + SkScalar x, SkScalar y, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawPosText(const SkDraw&, const void* text, size_t len,const SkScalar pos[], + int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path, + const SkMatrix* matrix, const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, + const SkPoint verts[], const SkPoint texs[], + const SkColor colors[], SkXfermode* xmode, + const uint16_t indices[], int indexCount, + const SkPaint& paint) { + // todo +} + +void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, + const SkPaint&) { + // todo +} diff --git a/experimental/svg/SkSVGDevice.h b/experimental/svg/SkSVGDevice.h new file mode 100644 index 0000000000..d6c48e2c0f --- /dev/null +++ b/experimental/svg/SkSVGDevice.h @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSVGDevice_DEFINED +#define SkSVGDevice_DEFINED + +#include "SkDevice.h" + +class SkWStream; +class SkXMLWriter; + +class SkSVGDevice : public SkBaseDevice { +public: + static SkBaseDevice* Create(const SkISize& size, SkWStream* wstream); + + virtual SkImageInfo imageInfo() const SK_OVERRIDE; + +protected: + virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, + const SkPoint[], const SkPaint& paint) SK_OVERRIDE; + virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) SK_OVERRIDE; + virtual void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) SK_OVERRIDE; + virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPath(const SkDraw&, const SkPath& path, + const SkPaint& paint, + const SkMatrix* prePathMatrix = NULL, + bool pathIsMutable = false) SK_OVERRIDE; + + virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, + const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE; + virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, + int x, int y, const SkPaint& paint) SK_OVERRIDE; + virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, + const SkRect* srcOrNull, const SkRect& dst, + const SkPaint& paint, + SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE; + + virtual void drawText(const SkDraw&, const void* text, size_t len, + SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPosText(const SkDraw&, const void* text, size_t len, + const SkScalar pos[], int scalarsPerPos, + const SkPoint& offset, const SkPaint& paint) SK_OVERRIDE; + virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, + const SkPath& path, const SkMatrix* matrix, + const SkPaint& paint) SK_OVERRIDE; + virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, + const SkPoint verts[], const SkPoint texs[], + const SkColor colors[], SkXfermode* xmode, + const uint16_t indices[], int indexCount, + const SkPaint& paint) SK_OVERRIDE; + + virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, + const SkPaint&) SK_OVERRIDE; + virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; + +private: + SkSVGDevice(const SkISize& size, SkWStream* wstream); + virtual ~SkSVGDevice(); + + void addPaint(const SkPaint& paint); + void addTransform(const SkMatrix& t); + + SkXMLWriter* fWriter; + SkBitmap fLegacyBitmap; +}; + +#endif // SkSVGDevice_DEFINED diff --git a/experimental/svg/skp2svg.cpp b/experimental/svg/skp2svg.cpp new file mode 100644 index 0000000000..95bb04a061 --- /dev/null +++ b/experimental/svg/skp2svg.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "LazyDecodeBitmap.h" +#include "SkCommandLineFlags.h" +#include "SkPicture.h" +#include "SkStream.h" +#include "SkSVGDevice.h" + +DEFINE_string2(input, i, "", "input skp file"); +DEFINE_string2(output, o, "", "output svg file (optional)"); + +// return codes: +static const int kSuccess = 0; +static const int kInvalidArgs = 1; +static const int kIOError = 2; +static const int kNotAnSKP = 3; + +int tool_main(int argc, char** argv); +int tool_main(int argc, char** argv) { + SkCommandLineFlags::SetUsage("Converts an SKP file to SVG."); + SkCommandLineFlags::Parse(argc, argv); + + if (FLAGS_input.count() != 1) { + SkDebugf("Missing input file\n"); + return kInvalidArgs; + } + + SkFILEStream stream(FLAGS_input[0]); + if (!stream.isValid()) { + SkDebugf("Couldn't open file: %s\n", FLAGS_input[0]); + return kIOError; + } + + SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(&stream, &sk_tools::LazyDecodeBitmap)); + if (!SkToBool(pic.get())) { + SkDebugf("Could not load SKP: %s\n", FLAGS_input[0]); + return kNotAnSKP; + } + + SkAutoTDelete<SkWStream> outStream; + if (FLAGS_output.count() > 0) { + SkFILEWStream* fileStream = SkNEW_ARGS(SkFILEWStream, (FLAGS_output[0])); + if (!fileStream->isValid()) { + SkDebugf("Couldn't open output file for writing: %s\n", FLAGS_output[0]); + return kIOError; + } + outStream.reset(fileStream); + } else { + outStream.reset(SkNEW(SkDebugWStream)); + } + + SkISize size = pic->cullRect().roundOut().size(); + SkAutoTUnref<SkBaseDevice> svgDevice(SkSVGDevice::Create(size, outStream)); + SkCanvas svgCanvas(svgDevice.get()); + + pic->playback(&svgCanvas); + + return kSuccess; +} + +#if !defined SK_BUILD_FOR_IOS +int main(int argc, char * const argv[]) { + return tool_main(argc, (char**) argv); +} +#endif diff --git a/gyp/tools.gyp b/gyp/tools.gyp index 1b196a75b1..dfeb6efecd 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -25,6 +25,7 @@ 'render_pictures', 'skdiff', 'skhello', + 'skp2svg', 'skpdiff', 'skpinfo', 'skpmaker', @@ -264,6 +265,26 @@ ], }, { + 'target_name': 'skp2svg', + 'type': 'executable', + 'sources': [ + '../experimental/svg/skp2svg.cpp', + '../experimental/svg/SkSVGDevice.cpp', + '../experimental/svg/SkSVGDevice.h', + '../tools/LazyDecodeBitmap.cpp', + ], + 'include_dirs': [ + '../src/core/', + '../src/lazy/', + '../tools/', + ], + 'dependencies': [ + 'flags.gyp:flags', + 'skia_lib.gyp:skia_lib', + 'xml.gyp:xml', + ], + }, + { 'target_name': 'gpuveto', 'type': 'executable', 'sources': [ |