[PDF] Implement clear() method and a couple fixes.
+ If the clip matches the initial clip, don't set the clip. + Don't change the transform for drawPaint. Review URL: http://codereview.appspot.com/4424041 git-svn-id: http://skia.googlecode.com/svn/trunk@1142 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
fb0b0edd86
commit
77bcaa324a
@ -71,6 +71,8 @@ public:
|
||||
|
||||
virtual int height() const { return fHeight; };
|
||||
|
||||
virtual void clear(SkColor color);
|
||||
|
||||
/** Called with the correct matrix and clip before this device is drawn
|
||||
to using those settings. If your subclass overrides this, be sure to
|
||||
call through to the base class as well.
|
||||
@ -175,6 +177,8 @@ private:
|
||||
|
||||
SkDynamicMemoryWStream fContent;
|
||||
|
||||
void init();
|
||||
void cleanUp();
|
||||
void updateGSFromPaint(const SkPaint& newPaint, bool forText);
|
||||
void updateFont(const SkPaint& paint, uint16_t glyphID);
|
||||
int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
|
||||
@ -182,6 +186,8 @@ private:
|
||||
void pushGS();
|
||||
void popGS();
|
||||
void setTextTransform(SkScalar x, SkScalar y, SkScalar textSkewX);
|
||||
void internalDrawPaint(const SkPaint& paint);
|
||||
void internalDrawRect(const SkRect& r, const SkPaint& paint);
|
||||
void internalDrawBitmap(const SkMatrix& matrix, const SkBitmap& bitmap,
|
||||
const SkIRect* srcRect, const SkPaint& paint);
|
||||
|
||||
|
@ -21,13 +21,13 @@
|
||||
#include "SkGlyphCache.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkPDFImage.h"
|
||||
#include "SkPDFGraphicState.h"
|
||||
#include "SkPDFFont.h"
|
||||
#include "SkPDFFormXObject.h"
|
||||
#include "SkPDFTypes.h"
|
||||
#include "SkPDFGraphicState.h"
|
||||
#include "SkPDFImage.h"
|
||||
#include "SkPDFShader.h"
|
||||
#include "SkPDFStream.h"
|
||||
#include "SkPDFTypes.h"
|
||||
#include "SkPDFUtils.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkString.h"
|
||||
@ -135,6 +135,21 @@ SkPDFDevice::SkPDFDevice(int width, int height,
|
||||
fWidth(width),
|
||||
fHeight(height),
|
||||
fGraphicStackIndex(0) {
|
||||
// Skia generally uses the top left as the origin but PDF natively has the
|
||||
// origin at the bottom left. This matrix corrects for that. When layering,
|
||||
// we specify an inverse correction to cancel this out.
|
||||
fInitialTransform.setTranslate(0, height);
|
||||
fInitialTransform.preScale(1, -1);
|
||||
fInitialTransform.preConcat(initialTransform);
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
SkPDFDevice::~SkPDFDevice() {
|
||||
this->cleanUp();
|
||||
}
|
||||
|
||||
void SkPDFDevice::init() {
|
||||
fGraphicStack[0].fColor = SK_ColorBLACK;
|
||||
fGraphicStack[0].fTextSize = SK_ScalarNaN; // This has no default value.
|
||||
fGraphicStack[0].fTextScaleX = SK_Scalar1;
|
||||
@ -142,27 +157,41 @@ SkPDFDevice::SkPDFDevice(int width, int height,
|
||||
fGraphicStack[0].fFont = NULL;
|
||||
fGraphicStack[0].fShader = NULL;
|
||||
fGraphicStack[0].fGraphicState = NULL;
|
||||
fGraphicStack[0].fClip.setRect(0,0, width, height);
|
||||
fGraphicStack[0].fClip.setRect(0,0, fWidth, fHeight);
|
||||
fGraphicStack[0].fTransform.reset();
|
||||
fGraphicStackIndex = 0;
|
||||
fResourceDict = NULL;
|
||||
fContent.reset();
|
||||
|
||||
// Skia generally uses the top left as the origin but PDF natively has the
|
||||
// origin at the bottom left. This matrix corrects for that. When layering,
|
||||
// we specify an inverse correction to cancel this out.
|
||||
fInitialTransform.setTranslate(0, height);
|
||||
fInitialTransform.preScale(1, -1);
|
||||
fInitialTransform.preConcat(initialTransform);
|
||||
if (fInitialTransform.getType() != SkMatrix::kIdentity_Mask) {
|
||||
SkPDFUtils::AppendTransform(fInitialTransform, &fContent);
|
||||
}
|
||||
}
|
||||
|
||||
SkPDFDevice::~SkPDFDevice() {
|
||||
void SkPDFDevice::cleanUp() {
|
||||
fGraphicStateResources.unrefAll();
|
||||
fXObjectResources.unrefAll();
|
||||
fFontResources.unrefAll();
|
||||
fShaderResources.unrefAll();
|
||||
}
|
||||
|
||||
void SkPDFDevice::clear(SkColor color) {
|
||||
SkMatrix curTransform = fGraphicStack[fGraphicStackIndex].fTransform;
|
||||
SkRegion curClip = fGraphicStack[fGraphicStackIndex].fClip;
|
||||
|
||||
this->cleanUp();
|
||||
this->init();
|
||||
|
||||
SkPaint paint;
|
||||
paint.setColor(color);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
updateGSFromPaint(paint, false);
|
||||
internalDrawPaint(paint);
|
||||
|
||||
SkClipStack clipStack;
|
||||
setMatrixClip(curTransform, curClip, clipStack);
|
||||
}
|
||||
|
||||
void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
|
||||
const SkRegion& region,
|
||||
const SkClipStack&) {
|
||||
@ -180,12 +209,14 @@ void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
|
||||
if (region != fGraphicStack[fGraphicStackIndex].fClip) {
|
||||
while (fGraphicStackIndex > 0)
|
||||
popGS();
|
||||
|
||||
if (region != fGraphicStack[fGraphicStackIndex].fClip) {
|
||||
pushGS();
|
||||
|
||||
SkPath clipPath;
|
||||
if (region.getBoundaryPath(&clipPath)) {
|
||||
SkPDFUtils::EmitPath(clipPath, &fContent);
|
||||
SkAssertResult(region.getBoundaryPath(&clipPath));
|
||||
|
||||
SkPDFUtils::EmitPath(clipPath, &fContent);
|
||||
SkPath::FillType clipFill = clipPath.getFillType();
|
||||
NOT_IMPLEMENTED(clipFill == SkPath::kInverseEvenOdd_FillType,
|
||||
false);
|
||||
@ -195,10 +226,10 @@ void SkPDFDevice::setMatrixClip(const SkMatrix& matrix,
|
||||
fContent.writeText("W* n ");
|
||||
else
|
||||
fContent.writeText("W n ");
|
||||
}
|
||||
|
||||
fGraphicStack[fGraphicStackIndex].fClip = region;
|
||||
}
|
||||
}
|
||||
setTransform(matrix);
|
||||
}
|
||||
|
||||
@ -207,18 +238,24 @@ void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkMatrix identityTransform;
|
||||
identityTransform.reset();
|
||||
SkMatrix curTransform = setTransform(identityTransform);
|
||||
|
||||
SkPaint newPaint = paint;
|
||||
newPaint.setStyle(SkPaint::kFill_Style);
|
||||
updateGSFromPaint(newPaint, false);
|
||||
|
||||
SkRect all = SkRect::MakeWH(SkIntToScalar(this->width()),
|
||||
internalDrawPaint(newPaint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawPaint(const SkPaint& paint) {
|
||||
SkRect bbox = SkRect::MakeWH(SkIntToScalar(this->width()),
|
||||
SkIntToScalar(this->height()));
|
||||
drawRect(d, all, newPaint);
|
||||
setTransform(curTransform);
|
||||
SkMatrix totalTransform = fInitialTransform;
|
||||
totalTransform.preConcat(fGraphicStack[fGraphicStackIndex].fTransform);
|
||||
SkMatrix inverse;
|
||||
inverse.reset();
|
||||
totalTransform.invert(&inverse);
|
||||
inverse.mapRect(&bbox);
|
||||
|
||||
internalDrawRect(bbox, paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
|
||||
@ -293,6 +330,10 @@ void SkPDFDevice::drawRect(const SkDraw& d, const SkRect& r,
|
||||
}
|
||||
updateGSFromPaint(paint, false);
|
||||
|
||||
internalDrawRect(r, paint);
|
||||
}
|
||||
|
||||
void SkPDFDevice::internalDrawRect(const SkRect& r, const SkPaint& paint) {
|
||||
// Skia has 0,0 at top left, pdf at bottom left. Do the right thing.
|
||||
SkScalar bottom = r.fBottom < r.fTop ? r.fBottom : r.fTop;
|
||||
SkPDFUtils::AppendRectangle(r.fLeft, bottom, r.width(), r.height(),
|
||||
|
Loading…
Reference in New Issue
Block a user