skia2/include/pdf/SkPDFGraphicState.h
vandebo@chromium.org 6112c215fb [PDF] Add support for SrcIn, SrcOut, DstIn, DstOut xfermodes.
This change uses the soft mask (aka soft clip) functionality of PDF to implement the xfermodes.  It has to put existing content (dst) into a form xobject as well as putting the new (src) content into a different form xobject.  It then draws one of them with the other as the soft mask.
To accomplish this, we add a call to finishContentEntry after each call to setUpContentEntry - this is kind of a hack, but I don't see a better way to extract src.
Unfortunately, soft mask is specified in the Graphic State PDF object (and not in the form xobject), so when handling one of these modes, we add a one time GS object to set the soft mask and invoke a simple GS to reset the soft mask when done.

Review URL: http://codereview.appspot.com/4496041

git-svn-id: http://skia.googlecode.com/svn/trunk@1320 2bbb7eff-a529-9590-31e7-b0007b416f81
2011-05-13 03:50:38 +00:00

105 lines
3.8 KiB
C++

/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SkPDFGraphicState_DEFINED
#define SkPDFGraphicState_DEFINED
#include "SkPaint.h"
#include "SkPDFTypes.h"
#include "SkTemplates.h"
#include "SkThread.h"
class SkPDFFormXObject;
/** \class SkPDFGraphicState
SkPaint objects roughly correspond to graphic state dictionaries that can
be installed. So that a given dictionary is only output to the pdf file
once, we want to canonicalize them. Static methods in this class manage
a weakly referenced set of SkPDFGraphicState objects: when the last
reference to a SkPDFGraphicState is removed, it removes itself from the
static set of objects.
*/
class SkPDFGraphicState : public SkPDFDict {
public:
virtual ~SkPDFGraphicState();
virtual void getResources(SkTDArray<SkPDFObject*>* resourceList);
// Override emitObject and getOutputSize so that we can populate
// the dictionary on demand.
virtual void emitObject(SkWStream* stream, SkPDFCatalog* catalog,
bool indirect);
virtual size_t getOutputSize(SkPDFCatalog* catalog, bool indirect);
/** Get the graphic state for the passed SkPaint. The reference count of
* the object is incremented and it is the caller's responsibility to
* unreference it when done. This is needed to accommodate the weak
* reference pattern used when the returned object is new and has no
* other references.
* @param paint The SkPaint to emulate.
*/
static SkPDFGraphicState* getGraphicStateForPaint(const SkPaint& paint);
/** Make a graphic state that only sets the passed soft mask. The
* reference count of the object is incremented and it is the caller's
* responsibility to unreference it when done.
* @param sMask The form xobject to use as a soft mask.
* @param invert Indicates if the alpha of the sMask should be inverted.
*/
static SkPDFGraphicState* getSMaskGraphicState(SkPDFFormXObject* sMask,
bool invert);
/** Get a graphic state that only unsets the soft mask. The reference
* count of the object is incremented and it is the caller's responsibility
* to unreference it when done. This is needed to accommodate the weak
* reference pattern used when the returned object is new and has no
* other references.
*/
static SkPDFGraphicState* getNoSMaskGraphicState();
private:
const SkPaint fPaint;
SkTDArray<SkPDFObject*> fResources;
bool fPopulated;
bool fSMask;
class GSCanonicalEntry {
public:
SkPDFGraphicState* fGraphicState;
const SkPaint* fPaint;
bool operator==(const GSCanonicalEntry& b) const;
explicit GSCanonicalEntry(SkPDFGraphicState* gs)
: fGraphicState(gs),
fPaint(&gs->fPaint) {}
explicit GSCanonicalEntry(const SkPaint* paint) : fPaint(paint) {}
};
// This should be made a hash table if performance is a problem.
static SkTDArray<GSCanonicalEntry>& canonicalPaints();
static SkMutex& canonicalPaintsMutex();
SkPDFGraphicState();
explicit SkPDFGraphicState(const SkPaint& paint);
void populateDict();
static int find(const SkPaint& paint);
};
#endif