Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Unified Diff: src/pdf/SkPDFGraphicState.cpp

Issue 1046293002: SkPDF: SkPDFGraphicState Lookup hashtabled (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2015-04-01 (Wednesday) 16:16:21 EDT Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pdf/SkPDFGraphicState.h ('k') | src/pdf/SkPDFShader.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFGraphicState.cpp
diff --git a/src/pdf/SkPDFGraphicState.cpp b/src/pdf/SkPDFGraphicState.cpp
index 6922b08e9efcb3e3b12a37da0177f45aec76628d..04eda5812ad16f7e9981d8266e78a24b519d8674 100644
--- a/src/pdf/SkPDFGraphicState.cpp
+++ b/src/pdf/SkPDFGraphicState.cpp
@@ -70,66 +70,58 @@ static const char* as_blend_mode(SkXfermode::Mode mode) {
return NULL;
}
-static bool equivalent(const SkPaint& a, const SkPaint& b) {
- // We're only interested in some fields of the SkPaint, so we have
- // a custom equality function.
- if (SkColorGetA(a.getColor()) != SkColorGetA(b.getColor()) ||
- a.getStrokeCap() != b.getStrokeCap() ||
- a.getStrokeJoin() != b.getStrokeJoin() ||
- a.getStrokeWidth() != b.getStrokeWidth() ||
- a.getStrokeMiter() != b.getStrokeMiter()) {
- return false;
+// If a SkXfermode is unsupported in PDF, this function returns
+// SrcOver, otherwise, it returns that Xfermode as a Mode.
+static SkXfermode::Mode mode_for_pdf(const SkXfermode* xfermode) {
+ SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
+ if (xfermode) {
+ xfermode->asMode(&mode);
}
-
- SkXfermode::Mode aXfermodeName = SkXfermode::kSrcOver_Mode;
- SkXfermode* aXfermode = a.getXfermode();
- if (aXfermode) {
- aXfermode->asMode(&aXfermodeName);
- }
- if (aXfermodeName < 0 || aXfermodeName > SkXfermode::kLastMode ||
- as_blend_mode(aXfermodeName) == NULL) {
- aXfermodeName = SkXfermode::kSrcOver_Mode;
- }
- const char* aXfermodeString = as_blend_mode(aXfermodeName);
- SkASSERT(aXfermodeString != NULL);
-
- SkXfermode::Mode bXfermodeName = SkXfermode::kSrcOver_Mode;
- SkXfermode* bXfermode = b.getXfermode();
- if (bXfermode) {
- bXfermode->asMode(&bXfermodeName);
- }
- if (bXfermodeName < 0 || bXfermodeName > SkXfermode::kLastMode ||
- as_blend_mode(bXfermodeName) == NULL) {
- bXfermodeName = SkXfermode::kSrcOver_Mode;
+ switch (mode) {
+ case SkXfermode::kSrcOver_Mode:
+ case SkXfermode::kMultiply_Mode:
+ case SkXfermode::kScreen_Mode:
+ case SkXfermode::kOverlay_Mode:
+ case SkXfermode::kDarken_Mode:
+ case SkXfermode::kLighten_Mode:
+ case SkXfermode::kColorDodge_Mode:
+ case SkXfermode::kColorBurn_Mode:
+ case SkXfermode::kHardLight_Mode:
+ case SkXfermode::kSoftLight_Mode:
+ case SkXfermode::kDifference_Mode:
+ case SkXfermode::kExclusion_Mode:
+ case SkXfermode::kHue_Mode:
+ case SkXfermode::kSaturation_Mode:
+ case SkXfermode::kColor_Mode:
+ case SkXfermode::kLuminosity_Mode:
+ // Mode is suppported and handled by pdf graphics state.
+ return mode;
+ default:
+ return SkXfermode::kSrcOver_Mode; // Default mode.
}
- const char* bXfermodeString = as_blend_mode(bXfermodeName);
- SkASSERT(bXfermodeString != NULL);
-
- return strcmp(aXfermodeString, bXfermodeString) == 0;
-}
-
-bool SkPDFGraphicState::equals(const SkPaint& paint) const {
- return equivalent(paint, fPaint);
}
-SkPDFGraphicState::~SkPDFGraphicState() {}
-
-void SkPDFGraphicState::emitObject(SkWStream* stream,
- const SkPDFObjNumMap& objNumMap,
- const SkPDFSubstituteMap& substitutes) {
- populateDict();
- SkPDFDict::emitObject(stream, objNumMap, substitutes);
-}
+SkPDFGraphicState::SkPDFGraphicState(const SkPaint& p)
+ : fStrokeWidth(p.getStrokeWidth())
+ , fStrokeMiter(p.getStrokeMiter())
+ , fAlpha(p.getAlpha())
+ , fStrokeCap(SkToU8(p.getStrokeCap()))
+ , fStrokeJoin(SkToU8(p.getStrokeJoin()))
+ , fMode(SkToU8(mode_for_pdf(p.getXfermode()))) {}
// static
SkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(
SkPDFCanon* canon, const SkPaint& paint) {
SkASSERT(canon);
- SkPDFGraphicState* pdfGraphicState = canon->findGraphicState(paint);
- if (pdfGraphicState) {
- return SkRef(pdfGraphicState);
+ SkPDFGraphicState key(paint);
+ if (const SkPDFGraphicState* canonGS = canon->findGraphicState(key)) {
+ // The returned SkPDFGraphicState must be made non-const,
+ // since the emitObject() interface is non-const. But We
+ // promise that there is no way to mutate this object from
+ // here on out.
+ return SkRef(const_cast<SkPDFGraphicState*>(canonGS));
}
- pdfGraphicState = new SkPDFGraphicState(paint);
+ SkPDFGraphicState* pdfGraphicState = new SkPDFGraphicState(paint);
canon->addGraphicState(pdfGraphicState);
return pdfGraphicState;
}
@@ -159,12 +151,15 @@ SkPDFObject* create_invert_function() {
template <typename T> void unref(T* ptr) { ptr->unref(); }
} // namespace
-SK_DECLARE_STATIC_LAZY_PTR(SkPDFObject, invertFunction,
- create_invert_function, unref<SkPDFObject>);
+SK_DECLARE_STATIC_LAZY_PTR(SkPDFObject,
+ invertFunction,
+ create_invert_function,
+ unref<SkPDFObject>);
// static
-SkPDFGraphicState* SkPDFGraphicState::GetSMaskGraphicState(
- SkPDFFormXObject* sMask, bool invert, SkPDFSMaskMode sMaskMode) {
+SkPDFDict* SkPDFGraphicState::GetSMaskGraphicState(SkPDFFormXObject* sMask,
+ bool invert,
+ SkPDFSMaskMode sMaskMode) {
// The practical chances of using the same mask more than once are unlikely
// enough that it's not worth canonicalizing.
SkAutoTUnref<SkPDFDict> sMaskDict(new SkPDFDict("Mask"));
@@ -174,81 +169,64 @@ SkPDFGraphicState* SkPDFGraphicState::GetSMaskGraphicState(
sMaskDict->insertName("S", "Luminosity");
}
sMaskDict->insert("G", new SkPDFObjRef(sMask))->unref();
-
- SkPDFGraphicState* result = new SkPDFGraphicState;
- result->fPopulated = true;
- result->insertName("Type", "ExtGState");
- result->insert("SMask", sMaskDict.get());
-
if (invert) {
sMaskDict->insert("TR", new SkPDFObjRef(invertFunction.get()))->unref();
}
+ SkPDFDict* result = new SkPDFDict("ExtGState");
+ result->insert("SMask", sMaskDict.get());
return result;
}
-SkPDFGraphicState* SkPDFGraphicState::CreateNoSMaskGraphicState() {
- SkPDFGraphicState* noSMaskGS = SkNEW(SkPDFGraphicState);
- noSMaskGS->fPopulated = true;
- noSMaskGS->insertName("Type", "ExtGState");
+namespace {
+SkPDFDict* create_no_smask_graphic_state() {
+ SkPDFDict* noSMaskGS = new SkPDFDict("ExtGState");
noSMaskGS->insertName("SMask", "None");
return noSMaskGS;
}
-
-SK_DECLARE_STATIC_LAZY_PTR(
- SkPDFGraphicState, noSMaskGraphicState,
- SkPDFGraphicState::CreateNoSMaskGraphicState, unref<SkPDFGraphicState>);
+} // namespace
+SK_DECLARE_STATIC_LAZY_PTR(SkPDFDict,
+ noSMaskGraphicState,
+ create_no_smask_graphic_state,
+ unref<SkPDFDict>);
// static
-SkPDFGraphicState* SkPDFGraphicState::GetNoSMaskGraphicState() {
+SkPDFDict* SkPDFGraphicState::GetNoSMaskGraphicState() {
return SkRef(noSMaskGraphicState.get());
}
-SkPDFGraphicState::SkPDFGraphicState()
- : fPopulated(false) {}
-
-SkPDFGraphicState::SkPDFGraphicState(const SkPaint& paint)
- : fPaint(paint), fPopulated(false) {}
-
-// populateDict and operator== have to stay in sync with each other.
-void SkPDFGraphicState::populateDict() {
- if (!fPopulated) {
- fPopulated = true;
- insertName("Type", "ExtGState");
-
- SkAutoTUnref<SkPDFScalar> alpha(
- new SkPDFScalar(SkScalarDiv(fPaint.getAlpha(), 0xFF)));
- insert("CA", alpha.get());
- insert("ca", alpha.get());
-
- SK_COMPILE_ASSERT(SkPaint::kButt_Cap == 0, paint_cap_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kRound_Cap == 1, paint_cap_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kSquare_Cap == 2, paint_cap_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kCapCount == 3, paint_cap_mismatch);
- SkASSERT(fPaint.getStrokeCap() >= 0 && fPaint.getStrokeCap() <= 2);
- insertInt("LC", fPaint.getStrokeCap());
-
- SK_COMPILE_ASSERT(SkPaint::kMiter_Join == 0, paint_join_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kRound_Join == 1, paint_join_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kBevel_Join == 2, paint_join_mismatch);
- SK_COMPILE_ASSERT(SkPaint::kJoinCount == 3, paint_join_mismatch);
- SkASSERT(fPaint.getStrokeJoin() >= 0 && fPaint.getStrokeJoin() <= 2);
- insertInt("LJ", fPaint.getStrokeJoin());
-
- insertScalar("LW", fPaint.getStrokeWidth());
- insertScalar("ML", fPaint.getStrokeMiter());
- insert("SA", new SkPDFBool(true))->unref(); // Auto stroke adjustment.
-
- SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode;
- // If asMode fails, default to kSrcOver_Mode.
- if (fPaint.getXfermode())
- fPaint.getXfermode()->asMode(&xfermode);
- // If we don't support the mode, just use kSrcOver_Mode.
- if (xfermode < 0 || xfermode > SkXfermode::kLastMode ||
- as_blend_mode(xfermode) == NULL) {
- xfermode = SkXfermode::kSrcOver_Mode;
- NOT_IMPLEMENTED("unsupported xfermode", false);
- }
- insertName("BM", as_blend_mode(xfermode));
- }
+void SkPDFGraphicState::emitObject(SkWStream* stream,
+ const SkPDFObjNumMap& objNumMap,
+ const SkPDFSubstituteMap& substitutes) {
+ SkAutoTUnref<SkPDFDict> dict(SkNEW_ARGS(SkPDFDict, ("ExtGState")));
+ dict->insertName("Type", "ExtGState");
+
+ SkAutoTUnref<SkPDFScalar> alpha(new SkPDFScalar(SkScalarDiv(fAlpha, 0xFF)));
+ dict->insert("CA", alpha.get());
+ dict->insert("ca", alpha.get());
+
+ SkPaint::Cap strokeCap = (SkPaint::Cap)fStrokeCap;
+ SkPaint::Join strokeJoin = (SkPaint::Join)fStrokeJoin;
+ SkXfermode::Mode xferMode = (SkXfermode::Mode)fMode;
+
+ SK_COMPILE_ASSERT(SkPaint::kButt_Cap == 0, paint_cap_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kRound_Cap == 1, paint_cap_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kSquare_Cap == 2, paint_cap_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kCapCount == 3, paint_cap_mismatch);
+ SkASSERT(strokeCap >= 0 && strokeCap <= 2);
+ dict->insertInt("LC", strokeCap);
+
+ SK_COMPILE_ASSERT(SkPaint::kMiter_Join == 0, paint_join_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kRound_Join == 1, paint_join_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kBevel_Join == 2, paint_join_mismatch);
+ SK_COMPILE_ASSERT(SkPaint::kJoinCount == 3, paint_join_mismatch);
+ SkASSERT(strokeJoin >= 0 && strokeJoin <= 2);
+ dict->insertInt("LJ", strokeJoin);
+
+ dict->insertScalar("LW", fStrokeWidth);
+ dict->insertScalar("ML", fStrokeMiter);
+ // SA = Auto stroke adjustment.
+ dict->insert("SA", new SkPDFBool(true))->unref();
+ dict->insertName("BM", as_blend_mode(xferMode));
+ dict->emitObject(stream, objNumMap, substitutes);
}
« no previous file with comments | « src/pdf/SkPDFGraphicState.h ('k') | src/pdf/SkPDFShader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698