Class: RTF::ImageNode

Inherits:
Node
  • Object
show all
Defined in:
lib/rtf/node.rb

Overview

This class represents an image within a RTF document. Currently only the PNG, JPEG and Windows Bitmap formats are supported. Efforts are made to identify the file type but these are not guaranteed to work.

Constant Summary collapse

PNG =

A definition for an image type constant.

:pngblip
JPEG =

A definition for an image type constant.

:jpegblip
BITMAP =

A definition for an image type constant.

:dibitmap0
LITTLE_ENDIAN =

A definition for an architecture endian constant.

:little
BIG_ENDIAN =

A definition for an architecture endian constant.

:big
DIMENSIONS_OFFSET =

Offsets for reading dimension data by filetype

{
  JPEG   => 2,
  PNG    => 8,
  BITMAP => 8,
}.freeze

Instance Attribute Summary collapse

Attributes inherited from Node

#parent

Instance Method Summary collapse

Methods inherited from Node

#is_root?, #next_node, #previous_node, #root

Constructor Details

#initialize(parent, source, id) ⇒ ImageNode

This is the constructor for the ImageNode class.

Parameters

parent

A reference to the node that owns the new image node.

source

A reference to the image source. This must be a String or a File.

id

The unique identifier for the image node.

Exceptions

RTFError

Generated whenever the image specified is not recognised as a supported image type, something other than a String or File or IO is passed as the source parameter or if the specified source does not exist or cannot be accessed.



1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
# File 'lib/rtf/node.rb', line 1300

def initialize(parent, source, id)
   super(parent)
   @source = nil
   @id     = id
   @type   = nil
   @x_scaling = @y_scaling = nil
   @top_crop = @right_crop = @bottom_crop = @left_crop = nil
   @width = @height = nil
   @displayed_width = @displayed_height = nil

   # store path to image
   @source = source if source.instance_of?(String) || source.instance_of?(Tempfile)
   @source = source.path if source.instance_of?(File)

   # Check the file's existence and accessibility.
   if !File.exist?(@source)
      RTFError.fire("Unable to find the #{File.basename(@source)} file.")
   end
   if !File.readable?(@source)
      RTFError.fire("Access to the #{File.basename(@source)} file denied.")
   end

   @type = get_file_type
   if @type == nil
      RTFError.fire("The #{File.basename(@source)} file contains an "\
                    "unknown or unsupported image type.")
   end

   @width, @height = get_dimensions
end

Instance Attribute Details

#bottom_cropObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def bottom_crop
  @bottom_crop
end

#displayed_heightObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def displayed_height
  @displayed_height
end

#displayed_widthObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def displayed_width
  @displayed_width
end

#heightObject (readonly)

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def height
  @height
end

#left_cropObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def left_crop
  @left_crop
end

#right_cropObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def right_crop
  @right_crop
end

#top_cropObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def top_crop
  @top_crop
end

#widthObject (readonly)

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def width
  @width
end

#x_scalingObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def x_scaling
  @x_scaling
end

#y_scalingObject

Attribute accessor.



1279
1280
1281
# File 'lib/rtf/node.rb', line 1279

def y_scaling
  @y_scaling
end

Instance Method Details

#read_source(file, read, size = nil) ⇒ Object

This method loads the data for an image from its source. The method accepts two call approaches. If called without a block then the method considers the size parameter it is passed. If called with a block the method executes until the block returns true.

Parameters

size

The maximum number of bytes to be read from the file. Defaults to nil to indicate that the remainder of the file should be read in.



1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
# File 'lib/rtf/node.rb', line 1444

def read_source(file, read, size=nil)
   if block_given?
      done = false

      while done == false && file.eof? == false
        read << file.getbyte
         done = yield read[-1]
      end
   else
      if size != nil
         if size > 0
            total = 0
            while file.eof? == false && total < size
               read << file.getbyte
               total += 1
            end
         end
      else
         file.each_byte {|byte| read << byte}
      end
   end
end

#to_rtfObject

This method generates the RTF for an ImageNode object.



1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
# File 'lib/rtf/node.rb', line 1370

def to_rtf
  text  = StringIO.new
  count = 0
  
  #text << '{\pard{\*\shppict{\pict'
  text << '{\*\shppict{\pict'
  text << "\\picscalex#{@x_scaling}" if @x_scaling != nil
  text << "\\picscaley#{@y_scaling}" if @y_scaling != nil
  text << "\\piccropl#{@left_crop}" if @left_crop != nil
  text << "\\piccropr#{@right_crop}" if @right_crop != nil
  text << "\\piccropt#{@top_crop}" if @top_crop != nil
  text << "\\piccropb#{@bottom_crop}" if @bottom_crop != nil
  text << "\\picwgoal#{@displayed_width}" if @displayed_width != nil
  text << "\\pichgoal#{@displayed_height}" if @displayed_height != nil        
  text << "\\picw#{@width}\\pich#{@height}\\bliptag#{@id}"
  text << "\\#{@type.id2name}\n"
  
  open_file do |file|
    file.each_byte do |byte|
      hex_str = byte.to_s(16)
      hex_str.insert(0,'0') if hex_str.length == 1
      text << hex_str    
      count += 1
      if count == 40
        text << "\n"
        count = 0
      end
    end
  end
  #text << "\n}}\\par}"
  text << "\n}}"

  text.string
end