add experimental canvas pipe
git-svn-id: http://skia.googlecode.com/svn/trunk@1187 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
06afe7b5a1
commit
bb6992a9d6
61
include/pipe/SkGPipe.h
Normal file
61
include/pipe/SkGPipe.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkGPipe_DEFINED
|
||||
#define SkGPipe_DEFINED
|
||||
|
||||
#include "SkWriter32.h"
|
||||
|
||||
class SkCanvas;
|
||||
|
||||
class SkGPipeReader {
|
||||
public:
|
||||
SkGPipeReader(SkCanvas* target);
|
||||
~SkGPipeReader();
|
||||
|
||||
enum Status {
|
||||
kDone_Status, //!< no more data expected from reader
|
||||
kEOF_Status, //!< need more data from reader
|
||||
kError_Status //!< encountered error
|
||||
};
|
||||
|
||||
Status playback(const void* data, size_t length);
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
class SkGPipeState* fState;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkGPipeWriter {
|
||||
public:
|
||||
SkGPipeWriter();
|
||||
~SkGPipeWriter();
|
||||
|
||||
bool isRecording() const { return NULL != fCanvas; }
|
||||
SkCanvas* startRecording();
|
||||
void endRecording();
|
||||
|
||||
size_t flatten(void* buffer);
|
||||
|
||||
private:
|
||||
class SkGPipeCanvas* fCanvas;
|
||||
SkWriter32 fWriter;
|
||||
};
|
||||
|
||||
#endif
|
202
src/pipe/SkGPipePriv.h
Normal file
202
src/pipe/SkGPipePriv.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkGPipePriv_DEFINED
|
||||
#define SkGPipePriv_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
#define UNIMPLEMENTED
|
||||
|
||||
enum DrawOps {
|
||||
// these match Canvas apis
|
||||
kClipPath_DrawOp,
|
||||
kClipRegion_DrawOp,
|
||||
kClipRect_DrawOp,
|
||||
kConcat_DrawOp,
|
||||
kDrawBitmap_DrawOp,
|
||||
kDrawBitmapMatrix_DrawOp,
|
||||
kDrawBitmapRect_DrawOp,
|
||||
kDrawClear_DrawOp,
|
||||
kDrawData_DrawOp,
|
||||
kDrawPaint_DrawOp,
|
||||
kDrawPath_DrawOp,
|
||||
kDrawPicture_DrawOp,
|
||||
kDrawPoints_DrawOp,
|
||||
kDrawPosText_DrawOp,
|
||||
kDrawPosTextH_DrawOp,
|
||||
kDrawRect_DrawOp,
|
||||
kDrawShape_DrawOp,
|
||||
kDrawSprite_DrawOp,
|
||||
kDrawText_DrawOp,
|
||||
kDrawTextOnPath_DrawOp,
|
||||
kDrawVertices_DrawOp,
|
||||
kRestore_DrawOp,
|
||||
kRotate_DrawOp,
|
||||
kSave_DrawOp,
|
||||
kSaveLayer_DrawOp,
|
||||
kScale_DrawOp,
|
||||
kSetMatrix_DrawOp,
|
||||
kSkew_DrawOp,
|
||||
kTranslate_DrawOp,
|
||||
|
||||
// these edit paints
|
||||
kPaintOp_DrawOp,
|
||||
|
||||
// these are signals to playback, not drawing verbs
|
||||
kDone_DrawOp,
|
||||
};
|
||||
|
||||
/**
|
||||
* DrawOp packs into a 32bit int as follows
|
||||
*
|
||||
* DrawOp:8 - Flags:4 - Data:20
|
||||
*
|
||||
* Flags and Data are called out separately, so we can reuse Data between
|
||||
* different Ops that might have different Flags. e.g. Data might be a Paint
|
||||
* index for both drawRect (no flags) and saveLayer (does have flags).
|
||||
*
|
||||
* All Ops that take a SkPaint use their Data field to store the index to
|
||||
* the paint (previously defined with kPaintOp_DrawOp).
|
||||
*/
|
||||
|
||||
#define DRAWOPS_OP_BITS 8
|
||||
#define DRAWOPS_FLAG_BITS 4
|
||||
#define DRAWOPS_DATA_BITS 20
|
||||
|
||||
#define DRAWOPS_OP_MASK ((1 << DRAWOPS_OP_BITS) - 1)
|
||||
#define DRAWOPS_FLAG_MASK ((1 << DRAWOPS_FLAG_BITS) - 1)
|
||||
#define DRAWOPS_DATA_MASK ((1 << DRAWOPS_DATA_BITS) - 1)
|
||||
|
||||
static unsigned DrawOp_unpackOp(uint32_t op32) {
|
||||
return (op32 >> (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS));
|
||||
}
|
||||
|
||||
static unsigned DrawOp_unpackFlags(uint32_t op32) {
|
||||
return (op32 >> DRAWOPS_DATA_BITS) & DRAWOPS_FLAG_MASK;
|
||||
}
|
||||
|
||||
static unsigned DrawOp_unpackData(uint32_t op32) {
|
||||
return op32 & DRAWOPS_DATA_MASK;
|
||||
}
|
||||
|
||||
static uint32_t DrawOp_packOpFlagData(DrawOps op, unsigned flags, unsigned data) {
|
||||
SkASSERT(0 == (op & ~DRAWOPS_OP_MASK));
|
||||
SkASSERT(0 == (flags & ~DRAWOPS_FLAG_MASK));
|
||||
SkASSERT(0 == (data & ~DRAWOPS_DATA_MASK));
|
||||
|
||||
return (op << DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS) |
|
||||
(flags << DRAWOPS_DATA_BITS) |
|
||||
data;
|
||||
}
|
||||
|
||||
/** DrawOp specific flag bits
|
||||
*/
|
||||
|
||||
enum {
|
||||
kSaveLayer_HasBounds_DrawOpFlag = 1 << 0,
|
||||
kSaveLayer_HasPaint_DrawOpFlag = 1 << 1,
|
||||
};
|
||||
enum {
|
||||
kClear_HasColor_DrawOpFlag = 1 << 0
|
||||
};
|
||||
enum {
|
||||
kDrawTextOnPath_HasMatrix_DrawOpFlag = 1 << 0
|
||||
};
|
||||
enum {
|
||||
kDrawVertices_HasTexs_DrawOpFlag = 1 << 0,
|
||||
kDrawVertices_HasColors_DrawOpFlag = 1 << 1,
|
||||
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum PaintOps {
|
||||
kReset_PaintOp, // no arg
|
||||
|
||||
kFlags_PaintOp, // arg inline
|
||||
kColor_PaintOp, // arg 32
|
||||
kStyle_PaintOp, // arg inline
|
||||
kJoin_PaintOp, // arg inline
|
||||
kCap_PaintOp, // arg inline
|
||||
kWidth_PaintOp, // arg scalar
|
||||
kMiter_PaintOp,// arg scalar
|
||||
|
||||
kEncoding_PaintOp, // arg inline - text
|
||||
kHinting_PaintOp, // arg inline - text
|
||||
kAlign_PaintOp, // arg inline - text
|
||||
kTextSize_PaintOp, // arg scalar - text
|
||||
kTextScaleX_PaintOp,// arg scalar - text
|
||||
kTextSkewX_PaintOp, // arg scalar - text
|
||||
|
||||
kPathEffect_PaintOp, // arg inline
|
||||
kShader_PaintOp,
|
||||
kXfermode_PaintOp,
|
||||
kMaskFilter_PaintOp,
|
||||
kColorFilter_PaintOp,
|
||||
kRasterizer_PaintOp,
|
||||
kDrawLooper_PaintOp,
|
||||
};
|
||||
|
||||
#define PAINTOPS_OP_BITS 8
|
||||
#define PAINTOPS_FLAG_BITS 4
|
||||
#define PAINTOPS_DATA_BITS 20
|
||||
|
||||
#define PAINTOPS_OP_MASK ((1 << PAINTOPS_OP_BITS) - 1)
|
||||
#define PAINTOPS_FLAG_MASK ((1 << PAINTOPS_FLAG_BITS) - 1)
|
||||
#define PAINTOPS_DATA_MASK ((1 << PAINTOPS_DATA_BITS) - 1)
|
||||
|
||||
static unsigned PaintOp_unpackOp(uint32_t op32) {
|
||||
return (op32 >> (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS));
|
||||
}
|
||||
|
||||
static unsigned PaintOp_unpackFlags(uint32_t op32) {
|
||||
return (op32 >> PAINTOPS_DATA_BITS) & PAINTOPS_FLAG_MASK;
|
||||
}
|
||||
|
||||
static unsigned PaintOp_unpackData(uint32_t op32) {
|
||||
return op32 & PAINTOPS_DATA_MASK;
|
||||
}
|
||||
|
||||
static uint32_t PaintOp_packOp(PaintOps op) {
|
||||
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
|
||||
|
||||
return (op << PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS);
|
||||
}
|
||||
|
||||
static uint32_t PaintOp_packOpData(PaintOps op, unsigned data) {
|
||||
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
|
||||
SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));
|
||||
|
||||
return (op << PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS) | data;
|
||||
}
|
||||
|
||||
static uint32_t PaintOp_packOpFlagData(PaintOps op, unsigned flags, unsigned data) {
|
||||
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
|
||||
SkASSERT(0 == (flags & ~PAINTOPS_FLAG_MASK));
|
||||
SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));
|
||||
|
||||
return (op << PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS) |
|
||||
(flags << PAINTOPS_DATA_BITS) |
|
||||
data;
|
||||
}
|
||||
|
||||
enum {
|
||||
kLastOp_PaintOpFlag = 1 << 0
|
||||
};
|
||||
|
||||
#endif
|
500
src/pipe/SkGPipeRead.cpp
Normal file
500
src/pipe/SkGPipeRead.cpp
Normal file
@ -0,0 +1,500 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkGPipePriv.h"
|
||||
#include "SkReader32.h"
|
||||
|
||||
class SkGPipeState {
|
||||
public:
|
||||
SkGPipeState();
|
||||
~SkGPipeState();
|
||||
|
||||
const SkPaint& getPaint(uint32_t drawOp32) const;
|
||||
|
||||
// Extracts index from DrawOp_unpackData().
|
||||
// Returns the specified paint from our list, or creates a new paint if
|
||||
// index == count. If index > count, return NULL
|
||||
SkPaint* editPaint(uint32_t drawOp32);
|
||||
|
||||
private:
|
||||
SkTDArray<SkPaint*> fPaints;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T> const T* skip(SkReader32* reader, int count = 1) {
|
||||
SkASSERT(count >= 0);
|
||||
size_t size = sizeof(T) * count;
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
return reinterpret_cast<const T*>(reader->skip(size));
|
||||
}
|
||||
|
||||
template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
|
||||
SkASSERT(count >= 0);
|
||||
size_t size = SkAlign4(sizeof(T) * count);
|
||||
return reinterpret_cast<const T*>(reader->skip(size));
|
||||
}
|
||||
|
||||
static void readRegion(SkReader32* reader, SkRegion* rgn) {
|
||||
size_t size = rgn->unflatten(reader->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)reader->skip(size);
|
||||
}
|
||||
|
||||
static void readMatrix(SkReader32* reader, SkMatrix* matrix) {
|
||||
size_t size = matrix->unflatten(reader->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)reader->skip(size);
|
||||
}
|
||||
|
||||
const SkPaint& SkGPipeState::getPaint(uint32_t op32) const {
|
||||
unsigned index = DrawOp_unpackData(op32);
|
||||
if (index >= fPaints.count()) {
|
||||
SkASSERT(!"paint index out of range");
|
||||
index = 0; // we always have at least 1 paint
|
||||
}
|
||||
return *fPaints[index];
|
||||
}
|
||||
|
||||
SkPaint* SkGPipeState::editPaint(uint32_t op32) {
|
||||
unsigned index = DrawOp_unpackData(op32);
|
||||
|
||||
if (index > fPaints.count()) {
|
||||
SkASSERT(!"paint index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (index == fPaints.count()) {
|
||||
*fPaints.append() = SkNEW(SkPaint);
|
||||
}
|
||||
return fPaints[index];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkPath path;
|
||||
path.unflatten(*reader);
|
||||
canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
|
||||
}
|
||||
|
||||
static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkRegion rgn;
|
||||
readRegion(reader, &rgn);
|
||||
canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
|
||||
}
|
||||
|
||||
static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkMatrix matrix;
|
||||
readMatrix(reader, &matrix);
|
||||
canvas->setMatrix(matrix);
|
||||
}
|
||||
|
||||
static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkMatrix matrix;
|
||||
readMatrix(reader, &matrix);
|
||||
canvas->concat(matrix);
|
||||
}
|
||||
|
||||
static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
const SkScalar* param = skip<SkScalar>(reader, 2);
|
||||
canvas->scale(param[0], param[1]);
|
||||
}
|
||||
|
||||
static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
const SkScalar* param = skip<SkScalar>(reader, 2);
|
||||
canvas->skew(param[0], param[1]);
|
||||
}
|
||||
|
||||
static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->rotate(reader->readScalar());
|
||||
}
|
||||
|
||||
static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
const SkScalar* param = skip<SkScalar>(reader, 2);
|
||||
canvas->translate(param[0], param[1]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
|
||||
}
|
||||
|
||||
static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
unsigned flags = DrawOp_unpackData(op32);
|
||||
|
||||
const SkRect* bounds = NULL;
|
||||
if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
|
||||
bounds = skip<SkRect>(reader);
|
||||
}
|
||||
const SkPaint* paint = NULL;
|
||||
if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
|
||||
paint = &state->getPaint(reader->readU32());
|
||||
}
|
||||
canvas->saveLayer(bounds, paint,
|
||||
(SkCanvas::SaveFlags)DrawOp_unpackFlags(op32));
|
||||
}
|
||||
|
||||
static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkColor color = 0;
|
||||
if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
|
||||
color = reader->readU32();
|
||||
}
|
||||
canvas->clear(color);
|
||||
}
|
||||
|
||||
static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->drawPaint(state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
|
||||
size_t count = reader->readU32();
|
||||
const SkPoint* pts = skip<SkPoint>(reader, count);
|
||||
canvas->drawPoints(mode, count, pts, state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
canvas->drawRect(*skip<SkRect>(reader), state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkPath path;
|
||||
path.unflatten(*reader);
|
||||
canvas->drawPath(path, state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
unsigned flags = DrawOp_unpackFlags(op32);
|
||||
|
||||
SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
|
||||
int vertexCount = reader->readU32();
|
||||
const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
|
||||
|
||||
const SkPoint* texs = NULL;
|
||||
if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
|
||||
texs = skip<SkPoint>(reader, vertexCount);
|
||||
}
|
||||
|
||||
const SkColor* colors = NULL;
|
||||
if (flags & kDrawVertices_HasColors_DrawOpFlag) {
|
||||
colors = skip<SkColor>(reader, vertexCount);
|
||||
}
|
||||
|
||||
// TODO: flatten/unflatten xfermodes
|
||||
SkXfermode* xfer = NULL;
|
||||
|
||||
int indexCount = 0;
|
||||
const uint16_t* indices = NULL;
|
||||
if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
|
||||
indexCount = reader->readU32();
|
||||
indices = skipAlign<uint16_t>(reader, indexCount);
|
||||
}
|
||||
|
||||
canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
|
||||
indices, indexCount, state->getPaint(op32));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
size_t len = reader->readU32();
|
||||
const void* text = reader->skip(SkAlign4(len));
|
||||
const SkScalar* xy = skip<SkScalar>(reader, 2);
|
||||
canvas->drawText(text, len, xy[0], xy[1], state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
size_t len = reader->readU32();
|
||||
const void* text = reader->skip(SkAlign4(len));
|
||||
size_t posCount = reader->readU32(); // compute by our writer
|
||||
const SkPoint* pos = skip<SkPoint>(reader, posCount);
|
||||
canvas->drawPosText(text, len, pos, state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
size_t len = reader->readU32();
|
||||
const void* text = reader->skip(SkAlign4(len));
|
||||
size_t posCount = reader->readU32(); // compute by our writer
|
||||
const SkScalar* xpos = skip<SkScalar>(reader, posCount);
|
||||
SkScalar constY = reader->readScalar();
|
||||
canvas->drawPosTextH(text, len, xpos, constY, state->getPaint(op32));
|
||||
}
|
||||
|
||||
static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
size_t len = reader->readU32();
|
||||
const void* text = reader->skip(SkAlign4(len));
|
||||
|
||||
SkPath path;
|
||||
path.unflatten(*reader);
|
||||
|
||||
SkMatrix matrixStorage;
|
||||
const SkMatrix* matrix = NULL;
|
||||
if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
|
||||
readMatrix(reader, &matrixStorage);
|
||||
matrix = &matrixStorage;
|
||||
}
|
||||
|
||||
canvas->drawTextOnPath(text, len, path, matrix, state->getPaint(op32));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
// since we don't have a paint, we can use data for our (small) sizes
|
||||
size_t size = DrawOp_unpackData(op32);
|
||||
if (0 == size) {
|
||||
size = reader->readU32();
|
||||
}
|
||||
const void* data = reader->skip(SkAlign4(size));
|
||||
canvas->drawData(data, size);
|
||||
}
|
||||
|
||||
static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void inflate_patheffect(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_shader(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_xfermode(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_maskfilter(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_colorfilter(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_rasterizer(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void inflate_drawlooper(SkReader32* reader, SkPaint* paint) {
|
||||
}
|
||||
|
||||
static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
|
||||
SkGPipeState* state) {
|
||||
SkPaint* p = state->editPaint(op32);
|
||||
int done;
|
||||
|
||||
do {
|
||||
uint32_t p32 = reader->readU32();
|
||||
unsigned op = PaintOp_unpackOp(p32);
|
||||
unsigned data = PaintOp_unpackData(p32);
|
||||
done = PaintOp_unpackFlags(p32) & kLastOp_PaintOpFlag;
|
||||
|
||||
SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
|
||||
|
||||
switch (op) {
|
||||
case kReset_PaintOp: p->reset(); break;
|
||||
case kFlags_PaintOp: p->setFlags(data); break;
|
||||
case kColor_PaintOp: p->setColor(reader->readU32()); break;
|
||||
case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
|
||||
case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
|
||||
case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
|
||||
case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
|
||||
case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
|
||||
case kEncoding_PaintOp:
|
||||
p->setTextEncoding((SkPaint::TextEncoding)data);
|
||||
break;
|
||||
case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
|
||||
case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
|
||||
case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
|
||||
case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
|
||||
case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
|
||||
|
||||
// flag to reference a cached index instead of inflating?
|
||||
case kPathEffect_PaintOp: inflate_patheffect(reader, p); break;
|
||||
case kShader_PaintOp: inflate_shader(reader, p); break;
|
||||
case kXfermode_PaintOp: inflate_xfermode(reader, p); break;
|
||||
case kMaskFilter_PaintOp: inflate_maskfilter(reader, p); break;
|
||||
case kColorFilter_PaintOp: inflate_colorfilter(reader, p); break;
|
||||
case kRasterizer_PaintOp: inflate_rasterizer(reader, p); break;
|
||||
case kDrawLooper_PaintOp: inflate_drawlooper(reader, p); break;
|
||||
default: SkASSERT(!"bad paintop"); return;
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
|
||||
|
||||
typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
|
||||
|
||||
static const ReadProc gReadTable[] = {
|
||||
clipPath_rp,
|
||||
clipRegion_rp,
|
||||
clipRect_rp,
|
||||
concat_rp,
|
||||
drawBitmap_rp,
|
||||
drawBitmapMatrix_rp,
|
||||
drawBitmapRect_rp,
|
||||
drawClear_rp,
|
||||
drawData_rp,
|
||||
drawPaint_rp,
|
||||
drawPath_rp,
|
||||
drawPicture_rp,
|
||||
drawPoints_rp,
|
||||
drawPosText_rp,
|
||||
drawPosTextH_rp,
|
||||
drawRect_rp,
|
||||
drawShape_rp,
|
||||
drawSprite_rp,
|
||||
drawText_rp,
|
||||
drawTextOnPath_rp,
|
||||
drawVertices_rp,
|
||||
restore_rp,
|
||||
rotate_rp,
|
||||
save_rp,
|
||||
saveLayer_rp,
|
||||
scale_rp,
|
||||
setMatrix_rp,
|
||||
skew_rp,
|
||||
translate_rp,
|
||||
paintOp_rp,
|
||||
done_rp
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkGPipeState::SkGPipeState() {
|
||||
// start out with one paint in default state
|
||||
*fPaints.append() = SkNEW(SkPaint);
|
||||
}
|
||||
|
||||
SkGPipeState::~SkGPipeState() {
|
||||
fPaints.deleteAll();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkGPipe.h"
|
||||
|
||||
SkGPipeReader::SkGPipeReader(SkCanvas* target) {
|
||||
SkSafeRef(target);
|
||||
fCanvas = target;
|
||||
fState = NULL;
|
||||
}
|
||||
|
||||
SkGPipeReader::~SkGPipeReader() {
|
||||
SkSafeUnref(fCanvas);
|
||||
delete fState;
|
||||
}
|
||||
|
||||
SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length) {
|
||||
if (NULL == fCanvas) {
|
||||
return kError_Status;
|
||||
}
|
||||
|
||||
if (NULL == fState) {
|
||||
fState = new SkGPipeState;
|
||||
}
|
||||
|
||||
const ReadProc* table = gReadTable;
|
||||
SkReader32 reader(data, length);
|
||||
SkCanvas* canvas = fCanvas;
|
||||
|
||||
while (!reader.eof()) {
|
||||
uint32_t op32 = reader.readU32();
|
||||
unsigned op = DrawOp_unpackOp(op32);
|
||||
|
||||
if (op >= SK_ARRAY_COUNT(gReadTable)) {
|
||||
SkDebugf("---- bad op during GPipeState::playback\n");
|
||||
return kError_Status;
|
||||
}
|
||||
if (kDone_DrawOp == op) {
|
||||
return kDone_Status;
|
||||
}
|
||||
table[op](canvas, &reader, op32, fState);
|
||||
}
|
||||
return kEOF_Status;
|
||||
}
|
||||
|
||||
|
539
src/pipe/SkGPipeWrite.cpp
Normal file
539
src/pipe/SkGPipeWrite.cpp
Normal file
@ -0,0 +1,539 @@
|
||||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkGPipePriv.h"
|
||||
#include "SkGPipeState.h"
|
||||
#include "SkWriter32.h"
|
||||
|
||||
static void writeRegion(SkWriter32* writer, const SkRegion& rgn) {
|
||||
size_t size = rgn.flatten(NULL);
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
rgn.flatten(writer->reserve(size));
|
||||
}
|
||||
|
||||
static void writeMatrix(SkWriter32* writer, const SkMatrix& matrix) {
|
||||
size_t size = matrix.flatten(NULL);
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
matrix.flatten(writer->reserve(size));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkGPipeCanvas : public SkCanvas {
|
||||
public:
|
||||
SkGPipeCanvas(SkWriter32* writer);
|
||||
virtual ~SkGPipeCanvas();
|
||||
|
||||
void finish() {
|
||||
if (!fDone) {
|
||||
this->writeOp(kDone_DrawOp);
|
||||
fDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// overrides from SkCanvas
|
||||
virtual int save(SaveFlags);
|
||||
virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags);
|
||||
virtual void restore();
|
||||
virtual bool translate(SkScalar dx, SkScalar dy);
|
||||
virtual bool scale(SkScalar sx, SkScalar sy);
|
||||
virtual bool rotate(SkScalar degrees);
|
||||
virtual bool skew(SkScalar sx, SkScalar sy);
|
||||
virtual bool concat(const SkMatrix& matrix);
|
||||
virtual void setMatrix(const SkMatrix& matrix);
|
||||
virtual bool clipRect(const SkRect& rect, SkRegion::Op op);
|
||||
virtual bool clipPath(const SkPath& path, SkRegion::Op op);
|
||||
virtual bool clipRegion(const SkRegion& region, SkRegion::Op op);
|
||||
virtual void clear(SkColor);
|
||||
virtual void drawPaint(const SkPaint& paint);
|
||||
virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
|
||||
const SkPaint&);
|
||||
virtual void drawRect(const SkRect& rect, const SkPaint&);
|
||||
virtual void drawPath(const SkPath& path, const SkPaint&);
|
||||
virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
|
||||
const SkPaint*);
|
||||
virtual void drawBitmapRect(const SkBitmap&, const SkIRect* src,
|
||||
const SkRect& dst, const SkPaint*);
|
||||
virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
|
||||
const SkPaint*);
|
||||
virtual void drawSprite(const SkBitmap&, int left, int top,
|
||||
const SkPaint*);
|
||||
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint&);
|
||||
virtual void drawPosText(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint&);
|
||||
virtual void drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY, const SkPaint&);
|
||||
virtual void drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint&);
|
||||
virtual void drawPicture(SkPicture& picture);
|
||||
virtual void drawShape(SkShape*);
|
||||
virtual void drawVertices(VertexMode, int vertexCount,
|
||||
const SkPoint vertices[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode*,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint&);
|
||||
virtual void drawData(const void*, size_t);
|
||||
|
||||
private:
|
||||
SkWriter32& fWriter;
|
||||
bool fDone;
|
||||
|
||||
void writeOp(DrawOps op, unsigned flags, unsigned data) {
|
||||
fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
|
||||
}
|
||||
|
||||
void writeOp(DrawOps op) {
|
||||
fWriter.write32(DrawOp_packOpFlagData(op, 0, 0));
|
||||
}
|
||||
|
||||
SkTDArray<SkPaint*> fPaints;
|
||||
unsigned writePaint(const SkPaint&);
|
||||
|
||||
typedef SkCanvas INHERITED;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SkGPipeCanvas::SkGPipeCanvas(SkWriter32* writer) : fWriter(*writer) {
|
||||
fDone = false;
|
||||
// always begin with 1 default paint
|
||||
*fPaints.append() = SkNEW(SkPaint);
|
||||
}
|
||||
|
||||
SkGPipeCanvas::~SkGPipeCanvas() {
|
||||
this->finish();
|
||||
|
||||
fPaints.deleteAll();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int SkGPipeCanvas::save(SaveFlags flags) {
|
||||
this->writeOp(kSave_DrawOp, 0, flags);
|
||||
return this->INHERITED::save(flags);
|
||||
}
|
||||
|
||||
int SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
SaveFlags saveFlags) {
|
||||
unsigned index = 0; // just to avoid the warning
|
||||
unsigned opFlags = 0;
|
||||
|
||||
if (bounds) {
|
||||
opFlags |= kSaveLayer_HasBounds_DrawOpFlag;
|
||||
}
|
||||
if (paint) {
|
||||
opFlags |= kSaveLayer_HasPaint_DrawOpFlag;
|
||||
index = this->writePaint(*paint);
|
||||
}
|
||||
|
||||
this->writeOp(kSaveLayer_DrawOp, opFlags, saveFlags);
|
||||
if (bounds) {
|
||||
fWriter.writeRect(*bounds);
|
||||
}
|
||||
if (paint) {
|
||||
fWriter.write32(index);
|
||||
}
|
||||
|
||||
// we just pass on the save, so we don't create a layer
|
||||
return this->INHERITED::save(saveFlags);
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::restore() {
|
||||
this->writeOp(kRestore_DrawOp);
|
||||
this->INHERITED::restore();
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) {
|
||||
if (dx || dy) {
|
||||
this->writeOp(kTranslate_DrawOp);
|
||||
fWriter.writeScalar(dx);
|
||||
fWriter.writeScalar(dy);
|
||||
}
|
||||
return this->INHERITED::translate(dx, dy);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) {
|
||||
if (sx || sy) {
|
||||
this->writeOp(kScale_DrawOp);
|
||||
fWriter.writeScalar(sx);
|
||||
fWriter.writeScalar(sy);
|
||||
}
|
||||
return this->INHERITED::scale(sx, sy);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::rotate(SkScalar degrees) {
|
||||
if (degrees) {
|
||||
this->writeOp(kRotate_DrawOp);
|
||||
fWriter.writeScalar(degrees);
|
||||
}
|
||||
return this->INHERITED::rotate(degrees);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) {
|
||||
if (sx || sy) {
|
||||
this->writeOp(kSkew_DrawOp);
|
||||
fWriter.writeScalar(sx);
|
||||
fWriter.writeScalar(sy);
|
||||
}
|
||||
return this->INHERITED::skew(sx, sy);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::concat(const SkMatrix& matrix) {
|
||||
if (!matrix.isIdentity()) {
|
||||
this->writeOp(kConcat_DrawOp);
|
||||
writeMatrix(&fWriter, matrix);
|
||||
}
|
||||
return this->INHERITED::concat(matrix);
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::setMatrix(const SkMatrix& matrix) {
|
||||
this->writeOp(kSetMatrix_DrawOp);
|
||||
writeMatrix(&fWriter, matrix);
|
||||
this->INHERITED::setMatrix(matrix);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp) {
|
||||
this->writeOp(kClipRect_DrawOp, 0, rgnOp);
|
||||
fWriter.writeRect(rect);
|
||||
return this->INHERITED::clipRect(rect, rgnOp);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp) {
|
||||
this->writeOp(kClipPath_DrawOp, 0, rgnOp);
|
||||
path.flatten(fWriter);
|
||||
// we just pass on the bounds of the path
|
||||
return this->INHERITED::clipRect(path.getBounds(), rgnOp);
|
||||
}
|
||||
|
||||
bool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) {
|
||||
this->writeOp(kClipRegion_DrawOp, 0, rgnOp);
|
||||
writeRegion(&fWriter, region);
|
||||
return this->INHERITED::clipRegion(region, rgnOp);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGPipeCanvas::clear(SkColor color) {
|
||||
unsigned flags = 0;
|
||||
if (color) {
|
||||
flags |= kClear_HasColor_DrawOpFlag;
|
||||
}
|
||||
this->writeOp(kDrawClear_DrawOp, flags, 0);
|
||||
if (color) {
|
||||
fWriter.write32(color);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPaint(const SkPaint& paint) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawPaint_DrawOp, 0, paintIndex);
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPoints(PointMode mode, size_t count,
|
||||
const SkPoint pts[], const SkPaint& paint) {
|
||||
if (count) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawPoints_DrawOp, mode, paintIndex);
|
||||
fWriter.write32(count);
|
||||
fWriter.write(pts, count * sizeof(SkPoint));
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawRect_DrawOp, 0, paintIndex);
|
||||
fWriter.writeRect(rect);
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawPath_DrawOp, 0, paintIndex);
|
||||
path.flatten(fWriter);
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
|
||||
const SkPaint*) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawBitmapRect(const SkBitmap&, const SkIRect* src,
|
||||
const SkRect& dst, const SkPaint*) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
|
||||
const SkPaint*) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawSprite(const SkBitmap&, int left, int top,
|
||||
const SkPaint*) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
|
||||
SkScalar y, const SkPaint& paint) {
|
||||
if (byteLength) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawText_DrawOp, 0, paintIndex);
|
||||
fWriter.write32(byteLength);
|
||||
fWriter.writePad(text, byteLength);
|
||||
fWriter.writeScalar(x);
|
||||
fWriter.writeScalar(y);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPosText(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint) {
|
||||
if (byteLength) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawPosText_DrawOp, 0, paintIndex);
|
||||
fWriter.write32(byteLength);
|
||||
fWriter.writePad(text, byteLength);
|
||||
int count = paint.textToGlyphs(text, byteLength, NULL);
|
||||
fWriter.write32(count);
|
||||
fWriter.write(pos, count * sizeof(SkPoint));
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPosTextH(const void* text, size_t byteLength,
|
||||
const SkScalar xpos[], SkScalar constY,
|
||||
const SkPaint& paint) {
|
||||
if (byteLength) {
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawPosTextH_DrawOp, 0, paintIndex);
|
||||
fWriter.write32(byteLength);
|
||||
fWriter.writePad(text, byteLength);
|
||||
int count = paint.textToGlyphs(text, byteLength, NULL);
|
||||
fWriter.write32(count);
|
||||
fWriter.write(xpos, count * sizeof(SkScalar));
|
||||
fWriter.writeScalar(constY);
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) {
|
||||
if (byteLength) {
|
||||
unsigned flags = 0;
|
||||
if (matrix) {
|
||||
flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag;
|
||||
}
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
this->writeOp(kDrawTextOnPath_DrawOp, flags, paintIndex);
|
||||
|
||||
fWriter.write32(byteLength);
|
||||
fWriter.writePad(text, byteLength);
|
||||
|
||||
path.flatten(fWriter);
|
||||
if (matrix) {
|
||||
writeMatrix(&fWriter, *matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawPicture(SkPicture& picture) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawShape(SkShape* shape) {
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawVertices(VertexMode mode, int vertexCount,
|
||||
const SkPoint vertices[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode*,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) {
|
||||
if (0 == vertexCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned paintIndex = this->writePaint(paint);
|
||||
unsigned flags = 0;
|
||||
if (texs) {
|
||||
flags |= kDrawVertices_HasTexs_DrawOpFlag;
|
||||
}
|
||||
if (colors) {
|
||||
flags |= kDrawVertices_HasColors_DrawOpFlag;
|
||||
}
|
||||
if (indices && indexCount > 0) {
|
||||
flags |= kDrawVertices_HasIndices_DrawOpFlag;
|
||||
}
|
||||
|
||||
this->writeOp(kDrawVertices_DrawOp, flags, paintIndex);
|
||||
fWriter.write32(mode);
|
||||
fWriter.write32(vertexCount);
|
||||
fWriter.write(vertices, vertexCount * sizeof(SkPoint));
|
||||
if (texs) {
|
||||
fWriter.write(texs, vertexCount * sizeof(SkPoint));
|
||||
}
|
||||
if (colors) {
|
||||
fWriter.write(colors, vertexCount * sizeof(SkColor));
|
||||
}
|
||||
|
||||
// TODO: flatten xfermode
|
||||
|
||||
if (indices && indexCount > 0) {
|
||||
fWriter.write32(indexCount);
|
||||
fWriter.writePad(indices, indexCount * sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::drawData(const void* data, size_t size) {
|
||||
if (size) {
|
||||
unsigned data = 0;
|
||||
if (size < (1 << DRAWOPS_DATA_BITS)) {
|
||||
data = (unsigned)size;
|
||||
}
|
||||
this->writeOp(kDrawData_DrawOp, 0, data);
|
||||
if (0 == data) {
|
||||
fWriter.write32(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T> uint32_t castToU32(T value) {
|
||||
union {
|
||||
T fSrc;
|
||||
uint32_t fDst;
|
||||
} data;
|
||||
data.fSrc = value;
|
||||
return data.fDst;
|
||||
}
|
||||
|
||||
unsigned SkGPipeCanvas::writePaint(const SkPaint& paint) {
|
||||
const SkPaint& base = *fPaints[0];
|
||||
uint32_t storage[32];
|
||||
uint32_t* ptr = storage;
|
||||
uint32_t* last = NULL;
|
||||
|
||||
if (base.getFlags() != paint.getFlags()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
|
||||
}
|
||||
if (base.getColor() != paint.getColor()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kColor_PaintOp);
|
||||
*ptr++ = paint.getColor();
|
||||
}
|
||||
if (base.getStyle() != paint.getStyle()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
|
||||
}
|
||||
if (base.getStrokeJoin() != paint.getStrokeJoin()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
|
||||
}
|
||||
if (base.getStrokeCap() != paint.getStrokeCap()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
|
||||
}
|
||||
if (base.getStrokeWidth() != paint.getStrokeWidth()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kWidth_PaintOp);
|
||||
*ptr++ = castToU32(paint.getStrokeWidth());
|
||||
}
|
||||
if (base.getStrokeMiter() != paint.getStrokeMiter()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kMiter_PaintOp);
|
||||
*ptr++ = castToU32(paint.getStrokeMiter());
|
||||
}
|
||||
if (base.getTextEncoding() != paint.getTextEncoding()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
|
||||
}
|
||||
if (base.getHinting() != paint.getHinting()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
|
||||
}
|
||||
if (base.getTextAlign() != paint.getTextAlign()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
|
||||
}
|
||||
if (base.getTextSize() != paint.getTextSize()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextSize_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextSize());
|
||||
}
|
||||
if (base.getTextScaleX() != paint.getTextScaleX()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextScaleX());
|
||||
}
|
||||
if (base.getTextSkewX() != paint.getTextSkewX()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextSkewX());
|
||||
}
|
||||
*fPaints[0] = paint;
|
||||
|
||||
if (ptr > storage) {
|
||||
this->writeOp(kPaintOp_DrawOp, 0, 0);
|
||||
size_t size = (char*)ptr - (char*)storage;
|
||||
*last |= kLastOp_PaintOpFlag << PAINTOPS_DATA_BITS;
|
||||
fWriter.write(storage, (char*)ptr - (char*)storage);
|
||||
for (size_t i = 0; i < size/4; i++) {
|
||||
SkDebugf("[%d] %08X\n", i, storage[i]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkGPipe.h"
|
||||
|
||||
#define MIN_WRITE_BLOCK_SIZE (4 * 1024)
|
||||
|
||||
SkGPipeWriter::SkGPipeWriter() : fWriter(MIN_WRITE_BLOCK_SIZE) {
|
||||
fCanvas = NULL;
|
||||
}
|
||||
|
||||
SkGPipeWriter::~SkGPipeWriter() {
|
||||
SkSafeUnref(fCanvas);
|
||||
}
|
||||
|
||||
SkCanvas* SkGPipeWriter::startRecording() {
|
||||
if (NULL == fCanvas) {
|
||||
fCanvas = SkNEW_ARGS(SkGPipeCanvas, (&fWriter));
|
||||
}
|
||||
return fCanvas;
|
||||
}
|
||||
|
||||
void SkGPipeWriter::endRecording() {
|
||||
if (fCanvas) {
|
||||
fCanvas->finish();
|
||||
fCanvas->unref();
|
||||
fCanvas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t SkGPipeWriter::flatten(void* buffer) {
|
||||
if (buffer) {
|
||||
fWriter.flatten(buffer);
|
||||
}
|
||||
return fWriter.size();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user