зеркало из https://github.com/mozilla/moz-skia.git
add typeface flattening
git-svn-id: http://skia.googlecode.com/svn/trunk@1245 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
8a6400ef3e
Коммит
f5842f773b
|
@ -58,6 +58,7 @@ enum DrawOps {
|
|||
|
||||
// these edit paints
|
||||
kPaintOp_DrawOp,
|
||||
kDefineTypeface_DrawOp,
|
||||
|
||||
// these are signals to playback, not drawing verbs
|
||||
kDone_DrawOp,
|
||||
|
@ -144,7 +145,8 @@ enum PaintOps {
|
|||
kTextSize_PaintOp, // arg scalar - text
|
||||
kTextScaleX_PaintOp,// arg scalar - text
|
||||
kTextSkewX_PaintOp, // arg scalar - text
|
||||
|
||||
kTypeface_PaintOp, // arg inline (index) - text
|
||||
|
||||
kPathEffect_PaintOp, // arg inline
|
||||
kShader_PaintOp,
|
||||
kXfermode_PaintOp,
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "SkGPipe.h"
|
||||
#include "SkGPipePriv.h"
|
||||
#include "SkReader32.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkGPipeState {
|
||||
public:
|
||||
|
@ -32,9 +34,22 @@ public:
|
|||
// 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);
|
||||
|
||||
|
||||
SkTypeface* findTypeface(int id) const {
|
||||
SkASSERT(id <= fTypefaces.count());
|
||||
return id ? fTypefaces[id - 1] : NULL;
|
||||
}
|
||||
void addTypeface(SkReader32* reader) {
|
||||
size_t size = reader->readU32();
|
||||
const void* data = reader->skip(SkAlign4(size));
|
||||
SkMemoryStream stream(data, size, false);
|
||||
// fTypefaces takes over ownership of the typeface reference
|
||||
*fTypefaces.append() = SkTypeface::Deserialize(&stream);
|
||||
}
|
||||
|
||||
private:
|
||||
SkTDArray<SkPaint*> fPaints;
|
||||
SkTDArray<SkTypeface*> fTypefaces;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -389,6 +404,7 @@ static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
|
|||
case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
|
||||
case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
|
||||
case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
|
||||
case kTypeface_PaintOp: p->setTypeface(state->findTypeface(data)); break;
|
||||
|
||||
// flag to reference a cached index instead of inflating?
|
||||
case kPathEffect_PaintOp: inflate_patheffect(reader, p); break;
|
||||
|
@ -403,6 +419,11 @@ static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
|
|||
} while (!done);
|
||||
}
|
||||
|
||||
static void defTypeface_rp(SkCanvas*, SkReader32* reader, uint32_t,
|
||||
SkGPipeState* state) {
|
||||
state->addTypeface(reader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
|
||||
|
@ -446,6 +467,7 @@ static const ReadProc gReadTable[] = {
|
|||
skew_rp,
|
||||
translate_rp,
|
||||
paintOp_rp,
|
||||
defTypeface_rp,
|
||||
done_rp
|
||||
};
|
||||
|
||||
|
@ -457,6 +479,7 @@ SkGPipeState::SkGPipeState() {
|
|||
}
|
||||
|
||||
SkGPipeState::~SkGPipeState() {
|
||||
fTypefaces.unrefAll();
|
||||
fPaints.deleteAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "SkPaint.h"
|
||||
#include "SkGPipe.h"
|
||||
#include "SkGPipePriv.h"
|
||||
#include "SkStream.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "SkWriter32.h"
|
||||
|
||||
static size_t estimateFlattenSize(const SkPath& path) {
|
||||
|
@ -49,6 +51,18 @@ static void writeMatrix(SkWriter32* writer, const SkMatrix& matrix) {
|
|||
matrix.flatten(writer->reserve(size));
|
||||
}
|
||||
|
||||
static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) {
|
||||
SkASSERT(typeface);
|
||||
SkDynamicMemoryWStream stream;
|
||||
typeface->serialize(&stream);
|
||||
size_t size = stream.getOffset();
|
||||
if (writer) {
|
||||
writer->write32(size);
|
||||
writer->write(stream.getStream(), size);
|
||||
}
|
||||
return 4 + size;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkGPipeCanvas : public SkCanvas {
|
||||
|
@ -115,6 +129,10 @@ private:
|
|||
size_t fBytesNotified;
|
||||
bool fDone;
|
||||
|
||||
SkRefCntSet fTypefaceSet;
|
||||
|
||||
uint32_t getTypefaceID(SkTypeface*);
|
||||
|
||||
inline void writeOp(DrawOps op, unsigned flags, unsigned data) {
|
||||
fWriter.write32(DrawOp_packOpFlagData(op, flags, data));
|
||||
}
|
||||
|
@ -186,6 +204,22 @@ bool SkGPipeCanvas::needOpBytes(size_t needed) {
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) {
|
||||
uint32_t id = 0; // 0 means default/null typeface
|
||||
if (face) {
|
||||
id = fTypefaceSet.find(face);
|
||||
if (0 == id) {
|
||||
id = fTypefaceSet.add(face);
|
||||
size_t size = writeTypeface(NULL, face);
|
||||
if (this->needOpBytes(size)) {
|
||||
this->writeOp(kDefineTypeface_DrawOp);
|
||||
writeTypeface(&fWriter, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define NOTIFY_SETUP(canvas) \
|
||||
|
@ -567,7 +601,7 @@ template <typename T> uint32_t castToU32(T value) {
|
|||
}
|
||||
|
||||
unsigned SkGPipeCanvas::writePaint(const SkPaint& paint) {
|
||||
const SkPaint& base = *fPaints[0];
|
||||
SkPaint& base = *fPaints[0];
|
||||
uint32_t storage[32];
|
||||
uint32_t* ptr = storage;
|
||||
uint32_t* last = NULL;
|
||||
|
@ -575,66 +609,84 @@ unsigned SkGPipeCanvas::writePaint(const SkPaint& paint) {
|
|||
if (base.getFlags() != paint.getFlags()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags());
|
||||
base.setFlags(paint.getFlags());
|
||||
}
|
||||
if (base.getColor() != paint.getColor()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kColor_PaintOp);
|
||||
*ptr++ = paint.getColor();
|
||||
base.setColor(paint.getColor());
|
||||
}
|
||||
if (base.getStyle() != paint.getStyle()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle());
|
||||
base.setStyle(paint.getStyle());
|
||||
}
|
||||
if (base.getStrokeJoin() != paint.getStrokeJoin()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin());
|
||||
base.setStrokeJoin(paint.getStrokeJoin());
|
||||
}
|
||||
if (base.getStrokeCap() != paint.getStrokeCap()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap());
|
||||
base.setStrokeCap(paint.getStrokeCap());
|
||||
}
|
||||
if (base.getStrokeWidth() != paint.getStrokeWidth()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kWidth_PaintOp);
|
||||
*ptr++ = castToU32(paint.getStrokeWidth());
|
||||
base.setStrokeWidth(paint.getStrokeWidth());
|
||||
}
|
||||
if (base.getStrokeMiter() != paint.getStrokeMiter()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kMiter_PaintOp);
|
||||
*ptr++ = castToU32(paint.getStrokeMiter());
|
||||
base.setStrokeMiter(paint.getStrokeMiter());
|
||||
}
|
||||
if (base.getTextEncoding() != paint.getTextEncoding()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding());
|
||||
base.setTextEncoding(paint.getTextEncoding());
|
||||
}
|
||||
if (base.getHinting() != paint.getHinting()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting());
|
||||
base.setHinting(paint.getHinting());
|
||||
}
|
||||
if (base.getTextAlign() != paint.getTextAlign()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign());
|
||||
base.setTextAlign(paint.getTextAlign());
|
||||
}
|
||||
if (base.getTextSize() != paint.getTextSize()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextSize_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextSize());
|
||||
base.setTextSize(paint.getTextSize());
|
||||
}
|
||||
if (base.getTextScaleX() != paint.getTextScaleX()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextScaleX_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextScaleX());
|
||||
base.setTextScaleX(paint.getTextScaleX());
|
||||
}
|
||||
if (base.getTextSkewX() != paint.getTextSkewX()) {
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOp(kTextSkewX_PaintOp);
|
||||
*ptr++ = castToU32(paint.getTextSkewX());
|
||||
base.setTextSkewX(paint.getTextSkewX());
|
||||
}
|
||||
|
||||
if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) {
|
||||
uint32_t id = this->getTypefaceID(paint.getTypeface());
|
||||
last = ptr;
|
||||
*ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id);
|
||||
base.setTypeface(paint.getTypeface());
|
||||
}
|
||||
|
||||
size_t size = (char*)ptr - (char*)storage;
|
||||
if (size && this->needOpBytes(size)) {
|
||||
*fPaints[0] = paint;
|
||||
|
||||
this->writeOp(kPaintOp_DrawOp, 0, 0);
|
||||
size_t size = (char*)ptr - (char*)storage;
|
||||
*last |= kLastOp_PaintOpFlag << PAINTOPS_DATA_BITS;
|
||||
|
|
Загрузка…
Ссылка в новой задаче