/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPictureFlat_DEFINED
#define SkPictureFlat_DEFINED
#include "SkChunkAlloc.h"
#include "SkBitmap.h"
#include "SkPicture.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
enum DrawType {
UNUSED,
CLIP_PATH,
CLIP_REGION,
CLIP_RECT,
CONCAT,
DRAW_BITMAP,
DRAW_BITMAP_MATRIX,
DRAW_BITMAP_RECT,
DRAW_CLEAR,
DRAW_DATA,
DRAW_PAINT,
DRAW_PATH,
DRAW_PICTURE,
DRAW_POINTS,
DRAW_POS_TEXT,
DRAW_POS_TEXT_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT
DRAW_POS_TEXT_H,
DRAW_POS_TEXT_H_TOP_BOTTOM, // fast variant of DRAW_POS_TEXT_H
DRAW_RECT,
DRAW_SHAPE,
DRAW_SPRITE,
DRAW_TEXT,
DRAW_TEXT_ON_PATH,
DRAW_TEXT_TOP_BOTTOM, // fast variant of DRAW_TEXT
DRAW_VERTICES,
RESTORE,
ROTATE,
SAVE,
SAVE_LAYER,
SCALE,
SET_MATRIX,
SKEW,
TRANSLATE,
DRAW_BITMAP_NINE
};
enum DrawVertexFlags {
DRAW_VERTICES_HAS_TEXS = 0x01,
DRAW_VERTICES_HAS_COLORS = 0x02,
DRAW_VERTICES_HAS_INDICES = 0x04
};
///////////////////////////////////////////////////////////////////////////////
// clipparams are packed in 5 bits
// doAA:1 | regionOp:4
static inline uint32_t ClipParams_pack(SkRegion::Op op, bool doAA) {
unsigned doAABit = doAA ? 1 : 0;
return (doAABit << 4) | op;
}
static inline SkRegion::Op ClipParams_unpackRegionOp(uint32_t packed) {
return (SkRegion::Op)(packed & 0xF);
}
static inline bool ClipParams_unpackDoAA(uint32_t packed) {
return SkToBool((packed >> 4) & 1);
}
///////////////////////////////////////////////////////////////////////////////
class SkRefCntPlayback {
public:
SkRefCntPlayback();
virtual ~SkRefCntPlayback();
int count() const { return fCount; }
void reset(const SkRefCntSet*);
void setCount(int count);
SkRefCnt* set(int index, SkRefCnt*);
virtual void setupBuffer(SkFlattenableReadBuffer& buffer) const {
buffer.setRefCntArray(fArray, fCount);
}
protected:
int fCount;
SkRefCnt** fArray;
};
class SkTypefacePlayback : public SkRefCntPlayback {
public:
virtual void setupBuffer(SkFlattenableReadBuffer& buffer) const {
buffer.setTypefaceArray((SkTypeface**)fArray, fCount);
}
};
class SkFactoryPlayback {
public:
SkFactoryPlayback(int count) : fCount(count) {
fArray = SkNEW_ARRAY(SkFlattenable::Factory, count);
}
~SkFactoryPlayback() {
SkDELETE_ARRAY(fArray);
}
SkFlattenable::Factory* base() const { return fArray; }
void setupBuffer(SkFlattenableReadBuffer& buffer) const {
buffer.setFactoryPlayback(fArray, fCount);
}
private:
int fCount;
SkFlattenable::Factory* fArray;
};
class SkFlatData {
public:
static int Compare(const SkFlatData* a, const SkFlatData* b) {
return memcmp(&a->fAllocSize, &b->fAllocSize, a->fAllocSize);
}
int index() const { return fIndex; }
#ifdef SK_DEBUG_SIZE
size_t size() const { return sizeof(fIndex) + fAllocSize; }
#endif
protected:
static SkFlatData* Alloc(SkChunkAlloc* heap, int32_t size, int index);
int fIndex;
int32_t fAllocSize;
};
class SkFlatBitmap : public SkFlatData {
public:
static SkFlatBitmap* Flatten(SkChunkAlloc*, const SkBitmap&, int index,
SkRefCntSet*);
void unflatten(SkBitmap* bitmap, SkRefCntPlayback* rcp) const {
SkFlattenableReadBuffer buffer(fBitmapData);
if (rcp) {
rcp->setupBuffer(buffer);
}
bitmap->unflatten(buffer);
}
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
}
#endif
private:
char fBitmapData[1];
typedef SkFlatData INHERITED;
};
class SkFlatMatrix : public SkFlatData {
public:
static SkFlatMatrix* Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index);
void unflatten(SkMatrix* result) const {
result->unflatten(fMatrixData);
}
#ifdef SK_DEBUG_DUMP
void dump() const;
#endif
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
}
#endif
private:
char fMatrixData[1];
typedef SkFlatData INHERITED;
};
class SkFlatPaint : public SkFlatData {
public:
static SkFlatPaint* Flatten(SkChunkAlloc* heap, const SkPaint& paint,
int index, SkRefCntSet*,
SkRefCntSet* faceRecorder);
void unflatten(SkPaint* result, SkRefCntPlayback* rcp,
SkTypefacePlayback* facePlayback) const {
Read(fPaintData, result, rcp, facePlayback);
}
static void Read(const void* storage, SkPaint* paint, SkRefCntPlayback*,
SkTypefacePlayback* facePlayback);
#ifdef SK_DEBUG_DUMP
void dump() const;
#endif
private:
char fPaintData[1];
typedef SkFlatData INHERITED;
};
class SkFlatRegion : public SkFlatData {
public:
static SkFlatRegion* Flatten(SkChunkAlloc* heap, const SkRegion& region, int index);
void unflatten(SkRegion* result) const {
result->unflatten(fRegionData);
}
#ifdef SK_DEBUG_VALIDATE
void validate() const {
// to be written
}
#endif
private:
char fRegionData[1];
typedef SkFlatData INHERITED;
};
#endif