aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkAnnotation.h80
-rw-r--r--include/core/SkCanvas.h14
-rw-r--r--include/core/SkDevice.h2
-rw-r--r--include/core/SkPaint.h5
-rw-r--r--include/core/SkPicture.h5
-rw-r--r--include/core/SkWriter32.h12
-rw-r--r--include/private/SkRecords.h10
-rw-r--r--include/utils/SkDumpCanvas.h2
-rw-r--r--include/utils/SkNWayCanvas.h1
-rw-r--r--samplecode/SampleFilterFuzz.cpp4
-rw-r--r--src/core/SkAnnotation.cpp55
-rw-r--r--src/core/SkAnnotationKeys.h33
-rw-r--r--src/core/SkBitmapDevice.cpp10
-rw-r--r--src/core/SkCanvas.cpp17
-rw-r--r--src/core/SkPaint.cpp39
-rw-r--r--src/core/SkPictureFlat.h4
-rw-r--r--src/core/SkPicturePlayback.cpp6
-rw-r--r--src/core/SkPictureRecord.cpp12
-rw-r--r--src/core/SkPictureRecord.h1
-rw-r--r--src/core/SkReadBuffer.h1
-rw-r--r--src/core/SkReader32.h10
-rw-r--r--src/core/SkRecordDraw.cpp5
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
-rw-r--r--src/core/SkRemote.cpp10
-rw-r--r--src/core/SkRemote.h3
-rw-r--r--src/core/SkRemote_protocol.h1
-rw-r--r--src/gpu/SkGpuDevice.cpp12
-rw-r--r--src/pdf/SkPDFDevice.cpp80
-rw-r--r--src/pdf/SkPDFDevice.h8
-rw-r--r--src/utils/SkDumpCanvas.cpp8
-rw-r--r--src/utils/SkNWayCanvas.cpp7
-rw-r--r--tests/SerializationTest.cpp83
-rw-r--r--tests/Writer32Test.cpp41
34 files changed, 333 insertions, 253 deletions
diff --git a/include/core/SkAnnotation.h b/include/core/SkAnnotation.h
index 80503c78d2..2ea66d37ac 100644
--- a/include/core/SkAnnotation.h
+++ b/include/core/SkAnnotation.h
@@ -1,3 +1,4 @@
+
/*
* Copyright 2012 Google Inc.
*
@@ -8,83 +9,21 @@
#ifndef SkAnnotation_DEFINED
#define SkAnnotation_DEFINED
-#include "SkRefCnt.h"
-#include "SkString.h"
#include "SkTypes.h"
+// for chrome in PrintContextTest.cpp
+#define SK_SUPPORT_NEW_ANNOTATION_CANVAS_VIRTUAL
+
class SkData;
-class SkReadBuffer;
-class SkWriteBuffer;
struct SkPoint;
-
-/**
- * Experimental class for annotating draws. Do not use directly yet.
- * Use helper functions at the bottom of this file for now.
- */
-class SkAnnotation : public SkRefCnt {
-public:
- virtual ~SkAnnotation();
-
- static SkAnnotation* Create(const char key[], SkData* value) {
- return new SkAnnotation(key, value);
- }
-
- static SkAnnotation* Create(SkReadBuffer& buffer) { return new SkAnnotation(buffer); }
-
- /**
- * Return the data for the specified key, or NULL.
- */
- SkData* find(const char key[]) const;
-
- void writeToBuffer(SkWriteBuffer&) const;
-
-private:
- SkAnnotation(const char key[], SkData* value);
- SkAnnotation(SkReadBuffer&);
-
- SkString fKey;
- SkData* fData;
-
- typedef SkRefCnt INHERITED;
-};
-
-/**
- * Experimental collection of predefined Keys into the Annotation dictionary
- */
-class SkAnnotationKeys {
-public:
- /**
- * Returns the canonical key whose payload is a URL
- */
- static const char* URL_Key();
-
- /**
- * Returns the canonical key whose payload is the name of a destination to
- * be defined.
- */
- static const char* Define_Named_Dest_Key();
-
- /**
- * Returns the canonical key whose payload is the name of a destination to
- * be linked to.
- */
- static const char* Link_Named_Dest_Key();
-};
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// Experimental helper functions to use Annotations
-//
-
struct SkRect;
class SkCanvas;
/**
- * Experimental!
- *
* Annotate the canvas by associating the specified URL with the
- * specified rectangle (in local coordinates, just like drawRect). If the
- * backend of this canvas does not support annotations, this call is
+ * specified rectangle (in local coordinates, just like drawRect).
+ *
+ * If the backend of this canvas does not support annotations, this call is
* safely ignored.
*
* The caller is responsible for managing its ownership of the SkData.
@@ -92,8 +31,6 @@ class SkCanvas;
SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
/**
- * Experimental!
- *
* Annotate the canvas by associating a name with the specified point.
*
* If the backend of this canvas does not support annotations, this call is
@@ -104,8 +41,6 @@ SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
/**
- * Experimental!
- *
* Annotate the canvas by making the specified rectangle link to a named
* destination.
*
@@ -116,5 +51,4 @@ SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
*/
SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*);
-
#endif
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index c23d748e78..1b4571a09c 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -22,6 +22,7 @@ class GrRenderTarget;
class SkBaseDevice;
class SkCanvasClipVisitor;
class SkClipStack;
+class SkData;
class SkDraw;
class SkDrawable;
class SkDrawFilter;
@@ -1072,6 +1073,18 @@ public:
void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL);
void drawDrawable(SkDrawable*, SkScalar x, SkScalar y);
+ /**
+ * Send an "annotation" to the canvas. The annotation is a key/value pair, where the key is
+ * a null-terminated utf8 string, and the value is a blob of data stored in an SkData
+ * (which may be null). The annotation is associated with the specified rectangle.
+ *
+ * The caller still retains its ownership of the data (if any).
+ *
+ * Note: on may canvas types, this information is ignored, but some canvases (e.g. recording
+ * a picture or drawing to a PDF document) will pass on this information.
+ */
+ void drawAnnotation(const SkRect&, const char key[], SkData* value);
+
//////////////////////////////////////////////////////////////////////////
#ifdef SK_INTERNAL
#ifndef SK_SUPPORT_LEGACY_DRAWFILTER
@@ -1221,6 +1234,7 @@ protected:
virtual void didConcat(const SkMatrix&) {}
virtual void didSetMatrix(const SkMatrix&) {}
+ virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value);
virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 65ec56f902..cd13d5482e 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -252,6 +252,8 @@ protected:
virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
const SkColor[], int count, SkXfermode::Mode, const SkPaint&);
+ virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {}
+
/** The SkDevice passed will be an SkDevice which was returned by a call to
onCreateDevice on this device with kNeverTile_TileExpectation.
*/
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index b58a3f3d4f..7090f3e249 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -13,7 +13,6 @@
#include "SkMatrix.h"
#include "SkXfermode.h"
-class SkAnnotation;
class SkAutoDescriptor;
class SkAutoGlyphCache;
class SkColorFilter;
@@ -625,9 +624,6 @@ public:
SkImageFilter* getImageFilter() const { return fImageFilter; }
SkImageFilter* setImageFilter(SkImageFilter*);
- SkAnnotation* getAnnotation() const { return fAnnotation; }
- SkAnnotation* setAnnotation(SkAnnotation*);
-
/**
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
* reference count.
@@ -1039,7 +1035,6 @@ private:
SkRasterizer* fRasterizer;
SkDrawLooper* fLooper;
SkImageFilter* fImageFilter;
- SkAnnotation* fAnnotation;
SkScalar fTextSize;
SkScalar fTextScaleX;
diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h
index 7c8c187fd8..36f5310230 100644
--- a/include/core/SkPicture.h
+++ b/include/core/SkPicture.h
@@ -192,10 +192,11 @@ private:
// V41: Added serialization of SkBitmapSource's filterQuality parameter
// V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture?
// V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data
+ // V44: Move annotations from paint to drawAnnotation
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
- static const uint32_t CURRENT_PICTURE_VERSION = 43;
+ static const uint32_t CURRENT_PICTURE_VERSION = 44;
static_assert(MIN_PICTURE_VERSION <= 41,
"Remove kFontFileName and related code from SkFontDescriptor.cpp.");
@@ -205,7 +206,7 @@ private:
static_assert(MIN_PICTURE_VERSION <= 43,
"Remove SkBitmapSourceDeserializer.");
-
+
static bool IsValidPictInfo(const SkPictInfo& info);
static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*);
diff --git a/include/core/SkWriter32.h b/include/core/SkWriter32.h
index 1e7ec6d348..a2c6f5d472 100644
--- a/include/core/SkWriter32.h
+++ b/include/core/SkWriter32.h
@@ -206,6 +206,18 @@ public:
*/
static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
+ void writeData(const SkData* data) {
+ uint32_t len = data ? SkToU32(data->size()) : 0;
+ this->write32(len);
+ if (data) {
+ this->writePad(data->data(), len);
+ }
+ }
+
+ static size_t WriteDataSize(const SkData* data) {
+ return 4 + SkAlign4(data ? data->size() : 0);
+ }
+
/**
* Move the cursor back to offset bytes from the beginning.
* offset must be a multiple of 4 no greater than size().
diff --git a/include/private/SkRecords.h b/include/private/SkRecords.h
index ecd73a12d9..1e274e9f46 100644
--- a/include/private/SkRecords.h
+++ b/include/private/SkRecords.h
@@ -8,6 +8,7 @@
#ifndef SkRecords_DEFINED
#define SkRecords_DEFINED
+#include "SkData.h"
#include "SkCanvas.h"
#include "SkDrawable.h"
#include "SkImageFilter.h"
@@ -17,6 +18,7 @@
#include "SkRect.h"
#include "SkRRect.h"
#include "SkRSXform.h"
+#include "SkString.h"
#include "SkTextBlob.h"
namespace SkRecords {
@@ -66,7 +68,8 @@ namespace SkRecords {
M(DrawRect) \
M(DrawTextBlob) \
M(DrawAtlas) \
- M(DrawVertices)
+ M(DrawVertices) \
+ M(DrawAnnotation)
// Defines SkRecords::Type, an enum of all record types.
#define ENUM(T) T##_Type,
@@ -358,7 +361,10 @@ RECORD(DrawVertices, kDraw_Tag,
RefBox<SkXfermode> xmode;
PODArray<uint16_t> indices;
int indexCount);
-
+RECORD(DrawAnnotation, 0,
+ SkRect rect;
+ SkString key;
+ RefBox<SkData> value);
#undef RECORD
} // namespace SkRecords
diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h
index d4c6dbf81b..1c16bf3f03 100644
--- a/include/utils/SkDumpCanvas.h
+++ b/include/utils/SkDumpCanvas.h
@@ -48,6 +48,7 @@ public:
kDrawVertices_Verb,
kDrawPatch_Verb,
kDrawData_Verb, // obsolete
+ kDrawAnnotation_Verb,
kCull_Verb
};
@@ -120,6 +121,7 @@ protected:
void onClipRegion(const SkRegion&, SkRegion::Op) override;
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+ void onDrawAnnotation(const SkRect&, const char key[], SkData* value) override;
static const char* EdgeStyleToAAString(ClipEdgeStyle edgeStyle);
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index 175701edbe..f2a99db802 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -79,6 +79,7 @@ protected:
void onClipRegion(const SkRegion&, SkRegion::Op) override;
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+ void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
class Iter;
diff --git a/samplecode/SampleFilterFuzz.cpp b/samplecode/SampleFilterFuzz.cpp
index 687921ae0b..28155f14fd 100644
--- a/samplecode/SampleFilterFuzz.cpp
+++ b/samplecode/SampleFilterFuzz.cpp
@@ -9,7 +9,6 @@
#include "Sk2DPathEffect.h"
#include "SkAlphaThresholdFilter.h"
#include "SkArcToPathEffect.h"
-#include "SkAnnotation.h"
#include "SkBlurImageFilter.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
@@ -545,9 +544,6 @@ static SkPaint make_paint() {
paint.setRasterizer(rasterizer);
paint.setImageFilter(make_image_filter());
SkAutoDataUnref data(make_3Dlut(nullptr, make_bool(), make_bool(), make_bool()));
- SkAutoTUnref<SkAnnotation> annotation(
- SkAnnotation::Create(make_string().c_str(), data));
- paint.setAnnotation(annotation);
paint.setTextAlign(make_paint_align());
paint.setTextSize(make_scalar());
paint.setTextScaleX(make_scalar());
diff --git a/src/core/SkAnnotation.cpp b/src/core/SkAnnotation.cpp
index 84d41fc669..09a6296fba 100644
--- a/src/core/SkAnnotation.cpp
+++ b/src/core/SkAnnotation.cpp
@@ -6,38 +6,10 @@
*/
#include "SkAnnotation.h"
-#include "SkData.h"
-#include "SkPaint.h"
+#include "SkAnnotationKeys.h"
+#include "SkCanvas.h"
#include "SkPoint.h"
-#include "SkReadBuffer.h"
-#include "SkWriteBuffer.h"
-
-SkAnnotation::SkAnnotation(const char key[], SkData* value) : fKey(key) {
- if (nullptr == value) {
- value = SkData::NewEmpty();
- } else {
- value->ref();
- }
- fData = value;
-}
-
-SkAnnotation::~SkAnnotation() {
- fData->unref();
-}
-
-SkData* SkAnnotation::find(const char key[]) const {
- return fKey.equals(key) ? fData : nullptr;
-}
-
-SkAnnotation::SkAnnotation(SkReadBuffer& buffer) {
- buffer.readString(&fKey);
- fData = buffer.readByteArrayAsData();
-}
-
-void SkAnnotation::writeToBuffer(SkWriteBuffer& buffer) const {
- buffer.writeString(fKey.c_str());
- buffer.writeDataAsByteArray(fData);
-}
+#include "SkRect.h"
const char* SkAnnotationKeys::URL_Key() {
return "SkAnnotationKey_URL";
@@ -51,37 +23,26 @@ const char* SkAnnotationKeys::Link_Named_Dest_Key() {
return "SkAnnotationKey_Link_Named_Dest";
};
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkCanvas.h"
-
-static void annotate_paint(SkPaint& paint, const char* key, SkData* value) {
- paint.setAnnotation(SkAnnotation::Create(key, value))->unref();
-}
+//////////////////////////////////////////////////////////////////////////////////////////////////
void SkAnnotateRectWithURL(SkCanvas* canvas, const SkRect& rect, SkData* value) {
if (nullptr == value) {
return;
}
- SkPaint paint;
- annotate_paint(paint, SkAnnotationKeys::URL_Key(), value);
- canvas->drawRect(rect, paint);
+ canvas->drawAnnotation(rect, SkAnnotationKeys::URL_Key(), value);
}
void SkAnnotateNamedDestination(SkCanvas* canvas, const SkPoint& point, SkData* name) {
if (nullptr == name) {
return;
}
- SkPaint paint;
- annotate_paint(paint, SkAnnotationKeys::Define_Named_Dest_Key(), name);
- canvas->drawPoint(point.x(), point.y(), paint);
+ const SkRect rect = SkRect::MakeXYWH(point.x(), point.y(), 0, 0);
+ canvas->drawAnnotation(rect, SkAnnotationKeys::Define_Named_Dest_Key(), name);
}
void SkAnnotateLinkToDestination(SkCanvas* canvas, const SkRect& rect, SkData* name) {
if (nullptr == name) {
return;
}
- SkPaint paint;
- annotate_paint(paint, SkAnnotationKeys::Link_Named_Dest_Key(), name);
- canvas->drawRect(rect, paint);
+ canvas->drawAnnotation(rect, SkAnnotationKeys::Link_Named_Dest_Key(), name);
}
diff --git a/src/core/SkAnnotationKeys.h b/src/core/SkAnnotationKeys.h
new file mode 100644
index 0000000000..dff9338807
--- /dev/null
+++ b/src/core/SkAnnotationKeys.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAnnotationKeys_DEFINED
+#define SkAnnotationKeys_DEFINED
+
+#include "SkTypes.h"
+
+class SkAnnotationKeys {
+public:
+ /**
+ * Returns the canonical key whose payload is a URL
+ */
+ static const char* URL_Key();
+
+ /**
+ * Returns the canonical key whose payload is the name of a destination to
+ * be defined.
+ */
+ static const char* Define_Named_Dest_Key();
+
+ /**
+ * Returns the canonical key whose payload is the name of a destination to
+ * be linked to.
+ */
+ static const char* Link_Named_Dest_Key();
+};
+
+#endif
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 8c3c562181..d5dfcc1733 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -20,9 +20,6 @@
class SkColorTable;
-#define CHECK_FOR_ANNOTATION(paint) \
- do { if (paint.getAnnotation()) { return; } } while (0)
-
static bool valid_for_bitmap_device(const SkImageInfo& info,
SkAlphaType* newAlphaType) {
if (info.width() < 0 || info.height() < 0) {
@@ -204,18 +201,14 @@ void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
const SkPoint pts[], const SkPaint& paint) {
- CHECK_FOR_ANNOTATION(paint);
draw.drawPoints(mode, count, pts, paint);
}
void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
- CHECK_FOR_ANNOTATION(paint);
draw.drawRect(r, paint);
}
void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
- CHECK_FOR_ANNOTATION(paint);
-
SkPath path;
path.addOval(oval);
// call the VIRTUAL version, so any subclasses who do handle drawPath aren't
@@ -224,8 +217,6 @@ void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPa
}
void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
- CHECK_FOR_ANNOTATION(paint);
-
#ifdef SK_IGNORE_BLURRED_RRECT_OPT
SkPath path;
@@ -241,7 +232,6 @@ void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const S
void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable) {
- CHECK_FOR_ANNOTATION(paint);
draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
}
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index a628105001..f3f38386bd 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1973,6 +1973,12 @@ void SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const Sk
this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
}
+void SkCanvas::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ if (key) {
+ this->onDrawAnnotation(rect, key, value);
+ }
+}
+
void SkCanvas::legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
const SkPaint* paint, SrcRectConstraint constraint) {
if (src) {
@@ -2725,6 +2731,17 @@ void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const
LOOPER_END
}
+void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ SkASSERT(key);
+
+ SkPaint paint;
+ LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr)
+ while (iter.next()) {
+ iter.fDevice->drawAnnotation(iter, rect, key, value);
+ }
+ LOOPER_END
+}
+
//////////////////////////////////////////////////////////////////////////////
// These methods are NOT virtual, and therefore must call back into virtual
// methods, rather than actually drawing themselves.
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 017662ff48..cdfb110454 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -6,7 +6,6 @@
*/
#include "SkPaint.h"
-#include "SkAnnotation.h"
#include "SkAutoKern.h"
#include "SkChecksum.h"
#include "SkColorFilter.h"
@@ -54,7 +53,6 @@ SkPaint::SkPaint() {
fRasterizer = nullptr;
fLooper = nullptr;
fImageFilter = nullptr;
- fAnnotation = nullptr;
fTextSize = SkPaintDefaults_TextSize;
fTextScaleX = SK_Scalar1;
@@ -87,7 +85,6 @@ SkPaint::SkPaint(const SkPaint& src) {
REF_COPY(fRasterizer);
REF_COPY(fLooper);
REF_COPY(fImageFilter);
- REF_COPY(fAnnotation);
COPY(fTextSize);
COPY(fTextScaleX);
@@ -114,7 +111,6 @@ SkPaint::SkPaint(SkPaint&& src) {
REF_MOVE(fRasterizer);
REF_MOVE(fLooper);
REF_MOVE(fImageFilter);
- REF_MOVE(fAnnotation);
MOVE(fTextSize);
MOVE(fTextScaleX);
@@ -138,7 +134,6 @@ SkPaint::~SkPaint() {
SkSafeUnref(fRasterizer);
SkSafeUnref(fLooper);
SkSafeUnref(fImageFilter);
- SkSafeUnref(fAnnotation);
}
SkPaint& SkPaint::operator=(const SkPaint& src) {
@@ -158,7 +153,6 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
REF_COPY(fRasterizer);
REF_COPY(fLooper);
REF_COPY(fImageFilter);
- REF_COPY(fAnnotation);
COPY(fTextSize);
COPY(fTextScaleX);
@@ -191,7 +185,6 @@ SkPaint& SkPaint::operator=(SkPaint&& src) {
REF_MOVE(fRasterizer);
REF_MOVE(fLooper);
REF_MOVE(fImageFilter);
- REF_MOVE(fAnnotation);
MOVE(fTextSize);
MOVE(fTextScaleX);
@@ -218,7 +211,6 @@ bool operator==(const SkPaint& a, const SkPaint& b) {
&& EQUAL(fRasterizer)
&& EQUAL(fLooper)
&& EQUAL(fImageFilter)
- && EQUAL(fAnnotation)
&& EQUAL(fTextSize)
&& EQUAL(fTextScaleX)
&& EQUAL(fTextSkewX)
@@ -420,11 +412,6 @@ SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
return imageFilter;
}
-SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) {
- SkRefCnt_SafeAssign(fAnnotation, annotation);
- return annotation;
-}
-
///////////////////////////////////////////////////////////////////////////////
static SkScalar mag2(SkScalar x, SkScalar y) {
@@ -1897,7 +1884,6 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
asint(this->getColorFilter()) |
asint(this->getRasterizer()) |
asint(this->getLooper()) |
- asint(this->getAnnotation()) |
asint(this->getImageFilter())) {
flatFlags |= kHasEffects_FlatFlag;
}
@@ -1931,13 +1917,6 @@ void SkPaint::flatten(SkWriteBuffer& buffer) const {
buffer.writeFlattenable(this->getRasterizer());
buffer.writeFlattenable(this->getLooper());
buffer.writeFlattenable(this->getImageFilter());
-
- if (fAnnotation) {
- buffer.writeBool(true);
- fAnnotation->writeToBuffer(buffer);
- } else {
- buffer.writeBool(false);
- }
}
}
@@ -1981,8 +1960,14 @@ void SkPaint::unflatten(SkReadBuffer& buffer) {
SkSafeUnref(this->setLooper(buffer.readDrawLooper()));
SkSafeUnref(this->setImageFilter(buffer.readImageFilter()));
- if (buffer.readBool()) {
- this->setAnnotation(SkAnnotation::Create(buffer))->unref();
+ if (buffer.isVersionLT(SkReadBuffer::kAnnotationsMovedToCanvas_Version)) {
+ // We used to store annotations here (string+skdata) if this bool was true
+ if (buffer.readBool()) {
+ // Annotations have moved to drawAnnotation, so we just drop this one on the floor.
+ SkString key;
+ buffer.readString(&key);
+ SkSafeUnref(buffer.readByteArrayAsData());
+ }
}
} else {
this->setPathEffect(nullptr);
@@ -2205,12 +2190,6 @@ void SkPaint::toString(SkString* str) const {
str->append("</dd>");
}
- SkAnnotation* annotation = this->getAnnotation();
- if (annotation) {
- str->append("<dt>Annotation:</dt><dd>");
- str->append("</dd>");
- }
-
str->append("<dt>Color:</dt><dd>0x");
SkColor color = this->getColor();
str->appendHex(color);
@@ -2437,7 +2416,7 @@ bool SkPaint::nothingToDraw() const {
uint32_t SkPaint::getHash() const {
// We're going to hash 10 pointers and 7 32-bit values, finishing up with fBitfields,
// so fBitfields should be 10 pointers and 6 32-bit values from the start.
- static_assert(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * sizeof(uint32_t),
+ static_assert(offsetof(SkPaint, fBitfields) == 9 * sizeof(void*) + 6 * sizeof(uint32_t),
"SkPaint_notPackedTightly");
return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this),
offsetof(SkPaint, fBitfields) + sizeof(fBitfields));
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 4eee04fcda..00b7c2bb41 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -78,7 +78,9 @@ enum DrawType {
SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016,
SAVE_LAYER_SAVELAYERREC,
- LAST_DRAWTYPE_ENUM = SAVE_LAYER_SAVELAYERREC,
+ DRAW_ANNOTATION,
+
+ LAST_DRAWTYPE_ENUM = DRAW_ANNOTATION,
};
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index a5dd814b82..e8497daca1 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -175,6 +175,12 @@ void SkPicturePlayback::handleOp(SkReader32* reader,
canvas->concat(matrix);
break;
}
+ case DRAW_ANNOTATION: {
+ const SkRect& rect = reader->skipT<SkRect>();
+ const char* key = reader->readString();
+ SkAutoTUnref<SkData> value(reader->readData());
+ canvas->drawAnnotation(rect, key, value);
+ } break;
case DRAW_ATLAS: {
const SkPaint* paint = fPictureData->getPaint(reader);
const SkImage* atlas = fPictureData->getImage(reader);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 2822a1ac16..2718ee999d 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -777,6 +777,18 @@ void SkPictureRecord::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[],
this->validate(initialOffset, size);
}
+void SkPictureRecord::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ size_t keyLen = fWriter.WriteStringSize(key);
+ size_t valueLen = fWriter.WriteDataSize(value);
+ size_t size = 4 + sizeof(SkRect) + keyLen + valueLen;
+
+ size_t initialOffset = this->addDraw(DRAW_ANNOTATION, &size);
+ this->addRect(rect);
+ fWriter.writeString(key);
+ fWriter.writeData(value);
+ this->validate(initialOffset, size);
+}
+
///////////////////////////////////////////////////////////////////////////////
SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 2e1e62a021..607f6f10f7 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -204,6 +204,7 @@ protected:
void onClipRegion(const SkRegion&, SkRegion::Op) override;
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+ void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
int addPathToHeap(const SkPath& path); // does not write to ops stream
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index 3d6dd362ac..b9b30944ff 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -60,6 +60,7 @@ public:
kBitmapSourceFilterQuality_Version = 41,
kPictureShaderHasPictureBool_Version = 42,
kHasDrawImageOpCodes_Version = 43,
+ kAnnotationsMovedToCanvas_Version = 44,
};
/**
diff --git a/src/core/SkReader32.h b/src/core/SkReader32.h
index 68dda23c6e..645d64cc24 100644
--- a/src/core/SkReader32.h
+++ b/src/core/SkReader32.h
@@ -1,4 +1,3 @@
-
/*
* Copyright 2008 The Android Open Source Project
*
@@ -10,6 +9,7 @@
#ifndef SkReader32_DEFINED
#define SkReader32_DEFINED
+#include "SkData.h"
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkRegion.h"
@@ -135,6 +135,14 @@ public:
*/
size_t readIntoString(SkString* copy);
+ SkData* readData() {
+ uint32_t byteLength = this->readU32();
+ if (0 == byteLength) {
+ return SkData::NewEmpty();
+ }
+ return SkData::NewWithCopy(this->skip(byteLength), byteLength);
+ }
+
private:
template <typename T> bool readObjectFromMemory(T* obj) {
size_t size = obj->readFromMemory(this->peek(), this->available());
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 5ca9517d3f..0e4b5af580 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -117,6 +117,7 @@ DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.p
DRAW(DrawAtlas, drawAtlas(r.atlas, r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint));
DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
r.xmode, r.indices, r.indexCount, r.paint));
+DRAW(DrawAnnotation, drawAnnotation(r.rect, r.key.c_str(), r.value));
#undef DRAW
template <> void Draw::draw(const DrawDrawable& r) {
@@ -517,6 +518,10 @@ private:
return this->adjustAndMap(op.worstCaseBounds, nullptr);
}
+ Bounds bounds(const DrawAnnotation& op) const {
+ return this->adjustAndMap(op.rect, nullptr);
+ }
+
static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) {
#ifdef SK_DEBUG
SkRect correct = *rect;
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 01c28dfc2b..f9fd8bb374 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -332,6 +332,10 @@ void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], cons
this->copy(cull));
}
+void SkRecorder::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ APPEND(DrawAnnotation, rect, SkString(key), value);
+}
+
void SkRecorder::willSave() {
APPEND(Save);
}
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index cd5bc8ad04..7372e540e7 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -120,6 +120,7 @@ public:
void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) override;
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
+ void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override { return nullptr; }
diff --git a/src/core/SkRemote.cpp b/src/core/SkRemote.cpp
index 22185cddb0..9b0383d406 100644
--- a/src/core/SkRemote.cpp
+++ b/src/core/SkRemote.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-#include "SkAnnotation.h"
#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkDrawLooper.h"
@@ -127,7 +126,6 @@ namespace SkRemote {
fIDs.rasterizer = fEncoder->define(paint.getRasterizer());
fIDs.looper = fEncoder->define(paint.getLooper());
fIDs.imagefilter = fEncoder->define(paint.getImageFilter());
- fIDs.annotation = fEncoder->define(paint.getAnnotation());
}
~AutoCommonIDs() {
if (fEncoder) {
@@ -140,7 +138,6 @@ namespace SkRemote {
fEncoder->undefine(fIDs.rasterizer);
fEncoder->undefine(fIDs.looper);
fEncoder->undefine(fIDs.imagefilter);
- fEncoder->undefine(fIDs.annotation);
}
}
@@ -461,7 +458,6 @@ namespace SkRemote {
ID define(SkRasterizer* v)O{return this->define(Type::kRasterizer, &fRasterizer, v);}
ID define(SkDrawLooper* v)O{return this->define(Type::kDrawLooper, &fDrawLooper, v);}
ID define(SkImageFilter* v)O{return this->define(Type::kImageFilter, &fImageFilter, v);}
- ID define(SkAnnotation* v)O{return this->define(Type::kAnnotation, &fAnnotation, v);}
#undef O
@@ -480,7 +476,6 @@ namespace SkRemote {
case Type::kRasterizer: return fRasterizer .remove(id);
case Type::kDrawLooper: return fDrawLooper .remove(id);
case Type::kImageFilter: return fImageFilter.remove(id);
- case Type::kAnnotation: return fAnnotation .remove(id);
};
}
@@ -494,7 +489,6 @@ namespace SkRemote {
paint->setRasterizer (fRasterizer .find(common.rasterizer));
paint->setLooper (fDrawLooper .find(common.looper));
paint->setImageFilter(fImageFilter.find(common.imagefilter));
- paint->setAnnotation (fAnnotation .find(common.annotation));
}
void save() override { fCanvas->save(); }
@@ -617,7 +611,6 @@ namespace SkRemote {
ReffedIDMap<SkRasterizer , Type::kRasterizer > fRasterizer;
ReffedIDMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper;
ReffedIDMap<SkImageFilter , Type::kImageFilter> fImageFilter;
- ReffedIDMap<SkAnnotation , Type::kAnnotation > fAnnotation;
SkCanvas* fCanvas;
uint64_t fNextID = 0;
@@ -653,7 +646,6 @@ namespace SkRemote {
fRasterizer .foreach(undef);
fDrawLooper .foreach(undef);
fImageFilter.foreach(undef);
- fAnnotation .foreach(undef);
}
template <typename Map, typename T>
@@ -679,7 +671,6 @@ namespace SkRemote {
ID define(SkRasterizer* v) override { return this->define(&fRasterizer , v); }
ID define(SkDrawLooper* v) override { return this->define(&fDrawLooper , v); }
ID define(SkImageFilter* v) override { return this->define(&fImageFilter, v); }
- ID define(SkAnnotation* v) override { return this->define(&fAnnotation , v); }
void undefine(ID) override {}
@@ -749,7 +740,6 @@ namespace SkRemote {
RefKeyMap<SkRasterizer , Type::kRasterizer > fRasterizer;
RefKeyMap<SkDrawLooper , Type::kDrawLooper > fDrawLooper;
RefKeyMap<SkImageFilter , Type::kImageFilter> fImageFilter;
- RefKeyMap<SkAnnotation , Type::kAnnotation > fAnnotation;
Encoder* fWrapped;
};
diff --git a/src/core/SkRemote.h b/src/core/SkRemote.h
index a1b1405b21..a8126d6c9e 100644
--- a/src/core/SkRemote.h
+++ b/src/core/SkRemote.h
@@ -79,14 +79,13 @@ namespace SkRemote {
virtual ID define(SkRasterizer*) = 0;
virtual ID define(SkDrawLooper*) = 0;
virtual ID define(SkImageFilter*) = 0;
- virtual ID define(SkAnnotation*) = 0;
virtual void undefine(ID) = 0;
// TODO: do these all belong here in CommonIDs?
struct CommonIDs {
ID misc, patheffect, shader, xfermode, maskfilter,
- colorfilter, rasterizer, looper, imagefilter, annotation;
+ colorfilter, rasterizer, looper, imagefilter;
};
virtual void save() = 0;
diff --git a/src/core/SkRemote_protocol.h b/src/core/SkRemote_protocol.h
index 19bdc33fdd..825a1c2732 100644
--- a/src/core/SkRemote_protocol.h
+++ b/src/core/SkRemote_protocol.h
@@ -28,7 +28,6 @@ namespace SkRemote {
kRasterizer,
kDrawLooper,
kImageFilter,
- kAnnotation,
};
} // namespace SkRemote
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 04bc14e563..a7bf82e6f0 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -68,11 +68,6 @@ enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
///////////////////////////////////////////////////////////////////////////////
-#define CHECK_FOR_ANNOTATION(paint) \
- do { if (paint.getAnnotation()) { return; } } while (0)
-
-///////////////////////////////////////////////////////////////////////////////
-
// Helper for turning a bitmap into a texture. If the bitmap is GrTexture backed this
// just accesses the backing GrTexture. Otherwise, it creates a cached texture
// representation and releases it in the destructor.
@@ -401,7 +396,6 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
size_t count, const SkPoint pts[], const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPoints", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
SkScalar width = paint.getStrokeWidth();
@@ -453,7 +447,6 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
@@ -500,7 +493,6 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
GrPaint grPaint;
@@ -565,7 +557,6 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
const SkRRect& inner, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDRRect", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
if (outer.isEmpty()) {
@@ -606,7 +597,6 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawOval", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
// Presumably the path effect warps this to something other than an oval
@@ -661,7 +651,6 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
}
}
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPath", fContext);
@@ -1472,7 +1461,6 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerNine", fContext);
- CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
bool useFallback = paint.getMaskFilter() || paint.isAntiAlias() ||
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index d102f0e977..239b73823b 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -7,7 +7,7 @@
#include "SkPDFDevice.h"
-#include "SkAnnotation.h"
+#include "SkAnnotationKeys.h"
#include "SkColor.h"
#include "SkColorFilter.h"
#include "SkClipStack.h"
@@ -753,6 +753,17 @@ void SkPDFDevice::cleanUp(bool clearFontUsage) {
}
}
+void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
+ SkData* value) {
+ if (0 == rect.width() && 0 == rect.height()) {
+ handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
+ } else {
+ SkPath path;
+ path.addRect(rect);
+ handlePathAnnotation(path, d, key, value);
+ }
+}
+
void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
SkPaint newPaint = paint;
replace_srcmode_on_opaque_paint(&newPaint);
@@ -792,12 +803,6 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
return;
}
- if (SkAnnotation* annotation = passedPaint.getAnnotation()) {
- if (handlePointAnnotation(points, count, *d.fMatrix, annotation)) {
- return;
- }
- }
-
// SkDraw::drawPoints converts to multiple calls to fDevice->drawPath.
// We only use this when there's a path effect because of the overhead
// of multiple calls to setUpContentEntry it causes.
@@ -935,14 +940,6 @@ void SkPDFDevice::drawRect(const SkDraw& d,
return;
}
- if (SkAnnotation* annotation = paint.getAnnotation()) {
- SkPath path;
- path.addRect(rect);
- if (handlePathAnnotation(path, d, annotation)) {
- return;
- }
- }
-
ScopedContentEntry content(this, d, paint);
if (!content.entry()) {
return;
@@ -1021,12 +1018,6 @@ void SkPDFDevice::drawPath(const SkDraw& d,
return;
}
- if (SkAnnotation* annotation = paint.getAnnotation()) {
- if (handlePathAnnotation(*pathPtr, d, annotation)) {
- return;
- }
- }
-
ScopedContentEntry content(this, d.fClipStack, *d.fClip, matrix, paint);
if (!content.entry()) {
return;
@@ -1664,26 +1655,26 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
return true;
}
-bool SkPDFDevice::handlePointAnnotation(const SkPoint* points, size_t count,
+void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
const SkMatrix& matrix,
- SkAnnotation* annotationInfo) {
- SkData* nameData = annotationInfo->find(
- SkAnnotationKeys::Define_Named_Dest_Key());
- if (nameData) {
- for (size_t i = 0; i < count; i++) {
- SkPoint transformedPoint;
- matrix.mapXY(points[i].x(), points[i].y(), &transformedPoint);
- fNamedDestinations.emplace_back(nameData, transformedPoint);
- }
- return true;
+ const char key[], SkData* value) {
+ if (!value) {
+ return;
+ }
+
+ if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
+ SkPoint transformedPoint;
+ matrix.mapXY(point.x(), point.y(), &transformedPoint);
+ fNamedDestinations.emplace_back(value, transformedPoint);
}
- return false;
}
-bool SkPDFDevice::handlePathAnnotation(const SkPath& path,
+void SkPDFDevice::handlePathAnnotation(const SkPath& path,
const SkDraw& d,
- SkAnnotation* annotation) {
- SkASSERT(annotation);
+ const char key[], SkData* value) {
+ if (!value) {
+ return;
+ }
SkPath transformedPath = path;
transformedPath.transform(*d.fMatrix);
@@ -1692,24 +1683,15 @@ bool SkPDFDevice::handlePathAnnotation(const SkPath& path,
false);
SkRect transformedRect = SkRect::Make(clip.getBounds());
- SkData* urlData = annotation->find(SkAnnotationKeys::URL_Key());
- if (urlData) {
+ if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
if (!transformedRect.isEmpty()) {
- fLinkToURLs.emplace_back(transformedRect, urlData);
+ fLinkToURLs.emplace_back(transformedRect, value);
}
- return true;
- }
-
- SkData* linkToDestination =
- annotation->find(SkAnnotationKeys::Link_Named_Dest_Key());
- if (linkToDestination) {
+ } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
if (!transformedRect.isEmpty()) {
- fLinkToDestinations.emplace_back(transformedRect, linkToDestination);
+ fLinkToDestinations.emplace_back(transformedRect, value);
}
- return true;
}
-
- return false;
}
void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
index cceb1238f1..d38f282bb0 100644
--- a/src/pdf/SkPDFDevice.h
+++ b/src/pdf/SkPDFDevice.h
@@ -197,6 +197,8 @@ protected:
SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) override;
+ void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
+
private:
struct RectWithData {
SkRect rect;
@@ -318,10 +320,8 @@ private:
bool handleInversePath(const SkDraw& d, const SkPath& origPath,
const SkPaint& paint, bool pathIsMutable,
const SkMatrix* prePathMatrix = nullptr);
- bool handlePointAnnotation(const SkPoint* points, size_t count,
- const SkMatrix& matrix, SkAnnotation* annot);
- bool handlePathAnnotation(const SkPath& path, const SkDraw& d,
- SkAnnotation* annot);
+ void handlePointAnnotation(const SkPoint&, const SkMatrix&, const char key[], SkData* value);
+ void handlePathAnnotation(const SkPath&, const SkDraw& d, const char key[], SkData* value);
typedef SkBaseDevice INHERITED;
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 916c32a655..75fa836a6a 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -9,6 +9,7 @@
#include "SkDumpCanvas.h"
#ifdef SK_DEVELOPER
+#include "SkData.h"
#include "SkPatchUtils.h"
#include "SkPicture.h"
#include "SkPixelRef.h"
@@ -482,6 +483,13 @@ void SkDumpCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4]
texCoords[2].x(), texCoords[2].y(), texCoords[3].x(), texCoords[3].y());
}
+void SkDumpCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ SkString str;
+ toString(rect, &str);
+ this->dump(kDrawAnnotation_Verb, nullptr, "drawAnnotation(%s \"%s\" (%zu))",
+ str.c_str(), key, value ? value->size() : 0);
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index e3b1e019b6..fd5fa82aa5 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -292,6 +292,13 @@ void SkNWayCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4]
}
}
+void SkNWayCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
+ Iter iter(fList);
+ while (iter.next()) {
+ iter->drawAnnotation(rect, key, data);
+ }
+}
+
#ifdef SK_SUPPORT_LEGACY_DRAWFILTER
SkDrawFilter* SkNWayCanvas::setDrawFilter(SkDrawFilter* filter) {
Iter iter(fList);
diff --git a/tests/SerializationTest.cpp b/tests/SerializationTest.cpp
index a4e40c54ee..eb84b3c957 100644
--- a/tests/SerializationTest.cpp
+++ b/tests/SerializationTest.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "SkAnnotationKeys.h"
#include "Resources.h"
#include "SkCanvas.h"
#include "SkFixed.h"
@@ -546,3 +547,85 @@ DEF_TEST(Serialization, reporter) {
TestPictureTypefaceSerialization(reporter);
}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#include "SkAnnotation.h"
+
+static SkPicture* copy_picture_via_serialization(SkPicture* src) {
+ SkDynamicMemoryWStream wstream;
+ src->serialize(&wstream);
+ SkAutoTDelete<SkStreamAsset> rstream(wstream.detachAsStream());
+ return SkPicture::CreateFromStream(rstream);
+}
+
+struct AnnotationRec {
+ const SkRect fRect;
+ const char* fKey;
+ SkData* fValue;
+};
+
+class TestAnnotationCanvas : public SkCanvas {
+ skiatest::Reporter* fReporter;
+ const AnnotationRec* fRec;
+ int fCount;
+ int fCurrIndex;
+
+public:
+ TestAnnotationCanvas(skiatest::Reporter* reporter, const AnnotationRec rec[], int count)
+ : SkCanvas(100, 100)
+ , fReporter(reporter)
+ , fRec(rec)
+ , fCount(count)
+ , fCurrIndex(0)
+ {}
+
+ ~TestAnnotationCanvas() {
+ REPORTER_ASSERT(fReporter, fCount == fCurrIndex);
+ }
+
+protected:
+ void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
+ REPORTER_ASSERT(fReporter, fCurrIndex < fCount);
+ REPORTER_ASSERT(fReporter, rect == fRec[fCurrIndex].fRect);
+ REPORTER_ASSERT(fReporter, !strcmp(key, fRec[fCurrIndex].fKey));
+ REPORTER_ASSERT(fReporter, value->equals(fRec[fCurrIndex].fValue));
+ fCurrIndex += 1;
+ }
+};
+
+/*
+ * Test the 3 annotation types by recording them into a picture, serializing, and then playing
+ * them back into another canvas.
+ */
+DEF_TEST(Annotations, reporter) {
+ SkPictureRecorder recorder;
+ SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::MakeWH(100, 100));
+
+ const char* str0 = "rect-with-url";
+ const SkRect r0 = SkRect::MakeWH(10, 10);
+ SkAutoTUnref<SkData> d0(SkData::NewWithCString(str0));
+ SkAnnotateRectWithURL(recordingCanvas, r0, d0);
+
+ const char* str1 = "named-destination";
+ const SkRect r1 = SkRect::MakeXYWH(5, 5, 0, 0); // collapsed to a point
+ SkAutoTUnref<SkData> d1(SkData::NewWithCString(str1));
+ SkAnnotateNamedDestination(recordingCanvas, {r1.x(), r1.y()}, d1);
+
+ const char* str2 = "link-to-destination";
+ const SkRect r2 = SkRect::MakeXYWH(20, 20, 5, 6);
+ SkAutoTUnref<SkData> d2(SkData::NewWithCString(str2));
+ SkAnnotateLinkToDestination(recordingCanvas, r2, d2);
+
+ const AnnotationRec recs[] = {
+ { r0, SkAnnotationKeys::URL_Key(), d0 },
+ { r1, SkAnnotationKeys::Define_Named_Dest_Key(), d1 },
+ { r2, SkAnnotationKeys::Link_Named_Dest_Key(), d2 },
+ };
+
+ SkAutoTUnref<SkPicture> pict0(recorder.endRecording());
+ SkAutoTUnref<SkPicture> pict1(copy_picture_via_serialization(pict0));
+
+ TestAnnotationCanvas canvas(reporter, recs, SK_ARRAY_COUNT(recs));
+ canvas.drawPicture(pict1);
+}
+
diff --git a/tests/Writer32Test.cpp b/tests/Writer32Test.cpp
index 39ae79cff6..e03a9163aa 100644
--- a/tests/Writer32Test.cpp
+++ b/tests/Writer32Test.cpp
@@ -278,3 +278,44 @@ DEF_TEST(Writer32_misc, reporter) {
test_rewind(reporter);
}
+DEF_TEST(Writer32_data, reporter) {
+ const char* str = "0123456789";
+ SkAutoTUnref<SkData> data0(SkData::NewWithCString(str));
+ SkAutoTUnref<SkData> data1(SkData::NewEmpty());
+
+ const size_t sizes[] = {
+ SkWriter32::WriteDataSize(nullptr),
+ SkWriter32::WriteDataSize(data0),
+ SkWriter32::WriteDataSize(data1),
+ };
+
+ SkSWriter32<1000> writer;
+ size_t sizeWritten = 0;
+
+ writer.writeData(nullptr);
+ sizeWritten += sizes[0];
+ REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
+
+ writer.writeData(data0);
+ sizeWritten += sizes[1];
+ REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
+
+ writer.writeData(data1);
+ sizeWritten += sizes[2];
+ REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
+
+ SkAutoTUnref<SkData> result(writer.snapshotAsData());
+
+ SkReader32 reader(result->data(), result->size());
+ SkAutoTUnref<SkData> d0(reader.readData()),
+ d1(reader.readData()),
+ d2(reader.readData());
+
+ REPORTER_ASSERT(reporter, 0 == d0->size());
+ REPORTER_ASSERT(reporter, strlen(str)+1 == d1->size());
+ REPORTER_ASSERT(reporter, !memcmp(str, d1->data(), strlen(str)+1));
+ REPORTER_ASSERT(reporter, 0 == d2->size());
+
+ REPORTER_ASSERT(reporter, reader.offset() == sizeWritten);
+ REPORTER_ASSERT(reporter, reader.eof());
+}