1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
# frozen_string_literal: true
# soft_mask.rb : Implements soft-masking
#
# Copyright September 2012, Alexander Mankuta. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
#
module Prawn
# The Prawn::SoftMask module is used to create arbitrary transparency in
# document. Using a soft mask allows creating more visually rich documents.
#
# You must group soft mask and graphics it's applied to under
# save_graphics_state because soft mask is a part of graphic state in PDF.
#
# Example:
# pdf.save_graphics_state do
# pdf.soft_mask do
# pdf.fill_color "444444"
# pdf.fill_polygon [0, 40], [60, 10], [120, 40], [60, 68]
# end
# pdf.fill_color '000000'
# pdf.fill_rectangle [0, 50], 120, 68
# end
#
module SoftMask
# @group Stable API
def soft_mask(&block)
renderer.min_version(1.4)
group_attrs = ref!(
Type: :Group,
S: :Transparency,
CS: :DeviceRGB,
I: false,
K: false
)
group = ref!(
Type: :XObject,
Subtype: :Form,
BBox: state.page.dimensions,
Group: group_attrs
)
state.page.stamp_stream(group, &block)
mask = ref!(
Type: :Mask,
S: :Luminosity,
G: group
)
g_state = ref!(
Type: :ExtGState,
SMask: mask,
AIS: false,
BM: :Normal,
OP: false,
op: false,
OPM: 1,
SA: true
)
registry_key = {
bbox: state.page.dimensions,
mask: [group.stream.filters.normalized, group.stream.filtered_stream],
page: state.page_count
}.hash
if soft_mask_registry[registry_key]
renderer.add_content "/#{soft_mask_registry[registry_key]} gs"
else
masks = page.resources[:ExtGState] ||= {}
id = masks.empty? ? 'GS1' : masks.keys.max.succ
masks[id] = g_state
soft_mask_registry[registry_key] = id
renderer.add_content "/#{id} gs"
end
end
private
def soft_mask_registry
@soft_mask_registry ||= {}
end
end
end
|