[PDF] Reuse the invert function object for xform object masks.

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

git-svn-id: http://skia.googlecode.com/svn/trunk@1417 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
vandebo@chromium.org 2011-05-25 00:41:30 +00:00
parent 13d14a9dbd
commit 19e3c1ed1b
2 changed files with 32 additions and 21 deletions

View File

@ -98,6 +98,8 @@ private:
void populateDict();
static SkPDFObject* GetInvertFunction();
static int find(const SkPaint& paint);
};

View File

@ -116,6 +116,32 @@ SkPDFGraphicState* SkPDFGraphicState::getGraphicStateForPaint(
return newEntry.fGraphicState;
}
// static
SkPDFObject* SkPDFGraphicState::GetInvertFunction() {
// This assumes that canonicalPaintsMutex is held.
static SkPDFStream* invertFunction = NULL;
if (!invertFunction) {
// Acrobat crashes if we use a type 0 function, kpdf crashes if we use
// a type 2 function, so we use a type 4 function.
SkRefPtr<SkPDFArray> domainAndRange = new SkPDFArray;
domainAndRange->unref(); // SkRefPtr and new both took a reference.
domainAndRange->reserve(2);
domainAndRange->append(new SkPDFInt(0))->unref();
domainAndRange->append(new SkPDFInt(1))->unref();
static const char psInvert[] = "{1 exch sub}";
SkRefPtr<SkMemoryStream> psInvertStream =
new SkMemoryStream(&psInvert, strlen(psInvert), true);
psInvertStream->unref(); // SkRefPtr and new both took a reference.
invertFunction = new SkPDFStream(psInvertStream.get());
invertFunction->insert("FunctionType", new SkPDFInt(4))->unref();
invertFunction->insert("Domain", domainAndRange.get());
invertFunction->insert("Range", domainAndRange.get());
}
return invertFunction;
}
// static
SkPDFGraphicState* SkPDFGraphicState::getSMaskGraphicState(
SkPDFFormXObject* sMask, bool invert) {
@ -137,27 +163,10 @@ SkPDFGraphicState* SkPDFGraphicState::getSMaskGraphicState(
sMask->ref();
if (invert) {
// Acrobat crashes if we use a type 0 function, kpdf crashes if we use
// a type 2 function, so we use a type 4 function.
SkRefPtr<SkPDFArray> domainAndRange = new SkPDFArray;
domainAndRange->unref(); // SkRefPtr and new both took a reference.
domainAndRange->reserve(2);
domainAndRange->append(new SkPDFInt(0))->unref();
domainAndRange->append(new SkPDFInt(1))->unref();
static const char psInvert[] = "{1 exch sub}";
SkRefPtr<SkMemoryStream> psInvertStream =
new SkMemoryStream(&psInvert, strlen(psInvert), true);
psInvertStream->unref(); // SkRefPtr and new both took a reference.
SkRefPtr<SkPDFStream> invertFunc =
new SkPDFStream(psInvertStream.get());
result->fResources.push(invertFunc.get()); // Pass the ref from new.
invertFunc->insert("FunctionType", new SkPDFInt(4))->unref();
invertFunc->insert("Domain", domainAndRange.get());
invertFunc->insert("Range", domainAndRange.get());
sMaskDict->insert("TR", new SkPDFObjRef(invertFunc.get()))->unref();
SkPDFObject* invertFunction = GetInvertFunction();
result->fResources.push(invertFunction);
invertFunction->ref();
sMaskDict->insert("TR", new SkPDFObjRef(invertFunction))->unref();
}
return result;