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
- #artifact(type = nil) ⇒ Object
- #blend_mode=(mode) ⇒ Object
- #clip ⇒ Object
- #clip_even_odd ⇒ Object
- #close_path ⇒ Object
- #concat(a, b, c, d, e, f) ⇒ Object
- #curve_to(c1x, c1y, c2x, c2y, x, y) ⇒ Object
- #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
- #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.
- #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
- #populate_resources!(page) ⇒ Object
- #rectangle(x, y, width, height) ⇒ Object
- #rotate(angle_in_radians) ⇒ Object
- #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
#artifact(type = nil) ⇒ Object
311 312 313 314 315 316 317 |
# File 'lib/pdfrb/content/canvas.rb', line 311 def artifact(type = nil, &) if type marked_content(:Artifact, { Type: type }, &) else marked_content(:Artifact, &) end end |
#blend_mode=(mode) ⇒ Object
154 155 156 157 |
# File 'lib/pdfrb/content/canvas.rb', line 154 def blend_mode=(mode) emit_op(Pdfrb::Content::Operator::ApplyExtGState, create_ext_g_state(BM: mode.to_s)) end |
#clip ⇒ Object
112 113 114 115 116 |
# File 'lib/pdfrb/content/canvas.rb', line 112 def clip emit_op(Pdfrb::Content::Operator::ClipNonZero) emit_op(Pdfrb::Content::Operator::EndPath) self end |
#clip_even_odd ⇒ Object
118 119 120 121 122 |
# File 'lib/pdfrb/content/canvas.rb', line 118 def clip_even_odd emit_op(Pdfrb::Content::Operator::ClipEvenOdd) emit_op(Pdfrb::Content::Operator::EndPath) self end |
#close_path ⇒ Object
81 82 83 84 |
# File 'lib/pdfrb/content/canvas.rb', line 81 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 |
#curve_to(c1x, c1y, c2x, c2y, x, y) ⇒ Object
71 72 73 74 |
# File 'lib/pdfrb/content/canvas.rb', line 71 def curve_to(c1x, c1y, c2x, c2y, x, y) emit_op(Pdfrb::Content::Operator::CurveTo, c1x, c1y, c2x, c2y, x, y) self end |
#dash_pattern=(spec) ⇒ Object
277 278 279 280 |
# File 'lib/pdfrb/content/canvas.rb', line 277 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.
203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/pdfrb/content/canvas.rb', line 203 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
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/pdfrb/content/canvas.rb', line 172 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
188 189 190 191 192 193 194 195 |
# File 'lib/pdfrb/content/canvas.rb', line 188 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 |
#emit_op(op_class, *operands) ⇒ Object
335 336 337 338 |
# File 'lib/pdfrb/content/canvas.rb', line 335 def emit_op(op_class, *operands) bytes = op_class.serialize(@serializer, *operands) append(bytes) end |
#end_marked_content ⇒ Object
299 300 301 302 |
# File 'lib/pdfrb/content/canvas.rb', line 299 def end_marked_content emit_op(Pdfrb::Content::Operator::EndMarkedContent) self end |
#end_path ⇒ Object
107 108 109 110 |
# File 'lib/pdfrb/content/canvas.rb', line 107 def end_path emit_op(Pdfrb::Content::Operator::EndPath) self end |
#fill(rule: :nonzero) ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/pdfrb/content/canvas.rb', line 91 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
129 130 131 132 133 134 135 136 137 |
# File 'lib/pdfrb/content/canvas.rb', line 129 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
124 125 126 127 |
# File 'lib/pdfrb/content/canvas.rb', line 124 def fill_shading(name) append(" /#{name} sh\n") self end |
#fill_stroke(rule: :nonzero) ⇒ Object
99 100 101 102 103 104 105 |
# File 'lib/pdfrb/content/canvas.rb', line 99 def fill_stroke(rule: :nonzero) op = rule == :even_odd ? Pdfrb::Content::Operator::FillStrokeEvenOdd : Pdfrb::Content::Operator::FillStrokeNonZero emit_op(op) 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
265 266 267 |
# File 'lib/pdfrb/content/canvas.rb', line 265 def line_cap=(n) emit_op(Pdfrb::Content::Operator::LineCap, n) end |
#line_join=(n) ⇒ Object
269 270 271 |
# File 'lib/pdfrb/content/canvas.rb', line 269 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
261 262 263 |
# File 'lib/pdfrb/content/canvas.rb', line 261 def line_width=(n) emit_op(Pdfrb::Content::Operator::LineWidth, n) end |
#marked_content(tag, properties = nil) ⇒ Object
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/pdfrb/content/canvas.rb', line 282 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
273 274 275 |
# File 'lib/pdfrb/content/canvas.rb', line 273 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
149 150 151 152 |
# File 'lib/pdfrb/content/canvas.rb', line 149 def opacity=(alpha) emit_op(Pdfrb::Content::Operator::ApplyExtGState, create_ext_g_state(ca: alpha, CA: alpha)) end |
#populate_resources!(page) ⇒ Object
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/pdfrb/content/canvas.rb', line 319 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
76 77 78 79 |
# File 'lib/pdfrb/content/canvas.rb', line 76 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 |
#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
86 87 88 89 |
# File 'lib/pdfrb/content/canvas.rb', line 86 def stroke emit_op(Pdfrb::Content::Operator::Stroke) self end |
#stroke_color(color) ⇒ Object
139 140 141 142 143 144 145 146 147 |
# File 'lib/pdfrb/content/canvas.rb', line 139 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
304 305 306 307 308 309 |
# File 'lib/pdfrb/content/canvas.rb', line 304 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
217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/pdfrb/content/canvas.rb', line 217 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
230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/pdfrb/content/canvas.rb', line 230 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
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/pdfrb/content/canvas.rb', line 242 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
159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/pdfrb/content/canvas.rb', line 159 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 |