move annotations to canvas virtual
In an effort to do it all at once, this change assumes that its ok to ignore annotations that were previously stored on paints in old SKP files (since this feature is only interesting to PDF printing). BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1744103002 Review URL: https://codereview.chromium.org/1744103002
This commit is contained in:
parent
c6663dc36b
commit
0eda2587cc
@ -8,83 +8,18 @@
|
||||
#ifndef SkAnnotation_DEFINED
|
||||
#define SkAnnotation_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
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 +27,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 +37,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 +47,4 @@ SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
|
||||
*/
|
||||
SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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().
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
33
src/core/SkAnnotationKeys.h
Normal file
33
src/core/SkAnnotationKeys.h
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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*
|
||||
|
@ -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);
|
||||
|
@ -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&) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -60,6 +60,7 @@ public:
|
||||
kBitmapSourceFilterQuality_Version = 41,
|
||||
kPictureShaderHasPictureBool_Version = 42,
|
||||
kHasDrawImageOpCodes_Version = 43,
|
||||
kAnnotationsMovedToCanvas_Version = 44,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -28,7 +28,6 @@ namespace SkRemote {
|
||||
kRasterizer,
|
||||
kDrawLooper,
|
||||
kImageFilter,
|
||||
kAnnotation,
|
||||
};
|
||||
|
||||
} // namespace SkRemote
|
||||
|
@ -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() ||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "SkPDFDevice.h"
|
||||
|
||||
#include "SkAnnotation.h"
|
||||
#include "SkAnnotationKeys.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkClipStack.h"
|
||||
@ -757,6 +757,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);
|
||||
@ -796,12 +807,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.
|
||||
@ -939,14 +944,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;
|
||||
@ -1025,12 +1022,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;
|
||||
@ -1684,26 +1675,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.push(new NamedDestination(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.push(new NamedDestination(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);
|
||||
@ -1712,24 +1703,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.push(new RectWithData(transformedRect, urlData));
|
||||
fLinkToURLs.push(new RectWithData(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.push(new RectWithData(transformedRect, linkToDestination));
|
||||
fLinkToDestinations.push(new RectWithData(transformedRect, value));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
|
||||
|
@ -198,6 +198,8 @@ protected:
|
||||
|
||||
SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
||||
void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
|
||||
|
||||
private:
|
||||
// TODO(vandebo): push most of SkPDFDevice's state into a core object in
|
||||
// order to get the right access levels without using friend.
|
||||
@ -303,10 +305,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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user