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); }
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); }
Hash *h_clone(Hash *self, h_clone_ft clone_key, h_clone_ft clone_value) { void *key, *value; HashEntry *he; int i = self->size; Hash *ht_clone; ht_clone = h_new(self->hash_i, self->eq_i, self->free_key_i, self->free_value_i); for (he = self->table; i > 0; he++) { if (he->key && he->key != dummy_key) { /* active entry */ key = clone_key ? clone_key(he->key) : he->key; value = clone_value ? clone_value(he->value) : he->value; h_set(ht_clone, key, value); i--; } } return ht_clone; }