14ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org/* 2685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Copyright 2011 Google Inc. 34ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org * 4685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5685cfc0ee13d7c355ae2f4f3d225ad45e945763fepoger@google.com * found in the LICENSE file. 64ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org */ 74ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 8e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org#include "SkPDFFormXObject.h" 94ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkPDFGraphicState.h" 108c32f5efcf180adc0cbf8ad3a7cac691eba42f20vandebo@chromium.org#include "SkPDFUtils.h" 114ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org#include "SkStream.h" 1219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org#include "SkTypes.h" 1319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 14e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.orgstatic const char* blend_mode_from_xfermode(SkXfermode::Mode mode) { 1519caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org switch (mode) { 1619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSrcOver_Mode: return "Normal"; 17cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org // kModulate is not really like multipy but similar most of the time. 18f0099aa86b3a1086e62837426097f620fa4c0eeaskia.committer@gmail.com case SkXfermode::kModulate_Mode: 19cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org case SkXfermode::kMultiply_Mode: return "Multiply"; 2019caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kScreen_Mode: return "Screen"; 2119caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kOverlay_Mode: return "Overlay"; 2219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDarken_Mode: return "Darken"; 2319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kLighten_Mode: return "Lighten"; 2419caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kColorDodge_Mode: return "ColorDodge"; 2519caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kColorBurn_Mode: return "ColorBurn"; 2619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kHardLight_Mode: return "HardLight"; 2719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSoftLight_Mode: return "SoftLight"; 2819caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDifference_Mode: return "Difference"; 2919caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kExclusion_Mode: return "Exclusion"; 30cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org case SkXfermode::kHue_Mode: return "Hue"; 31cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org case SkXfermode::kSaturation_Mode: return "Saturation"; 32cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org case SkXfermode::kColor_Mode: return "Color"; 33cb608f40e52e6eb81361102f1437587438a1012ccommit-bot@chromium.org case SkXfermode::kLuminosity_Mode: return "Luminosity"; 3419caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 35a6cf7e9cd05d84108d7668e9e1bde927bee7a9f5vandebo@chromium.org // These are handled in SkPDFDevice::setUpContentEntry. 3619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kClear_Mode: 3719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSrc_Mode: 3819caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDst_Mode: 3919caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDstOver_Mode: 4019caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSrcIn_Mode: 4119caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDstIn_Mode: 4219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSrcOut_Mode: 4319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDstOut_Mode: 44e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org return "Normal"; 45e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 46c0db31ffa3b2863d27f630b4809036f8fcc74c7ectguil@chromium.org // TODO(vandebo): Figure out if we can support more of these modes. 4719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kSrcATop_Mode: 4819caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kDstATop_Mode: 4919caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kXor_Mode: 5019caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org case SkXfermode::kPlus_Mode: 5119caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org return NULL; 5219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org } 5319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org return NULL; 5419caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org} 5519caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 564ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgSkPDFGraphicState::~SkPDFGraphicState() { 5709e900419f232872200a76c64357b105531791c4reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 58e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org if (!fSMask) { 5909e900419f232872200a76c64357b105531791c4reed@google.com int index = Find(fPaint); 60e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org SkASSERT(index >= 0); 61413a85d9b0ff773b6a4422d918a3817f0cdfe33fvandebo@chromium.org SkASSERT(CanonicalPaints()[index].fGraphicState == this); 6209e900419f232872200a76c64357b105531791c4reed@google.com CanonicalPaints().removeShuffle(index); 63e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org } 64e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org fResources.unrefAll(); 65e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org} 66e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 6709b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.comvoid SkPDFGraphicState::getResources( 6809b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.com const SkTSet<SkPDFObject*>& knownResourceObjects, 6909b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.com SkTSet<SkPDFObject*>* newResourceObjects) { 7009b4813b6bd356d371952c4346f1f9fbe02fdfceedisonn@google.com GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); 714ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 724ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 734ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgvoid SkPDFGraphicState::emitObject(SkWStream* stream, SkPDFCatalog* catalog, 744ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org bool indirect) { 754ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org populateDict(); 764ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org SkPDFDict::emitObject(stream, catalog, indirect); 774ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 784ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 7919caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org// static 804ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgsize_t SkPDFGraphicState::getOutputSize(SkPDFCatalog* catalog, bool indirect) { 814ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org populateDict(); 824ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org return SkPDFDict::getOutputSize(catalog, indirect); 834ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 844ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 854ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// static 864ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgSkTDArray<SkPDFGraphicState::GSCanonicalEntry>& 8709e900419f232872200a76c64357b105531791c4reed@google.comSkPDFGraphicState::CanonicalPaints() { 884ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org // This initialization is only thread safe with gcc. 894ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org static SkTDArray<SkPDFGraphicState::GSCanonicalEntry> gCanonicalPaints; 904ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org return gCanonicalPaints; 914ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 924ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 934ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// static 9400819c385f318d9219e9a033fe23a1fa71ca40e5digit@google.comSkBaseMutex& SkPDFGraphicState::CanonicalPaintsMutex() { 9500819c385f318d9219e9a033fe23a1fa71ca40e5digit@google.com // This initialization is only thread safe with gcc or when 9600819c385f318d9219e9a033fe23a1fa71ca40e5digit@google.com // POD-style mutex initialization is used. 9700819c385f318d9219e9a033fe23a1fa71ca40e5digit@google.com SK_DECLARE_STATIC_MUTEX(gCanonicalPaintsMutex); 984ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org return gCanonicalPaintsMutex; 994ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 1004ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 1014ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// static 10209e900419f232872200a76c64357b105531791c4reed@google.comSkPDFGraphicState* SkPDFGraphicState::GetGraphicStateForPaint( 1034ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org const SkPaint& paint) { 10409e900419f232872200a76c64357b105531791c4reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 10509e900419f232872200a76c64357b105531791c4reed@google.com int index = Find(paint); 1064ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org if (index >= 0) { 10709e900419f232872200a76c64357b105531791c4reed@google.com CanonicalPaints()[index].fGraphicState->ref(); 10809e900419f232872200a76c64357b105531791c4reed@google.com return CanonicalPaints()[index].fGraphicState; 1094ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org } 1104ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org GSCanonicalEntry newEntry(new SkPDFGraphicState(paint)); 11109e900419f232872200a76c64357b105531791c4reed@google.com CanonicalPaints().push(newEntry); 1124ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org return newEntry.fGraphicState; 1134ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 1144ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 1154ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// static 11677d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.orgSkPDFObject* SkPDFGraphicState::GetInvertFunction() { 11777d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org // This assumes that canonicalPaintsMutex is held. 11877d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org static SkPDFStream* invertFunction = NULL; 11977d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org if (!invertFunction) { 12077d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org // Acrobat crashes if we use a type 0 function, kpdf crashes if we use 12177d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org // a type 2 function, so we use a type 4 function. 1225b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org SkAutoTUnref<SkPDFArray> domainAndRange(new SkPDFArray); 12377d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org domainAndRange->reserve(2); 1244a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com domainAndRange->appendInt(0); 1254a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com domainAndRange->appendInt(1); 12677d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org 12777d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org static const char psInvert[] = "{1 exch sub}"; 1285b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org SkAutoTUnref<SkMemoryStream> psInvertStream( 1295b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org new SkMemoryStream(&psInvert, strlen(psInvert), true)); 13077d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org 13177d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org invertFunction = new SkPDFStream(psInvertStream.get()); 1324a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com invertFunction->insertInt("FunctionType", 4); 13377d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org invertFunction->insert("Domain", domainAndRange.get()); 13477d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org invertFunction->insert("Range", domainAndRange.get()); 13577d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org } 13677d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org return invertFunction; 13777d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org} 13877d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org 13977d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org// static 14009e900419f232872200a76c64357b105531791c4reed@google.comSkPDFGraphicState* SkPDFGraphicState::GetSMaskGraphicState( 1419d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org SkPDFFormXObject* sMask, bool invert, SkPDFSMaskMode sMaskMode) { 142e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org // The practical chances of using the same mask more than once are unlikely 143e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org // enough that it's not worth canonicalizing. 14409e900419f232872200a76c64357b105531791c4reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 145e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 1465b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org SkAutoTUnref<SkPDFDict> sMaskDict(new SkPDFDict("Mask")); 1479d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org if (sMaskMode == kAlpha_SMaskMode) { 1489d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org sMaskDict->insertName("S", "Alpha"); 1499d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org } else if (sMaskMode == kLuminosity_SMaskMode) { 1509d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org sMaskDict->insertName("S", "Luminosity"); 1519d2ebe897190c9ea93f3c737440bf5ae891a910bcommit-bot@chromium.org } 152e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org sMaskDict->insert("G", new SkPDFObjRef(sMask))->unref(); 153e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 154e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org SkPDFGraphicState* result = new SkPDFGraphicState; 155e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org result->fPopulated = true; 156e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org result->fSMask = true; 1574a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com result->insertName("Type", "ExtGState"); 158e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org result->insert("SMask", sMaskDict.get()); 159e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org result->fResources.push(sMask); 160e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org sMask->ref(); 161e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 162e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org if (invert) { 16377d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org SkPDFObject* invertFunction = GetInvertFunction(); 16477d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org result->fResources.push(invertFunction); 16577d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org invertFunction->ref(); 16677d0944aa6a8155375584e197f8e9613c83a9811vandebo@chromium.org sMaskDict->insert("TR", new SkPDFObjRef(invertFunction))->unref(); 167e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org } 168e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 169e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org return result; 170e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org} 171e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 172e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org// static 17309e900419f232872200a76c64357b105531791c4reed@google.comSkPDFGraphicState* SkPDFGraphicState::GetNoSMaskGraphicState() { 17409e900419f232872200a76c64357b105531791c4reed@google.com SkAutoMutexAcquire lock(CanonicalPaintsMutex()); 175e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org static SkPDFGraphicState* noSMaskGS = NULL; 176e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org if (!noSMaskGS) { 177e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org noSMaskGS = new SkPDFGraphicState; 178e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org noSMaskGS->fPopulated = true; 179e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org noSMaskGS->fSMask = true; 1804a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com noSMaskGS->insertName("Type", "ExtGState"); 1814a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com noSMaskGS->insertName("SMask", "None"); 182e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org } 183e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org noSMaskGS->ref(); 184e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org return noSMaskGS; 185e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org} 186e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 187e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org// static 18809e900419f232872200a76c64357b105531791c4reed@google.comint SkPDFGraphicState::Find(const SkPaint& paint) { 1894ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org GSCanonicalEntry search(&paint); 19009e900419f232872200a76c64357b105531791c4reed@google.com return CanonicalPaints().find(search); 1914ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 1924ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 193e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.orgSkPDFGraphicState::SkPDFGraphicState() 194e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org : fPopulated(false), 195e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org fSMask(false) { 196e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org} 197e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org 1984ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgSkPDFGraphicState::SkPDFGraphicState(const SkPaint& paint) 1994ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org : fPaint(paint), 200e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org fPopulated(false), 201e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org fSMask(false) { 2024ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 2034ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 2044ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// populateDict and operator== have to stay in sync with each other. 2054ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgvoid SkPDFGraphicState::populateDict() { 2064ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org if (!fPopulated) { 2074ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org fPopulated = true; 2084a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertName("Type", "ExtGState"); 2094ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 2105b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org SkAutoTUnref<SkPDFScalar> alpha( 2115b20098a0c3b7d3fe65d8e636bc898fb661f6fa8vandebo@chromium.org new SkPDFScalar(SkScalarDiv(fPaint.getAlpha(), 0xFF))); 2124ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org insert("CA", alpha.get()); 2134ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org insert("ca", alpha.get()); 2144ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 215a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kButt_Cap == 0, paint_cap_mismatch); 216a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kRound_Cap == 1, paint_cap_mismatch); 217a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kSquare_Cap == 2, paint_cap_mismatch); 218a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kCapCount == 3, paint_cap_mismatch); 2194ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org SkASSERT(fPaint.getStrokeCap() >= 0 && fPaint.getStrokeCap() <= 2); 2204a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertInt("LC", fPaint.getStrokeCap()); 2214ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 222a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kMiter_Join == 0, paint_join_mismatch); 223a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kRound_Join == 1, paint_join_mismatch); 224a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kBevel_Join == 2, paint_join_mismatch); 225a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org SK_COMPILE_ASSERT(SkPaint::kJoinCount == 3, paint_join_mismatch); 2264ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org SkASSERT(fPaint.getStrokeJoin() >= 0 && fPaint.getStrokeJoin() <= 2); 2274a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertInt("LJ", fPaint.getStrokeJoin()); 2284ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 2294a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertScalar("LW", fPaint.getStrokeWidth()); 2304a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertScalar("ML", fPaint.getStrokeMiter()); 231a9a5a610cd95fcedb790e5b1a815654c46f92e52vandebo@chromium.org insert("SA", new SkPDFBool(true))->unref(); // Auto stroke adjustment. 23219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 23319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org SkXfermode::Mode xfermode = SkXfermode::kSrcOver_Mode; 2348c32f5efcf180adc0cbf8ad3a7cac691eba42f20vandebo@chromium.org // If asMode fails, default to kSrcOver_Mode. 23519caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org if (fPaint.getXfermode()) 23619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org fPaint.getXfermode()->asMode(&xfermode); 23719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org // If we don't support the mode, just use kSrcOver_Mode. 23819caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org if (xfermode < 0 || xfermode > SkXfermode::kLastMode || 239e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org blend_mode_from_xfermode(xfermode) == NULL) { 24019caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org xfermode = SkXfermode::kSrcOver_Mode; 2418c32f5efcf180adc0cbf8ad3a7cac691eba42f20vandebo@chromium.org NOT_IMPLEMENTED("unsupported xfermode", false); 24219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org } 2434a4ebbe3a50777da8ea52b622d19033fcbe22946reed@google.com insertName("BM", blend_mode_from_xfermode(xfermode)); 2444ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org } 2454ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 2464ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org 2474ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// We're only interested in some fields of the SkPaint, so we have a custom 2484ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org// operator== function. 2494ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.orgbool SkPDFGraphicState::GSCanonicalEntry::operator==( 2504ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org const SkPDFGraphicState::GSCanonicalEntry& gs) const { 2514ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org const SkPaint* a = fPaint; 2524ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org const SkPaint* b = gs.fPaint; 2534ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org SkASSERT(a != NULL); 2544ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org SkASSERT(b != NULL); 25519caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 25619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org if (SkColorGetA(a->getColor()) != SkColorGetA(b->getColor()) || 25719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org a->getStrokeCap() != b->getStrokeCap() || 25819caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org a->getStrokeJoin() != b->getStrokeJoin() || 25919caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org a->getStrokeWidth() != b->getStrokeWidth() || 26019caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org a->getStrokeMiter() != b->getStrokeMiter()) { 26119caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org return false; 26219caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org } 26319caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 26419caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org SkXfermode::Mode aXfermodeName = SkXfermode::kSrcOver_Mode; 2656d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org SkXfermode* aXfermode = a->getXfermode(); 2666d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org if (aXfermode) { 2676d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org aXfermode->asMode(&aXfermodeName); 2686d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org } 2696d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org if (aXfermodeName < 0 || aXfermodeName > SkXfermode::kLastMode || 270e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org blend_mode_from_xfermode(aXfermodeName) == NULL) { 2716d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org aXfermodeName = SkXfermode::kSrcOver_Mode; 2726d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org } 273e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org const char* aXfermodeString = blend_mode_from_xfermode(aXfermodeName); 2746d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org SkASSERT(aXfermodeString != NULL); 2756d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org 27619caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org SkXfermode::Mode bXfermodeName = SkXfermode::kSrcOver_Mode; 2776d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org SkXfermode* bXfermode = b->getXfermode(); 2786d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org if (bXfermode) { 2796d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org bXfermode->asMode(&bXfermodeName); 2806d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org } 2816d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org if (bXfermodeName < 0 || bXfermodeName > SkXfermode::kLastMode || 282e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org blend_mode_from_xfermode(bXfermodeName) == NULL) { 2836d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org bXfermodeName = SkXfermode::kSrcOver_Mode; 2846d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org } 285e432d6e672ecd3447e82137e6582a99d7bb9407bvandebo@chromium.org const char* bXfermodeString = blend_mode_from_xfermode(bXfermodeName); 2866d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org SkASSERT(bXfermodeString != NULL); 28719caab4ade022f5f4e876e162330e4ea95f2bd28vandebo@chromium.org 2886d7c64d5630e67e282536f1e79dccffca02e7450vandebo@chromium.org return strcmp(aXfermodeString, bXfermodeString) == 0; 2894ed46bdbcb3152b1ca2265e2720b8a4051f4ea63vandebo@chromium.org} 290