]> source.dussan.org Git - redmine.git/commitdiff
improve rmagick feature of rfpdf plugin for PDF inline images (#3261)
authorToshi MARUYAMA <marutosijp2@yahoo.co.jp>
Mon, 14 Nov 2011 07:52:03 +0000 (07:52 +0000)
committerToshi MARUYAMA <marutosijp2@yahoo.co.jp>
Mon, 14 Nov 2011 07:52:03 +0000 (07:52 +0000)
Contributed by Jun NAITOH.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@7806 e93f8b46-1217-0410-a6f0-8f06a7374b81

vendor/plugins/rfpdf/lib/core/rmagick.rb
vendor/plugins/rfpdf/lib/tcpdf.rb

index 43e9fae0c439f3c8b4d2f4ab7643b938e6fae538..d561047cee3047bfeb048fd8beda972e0f2e6ff3 100644 (file)
@@ -57,6 +57,11 @@ module RFPDF
     end
 
     out['bits'] = image.channel_depth
+    File.open( TCPDF.k_path_cache + File::basename(filename), 'w'){|f|
+      f.binmode
+      f.print image.to_blob
+      f.close
+    }
     
     out
   end
index f41e96437017aa560ac8446a18abb746bd578bc1..110f7d5205a92340352b6e369bb2d498836df6a0 100755 (executable)
@@ -2049,17 +2049,27 @@ class TCPDF
                if (@images[file].nil?)
                        #First use of image, get info
                        if (type == '')
-                               pos = file.rindex('.');
-                               if (pos == 0)
+                               pos = File::basename(file).rindex('.');
+                               if (pos.nil? or pos == 0)
                                        Error('Image file has no extension and no type was specified: ' + file);
                                end
+                               pos = file.rindex('.');
                                type = file[pos+1..-1];
                        end
                        type.downcase!
                        if (type == 'jpg' or type == 'jpeg')
                                info=parsejpg(file);
-                       elsif (type == 'png')
-                               info=parsepng(file);
+                       elsif (type == 'png' or type == 'gif')
+                               img = Magick::ImageList.new(file)
+                               img.format = "PNG"     # convert to PNG from gif 
+                               img.opacity = 0        # PNG alpha channel delete
+                               File.open( @@k_path_cache + File::basename(file), 'w'){|f|
+                                       f.binmode
+                                       f.print img.to_blob
+                                       f.close
+                               }
+                               info=parsepng( @@k_path_cache + File::basename(file));
+                               File.delete( @@k_path_cache + File::basename(file))
                        else
                                #Allow for additional formats
                                mtd='parse' + type;
@@ -2075,15 +2085,37 @@ class TCPDF
                end
                #Automatic width and height calculation if needed
                if ((w == 0) and (h == 0))
+                       rescale_x = (@w - @r_margin - x) / (info['w'] / (@img_scale * @k)) 
+                       rescale_x = 1 if rescale_x >= 1 
+                       if (y + info['h'] * rescale_x / (@img_scale * @k) > @page_break_trigger and !@in_footer and AcceptPageBreak())
+                               #Automatic page break
+                               if @pages[@page+1].nil?
+                                       ws = @ws;
+                                       if (ws > 0)
+                                               @ws = 0;
+                                               out('0 Tw');
+                                       end
+                                       AddPage(@cur_orientation);
+                                       if (ws > 0)
+                                               @ws = ws;
+                                               out(sprintf('%.3f Tw', ws * @k));
+                                       end
+                               else
+                                       @page += 1;
+                               end
+                               y=@t_margin;
+                       end
+                       rescale_y = (@page_break_trigger - y) / (info['h'] / (@img_scale * @k)) 
+                       rescale_y = 1 if rescale_y >= 1 
+                       rescale = rescale_y >= rescale_x ? rescale_x : rescale_y
+
                        #Put image at 72 dpi
                        # 2004-06-14 :: Nicola Asuni, scale factor where added
-                       w = info['w'] / (@img_scale * @k);
-                       h = info['h'] / (@img_scale * @k);
-               end
-               if (w == 0)
+                       w = info['w'] * rescale / (@img_scale * @k);
+                       h = info['h'] * rescale / (@img_scale * @k);
+               elsif (w == 0)
                        w = h * info['w'] / info['h'];
-               end
-               if (h == 0)
+               elsif (h == 0)
                        h = w * info['h'] / info['w'];
                end
                out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', w*@k, h*@k, x*@k, (@h-(y+h))*@k, info['i']));
@@ -2846,7 +2878,7 @@ class TCPDF
                if (a.empty?)
                        Error('Missing or incorrect image file: ' + file);
                end
-               if (a[2]!='JPEG')
+               if (!a[2].nil? and a[2]!='JPEG')
                        Error('Not a JPEG file: ' + file);
                end
                if (a['channels'].nil? or a['channels']==3)
@@ -2859,9 +2891,12 @@ class TCPDF
                bpc=!a['bits'].nil? ? a['bits'] : 8;
                #Read whole file
                data='';
-         open(file,'rb') do |f|
+
+               open( @@k_path_cache + File::basename(file),'rb') do |f|
                        data<<f.read();
                end
+               File.delete( @@k_path_cache + File::basename(file))
+
                return {'w' => a[0],'h' => a[1],'cs' => colspace,'bpc' => bpc,'f'=>'DCTDecode','data' => data}
        end
 
@@ -2882,11 +2917,11 @@ class TCPDF
                end
                w=freadint(f);
                h=freadint(f);
-               bpc=f.read(1)[0];
+               bpc=f.read(1).unpack('C')[0];
                if (bpc>8)
                        Error('16-bit depth not supported: ' + file);
                end
-               ct=f.read(1)[0];
+               ct=f.read(1).unpack('C')[0];
                if (ct==0)
                        colspace='DeviceGray';
                elsif (ct==2)
@@ -2896,13 +2931,13 @@ class TCPDF
                else
                        Error('Alpha channel not supported: ' + file);
                end
-               if (f.read(1)[0] != 0)
+               if (f.read(1).unpack('C')[0] != 0)
                        Error('Unknown compression method: ' + file);
                end
-               if (f.read(1)[0]!=0)
+               if (f.read(1).unpack('C')[0] != 0)
                        Error('Unknown filter method: ' + file);
                end
-               if (f.read(1)[0]!=0)
+               if (f.read(1).unpack('C')[0] != 0)
                        Error('Interlacing not supported: ' + file);
                end
                f.read(4);
@@ -2922,9 +2957,9 @@ class TCPDF
                                #Read transparency info
                                t=f.read( n);
                                if (ct==0)
-                                       trns = t[1][0]
+                                       trns = t[1].unpack('C')[0]
                                elsif (ct==2)
-                                       trns = t[[1][0], t[3][0], t[5][0]]
+                                       trns = t[[1].unpack('C')[0], t[3].unpack('C')[0], t[5].unpack('C')[0]]
                                else
                                        pos=t.include?(0.chr);
                                        if (pos!=false)
@@ -3765,6 +3800,14 @@ class TCPDF
                end
        end
 
+       #
+       # Convert to accessible file path
+       # @param string :attrname image file name
+       #
+       def getImageFilename( attrname )
+               nil
+       end
+
        #
        # Process opening tags.
        # @param string :tag tag name (in upcase)
@@ -3878,10 +3921,17 @@ class TCPDF
                                
                        when 'img'
                                if (!attrs['src'].nil?)
-                               Write(@lasth, '!' + attrs['src'] + '!', '', fill);
-=begin Comment out. Because not implement image output yet.
-                                       # replace relative path with real server path
-                                       attrs['src'] = attrs['src'].gsub(@@k_path_url_cache, @@k_path_cache);
+                                       # Only generates image include a pdf if RMagick is avalaible
+                                       unless Object.const_defined?(:Magick)
+                                               Write(@lasth, attrs['src'], '', fill);
+                                               return
+                                       end
+                                       file = getImageFilename(attrs['src'])
+                                       if (file.nil?)
+                                               Write(@lasth, attrs['src'], '', fill);
+                                               return
+                                       end
+
                                        if (attrs['width'].nil?)
                                                attrs['width'] = 0;
                                        end
@@ -3889,10 +3939,17 @@ class TCPDF
                                                attrs['height'] = 0;
                                        end
                                        
-                                       Image(attrs['src'], GetX(),GetY(), pixelsToMillimeters(attrs['width']), pixelsToMillimeters(attrs['height']));
-                                       #SetX(@img_rb_x);
-                                       SetY(@img_rb_y);
-=end
+                                       begin
+                                               Image(file, GetX(),GetY(), pixelsToMillimeters(attrs['width']), pixelsToMillimeters(attrs['height']));
+                                               #SetX(@img_rb_x);
+                                               SetY(@img_rb_y);
+                                       rescue => err
+                                               logger.error "pdf: Image: error: #{err.message}"
+                                               Write(@lasth, attrs['src'], '', fill);
+                                               if File.file?( @@k_path_cache + File::basename(file))
+                                                       File.delete( @@k_path_cache + File::basename(file))
+                                               end
+                                       end
                                end
                                
                        when 'ul', 'ol'