static SkPDFIndirectReference make_alpha_function_shader(SkPDFDocument* doc, const SkPDFGradientShader::Key& state) { SkASSERT(state.fType != SkShader::kNone_GradientType); SkPDFGradientShader::Key opaqueState = clone_key(state); for (int i = 0; i < opaqueState.fInfo.fColorCount; i++) { opaqueState.fInfo.fColors[i] = SkColorSetA(opaqueState.fInfo.fColors[i], SK_AlphaOPAQUE); } opaqueState.fHash = hash(opaqueState); SkASSERT(!gradient_has_alpha(opaqueState)); SkRect bbox = SkRect::Make(state.fBBox); SkPDFIndirectReference colorShader = find_pdf_shader(doc, std::move(opaqueState), false); if (!colorShader) { return SkPDFIndirectReference(); } // Create resource dict with alpha graphics state as G0 and // pattern shader as P0, then write content stream. SkPDFIndirectReference alphaGsRef = create_smask_graphic_state(doc, state); std::unique_ptr<SkPDFDict> resourceDict = get_gradient_resource_dict(colorShader, alphaGsRef); std::unique_ptr<SkStreamAsset> colorStream = create_pattern_fill_content(alphaGsRef.fValue, colorShader.fValue, bbox); std::unique_ptr<SkPDFDict> alphaFunctionShader = SkPDFMakeDict(); SkPDFUtils::PopulateTilingPatternDict(alphaFunctionShader.get(), bbox, std::move(resourceDict), SkMatrix::I()); return SkPDFStreamOut(std::move(alphaFunctionShader), std::move(colorStream), doc); }
static SkPDFIndirectReference create_smask_graphic_state(SkPDFDocument* doc, const SkPDFGradientShader::Key& state) { SkASSERT(state.fType != SkShader::kNone_GradientType); SkPDFGradientShader::Key luminosityState = clone_key(state); for (int i = 0; i < luminosityState.fInfo.fColorCount; i++) { SkAlpha alpha = SkColorGetA(luminosityState.fInfo.fColors[i]); luminosityState.fInfo.fColors[i] = SkColorSetARGB(255, alpha, alpha, alpha); } luminosityState.fHash = hash(luminosityState); SkASSERT(!gradient_has_alpha(luminosityState)); SkPDFIndirectReference luminosityShader = find_pdf_shader(doc, std::move(luminosityState), false); std::unique_ptr<SkPDFDict> resources = get_gradient_resource_dict(luminosityShader, SkPDFIndirectReference()); SkRect bbox = SkRect::Make(state.fBBox); SkPDFIndirectReference alphaMask = SkPDFMakeFormXObject(doc, create_pattern_fill_content(-1, luminosityShader.fValue, bbox), SkPDFUtils::RectToArray(bbox), std::move(resources), SkMatrix::I(), "DeviceRGB"); return SkPDFGraphicState::GetSMaskGraphicState( alphaMask, false, SkPDFGraphicState::kLuminosity_SMaskMode, doc); }
/** * Creates a ExtGState with the SMask set to the luminosityShader in * luminosity mode. The shader pattern extends to the bbox. */ SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() { SkRect bbox; bbox.set(fState.get()->fBBox); SkAutoTUnref<SkPDFObject> luminosityShader( SkPDFShader::GetPDFShaderByState( fState->CreateAlphaToLuminosityState())); SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); SkAutoTUnref<SkPDFResourceDict> resources(get_gradient_resource_dict(luminosityShader, NULL)); SkAutoTUnref<SkPDFFormXObject> alphaMask( new SkPDFFormXObject(alphaStream.get(), bbox, resources.get())); return SkPDFGraphicState::GetSMaskGraphicState( alphaMask.get(), false, SkPDFGraphicState::kLuminosity_SMaskMode); }
SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state) : fState(state) { SkRect bbox; bbox.set(fState.get()->fBBox); fColorShader.reset( SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState())); // Create resource dict with alpha graphics state as G0 and // pattern shader as P0, then write content stream. SkAutoTUnref<SkPDFGraphicState> alphaGs(CreateSMaskGraphicState()); fResourceDict.reset( get_gradient_resource_dict(fColorShader.get(), alphaGs.get())); SkAutoTUnref<SkStream> colorStream( create_pattern_fill_content(0, bbox)); setData(colorStream.get()); populate_tiling_pattern_dict(this, bbox, fResourceDict.get(), SkMatrix::I()); }
/** * Creates a ExtGState with the SMask set to the luminosityShader in * luminosity mode. The shader pattern extends to the bbox. */ static SkPDFObject* create_smask_graphic_state( SkPDFCanon* canon, SkScalar dpi, const SkPDFShader::State& state) { SkRect bbox; bbox.set(state.fBBox); SkAutoTDelete<SkPDFShader::State> alphaToLuminosityState( state.CreateAlphaToLuminosityState()); SkAutoTUnref<SkPDFObject> luminosityShader( get_pdf_shader_by_state(canon, dpi, &alphaToLuminosityState)); SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox)); SkAutoTUnref<SkPDFDict> resources(get_gradient_resource_dict(luminosityShader, NULL)); SkAutoTUnref<SkPDFFormXObject> alphaMask( new SkPDFFormXObject(alphaStream.get(), bbox, resources.get())); return SkPDFGraphicState::GetSMaskGraphicState( alphaMask.get(), false, SkPDFGraphicState::kLuminosity_SMaskMode); }
SkPDFAlphaFunctionShader* SkPDFAlphaFunctionShader::Create( SkPDFCanon* canon, SkScalar dpi, SkAutoTDelete<SkPDFShader::State>* autoState) { const SkPDFShader::State& state = **autoState; SkRect bbox; bbox.set(state.fBBox); SkAutoTDelete<SkPDFShader::State> opaqueState(state.CreateOpaqueState()); SkAutoTUnref<SkPDFObject> colorShader( get_pdf_shader_by_state(canon, dpi, &opaqueState)); if (!colorShader) { return NULL; } // Create resource dict with alpha graphics state as G0 and // pattern shader as P0, then write content stream. SkAutoTUnref<SkPDFObject> alphaGs( create_smask_graphic_state(canon, dpi, state)); SkPDFAlphaFunctionShader* alphaFunctionShader = SkNEW_ARGS(SkPDFAlphaFunctionShader, (autoState->detach())); SkAutoTUnref<SkPDFDict> resourceDict( get_gradient_resource_dict(colorShader.get(), alphaGs.get())); SkAutoTDelete<SkStream> colorStream( create_pattern_fill_content(0, bbox)); alphaFunctionShader->setData(colorStream.get()); populate_tiling_pattern_dict(alphaFunctionShader, bbox, resourceDict.get(), SkMatrix::I()); canon->addAlphaShader(alphaFunctionShader); return alphaFunctionShader; }