pdftoruby 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,8 @@
1
+ === 0.0.4 / 2008-05-20
2
+
3
+ * 3 major enhancement
4
+
5
+ * Added support for SVN version of PDF::Reader using hash to get image parameters
6
+ * Added support for writing png files
7
+ * Added internal version of png library to allow fixes, changes, and hardwire it to pure ruby
8
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/pdftoruby.rb
6
+ lib/dumppdf.rb
7
+ lib/pdf-extended-ops.rb
8
+ lib/pdftoruby.rb
data/README.txt ADDED
@@ -0,0 +1,56 @@
1
+ = pdftoruby
2
+
3
+ * http://code.google.com/p/pdftoruby/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Convert pdf files into ruby classes - allow creation of complex pdf files from existing pdf files
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ Support for text
12
+ Support for Line Graphics
13
+ Support for Images (Indexed Color)
14
+
15
+ Problems:
16
+ JPG Embedded Images not supported
17
+
18
+ == SYNOPSIS:
19
+
20
+ pdftoruby.rb mypdf.pdf mypdf.rb MyPdf
21
+
22
+ Will read mypdf.pdf and create mypdf.rb with a Class of MyPdf.
23
+ A subdirectory of the name MyPdf will be created with resources.
24
+
25
+
26
+ == REQUIREMENTS:
27
+
28
+ PDF::Reader (Currently from SVN as of May 20, 2008
29
+ PDF::Writer
30
+
31
+ == INSTALL:
32
+
33
+ gem install pdftoruby
34
+
35
+ == LICENSE:
36
+
37
+ Copyright (c) 2008
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining
40
+ a copy of this software and associated documentation files (the
41
+ 'Software'), to deal in the Software without restriction, including
42
+ without limitation the rights to use, copy, modify, merge, publish,
43
+ distribute, sublicense, and/or sell copies of the Software, and to
44
+ permit persons to whom the Software is furnished to do so, subject to
45
+ the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be
48
+ included in all copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
51
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
53
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
54
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
55
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
56
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/pdftoruby.rb'
6
+
7
+ Hoe.new('pdftoruby', Pdftoruby::VERSION) do |p|
8
+ p.rubyforge_name = 'pdftoruby' # if different than lowercase project name
9
+ p.developer('glennswest', 'glennswest@yahoo.com.sg')
10
+ end
11
+
12
+ # vim: syntax=Ruby
data/bin/pdftoruby.rb ADDED
@@ -0,0 +1,632 @@
1
+ require 'rubygems'
2
+ require 'pdf/reader'
3
+ require 'pdf/writer'
4
+ require 'base64'
5
+ require 'zlib'
6
+ require 'pp'
7
+
8
+ $KCODE = 'u'
9
+ require 'jcode'
10
+ require 'iconv'
11
+ require 'base64'
12
+
13
+ class String # :nodoc:
14
+ ##
15
+ # Calculates a CRC using the algorithm in the PNG specification.
16
+ def png_crc
17
+ unless defined? @@crc then
18
+ @@crc = Array.new(256)
19
+ 256.times do |n|
20
+ c = n
21
+ 8.times do
22
+ c = (c & 1 == 1) ? 0xedb88320 ^ (c >> 1) : c >> 1
23
+ end
24
+ @@crc[n] = c
25
+ end
26
+ end
27
+
28
+ c = 0xffffffff
29
+ each_byte do |b|
30
+ c = @@crc[(c^b) & 0xff] ^ (c >> 8)
31
+ end
32
+ return c ^ 0xffffffff
33
+ end
34
+
35
+ end
36
+
37
+ ## gsw - Make sure we have version 1 - as version 2 will require major havoc - also fix the "binary" issue
38
+ # A pure Ruby Portable Network Graphics (PNG) writer.
39
+ #
40
+ # http://www.libpng.org/pub/png/spec/1.2/
41
+ #
42
+ # PNG supports:
43
+ # + 8 bit truecolor PNGs
44
+ #
45
+ # PNG does not support:
46
+ # + any other color depth
47
+ # + extra data chunks
48
+ # + filters
49
+ #
50
+ # = Example
51
+ #
52
+ # require 'png'
53
+ #
54
+ # canvas = PNG::Canvas.new 200, 200
55
+ # canvas[100, 100] = PNG::Color::Black
56
+ # canvas.line 50, 50, 100, 50, PNG::Color::Blue
57
+ # png = PNG.new canvas
58
+ # png.save 'blah.png'
59
+
60
+ class PNG
61
+
62
+ ##
63
+ # Creates a PNG chunk of type +type+ that contains +data+.
64
+
65
+ def self.chunk(type, data="")
66
+ [data.size, type, data, (type + data).png_crc].pack("Na*a*N")
67
+ end
68
+
69
+ ##
70
+ # Creates a new PNG object using +canvas+
71
+
72
+ def initialize(canvas)
73
+ @height = canvas.height
74
+ @width = canvas.width
75
+ @bits = 8
76
+ @data = canvas.data
77
+ end
78
+
79
+ ##
80
+ # Writes the PNG to +path+.
81
+
82
+ def save(path)
83
+ File.open(path, "wb") do |f|
84
+ f.write [137, 80, 78, 71, 13, 10, 26, 10].pack("C*") # PNG signature
85
+ f.write PNG.chunk('IHDR',
86
+ [ @height, @width, @bits, 2, 0, 0, 0 ].pack("N2C5"))
87
+ # 0 == filter type code "none"
88
+ data = @data.map { |row| [0] + row.map { |p| [p.values[0], p.values[1], p.values[2]] } }.flatten
89
+ #data = @data.map { |row| [0] + row.map { |p| p.values } }.flatten
90
+ f.write PNG.chunk('IDAT', Zlib::Deflate.deflate(data.pack("C*"), 9))
91
+ f.write PNG.chunk('IEND', '')
92
+ end
93
+ end
94
+
95
+ ##
96
+ # RGBA colors
97
+
98
+ class Color
99
+
100
+ attr_reader :values
101
+
102
+ ##
103
+ # Creates a new color with values +red+, +green+, +blue+, and +alpha+.
104
+
105
+ def initialize(red, green, blue, alpha)
106
+ @values = [red, green, blue, alpha]
107
+ end
108
+
109
+ ##
110
+ # Transparent white
111
+
112
+ Background = Color.new 0xFF, 0xFF, 0xFF, 0x00
113
+
114
+ White = Color.new 0xFF, 0xFF, 0xFF, 0xFF
115
+ Black = Color.new 0x00, 0x00, 0x00, 0xFF
116
+ Gray = Color.new 0x7F, 0x7F, 0x7F, 0xFF
117
+
118
+ Red = Color.new 0xFF, 0x00, 0x00, 0xFF
119
+ Orange = Color.new 0xFF, 0xA5, 0x00, 0xFF
120
+ Yellow = Color.new 0xFF, 0xFF, 0x00, 0xFF
121
+ Green = Color.new 0x00, 0xFF, 0x00, 0xFF
122
+ Blue = Color.new 0x00, 0x00, 0xFF, 0xFF
123
+ Purple = Color.new 0XFF, 0x00, 0xFF, 0xFF
124
+
125
+ ##
126
+ # Red component
127
+
128
+ def r; @values[0]; end
129
+
130
+ ##
131
+ # Green component
132
+
133
+ def g; @values[1]; end
134
+
135
+ ##
136
+ # Blue component
137
+
138
+ def b; @values[2]; end
139
+
140
+ ##
141
+ # Alpha transparency component
142
+
143
+ def a; @values[3]; end
144
+
145
+ ##
146
+ # Blends +color+ into this color returning a new blended color.
147
+
148
+ def blend(color)
149
+ return Color.new((r * (0xFF - color.a) + color.r * color.a) >> 8,
150
+ (g * (0xFF - color.a) + color.g * color.a) >> 8,
151
+ (b * (0xFF - color.a) + color.b * color.a) >> 8,
152
+ (a * (0xFF - color.a) + color.a * color.a) >> 8)
153
+ end
154
+
155
+ ##
156
+ # Returns a new color with an alpha value adjusted by +i+.
157
+
158
+ def intensity(i)
159
+ return Color.new(r,b,g,(a*i) >> 8)
160
+ end
161
+
162
+ def inspect # :nodoc:
163
+ "#<%s %02x %02x %02x %02x>" % [self.class, *@values]
164
+ end
165
+
166
+ end
167
+
168
+ ##
169
+ # PNG canvas
170
+
171
+ class Canvas
172
+
173
+ ##
174
+ # Height of the canvas
175
+
176
+ attr_reader :height
177
+
178
+ ##
179
+ # Width of the canvas
180
+
181
+ attr_reader :width
182
+
183
+ ##
184
+ # Raw data
185
+
186
+ attr_reader :data
187
+
188
+ def initialize(height, width, background = Color::White)
189
+ @height = height
190
+ @width = width
191
+ @data = Array.new(@width) { |x| Array.new(@height) { background } }
192
+ end
193
+
194
+ ##
195
+ # Retrieves the color of the pixel at (+x+, +y+).
196
+
197
+ def [](x, y)
198
+ raise "bad x value #{x} >= #{@height}" if x >= @height
199
+ raise "bad y value #{y} >= #{@width}" if y >= @width
200
+ @data[y][x]
201
+ end
202
+
203
+ ##
204
+ # Sets the color of the pixel at (+x+, +y+) to +color+.
205
+
206
+ def []=(x, y, color)
207
+ raise "bad x value #{x} >= #{@height}" if x >= @height
208
+ raise "bad y value #{y} >= #{@width}" if y >= @width
209
+ @data[y][x] = color
210
+ end
211
+
212
+ ##
213
+ # Iterates over each pixel in the canvas.
214
+
215
+ def each
216
+ @data.each_with_index do |row, y|
217
+ row.each_with_index do |pixel, x|
218
+ yield x, y, color
219
+ end
220
+ end
221
+ end
222
+
223
+ ##
224
+ # Blends +color+ onto the color at point (+x+, +y+).
225
+
226
+ def point(x, y, color)
227
+ self[x,y] = self[x,y].blend(color)
228
+ end
229
+
230
+ ##
231
+ # Draws a line using Xiaolin Wu's antialiasing technique.
232
+ #
233
+ # http://en.wikipedia.org/wiki/Xiaolin_Wu's_line_algorithm
234
+
235
+ def line(x0, y0, x1, y1, color)
236
+ dx = x1 - x0
237
+ sx = dx < 0 ? -1 : 1
238
+ dx *= sx # TODO: abs?
239
+ dy = y1 - y0
240
+
241
+ # 'easy' cases
242
+ if dy == 0 then
243
+ Range.new(*[x0,x1].sort).each do |x|
244
+ point(x, y0, color)
245
+ end
246
+ return
247
+ end
248
+
249
+ if dx == 0 then
250
+ (y0..y1).each do |y|
251
+ point(x0, y, color)
252
+ end
253
+ return
254
+ end
255
+
256
+ if dx == dy then
257
+ Range.new(*[x0,x1].sort).each do |x|
258
+ point(x, y0, color)
259
+ y0 += 1
260
+ end
261
+ return
262
+ end
263
+
264
+ # main loop
265
+ point(x0, y0, color)
266
+ e_acc = 0
267
+ if dy > dx then # vertical displacement
268
+ e = (dx << 16) / dy
269
+ (y0...y1-1).each do |i|
270
+ e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
271
+ x0 = x0 + sx if (e_acc <= e_acc_temp)
272
+ w = 0xFF-(e_acc >> 8)
273
+ point(x0, y0, color.intensity(w))
274
+ y0 = y0 + 1
275
+ point(x0 + sx, y0, color.intensity(0xFF-w))
276
+ end
277
+ point(x1, y1, color)
278
+ return
279
+ end
280
+
281
+ # horizontal displacement
282
+ e = (dy << 16) / dx
283
+ (x0...(x1-sx)).each do |i|
284
+ e_acc_temp, e_acc = e_acc, (e_acc + e) & 0xFFFF
285
+ y0 += 1 if (e_acc <= e_acc_temp)
286
+ w = 0xFF-(e_acc >> 8)
287
+ point(x0, y0, color.intensity(w))
288
+ x0 += sx
289
+ point(x0, y0 + 1, color.intensity(0xFF-w))
290
+ end
291
+ point(x1, y1, color)
292
+ end
293
+
294
+ end
295
+
296
+ end
297
+
298
+
299
+
300
+ class PDFReceiver < PDF::Reader
301
+ # def init_xref(xref)
302
+ # @xref = xref
303
+ # end
304
+
305
+ def initextclass(thefile, theclass)
306
+ @ruby = thefile
307
+ @rubyclass = theclass
308
+ @text_position_x = 0.0
309
+ @text_position_y = 0.0
310
+ @text_font = "F1"
311
+ @text_size = 10.0
312
+ @ruby.printf("require 'pdf/writer'\n")
313
+ @ruby.printf("if File.exists?(\"../lib/pdf-extended-ops.rb\")\n")
314
+ @ruby.printf(" require '../lib/pdf-extended-ops.rb'\n")
315
+ @ruby.printf(" else \n")
316
+ @ruby.printf(" require 'pdf-extended-ops.rb'\n")
317
+ @ruby.printf(" end\n")
318
+ @ruby.printf("class %s\n",@rubyclass.capitalize)
319
+ @ruby.printf("def initialize()\n")
320
+ @ruby.printf("end\n")
321
+ @ruby.printf("\n\n")
322
+ @ruby.printf("def rendertofile(thename)\n")
323
+ @ruby.printf(" File.open(thename,\"wb\"){ |f| f.write @pdf.render }\n")
324
+ @ruby.printf(" end\n\n")
325
+ @ruby.printf("def createpage()\n")
326
+ end
327
+
328
+ def begin_document(args)
329
+ end
330
+
331
+ def begin_page(values)
332
+ pp values
333
+ rotate_value = values[:Rotate]
334
+ media_box = values[:MediaBox]
335
+ pp rotate_value
336
+ if rotate_value == 90.0
337
+ mypaper = ":paper => [#{media_box[0]}, #{media_box[1]}, #{media_box[2]}, #{media_box[3]}]"
338
+ pp mypaper
339
+ # @ruby.printf(" @pdf = PDF::Writer.new(:orientation => :landscape,#{mypaper})\n")
340
+ @ruby.printf(" @pdf = PDF::Writer.new(#{mypaper})\n")
341
+ else
342
+ mypaper = ":paper => [#{media_box[0]}, #{media_box[1]}, #{media_box[2]}, #{media_box[3]}]"
343
+ pp mypaper
344
+ @ruby.printf(" @pdf = PDF::Writer.new(#{mypaper})\n")
345
+ end
346
+ #@ruby.printf(" @pdf = PDF::Writer.new\n")
347
+ #@ruby.printf(" @pdf.select_font (\"Helvetica\", { :encoding => \"WinAnsiEncoding\" })\n")
348
+
349
+ #thefile = File.open("test.img","w")
350
+ #ithefile.write(therawbytes)
351
+ #thefile.close
352
+ end
353
+
354
+ def begin_page_container(values)
355
+ @pagemediabox = values["MediaBox"]
356
+ @pageresources = values["Resources"]
357
+ @pagekids = values["Kids"]
358
+ @pagetype = values["Type"]
359
+ end
360
+
361
+ def begin_marked_content_with_pl(flag,mcid)
362
+ mcid.each do |key, value|
363
+ @ruby.printf(" @pdf.begin_marked_content_with_p1(\"#{flag}\",\"#{key}\",\"#{value}\")\n")
364
+ end
365
+ end
366
+
367
+ #{:name=>:set_gray_for_stroking, :args=>[0.0]}
368
+ def set_gray_for_stroking(value)
369
+ @ruby.printf(" @pdf.set_gray_for_stroking(#{value})\n")
370
+ end
371
+
372
+ #{:name=>:set_line_width, :args=>[0.72]}
373
+ def set_line_width(value)
374
+ @ruby.printf(" @pdf.set_line_width(#{value})\n")
375
+ end
376
+
377
+ #{:name=>:set_miter_limit, :args=>[10.0]}
378
+ def set_miter_limit(value)
379
+ @ruby.printf(" @pdf.set_miter_limit(#{value})\n")
380
+ end
381
+
382
+ #{:name=>:set_line_join_style, :args=>[0.0]}
383
+ def set_line_join_style(value)
384
+ @ruby.printf(" @pdf.set_line_join_style(#{value})\n")
385
+ end
386
+
387
+ #{:name=>:set_line_cap_style, :args=>[1.0]}
388
+ def set_line_cap_style(value)
389
+ @ruby.printf(" @pdf.set_line_cap_style(#{value})\n")
390
+ end
391
+
392
+ #{:name=>:set_line_dash, :args=>[[], 0.0]}
393
+ def set_line_dash(values,widths)
394
+ @ruby.printf(" @pdf.set_line_dash(#{values.inspect},#{widths})\n")
395
+ end
396
+
397
+ #{:name=>:close_subpath, :args=>[]}
398
+ def close_subpath()
399
+ @ruby.printf(" @pdf.close_subpath()\n")
400
+ end
401
+
402
+ #{:name=>:stroke_path, :args=>[]}
403
+ def stroke_path()
404
+ @ruby.printf(" @pdf.stroke_path()\n")
405
+ end
406
+
407
+ def begin_marked_content(value)
408
+ @ruby.printf(" @pdf.begin_marked_content(\"#{value}\")\n")
409
+ end
410
+
411
+
412
+ def end_marked_content()
413
+ @ruby.printf(" @pdf.end_marked_content()\n")
414
+ end
415
+
416
+ def begin_text_object()
417
+ @ruby.printf(" @pdf.begin_text_object()\n")
418
+ end
419
+
420
+ def end_text_object()
421
+ @ruby.printf(" @pdf.end_text_object()\n")
422
+ end
423
+
424
+ def set_character_spacing(space_value)
425
+ @ruby.printf(" @pdf.set_character_spacing(#{space_value})\n")
426
+ end
427
+
428
+ def move_text_position(x,y)
429
+ if x
430
+ @text_position_x = x
431
+ end
432
+ if y
433
+ @text_position_y = y
434
+ end
435
+ end
436
+
437
+ def set_text_font_and_size(thefont,thesize)
438
+ @ruby.printf(" @pdf.set_text_font_and_size(\"%s\", %.3f)\n", thefont, thesize)
439
+ end
440
+
441
+ def set_character_spacing(value)
442
+ @ruby.printf(" @pdf.set_character_spacing(#{value})\n",value)
443
+ end
444
+
445
+ def set_word_spacing(value)
446
+ @ruby.printf(" @pdf.set_word_spacing(#{value})\n",value)
447
+ end
448
+
449
+ # there's a few text callbacks, so make sure we process them all
450
+ def show_text(string)
451
+ #string = string.chomp.rstrip
452
+ #if string.empty?
453
+ # return
454
+ # end
455
+ string = string.chomp
456
+ @ruby.printf(" @pdf.show_text(\"#{string}\")\n")
457
+ end
458
+
459
+ def super_show_text(string, *params)
460
+ string.chomp!
461
+ if string.empty?
462
+ return
463
+ end
464
+ @ruby.printf(" @pdf.show_text \"%s\"\n", string)
465
+ end
466
+
467
+ def move_to_next_line_and_show_text (string)
468
+ string.chomp!
469
+ if string.empty?
470
+ return
471
+ end
472
+ @ruby.printf(" @pdf.add_text %f, %f, \"%s\"\n",
473
+ @text_position_x, @text_position_y, string)
474
+ end
475
+
476
+ def set_spacing_next_line_show_text (aw, ac, string)
477
+ string.chomp!
478
+ if string.empty?
479
+ return
480
+ end
481
+ @ruby.printf(" @pdf.add_text %f, %f, \"%s\"\n",
482
+ @text_position_x, @text_position_y, string)
483
+ end
484
+
485
+ def set_text_matrix_and_text_line_matrix (a,b,c,d,e,f)
486
+ @text_position_x = f
487
+ @text_position_y = e
488
+ @ruby.printf(" @pdf.set_text_matrix_and_text_line_matrix(%f,%f,%f,%f,%f,%f)\n",
489
+ a,b,c,d,e,f)
490
+ end
491
+
492
+ def append_rectangle(a,b,c,d)
493
+ @ruby.printf(" @pdf.append_rectangle(#{a},#{b},#{c},#{d})\n")
494
+ end
495
+
496
+ def fill_path_with_nonzero()
497
+ @ruby.printf(" @pdf.fill_path_with_nonzero()\n")
498
+ end
499
+
500
+ def begin_new_subpath(a,b)
501
+ @ruby.printf(" @pdf.begin_new_subpath(#{a},#{b})\n")
502
+ end
503
+
504
+ def append_line(a,b)
505
+ @ruby.printf(" @pdf.append_line(#{a},#{b})\n")
506
+ end
507
+
508
+ def end_document()
509
+ @ruby.printf(" end\n")
510
+ @ruby.printf("end\n")
511
+ @ruby.printf("\n\n#Class Test\n")
512
+ @ruby.printf("doc = %s.new\n",@rubyclass)
513
+ @ruby.printf("doc.createpage\n")
514
+ @ruby.printf("doc.rendertofile(\"%s_test.pdf\")\n",@rubyclass)
515
+ @ruby.close
516
+ end
517
+
518
+ def save_graphics_state()
519
+ @ruby.printf(" @pdf.save_graphics_state()\n")
520
+ end
521
+
522
+ def restore_graphics_state()
523
+ @ruby.printf(" @pdf.restore_graphics_state()\n")
524
+ end
525
+
526
+ def concatenate_matrix(a,b,c,d,e,f)
527
+ @ruby.printf(" @pdf.concatenate_matrix(#{a},#{b},#{c},#{d},#{e},#{f})\n")
528
+ end
529
+
530
+ def resource_xobject(name,image_data)
531
+ specs = image_data.hash
532
+ colorspace = specs[:ColorSpace]
533
+ colorspacetype = colorspace[0]
534
+ if colorspacetype.to_s == "Indexed"
535
+ cdata = String.new(colorspace[3])
536
+ end
537
+ filename = String.new(name.to_s)
538
+ width = specs[:Width]
539
+ height = specs[:Height]
540
+ external_image(filename,image_data,width,height,cdata)
541
+ end
542
+
543
+ def resource_colorspace(name,val)
544
+ return
545
+ type = val[0]
546
+ specs = val[1]
547
+ csdef = specs[0]
548
+ #pp "csdef= ", csdef
549
+ length = csdef["Length"]
550
+ data = specs[1]
551
+ dir_name = @rubyclass.to_s
552
+ FileUtils.mkdir_p dir_name
553
+ space_name = dir_name + "/" + name + ".colorspace"
554
+ raw = File.open(space_name,"wb")
555
+ raw.write data
556
+ raw.close
557
+ end
558
+
559
+ def invoke_xobject(name)
560
+ @ruby.printf(" @pdf.invoke_xobject(\"#{@rubyclass.to_s}\",\"#{name}\")\n")
561
+ end
562
+
563
+
564
+
565
+ def external_image(name,data,width,height,cdata)
566
+ dir_name = @rubyclass.to_s
567
+ FileUtils.mkdir_p dir_name
568
+ pp dir_name
569
+ raw_name = dir_name + "/" + name + ".raw"
570
+ cs_name = dir_name + "/" + name + ".cs"
571
+ png_name = dir_name + "/" + name + ".png"
572
+ raw = File.open(cs_name,"w")
573
+ raw.write cdata
574
+ raw.close
575
+ raw = File.open(raw_name,"w")
576
+ idx = 0
577
+ data.each_byte do |c|
578
+ offset = c * 3
579
+ raw.write(cdata[offset ].chr)
580
+ raw.write(cdata[offset+1].chr)
581
+ raw.write(cdata[offset+2].chr)
582
+ idx + 1
583
+ end
584
+ raw.close
585
+ #need to convert the RGB file to PNG
586
+ canvas = PNG::Canvas.new width, height
587
+ position = 0
588
+ for x in (0..height-1)
589
+ for y in (0..width-1)
590
+ c = data[position]
591
+ offset = c * 3
592
+ canvas[y,x] = PNG::Color.new cdata[offset], cdata[offset+1], cdata[offset+2], 0x00
593
+ position = position + 1
594
+ end
595
+ end
596
+ png = PNG.new canvas
597
+ pp png_name
598
+ png.save png_name
599
+ end
600
+
601
+ def inline_image_raw(data)
602
+ ccnt = 0
603
+ @ruby.printf(" image_data = String.new\n")
604
+ image_data.each_byte do |c|
605
+ if ccnt == 0
606
+ @ruby.printf(" image_data << \"")
607
+ end
608
+ @ruby.printf("\\x%2.2x", c)
609
+ ccnt = ccnt + 1
610
+ if ccnt == 32
611
+ @ruby.printf("\"\n")
612
+ ccnt = 0
613
+ end
614
+ end
615
+ if ccnt > 0
616
+ @ruby.printf("\"\n")
617
+ end
618
+ @ruby.printf(" @pdf.xobject(id,name,image_specs,image_data)\n")
619
+ end
620
+
621
+ end
622
+
623
+ pdf_filename = ARGV[0]
624
+ ruby_filename = ARGV[1]
625
+ methodname = ARGV[2]
626
+
627
+ rubyfile = File.open(ruby_filename, "w")
628
+
629
+ receiver = PDFReceiver.new
630
+ receiver.initextclass(rubyfile,methodname)
631
+
632
+ pdf = PDF::Reader.file(pdf_filename, receiver)
data/lib/dumppdf.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'pdf/reader'
3
+ require 'pdf/writer'
4
+ require 'pp'
5
+
6
+ $KCODE = 'u'
7
+ require 'jcode'
8
+ require 'iconv'
9
+ require 'base64'
10
+
11
+
12
+
13
+ pdf_filename = ARGV[0]
14
+
15
+ receiver = PDF::Reader::RegisterReceiver.new
16
+ pdf = PDF::Reader.file(pdf_filename, receiver)
17
+ receiver.callbacks.each do |cb|
18
+ pp cb
19
+ end
20
+
21
+
@@ -0,0 +1,151 @@
1
+ # Extensions by Glenn S. West
2
+ # Extra methods to allow a more "direct" mapping" from pdf-reader
3
+ require 'pp'
4
+
5
+ class PDF::Writer
6
+ #Hacked add image to not mess up coordinate space - gsw
7
+ def myimage(image, label)
8
+
9
+ if image.respond_to?(:read)
10
+ data = image.read
11
+ else
12
+ open(image, 'rb') { |ff| data = ff.read }
13
+ end
14
+
15
+ image_info ||= PDF::Writer::Graphics::ImageInfo.new(data)
16
+ tt = Time.now
17
+ @images << tt
18
+ id = @images.index(tt)
19
+ image_obj = PDF::Writer::External::Image.new(self, data, image_info, label)
20
+ @images[id] = image_obj
21
+
22
+ image_obj
23
+ end
24
+
25
+ def save_graphics_state()
26
+ add_content("\nq")
27
+ end
28
+
29
+ def restore_graphics_state()
30
+ add_content("\nQ")
31
+ end
32
+
33
+ def concatenate_matrix(a,b,c,d,e,f)
34
+ add_content("\n%f %f %f %f %f %f cm" % [ a, b, c, d, e, f])
35
+ @pdfeo_matrix = Array.[](a,b,c,d,e,f)
36
+ end
37
+
38
+ def invoke_xobject(form,name)
39
+ dir_name = @rubyclass.to_s
40
+ png_name = form + "/" + name + ".png"
41
+ myimage(png_name, name)
42
+ add_content("\n/#{name} Do")
43
+ end
44
+
45
+ # Page 405 - PDF Reference
46
+ def begin_text_object()
47
+ add_content("\nBT")
48
+ end
49
+
50
+ def set_character_spacing(value)
51
+ add_content("\n #{value} Tc")
52
+ end
53
+
54
+ def set_word_spacing(value)
55
+ add_content("\n #{value} Tw")
56
+ end
57
+
58
+ def set_text_font_and_size(fontabbr,fontsize)
59
+ add_content("\n/#{fontabbr} #{fontsize} Tf")
60
+ end
61
+
62
+ def end_text_object()
63
+ add_content("\nET")
64
+ end
65
+
66
+ def show_text(txt)
67
+ thetxt = txt.gsub('\\','\\\\')
68
+ thetxt = thetxt.gsub('(','\(')
69
+ thetxt = thetxt.gsub(')','\)')
70
+ add_content("\n(#{thetxt})Tj")
71
+ end
72
+
73
+ # set_line_matrix_and_text_line_matrix
74
+ def set_text_matrix_and_text_line_matrix(a, b, c, d, e, f)
75
+ add_content("\n%f %f %f %f %f %f Tm" % [ a, b, c, d, e, f ])
76
+ end
77
+
78
+ def begin_marked_content(value)
79
+ add_content("\n/#{value} BMC")
80
+ end
81
+
82
+ def begin_marked_content_with_p1(flag, mcid_type, mcid_value)
83
+ add_content("\n/#{flag} << /#{mcid_type} #{mcid_value} >>\nBDC")
84
+ end
85
+
86
+ #Page 679 - PDF Reference
87
+ def end_marked_content()
88
+ add_content("\nEMC")
89
+ end
90
+
91
+ def append_rectangle(a,b,c,d)
92
+ add_content("\n#{a} #{b} #{c} #{d} re")
93
+ end
94
+
95
+ def fill_path_with_nonzero()
96
+ add_content("\nf")
97
+ end
98
+
99
+ def begin_new_subpath(a,b)
100
+ add_content("\n#{a} #{b} m")
101
+ end
102
+
103
+ def append_line(a,b)
104
+ add_content("\n#{a} #{b} l")
105
+ end
106
+
107
+ #{:name=>:set_gray_for_stroking, :args=>[0.0]}
108
+ def set_gray_for_stroking(value)
109
+ add_content("\n#{value} G")
110
+ end
111
+
112
+ #{:name=>:set_line_width, :args=>[0.72]}
113
+ def set_line_width(value)
114
+ add_content("\n#{value} w")
115
+ end
116
+
117
+ #{:name=>:set_miter_limit, :args=>[10.0]}
118
+ def set_miter_limit(value)
119
+ add_content("\n#{value} M")
120
+ end
121
+
122
+ #{:name=>:set_line_join_style, :args=>[0.0]}
123
+ def set_line_join_style(value)
124
+ thevalue = value.to_i
125
+ add_content("\n#{thevalue} j")
126
+ end
127
+
128
+ #{:name=>:set_line_cap_style, :args=>[1.0]}
129
+ def set_line_cap_style(value)
130
+ thevalue = value.to_i
131
+ add_content("\n#{thevalue} J")
132
+ end
133
+
134
+ #{:name=>:set_line_dash, :args=>[[], 0.0]}
135
+ def set_line_dash(values,width)
136
+ hash_values = values.inspect
137
+ thecontent = "\n#{hash_values} #{width} d"
138
+ add_content(thecontent)
139
+ end
140
+
141
+ #{:name=>:close_subpath, :args=>[]}
142
+ def close_subpath()
143
+ add_content("\n h")
144
+ end
145
+
146
+ #{:name=>:stroke_path, :args=>[]}
147
+ def stroke_path()
148
+ add_content("\n S")
149
+ end
150
+
151
+ end
data/lib/pdftoruby.rb ADDED
@@ -0,0 +1,3 @@
1
+ class Pdftoruby
2
+ VERSION = '0.0.4'
3
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdftoruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - glennswest
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-20 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.5.1
23
+ version:
24
+ description: Convert pdf files into ruby classes - allow creation of complex pdf files from existing pdf files
25
+ email:
26
+ - glennswest@yahoo.com.sg
27
+ executables:
28
+ - pdftoruby.rb
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ files:
36
+ - History.txt
37
+ - Manifest.txt
38
+ - README.txt
39
+ - Rakefile
40
+ - bin/pdftoruby.rb
41
+ - lib/dumppdf.rb
42
+ - lib/pdf-extended-ops.rb
43
+ - lib/pdftoruby.rb
44
+ has_rdoc: true
45
+ homepage: http://code.google.com/p/pdftoruby/
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --main
49
+ - README.txt
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project: pdftoruby
67
+ rubygems_version: 1.1.1
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Convert pdf files into ruby classes - allow creation of complex pdf files from existing pdf files
71
+ test_files: []
72
+