19b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 39b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 69b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org */ 79b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 86112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org#include "SkPDFFormXObject.h" 99b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkPDFGraphicState.h" 10f71b2103d56dde247605b718a0c89123ad8f0094vandebo@chromium.org#include "SkPDFUtils.h" 119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org#include "SkStream.h" 1248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org#include "SkTypes.h" 1348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 146112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.orgstatic const char* blend_mode_from_xfermode(SkXfermode::Mode mode) { 1548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org switch (mode) { 1648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kSrcOver_Mode: return "Normal"; 17b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org case SkXfermode::kMultiply_Mode: return "Multiply"; 1848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kScreen_Mode: return "Screen"; 1948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kOverlay_Mode: return "Overlay"; 2048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDarken_Mode: return "Darken"; 2148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kLighten_Mode: return "Lighten"; 2248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kColorDodge_Mode: return "ColorDodge"; 2348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kColorBurn_Mode: return "ColorBurn"; 2448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kHardLight_Mode: return "HardLight"; 2548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kSoftLight_Mode: return "SoftLight"; 2648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDifference_Mode: return "Difference"; 2748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kExclusion_Mode: return "Exclusion"; 28b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org case SkXfermode::kHue_Mode: return "Hue"; 29b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org case SkXfermode::kSaturation_Mode: return "Saturation"; 30b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org case SkXfermode::kColor_Mode: return "Color"; 31b24f89353ed7a45b27ab0ffc69c222b81bbf87c3commit-bot@chromium.org case SkXfermode::kLuminosity_Mode: return "Luminosity"; 3248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 3325adce81ce24702174ede33445c414a8d21d8a23vandebo@chromium.org // These are handled in SkPDFDevice::setUpContentEntry. 3448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kClear_Mode: 3548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kSrc_Mode: 3648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDst_Mode: 3748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDstOver_Mode: 3848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kSrcIn_Mode: 3948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDstIn_Mode: 4048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kSrcOut_Mode: 4148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kDstOut_Mode: 423b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org case SkXfermode::kSrcATop_Mode: 433b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org case SkXfermode::kDstATop_Mode: 443b416216d1e90cb8b1bba41bb95806fe2d40da88vandebo@chromium.org case SkXfermode::kModulate_Mode: 456112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org return "Normal"; 466112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 47769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org // TODO(vandebo): Figure out if we can support more of these modes. 4848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kXor_Mode: 4948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org case SkXfermode::kPlus_Mode: 5048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return NULL; 5148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 5248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return NULL; 5348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org} 5448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 559b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgSkPDFGraphicState::~SkPDFGraphicState() { 56f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 576112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org if (!fSMask) { 58f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com int index = Find(fPaint); 596112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org SkASSERT(index >= 0); 60918352f86e939fe042495aad4f5ff33c4ecec9edvandebo@chromium.org SkASSERT(CanonicalPaints()[index].fGraphicState == this); 61f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com CanonicalPaints().removeShuffle(index); 626112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org } 636112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org fResources.unrefAll(); 646112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org} 656112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 666addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.comvoid SkPDFGraphicState::getResources( 676addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.com const SkTSet<SkPDFObject*>& knownResourceObjects, 686addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.com SkTSet<SkPDFObject*>* newResourceObjects) { 696addb1930013ebb2f984045141650fd7afcfa90fedisonn@google.com GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); 709b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 719b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 729b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgvoid SkPDFGraphicState::emitObject(SkWStream* stream, SkPDFCatalog* catalog, 739b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org bool indirect) { 749b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org populateDict(); 759b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkPDFDict::emitObject(stream, catalog, indirect); 769b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 779b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 7848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org// static 799b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgsize_t SkPDFGraphicState::getOutputSize(SkPDFCatalog* catalog, bool indirect) { 809b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org populateDict(); 819b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org return SkPDFDict::getOutputSize(catalog, indirect); 829b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 839b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 849b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// static 85b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtkleinSkTDArray<SkPDFGraphicState::GSCanonicalEntry>& SkPDFGraphicState::CanonicalPaints() { 86b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein CanonicalPaintsMutex().assertHeld(); 879b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org static SkTDArray<SkPDFGraphicState::GSCanonicalEntry> gCanonicalPaints; 889b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org return gCanonicalPaints; 899b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 909b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 919b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// static 921771cbf43d9a1334e3d870c635b4215bb888dd98digit@google.comSkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() { 931771cbf43d9a1334e3d870c635b4215bb888dd98digit@google.com SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex); 949b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org return gCanonicalPaintsMutex; 959b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 969b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 979b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// static 98b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtkleinSkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint(const SkPaint& paint) { 99f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 100f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com int index = Find(paint); 1019b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org if (index >= 0) { 102f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com CanonicalPaints()[index].fGraphicState->ref(); 103f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com return CanonicalPaints()[index].fGraphicState; 1049b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org } 1059b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org GSCanonicalEntry newEntry(new SkPDFGraphicState(paint)); 106f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com CanonicalPaints().push(newEntry); 1079b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org return newEntry.fGraphicState; 1089b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 1099b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 1109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// static 11119e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.orgSkPDFObject* SkPDFGraphicState::GetInvertFunction() { 11219e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org // This assumes that canonicalPaintsMutex is held. 113b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein CanonicalPaintsMutex().assertHeld(); 11419e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org static SkPDFStream* invertFunction = NULL; 11519e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org if (!invertFunction) { 11619e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org // Acrobat crashes if we use a type 0 function, kpdf crashes if we use 11719e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org // a type 2 function, so we use a type 4 function. 118d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org SkAutoTUnref<SkPDFArray> domainAndRange(new SkPDFArray); 11919e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org domainAndRange->reserve(2); 120c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com domainAndRange->appendInt(0); 121c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com domainAndRange->appendInt(1); 12219e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org 12319e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org static const char psInvert[] = "{1 exch sub}"; 124d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org SkAutoTUnref<SkMemoryStream> psInvertStream( 125d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org new SkMemoryStream(&psInvert, strlen(psInvert), true)); 12619e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org 12719e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org invertFunction = new SkPDFStream(psInvertStream.get()); 128c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com invertFunction->insertInt("FunctionType", 4); 12919e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org invertFunction->insert("Domain", domainAndRange.get()); 13019e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org invertFunction->insert("Range", domainAndRange.get()); 13119e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org } 13219e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org return invertFunction; 13319e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org} 13419e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org 13519e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org// static 136f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.comSkPDFGraphicState* SkPDFGraphicState::GetSMaskGraphicState( 13793a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org SkPDFFormXObject* sMask, bool invert, SkPDFSMaskMode sMaskMode) { 1386112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org // The practical chances of using the same mask more than once are unlikely 1396112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org // enough that it's not worth canonicalizing. 140f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 1416112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 142d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org SkAutoTUnref<SkPDFDict> sMaskDict(new SkPDFDict("Mask")); 14393a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org if (sMaskMode == kAlpha_SMaskMode) { 14493a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org sMaskDict->insertName("S", "Alpha"); 14593a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org } else if (sMaskMode == kLuminosity_SMaskMode) { 14693a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org sMaskDict->insertName("S", "Luminosity"); 14793a2e213441c75033b04365c7d68c8d3887288accommit-bot@chromium.org } 1486112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org sMaskDict->insert("G", new SkPDFObjRef(sMask))->unref(); 1496112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1506112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org SkPDFGraphicState* result = new SkPDFGraphicState; 1516112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org result->fPopulated = true; 1526112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org result->fSMask = true; 153c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com result->insertName("Type", "ExtGState"); 1546112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org result->insert("SMask", sMaskDict.get()); 1556112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org result->fResources.push(sMask); 1566112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org sMask->ref(); 1576112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1586112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org if (invert) { 15919e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org SkPDFObject* invertFunction = GetInvertFunction(); 16019e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org result->fResources.push(invertFunction); 16119e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org invertFunction->ref(); 16219e3c1ed1b20ce93cc092d25c3637b62f90c5bc5vandebo@chromium.org sMaskDict->insert("TR", new SkPDFObjRef(invertFunction))->unref(); 1636112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org } 1646112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1656112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org return result; 1666112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org} 1676112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1686112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org// static 169f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.comSkPDFGraphicState* SkPDFGraphicState::GetNoSMaskGraphicState() { 170f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 1716112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org static SkPDFGraphicState* noSMaskGS = NULL; 1726112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org if (!noSMaskGS) { 1736112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org noSMaskGS = new SkPDFGraphicState; 1746112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org noSMaskGS->fPopulated = true; 1756112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org noSMaskGS->fSMask = true; 176c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com noSMaskGS->insertName("Type", "ExtGState"); 177c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com noSMaskGS->insertName("SMask", "None"); 1786112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org } 1796112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org noSMaskGS->ref(); 1806112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org return noSMaskGS; 1816112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org} 1826112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1836112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org// static 184f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.comint SkPDFGraphicState::Find(const SkPaint& paint) { 185b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein CanonicalPaintsMutex().assertHeld(); 1869b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org GSCanonicalEntry search(&paint); 187f6c3ebdeb135dcdb9af225bd7af77f1fe1f92787reed@google.com return CanonicalPaints().find(search); 1889b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 1899b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 1906112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.orgSkPDFGraphicState::SkPDFGraphicState() 1916112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org : fPopulated(false), 1926112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org fSMask(false) { 1936112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org} 1946112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org 1959b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgSkPDFGraphicState::SkPDFGraphicState(const SkPaint& paint) 1969b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org : fPaint(paint), 1976112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org fPopulated(false), 1986112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org fSMask(false) { 1999b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 2009b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 2019b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// populateDict and operator== have to stay in sync with each other. 2029b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgvoid SkPDFGraphicState::populateDict() { 2039b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org if (!fPopulated) { 2049b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org fPopulated = true; 205c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertName("Type", "ExtGState"); 2069b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 207d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org SkAutoTUnref<SkPDFScalar> alpha( 208d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org new SkPDFScalar(SkScalarDiv(fPaint.getAlpha(), 0xFF))); 2099b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org insert("CA", alpha.get()); 2109b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org insert("ca", alpha.get()); 2119b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 212f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kButt_Cap == 0, paint_cap_mismatch); 213f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kRound_Cap == 1, paint_cap_mismatch); 214f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kSquare_Cap == 2, paint_cap_mismatch); 215f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kCapCount == 3, paint_cap_mismatch); 2169b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkASSERT(fPaint.getStrokeCap() >= 0 && fPaint.getStrokeCap() <= 2); 217c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertInt("LC", fPaint.getStrokeCap()); 2189b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 219f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kMiter_Join == 0, paint_join_mismatch); 220f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kRound_Join == 1, paint_join_mismatch); 221f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kBevel_Join == 2, paint_join_mismatch); 222f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kJoinCount == 3, paint_join_mismatch); 2239b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkASSERT(fPaint.getStrokeJoin() >= 0 && fPaint.getStrokeJoin() <= 2); 224c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertInt("LJ", fPaint.getStrokeJoin()); 2259b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 226c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertScalar("LW", fPaint.getStrokeWidth()); 227c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertScalar("ML", fPaint.getStrokeMiter()); 228f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org insert("SA", new SkPDFBool(true))->unref(); // Auto stroke adjustment. 22948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 23048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode; 231f71b2103d56dde247605b718a0c89123ad8f0094vandebo@chromium.org // If asMode fails, default to kSrcOver_Mode. 23248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (fPaint.getXfermode()) 23348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org fPaint.getXfermode()->asMode(&xfermode); 23448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org // If we don't support the mode, just use kSrcOver_Mode. 23548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (xfermode < 0 || xfermode > SkXfermode::kLastMode || 2366112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org blend_mode_from_xfermode(xfermode) == NULL) { 23748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org xfermode = SkXfermode::kSrcOver_Mode; 238f71b2103d56dde247605b718a0c89123ad8f0094vandebo@chromium.org NOT_IMPLEMENTED("unsupported xfermode", false); 23948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 240c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com insertName("BM", blend_mode_from_xfermode(xfermode)); 2419b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org } 2429b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 2439b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org 2449b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// We're only interested in some fields of the SkPaint, so we have a custom 2459b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org// operator== function. 2469b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.orgbool SkPDFGraphicState::GSCanonicalEntry::operator==( 2479b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org const SkPDFGraphicState::GSCanonicalEntry& gs) const { 2489b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org const SkPaint* a = fPaint; 2499b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org const SkPaint* b = gs.fPaint; 2509b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkASSERT(a != NULL); 2519b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org SkASSERT(b != NULL); 25248543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 25348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org if (SkColorGetA(a->getColor()) != SkColorGetA(b->getColor()) || 25448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org a->getStrokeCap() != b->getStrokeCap() || 25548543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org a->getStrokeJoin() != b->getStrokeJoin() || 25648543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org a->getStrokeWidth() != b->getStrokeWidth() || 25748543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org a->getStrokeMiter() != b->getStrokeMiter()) { 25848543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org return false; 25948543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org } 26048543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 26148543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkXfermode::Mode aXfermodeName = SkXfermode::kSrcOver_Mode; 26269d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org SkXfermode* aXfermode = a->getXfermode(); 26369d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org if (aXfermode) { 26469d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org aXfermode->asMode(&aXfermodeName); 26569d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org } 26669d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org if (aXfermodeName < 0 || aXfermodeName > SkXfermode::kLastMode || 2676112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org blend_mode_from_xfermode(aXfermodeName) == NULL) { 26869d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org aXfermodeName = SkXfermode::kSrcOver_Mode; 26969d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org } 2706112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org const char* aXfermodeString = blend_mode_from_xfermode(aXfermodeName); 27169d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org SkASSERT(aXfermodeString != NULL); 27269d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org 27348543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org SkXfermode::Mode bXfermodeName = SkXfermode::kSrcOver_Mode; 27469d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org SkXfermode* bXfermode = b->getXfermode(); 27569d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org if (bXfermode) { 27669d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org bXfermode->asMode(&bXfermodeName); 27769d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org } 27869d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org if (bXfermodeName < 0 || bXfermodeName > SkXfermode::kLastMode || 2796112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org blend_mode_from_xfermode(bXfermodeName) == NULL) { 28069d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org bXfermodeName = SkXfermode::kSrcOver_Mode; 28169d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org } 2826112c215fbdd53388e64ece36e6c7bba0fe3a451vandebo@chromium.org const char* bXfermodeString = blend_mode_from_xfermode(bXfermodeName); 28369d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org SkASSERT(bXfermodeString != NULL); 28448543277728fdf66b993f17421f65fba532a23a2vandebo@chromium.org 28569d4ca32ec0d6e61061f7d3c321f1b9ced6dd3eavandebo@chromium.org return strcmp(aXfermodeString, bXfermodeString) == 0; 2869b49dc0db8254e3dcdc2de4a1e0add4f8a7ac5a8vandebo@chromium.org} 287