Class: Pdfrb::Content::Canvas
- Inherits:
-
Object
- Object
- Pdfrb::Content::Canvas
- Defined in:
- lib/pdfrb/content/canvas.rb
Instance Attribute Summary collapse
-
#document ⇒ Object
readonly
Returns the value of attribute document.
-
#serializer ⇒ Object
readonly
Returns the value of attribute serializer.
-
#stream ⇒ Object
readonly
Returns the value of attribute stream.
-
#used_fonts ⇒ Object
readonly
Returns the value of attribute used_fonts.
-
#used_xobjects ⇒ Object
readonly
Returns the value of attribute used_xobjects.
Instance Method Summary collapse
-
#arc(cx, cy, radius, start_angle:, end_angle:, segments_per_rev: 16) ⇒ Object
Approximate a circular arc from
start_angletoend_angle(radians) centered at (cx, cy) withradius. - #artifact(type = nil) ⇒ Object
- #blend_mode=(mode) ⇒ Object
-
#circle(cx, cy, radius) ⇒ Object
Full circle centered at (cx, cy) with
radius. - #clip ⇒ Object
- #clip_even_odd ⇒ Object
- #close_path ⇒ Object
- #concat(a, b, c, d, e, f) ⇒ Object
-
#corner(x0, y0, x1, y1) ⇒ Object
Draw a quarter-circle corner from (x0, y0) to (x1, y1) by multi-segment linear interpolation.
- #curve_to(c1x, c1y, c2x, c2y, x, y) ⇒ Object
-
#dash=(spec) ⇒ Object
Convenience alias matching HexaPDF's naming.
- #dash_pattern=(spec) ⇒ Object
-
#draw_form_xobject(name, at: [0, 0], matrix: nil) ⇒ Object
Draw a Form XObject by resource name at (x, y) with an optional matrix transform.
- #draw_image(name, at: nil, width: nil, height: nil, matrix: nil) ⇒ Object
- #draw_image_matrix(name, a:, b:, c:, d:, e:, f:) ⇒ Object
-
#ellipse(cx, cy, rx, ry) ⇒ Object
Ellipse centered at (cx, cy) with x/y radii (rx, ry).
- #emit_op(op_class, *operands) ⇒ Object
- #end_marked_content ⇒ Object
- #end_path ⇒ Object
- #fill(rule: :nonzero) ⇒ Object
- #fill_color(color) ⇒ Object
- #fill_shading(name) ⇒ Object
- #fill_stroke(rule: :nonzero) ⇒ Object
-
#initialize(stream, document: nil) ⇒ Canvas
constructor
A new instance of Canvas.
-
#inline_image(dict:, data:) ⇒ Object
Emit an inline image (BI ... ID ... EI) directly into the content stream.
- #line(x1, y1, x2, y2) ⇒ Object
- #line_cap=(n) ⇒ Object
- #line_join=(n) ⇒ Object
- #line_to(x, y) ⇒ Object
- #line_width=(n) ⇒ Object
- #marked_content(tag, properties = nil) ⇒ Object
- #miter_limit=(n) ⇒ Object
- #move_to(x, y) ⇒ Object
- #opacity=(alpha) ⇒ Object
-
#polygon(points) ⇒ Object
Draw a closed polygon through
points. -
#polyline(points, close: false) ⇒ Object
Draw a connected polyline through
points. - #populate_resources!(page) ⇒ Object
- #rectangle(x, y, width, height) ⇒ Object
- #rotate(angle_in_radians) ⇒ Object
-
#rounded_rectangle(x, y, width, height, radius) ⇒ Object
Rectangle with rounded corners.
- #save_graphics_state ⇒ Object (also: #with_graphics_state)
- #scale(sx, sy = sx) ⇒ Object
- #stroke ⇒ Object
- #stroke_color(color) ⇒ Object
- #tagged(tag, mcid: nil, **props) ⇒ Object
- #text(str, at:, font:, size:, char_spacing: nil, word_spacing: nil) ⇒ Object
- #text_lines(lines, font:, size:, at:, leading: nil, char_spacing: nil, word_spacing: nil) ⇒ Object
- #text_rich(runs, at:) ⇒ Object
- #translate(tx, ty) ⇒ Object
- #with_transparency(opacity: 1.0, blend_mode: nil) ⇒ Object
Constructor Details
#initialize(stream, document: nil) ⇒ Canvas
Returns a new instance of Canvas.
8 9 10 11 12 13 14 15 16 |
# File 'lib/pdfrb/content/canvas.rb', line 8 def initialize(stream, document: nil) Pdfrb::Content::Operator.eager_load! @stream = stream @document = document || stream.document @serializer = Pdfrb::Serializer.new @used_fonts = {} @used_xobjects = {} ensure_stream_payload end |
Instance Attribute Details
#document ⇒ Object (readonly)
Returns the value of attribute document.
6 7 8 |
# File 'lib/pdfrb/content/canvas.rb', line 6 def document @document end |
#serializer ⇒ Object (readonly)
Returns the value of attribute serializer.
6 7 8 |
# File 'lib/pdfrb/content/canvas.rb', line 6 def serializer @serializer end |
#stream ⇒ Object (readonly)
Returns the value of attribute stream.
6 7 8 |
# File 'lib/pdfrb/content/canvas.rb', line 6 def stream @stream end |
#used_fonts ⇒ Object (readonly)
Returns the value of attribute used_fonts.
6 7 8 |
# File 'lib/pdfrb/content/canvas.rb', line 6 def used_fonts @used_fonts end |
#used_xobjects ⇒ Object (readonly)
Returns the value of attribute used_xobjects.
6 7 8 |
# File 'lib/pdfrb/content/canvas.rb', line 6 def used_xobjects @used_xobjects end |
Instance Method Details
#arc(cx, cy, radius, start_angle:, end_angle:, segments_per_rev: 16) ⇒ Object
Approximate a circular arc from start_angle to end_angle
(radians) centered at (cx, cy) with radius. Uses 16-line
segment approximation per full revolution.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/pdfrb/content/canvas.rb', line 91 def arc(cx, cy, radius, start_angle:, end_angle:, segments_per_rev: 16) span = end_angle - start_angle return self if span.abs < 1e-6 seg_count = [(segments_per_rev * span.abs / (2 * Math::PI)).ceil, 1].max step = span / seg_count seg_count.times do |i| a0 = start_angle + (i * step) a1 = a0 + step x0 = cx + (radius * Math.cos(a0)) y0 = cy + (radius * Math.sin(a0)) x1 = cx + (radius * Math.cos(a1)) y1 = cy + (radius * Math.sin(a1)) i.zero? ? move_to(x0, y0) : line_to(x0, y0) line_to(x1, y1) end self end |
#artifact(type = nil) ⇒ Object
448 449 450 451 452 453 454 |
# File 'lib/pdfrb/content/canvas.rb', line 448 def artifact(type = nil, &) if type marked_content(:Artifact, { Type: type }, &) else marked_content(:Artifact, &) end end |
#blend_mode=(mode) ⇒ Object
270 271 272 273 |
# File 'lib/pdfrb/content/canvas.rb', line 270 def blend_mode=(mode) emit_op(Pdfrb::Content::Operator::ApplyExtGState, create_ext_g_state(BM: mode.to_s)) end |
#circle(cx, cy, radius) ⇒ Object
Full circle centered at (cx, cy) with radius.
111 112 113 114 |
# File 'lib/pdfrb/content/canvas.rb', line 111 def circle(cx, cy, radius) arc(cx, cy, radius, start_angle: 0, end_angle: 2 * Math::PI) close_path end |
#clip ⇒ Object
228 229 230 231 232 |
# File 'lib/pdfrb/content/canvas.rb', line 228 def clip emit_op(Pdfrb::Content::Operator::ClipNonZero) emit_op(Pdfrb::Content::Operator::EndPath) self end |
#clip_even_odd ⇒ Object
234 235 236 237 238 |
# File 'lib/pdfrb/content/canvas.rb', line 234 def clip_even_odd emit_op(Pdfrb::Content::Operator::ClipEvenOdd) emit_op(Pdfrb::Content::Operator::EndPath) self end |
#close_path ⇒ Object
197 198 199 200 |
# File 'lib/pdfrb/content/canvas.rb', line 197 def close_path emit_op(Pdfrb::Content::Operator::ClosePath) self end |
#concat(a, b, c, d, e, f) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/pdfrb/content/canvas.rb', line 45 def concat(a, b, c, d, e, f, &) emit_op Pdfrb::Content::Operator::ConcatMatrix, a, b, c, d, e, f return self unless block_given? begin yield self ensure emit_op Pdfrb::Content::Operator::SaveGraphicsState end self end |
#corner(x0, y0, x1, y1) ⇒ Object
Draw a quarter-circle corner from (x0, y0) to (x1, y1) by multi-segment linear interpolation. Adequate for typical radii (< 30 pts); for larger radii use curve_to directly.
179 180 181 182 183 184 185 |
# File 'lib/pdfrb/content/canvas.rb', line 179 def corner(x0, y0, x1, y1) segments = 6 segments.times do |i| t = (i + 1) / segments.to_f line_to(x0 + ((x1 - x0) * t), y0 + ((y1 - y0) * t)) end end |
#curve_to(c1x, c1y, c2x, c2y, x, y) ⇒ Object
187 188 189 190 |
# File 'lib/pdfrb/content/canvas.rb', line 187 def curve_to(c1x, c1y, c2x, c2y, x, y) emit_op(Pdfrb::Content::Operator::CurveTo, c1x, c1y, c2x, c2y, x, y) self end |
#dash=(spec) ⇒ Object
Convenience alias matching HexaPDF's naming. Accepts either an Array (interpreted as the dash array, phase 0) or an [array, phase] pair.
162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/pdfrb/content/canvas.rb', line 162 def dash=(spec) array, phase = case spec when ::Array if spec.first.is_a?(::Array) spec else [spec, 0] end else [[spec], 0] end emit_op(Pdfrb::Content::Operator::DashPattern, array, phase) end |
#dash_pattern=(spec) ⇒ Object
414 415 416 417 |
# File 'lib/pdfrb/content/canvas.rb', line 414 def dash_pattern=(spec) array, phase = spec.is_a?(::Array) ? spec : [spec, 0] emit_op(Pdfrb::Content::Operator::DashPattern, array, phase) end |
#draw_form_xobject(name, at: [0, 0], matrix: nil) ⇒ Object
Draw a Form XObject by resource name at (x, y) with an optional matrix transform. Public API for page stamping, form flattening, and appearance-stream embedding.
319 320 321 322 323 324 325 326 327 328 329 330 331 |
# File 'lib/pdfrb/content/canvas.rb', line 319 def draw_form_xobject(name, at: [0, 0], matrix: nil) @used_xobjects[name] = true save_graphics_state do if matrix a, b, c, d, e, f = matrix concat(a, b, c, d, e, f) elsif at translate(at[0], at[1]) end emit_op(Pdfrb::Content::Operator::InvokeXObject, name) end self end |
#draw_image(name, at: nil, width: nil, height: nil, matrix: nil) ⇒ Object
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/pdfrb/content/canvas.rb', line 288 def draw_image(name, at: nil, width: nil, height: nil, matrix: nil) @used_xobjects[name] = true save_graphics_state do if matrix a, b, c, d, e, f = matrix concat(a, b, c, d, e, f) emit_op(Pdfrb::Content::Operator::InvokeXObject, name) else translate(at[0], at[1]) concat(width, 0, 0, height, 0, 0) append(" /#{name} Do\n") end end self end |
#draw_image_matrix(name, a:, b:, c:, d:, e:, f:) ⇒ Object
304 305 306 307 308 309 310 311 |
# File 'lib/pdfrb/content/canvas.rb', line 304 def draw_image_matrix(name, a:, b:, c:, d:, e:, f:) @used_xobjects[name] = true save_graphics_state do concat(a, b, c, d, e, f) emit_op(Pdfrb::Content::Operator::InvokeXObject, name) end self end |
#ellipse(cx, cy, rx, ry) ⇒ Object
Ellipse centered at (cx, cy) with x/y radii (rx, ry). Built from a scaled circle.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/pdfrb/content/canvas.rb', line 118 def ellipse(cx, cy, rx, ry) save_graphics_state do translate(cx, cy) concat(1, 0, 0, 1, 0, 0) # Approximate ellipse by scaling a unit circle. segments = 32 segments.times do |i| a0 = (i / segments.to_f) * 2 * Math::PI a1 = ((i + 1) / segments.to_f) * 2 * Math::PI x0 = rx * Math.cos(a0) y0 = ry * Math.sin(a0) x1 = rx * Math.cos(a1) y1 = ry * Math.sin(a1) i.zero? ? move_to(x0, y0) : line_to(x0, y0) line_to(x1, y1) end close_path end self end |
#emit_op(op_class, *operands) ⇒ Object
472 473 474 475 |
# File 'lib/pdfrb/content/canvas.rb', line 472 def emit_op(op_class, *operands) bytes = op_class.serialize(@serializer, *operands) append(bytes) end |
#end_marked_content ⇒ Object
436 437 438 439 |
# File 'lib/pdfrb/content/canvas.rb', line 436 def end_marked_content emit_op(Pdfrb::Content::Operator::EndMarkedContent) self end |
#end_path ⇒ Object
223 224 225 226 |
# File 'lib/pdfrb/content/canvas.rb', line 223 def end_path emit_op(Pdfrb::Content::Operator::EndPath) self end |
#fill(rule: :nonzero) ⇒ Object
207 208 209 210 211 212 213 |
# File 'lib/pdfrb/content/canvas.rb', line 207 def fill(rule: :nonzero) op = rule == :even_odd ? Pdfrb::Content::Operator::FillEvenOdd : Pdfrb::Content::Operator::FillNonZero emit_op(op) self end |
#fill_color(color) ⇒ Object
245 246 247 248 249 250 251 252 253 |
# File 'lib/pdfrb/content/canvas.rb', line 245 def fill_color(color) case color in [Symbol | String => family, *rest] emit_color_op(true, family.to_sym, rest) else emit_color_op(true, :gray, [color]) end self end |
#fill_shading(name) ⇒ Object
240 241 242 243 |
# File 'lib/pdfrb/content/canvas.rb', line 240 def fill_shading(name) append(" /#{name} sh\n") self end |
#fill_stroke(rule: :nonzero) ⇒ Object
215 216 217 218 219 220 221 |
# File 'lib/pdfrb/content/canvas.rb', line 215 def fill_stroke(rule: :nonzero) op = rule == :even_odd ? Pdfrb::Content::Operator::FillStrokeEvenOdd : Pdfrb::Content::Operator::FillStrokeNonZero emit_op(op) self end |
#inline_image(dict:, data:) ⇒ Object
Emit an inline image (BI ... ID ... EI) directly into the
content stream. Avoids the /Resources /XObject registration
overhead for one-shot images. The dict keys are the image
header keys (/W, /H, /CS, /BPC, /F, etc.); data is the
encoded image bytes (raw, Flate-compressed, or DCT).
342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/pdfrb/content/canvas.rb', line 342 def inline_image(dict:, data:) header = +"BI\n" dict.each do |k, v| header << @serializer.serialize(k) << " " << @serializer.serialize(v) << "\n" end header << "ID\n" append(header) append(data) append("\nEI\n") self end |
#line(x1, y1, x2, y2) ⇒ Object
67 68 69 |
# File 'lib/pdfrb/content/canvas.rb', line 67 def line(x1, y1, x2, y2) move_to(x1, y1).line_to(x2, y2) end |
#line_cap=(n) ⇒ Object
402 403 404 |
# File 'lib/pdfrb/content/canvas.rb', line 402 def line_cap=(n) emit_op(Pdfrb::Content::Operator::LineCap, n) end |
#line_join=(n) ⇒ Object
406 407 408 |
# File 'lib/pdfrb/content/canvas.rb', line 406 def line_join=(n) emit_op(Pdfrb::Content::Operator::LineJoin, n) end |
#line_to(x, y) ⇒ Object
62 63 64 65 |
# File 'lib/pdfrb/content/canvas.rb', line 62 def line_to(x, y) emit_op(Pdfrb::Content::Operator::LineTo, x, y) self end |
#line_width=(n) ⇒ Object
398 399 400 |
# File 'lib/pdfrb/content/canvas.rb', line 398 def line_width=(n) emit_op(Pdfrb::Content::Operator::LineWidth, n) end |
#marked_content(tag, properties = nil) ⇒ Object
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'lib/pdfrb/content/canvas.rb', line 419 def marked_content(tag, properties = nil, &) if properties emit_op(Pdfrb::Content::Operator::BeginMarkedContentWithProperties, tag, properties) else emit_op(Pdfrb::Content::Operator::BeginMarkedContent, tag) end return self unless block_given? begin yield self ensure emit_op(Pdfrb::Content::Operator::EndMarkedContent) end self end |
#miter_limit=(n) ⇒ Object
410 411 412 |
# File 'lib/pdfrb/content/canvas.rb', line 410 def miter_limit=(n) emit_op(Pdfrb::Content::Operator::MiterLimit, n) end |
#move_to(x, y) ⇒ Object
57 58 59 60 |
# File 'lib/pdfrb/content/canvas.rb', line 57 def move_to(x, y) emit_op(Pdfrb::Content::Operator::MoveTo, x, y) self end |
#opacity=(alpha) ⇒ Object
265 266 267 268 |
# File 'lib/pdfrb/content/canvas.rb', line 265 def opacity=(alpha) emit_op(Pdfrb::Content::Operator::ApplyExtGState, create_ext_g_state(ca: alpha, CA: alpha)) end |
#polygon(points) ⇒ Object
Draw a closed polygon through points.
84 85 86 |
# File 'lib/pdfrb/content/canvas.rb', line 84 def polygon(points) polyline(points, close: true) end |
#polyline(points, close: false) ⇒ Object
Draw a connected polyline through points. Each point is
[x, y]. If close is true, append a close-path operator.
73 74 75 76 77 78 79 80 81 |
# File 'lib/pdfrb/content/canvas.rb', line 73 def polyline(points, close: false) return self if points.empty? first = points.first move_to(first[0], first[1]) points.drop(1).each { |x, y| line_to(x, y) } close_path if close self end |
#populate_resources!(page) ⇒ Object
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/pdfrb/content/canvas.rb', line 456 def populate_resources!(page) r = page.value[:Resources] r = {} unless r.is_a?(::Hash) unless @used_fonts.empty? fd = r[:Font] || {} @used_fonts.each_key { |n| fd[n] = fd[n] || n } r[:Font] = fd end unless @used_xobjects.empty? xd = r[:XObject] || {} @used_xobjects.each_key { |n| xd[n] = xd[n] || n } r[:XObject] = xd end page.value[:Resources] = r end |
#rectangle(x, y, width, height) ⇒ Object
192 193 194 195 |
# File 'lib/pdfrb/content/canvas.rb', line 192 def rectangle(x, y, width, height) emit_op(Pdfrb::Content::Operator::Rectangle, x, y, width, height) self end |
#rotate(angle_in_radians) ⇒ Object
39 40 41 42 43 |
# File 'lib/pdfrb/content/canvas.rb', line 39 def rotate(angle_in_radians, &) c = Math.cos(angle_in_radians) s = Math.sin(angle_in_radians) concat(c, s, -s, c, 0, 0, &) end |
#rounded_rectangle(x, y, width, height, radius) ⇒ Object
Rectangle with rounded corners. radius is the corner radius
(a single value or 4-element [tl, tr, br, bl]).
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/pdfrb/content/canvas.rb', line 141 def rounded_rectangle(x, y, width, height, radius) radii = radius.is_a?(::Array) ? radius : [radius] * 4 tl, tr, br, bl = radii # bottom edge move_to(x + bl, y) line_to(x + width - br, y) corner(x + width - br, y, x + width, y + br) line_to(x + width, y + height - tr) corner(x + width, y + height - tr, x + width - tr, y + height) line_to(x + tl, y + height) corner(x + tl, y + height, x, y + height - tl) line_to(x, y + bl) corner(x, y + bl, x + bl, y) close_path self end |
#save_graphics_state ⇒ Object Also known as: with_graphics_state
18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/pdfrb/content/canvas.rb', line 18 def save_graphics_state(&) emit_op Pdfrb::Content::Operator::SaveGraphicsState if block_given? begin yield self ensure emit_op Pdfrb::Content::Operator::RestoreGraphicsState end end self end |
#scale(sx, sy = sx) ⇒ Object
35 36 37 |
# File 'lib/pdfrb/content/canvas.rb', line 35 def scale(sx, sy = sx, &) concat(sx, 0, 0, sy, 0, 0, &) end |
#stroke ⇒ Object
202 203 204 205 |
# File 'lib/pdfrb/content/canvas.rb', line 202 def stroke emit_op(Pdfrb::Content::Operator::Stroke) self end |
#stroke_color(color) ⇒ Object
255 256 257 258 259 260 261 262 263 |
# File 'lib/pdfrb/content/canvas.rb', line 255 def stroke_color(color) case color in [Symbol | String => family, *rest] emit_color_op(false, family.to_sym, rest) else emit_color_op(false, :gray, [color]) end self end |
#tagged(tag, mcid: nil, **props) ⇒ Object
441 442 443 444 445 446 |
# File 'lib/pdfrb/content/canvas.rb', line 441 def tagged(tag, mcid: nil, **props, &) p = props.dup p[:MCID] = mcid if mcid p = nil if p.empty? marked_content(tag, p, &) end |
#text(str, at:, font:, size:, char_spacing: nil, word_spacing: nil) ⇒ Object
354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/pdfrb/content/canvas.rb', line 354 def text(str, at:, font:, size:, char_spacing: nil, word_spacing: nil) @used_fonts[font] = size encoded = encode_for_font(str.to_s, font) emit_op(Pdfrb::Content::Operator::BeginText) emit_op(Pdfrb::Content::Operator::SetTextMatrix, 1, 0, 0, 1, at[0], at[1]) emit_op(Pdfrb::Content::Operator::Font, font, size) emit_op(Pdfrb::Content::Operator::CharSpacing, char_spacing) if char_spacing emit_op(Pdfrb::Content::Operator::WordSpacing, word_spacing) if word_spacing emit_op(Pdfrb::Content::Operator::ShowText, encoded) emit_op(Pdfrb::Content::Operator::EndText) self end |
#text_lines(lines, font:, size:, at:, leading: nil, char_spacing: nil, word_spacing: nil) ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 |
# File 'lib/pdfrb/content/canvas.rb', line 367 def text_lines(lines, font:, size:, at:, leading: nil, char_spacing: nil, word_spacing: nil) lead = leading || (size * 1.2) x, y = at lines.each do |line| text(line, at: [x, y], font: font, size: size, char_spacing: char_spacing, word_spacing: word_spacing) y -= lead end self end |
#text_rich(runs, at:) ⇒ Object
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'lib/pdfrb/content/canvas.rb', line 379 def text_rich(runs, at:) emit_op(Pdfrb::Content::Operator::BeginText) cx, cy = at runs.each do |run| @used_fonts[run[:font]] = run[:size] emit_op(Pdfrb::Content::Operator::SetTextMatrix, 1, 0, 0, 1, cx, cy) emit_op(Pdfrb::Content::Operator::Font, run[:font], run[:size]) fill_color(run[:color]) if run[:color] emit_op(Pdfrb::Content::Operator::ShowText, encode_for_font(run[:text].to_s, run[:font])) advance = @document&.fonts&.measure_text( run[:text], font: run[:font], size: run[:size] ) || 0 cx += advance end emit_op(Pdfrb::Content::Operator::EndText) self end |
#translate(tx, ty) ⇒ Object
31 32 33 |
# File 'lib/pdfrb/content/canvas.rb', line 31 def translate(tx, ty, &) concat(1, 0, 0, 1, tx, ty, &) end |
#with_transparency(opacity: 1.0, blend_mode: nil) ⇒ Object
275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/pdfrb/content/canvas.rb', line 275 def with_transparency(opacity: 1.0, blend_mode: nil) save_graphics_state self.opacity = opacity if opacity < 1.0 self.blend_mode = blend_mode if blend_mode begin yield self ensure emit_op(Pdfrb::Content::Operator::RestoreGraphicsState) end self end |