зеркало из https://github.com/mozilla/moz-skia.git
idea: add annotation to SkPaint
Review URL: https://codereview.appspot.com/6355050 git-svn-id: http://skia.googlecode.com/svn/trunk@4555 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
548a433ec3
Коммит
b0a34d80c5
|
@ -9,6 +9,7 @@
|
|||
'../src/core/ARGB32_Clamp_Bilinear_BitmapShader.h',
|
||||
'../src/core/Sk64.cpp',
|
||||
'../src/core/SkAAClip.cpp',
|
||||
'../src/core/SkAnnotation.cpp',
|
||||
'../src/core/SkAdvancedTypefaceMetrics.cpp',
|
||||
'../src/core/SkAlphaRuns.cpp',
|
||||
'../src/core/SkAntiRun.h',
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
],
|
||||
'sources': [
|
||||
'../tests/AAClipTest.cpp',
|
||||
'../tests/AnnotationTest.cpp',
|
||||
'../tests/BitmapCopyTest.cpp',
|
||||
'../tests/BitmapGetColorTest.cpp',
|
||||
'../tests/BitSetTest.cpp',
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAnnotation_DEFINED
|
||||
#define SkAnnotation_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkData;
|
||||
class SkDataSet;
|
||||
|
||||
/**
|
||||
* Experimental class for annotating draws. Do not use directly yet.
|
||||
* Use helper functions at the bottom of this file for now.
|
||||
*/
|
||||
class SkAnnotation : public SkFlattenable {
|
||||
public:
|
||||
enum Flags {
|
||||
// If set, the associated drawing primitive should not be drawn
|
||||
kNoDraw_Flag = 1 << 0,
|
||||
};
|
||||
|
||||
SkAnnotation(SkDataSet*, uint32_t flags);
|
||||
virtual ~SkAnnotation();
|
||||
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
SkDataSet* getDataSet() const { return fDataSet; }
|
||||
|
||||
bool isNoDraw() const { return SkToBool(fFlags & kNoDraw_Flag); }
|
||||
|
||||
/**
|
||||
* Helper for search the annotation's dataset.
|
||||
*/
|
||||
SkData* find(const char name[]) const;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAnnotation)
|
||||
|
||||
protected:
|
||||
SkAnnotation(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkDataSet* fDataSet;
|
||||
uint32_t fFlags;
|
||||
|
||||
void writeToStream(SkWStream*) const;
|
||||
void readFromStream(SkStream*);
|
||||
|
||||
typedef SkFlattenable 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();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
* safely ignored.
|
||||
*
|
||||
* The caller is responsible for managing its ownership of the SkData.
|
||||
*/
|
||||
SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#include "SkDrawLooper.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class SkAnnotation;
|
||||
class SkAutoGlyphCache;
|
||||
class SkColorFilter;
|
||||
class SkDescriptor;
|
||||
|
@ -581,6 +582,17 @@ public:
|
|||
|
||||
SkImageFilter* getImageFilter() const { return fImageFilter; }
|
||||
SkImageFilter* setImageFilter(SkImageFilter*);
|
||||
|
||||
SkAnnotation* getAnnotation() const { return fAnnotation; }
|
||||
SkAnnotation* setAnnotation(SkAnnotation*);
|
||||
|
||||
/**
|
||||
* Returns true if there is an annotation installed on this paint, and
|
||||
* the annotation specifics no-drawing.
|
||||
*/
|
||||
bool isNoDrawAnnotation() const {
|
||||
return SkToBool(fPrivFlags & kNoDrawAnnotation_PrivFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
|
||||
|
@ -903,17 +915,24 @@ private:
|
|||
SkRasterizer* fRasterizer;
|
||||
SkDrawLooper* fLooper;
|
||||
SkImageFilter* fImageFilter;
|
||||
SkAnnotation* fAnnotation;
|
||||
|
||||
SkColor fColor;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
unsigned fFlags : 15;
|
||||
// all of these bitfields should add up to 32
|
||||
unsigned fFlags : 16;
|
||||
unsigned fTextAlign : 2;
|
||||
unsigned fCapType : 2;
|
||||
unsigned fJoinType : 2;
|
||||
unsigned fStyle : 2;
|
||||
unsigned fTextEncoding : 2; // 3 values
|
||||
unsigned fHinting : 2;
|
||||
unsigned fPrivFlags : 4; // these are not flattened/unflattened
|
||||
|
||||
enum PrivFlags {
|
||||
kNoDrawAnnotation_PrivFlag = 1 << 0,
|
||||
};
|
||||
|
||||
SkDrawCacheProc getDrawCacheProc() const;
|
||||
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkAnnotation.h"
|
||||
#include "SkDataSet.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
SkAnnotation::SkAnnotation(SkDataSet* data, uint32_t flags) {
|
||||
if (NULL == data) {
|
||||
data = SkDataSet::NewEmpty();
|
||||
} else {
|
||||
data->ref();
|
||||
}
|
||||
fDataSet = data;
|
||||
fFlags = flags;
|
||||
}
|
||||
|
||||
SkAnnotation::~SkAnnotation() {
|
||||
fDataSet->unref();
|
||||
}
|
||||
|
||||
SkAnnotation::SkAnnotation(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
|
||||
fFlags = buffer.readU32();
|
||||
fDataSet = SkNEW_ARGS(SkDataSet, (buffer));
|
||||
}
|
||||
|
||||
void SkAnnotation::flatten(SkFlattenableWriteBuffer& buffer) const {
|
||||
buffer.write32(fFlags);
|
||||
fDataSet->flatten(buffer);
|
||||
}
|
||||
|
||||
SK_DEFINE_FLATTENABLE_REGISTRAR(SkAnnotation)
|
||||
|
||||
const char* SkAnnotationKeys::URL_Key() {
|
||||
return "SkAnnotationKey_URL";
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkCanvas.h"
|
||||
|
||||
void SkAnnotateRectWithURL(SkCanvas* canvas, const SkRect& rect, SkData* value) {
|
||||
if (NULL == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* key = SkAnnotationKeys::URL_Key();
|
||||
SkAutoTUnref<SkDataSet> dataset(SkNEW_ARGS(SkDataSet, (key, value)));
|
||||
SkAnnotation* ann = SkNEW_ARGS(SkAnnotation, (dataset,
|
||||
SkAnnotation::kNoDraw_Flag));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAnnotation(ann)->unref();
|
||||
SkASSERT(paint.isNoDrawAnnotation());
|
||||
|
||||
canvas->drawRect(rect, paint);
|
||||
}
|
||||
|
|
@ -15,6 +15,11 @@ SK_DEFINE_INST_COUNT(SkDevice)
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CHECK_FOR_NODRAW_ANNOTATION(paint) \
|
||||
do { if (paint.isNoDrawAnnotation()) { return; } } while (0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkDevice::SkDevice(const SkBitmap& bitmap) : fBitmap(bitmap) {
|
||||
fOrigin.setZero();
|
||||
fMetaData = NULL;
|
||||
|
@ -295,12 +300,14 @@ void SkDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t c
|
|||
|
||||
void SkDevice::drawRect(const SkDraw& draw, const SkRect& r,
|
||||
const SkPaint& paint) {
|
||||
CHECK_FOR_NODRAW_ANNOTATION(paint);
|
||||
draw.drawRect(r, paint);
|
||||
}
|
||||
|
||||
void SkDevice::drawPath(const SkDraw& draw, const SkPath& path,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
CHECK_FOR_NODRAW_ANNOTATION(paint);
|
||||
draw.drawPath(path, paint, prePathMatrix, pathIsMutable);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#include "SkPaint.h"
|
||||
#include "SkAnnotation.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkFontHost.h"
|
||||
#include "SkImageFilter.h"
|
||||
|
@ -55,6 +55,7 @@ SkPaint::SkPaint() {
|
|||
fRasterizer = NULL;
|
||||
fLooper = NULL;
|
||||
fImageFilter = NULL;
|
||||
fAnnotation = NULL;
|
||||
fWidth = 0;
|
||||
#endif
|
||||
|
||||
|
@ -69,6 +70,7 @@ SkPaint::SkPaint() {
|
|||
fStyle = kFill_Style;
|
||||
fTextEncoding = kUTF8_TextEncoding;
|
||||
fHinting = SkPaintDefaults_Hinting;
|
||||
fPrivFlags = 0;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
fGenerationID = 0;
|
||||
#endif
|
||||
|
@ -86,6 +88,7 @@ SkPaint::SkPaint(const SkPaint& src) {
|
|||
SkSafeRef(fRasterizer);
|
||||
SkSafeRef(fLooper);
|
||||
SkSafeRef(fImageFilter);
|
||||
SkSafeRef(fAnnotation);
|
||||
}
|
||||
|
||||
SkPaint::~SkPaint() {
|
||||
|
@ -98,6 +101,7 @@ SkPaint::~SkPaint() {
|
|||
SkSafeUnref(fRasterizer);
|
||||
SkSafeUnref(fLooper);
|
||||
SkSafeUnref(fImageFilter);
|
||||
SkSafeUnref(fAnnotation);
|
||||
}
|
||||
|
||||
SkPaint& SkPaint::operator=(const SkPaint& src) {
|
||||
|
@ -112,6 +116,7 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
|
|||
SkSafeRef(src.fRasterizer);
|
||||
SkSafeRef(src.fLooper);
|
||||
SkSafeRef(src.fImageFilter);
|
||||
SkSafeRef(src.fAnnotation);
|
||||
|
||||
SkSafeUnref(fTypeface);
|
||||
SkSafeUnref(fPathEffect);
|
||||
|
@ -122,6 +127,7 @@ SkPaint& SkPaint::operator=(const SkPaint& src) {
|
|||
SkSafeUnref(fRasterizer);
|
||||
SkSafeUnref(fLooper);
|
||||
SkSafeUnref(fImageFilter);
|
||||
SkSafeUnref(fAnnotation);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
uint32_t oldGenerationID = fGenerationID;
|
||||
|
@ -371,6 +377,16 @@ SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
|
|||
return imageFilter;
|
||||
}
|
||||
|
||||
SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) {
|
||||
SkRefCnt_SafeAssign(fAnnotation, annotation);
|
||||
GEN_ID_INC;
|
||||
|
||||
bool isNoDraw = annotation && annotation->isNoDraw();
|
||||
fPrivFlags = SkSetClearMask(fPrivFlags, isNoDraw, kNoDrawAnnotation_PrivFlag);
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkGlyphCache.h"
|
||||
|
@ -1809,7 +1825,7 @@ static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
|
|||
|
||||
enum FlatFlags {
|
||||
kHasTypeface_FlatFlag = 0x01,
|
||||
kHasEffects_FlatFlag = 0x02
|
||||
kHasEffects_FlatFlag = 0x02,
|
||||
};
|
||||
|
||||
// The size of a flat paint's POD fields
|
||||
|
@ -1833,6 +1849,7 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
|
|||
asint(this->getColorFilter()) |
|
||||
asint(this->getRasterizer()) |
|
||||
asint(this->getLooper()) |
|
||||
asint(this->getAnnotation()) |
|
||||
asint(this->getImageFilter())) {
|
||||
flatFlags |= kHasEffects_FlatFlag;
|
||||
}
|
||||
|
@ -1870,6 +1887,7 @@ void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
|
|||
buffer.writeFlattenable(this->getRasterizer());
|
||||
buffer.writeFlattenable(this->getLooper());
|
||||
buffer.writeFlattenable(this->getImageFilter());
|
||||
buffer.writeFlattenable(this->getAnnotation());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1878,6 +1896,8 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
|
|||
const void* podData = buffer.skip(kPODPaintSize);
|
||||
const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
|
||||
|
||||
fPrivFlags = 0;
|
||||
|
||||
// the order we read must match the order we wrote in flatten()
|
||||
this->setTextSize(read_scalar(pod));
|
||||
this->setTextScaleX(read_scalar(pod));
|
||||
|
@ -1920,6 +1940,7 @@ void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
|
|||
SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable()));
|
||||
SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable()));
|
||||
SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable()));
|
||||
SkSafeUnref(this->setAnnotation((SkAnnotation*) buffer.readFlattenable()));
|
||||
} else {
|
||||
this->setPathEffect(NULL);
|
||||
this->setShader(NULL);
|
||||
|
@ -2209,7 +2230,7 @@ bool SkImageFilter::asADilate(SkISize* radius) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
//////
|
||||
////////////////////
|
||||
|
||||
SK_DEFINE_INST_COUNT(SkDrawLooper)
|
||||
|
||||
|
|
|
@ -71,6 +71,12 @@ enum {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CHECK_FOR_NODRAW_ANNOTATION(paint) \
|
||||
do { if (paint.isNoDrawAnnotation()) { return; } } while (0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SkGpuDevice::SkAutoCachedTexture : public ::SkNoncopyable {
|
||||
public:
|
||||
SkAutoCachedTexture() { }
|
||||
|
@ -662,6 +668,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
|||
|
||||
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
|
||||
const SkPaint& paint) {
|
||||
CHECK_FOR_NODRAW_ANNOTATION(paint);
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
|
||||
|
@ -976,6 +983,7 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& path,
|
|||
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
||||
const SkPaint& paint, const SkMatrix* prePathMatrix,
|
||||
bool pathIsMutable) {
|
||||
CHECK_FOR_NODRAW_ANNOTATION(paint);
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
bool doFill = true;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#include "Test.h"
|
||||
#include "SkAnnotation.h"
|
||||
#include "SkData.h"
|
||||
#include "SkCanvas.h"
|
||||
|
||||
static void test_nodraw(skiatest::Reporter* reporter) {
|
||||
SkBitmap bm;
|
||||
bm.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
|
||||
bm.allocPixels();
|
||||
bm.eraseColor(0);
|
||||
|
||||
SkCanvas canvas(bm);
|
||||
SkRect r = SkRect::MakeWH(SkIntToScalar(10), SkIntToScalar(10));
|
||||
|
||||
SkAutoDataUnref data(SkData::NewWithCString("http://www.gooogle.com"));
|
||||
|
||||
REPORTER_ASSERT(reporter, 0 == *bm.getAddr32(0, 0));
|
||||
SkAnnotateRectWithURL(&canvas, r, data.get());
|
||||
REPORTER_ASSERT(reporter, 0 == *bm.getAddr32(0, 0));
|
||||
}
|
||||
|
||||
static void TestAnnotation(skiatest::Reporter* reporter) {
|
||||
test_nodraw(reporter);
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
DEFINE_TESTCLASS("Annotation", AnnotationClass, TestAnnotation)
|
Загрузка…
Ссылка в новой задаче