PDF: import rfpdf tcpdf patch for textilized PDF (#69).

Contributed by Jun NAITOH.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@6134 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Toshi MARUYAMA 2011-06-30 04:00:55 +00:00
parent e9cdaf0d4b
commit 79c9fdfa61
1 changed files with 528 additions and 82 deletions

View File

@ -99,6 +99,8 @@ class TCPDF
attr_accessor :default_table_columns attr_accessor :default_table_columns
attr_accessor :max_table_columns
attr_accessor :default_font attr_accessor :default_font
attr_accessor :draw_color attr_accessor :draw_color
@ -141,11 +143,11 @@ class TCPDF
attr_accessor :links attr_accessor :links
attr_accessor :listordered attr_accessor :list_ordered
attr_accessor :listcount attr_accessor :list_count
attr_accessor :lispacer attr_accessor :li_spacer
attr_accessor :n attr_accessor :n
@ -226,6 +228,12 @@ class TCPDF
@diffs ||= [] @diffs ||= []
@color_flag ||= false @color_flag ||= false
@default_table_columns ||= 4 @default_table_columns ||= 4
@table_columns ||= 0
@max_table_columns ||= []
@tr_id ||= 0
@max_td_page ||= []
@max_td_y ||= []
@t_columns ||= 0
@default_font ||= "FreeSans" if unicode @default_font ||= "FreeSans" if unicode
@default_font ||= "Helvetica" @default_font ||= "Helvetica"
@draw_color ||= '0 G' @draw_color ||= '0 G'
@ -248,9 +256,15 @@ class TCPDF
@is_unicode = unicode @is_unicode = unicode
@lasth ||= 0 @lasth ||= 0
@links ||= [] @links ||= []
@listordered ||= false @list_ordered ||= []
@listcount ||= 0 @list_count ||= []
@lispacer ||= "" @li_spacer ||= ""
@li_count ||= 0
@spacer ||= ""
@quote_count ||= 0
@prevquote_count ||= 0
@quote_top ||= []
@quote_page ||= []
@n ||= 2 @n ||= 2
@offsets ||= [] @offsets ||= []
@orientation_changes ||= [] @orientation_changes ||= []
@ -272,6 +286,7 @@ class TCPDF
@tempfontsize ||= 10 @tempfontsize ||= 10
@text_color ||= '0 g' @text_color ||= '0 g'
@underline ||= false @underline ||= false
@deleted ||= false
@ws ||= 0 @ws ||= 0
#Standard Unicode fonts #Standard Unicode fonts
@ -737,7 +752,7 @@ class TCPDF
Open(); Open();
end end
family=@font_family; family=@font_family;
style=@font_style + (@underline ? 'U' : ''); style=@font_style + (@underline ? 'U' : '') + (@deleted ? 'D' : '');
size=@font_size_pt; size=@font_size_pt;
lw=@line_width; lw=@line_width;
dc=@draw_color; dc=@draw_color;
@ -1312,6 +1327,7 @@ class TCPDF
style=style.upcase style=style.upcase
style=style.gsub('U',''); style=style.gsub('U','');
style=style.gsub('D','');
if (style == 'IB') if (style == 'IB')
style = 'BI'; style = 'BI';
end end
@ -1394,7 +1410,7 @@ class TCPDF
# #Removes bold # #Removes bold
# :pdf->SetFont(''); # :pdf->SetFont('');
# #Times bold, italic and underlined 14 # #Times bold, italic and underlined 14
# :pdf->SetFont('Times','BIU'); # :pdf->SetFont('Times','BIUD');
# </pre><br /> # </pre><br />
# If the file corresponding to the requested font is not found, the error "Could not include font metric file" is generated. # If the file corresponding to the requested font is not found, the error "Could not include font metric file" is generated.
# @param string :family Family font. It can be either a name defined by AddFont() or one of the standard families (case insensitive):<ul><li>Courier (fixed-width)</li><li>Helvetica or Arial (synonymous; sans serif)</li><li>Times (serif)</li><li>Symbol (symbolic)</li><li>ZapfDingbats (symbolic)</li></ul>It is also possible to pass an empty string. In that case, the current family is retained. # @param string :family Family font. It can be either a name defined by AddFont() or one of the standard families (case insensitive):<ul><li>Courier (fixed-width)</li><li>Helvetica or Arial (synonymous; sans serif)</li><li>Times (serif)</li><li>Symbol (symbolic)</li><li>ZapfDingbats (symbolic)</li></ul>It is also possible to pass an empty string. In that case, the current family is retained.
@ -1426,6 +1442,12 @@ class TCPDF
else else
@underline=false; @underline=false;
end end
if (style.include?('D'))
@deleted=true;
style= style.gsub('D','');
else
@deleted=false;
end
if (style=='IB') if (style=='IB')
style='BI'; style='BI';
end end
@ -1573,7 +1595,7 @@ class TCPDF
#Output a string #Output a string
s=sprintf('BT %.2f %.2f Td (%s) Tj ET', x * @k, (@h-y) * @k, escapetext(txt)); s=sprintf('BT %.2f %.2f Td (%s) Tj ET', x * @k, (@h-y) * @k, escapetext(txt));
if (@underline and (txt!='')) if (@underline and (txt!=''))
s += ' ' + dounderline(x, y, txt); s += ' ' + dolinetxt(x, y, txt);
end end
if (@color_flag) if (@color_flag)
s='q ' + @text_color + ' ' + s + ' Q'; s='q ' + @text_color + ' ' + s + ' Q';
@ -1661,6 +1683,7 @@ class TCPDF
k=@k; k=@k;
if ((@y + h) > @page_break_trigger and !@in_footer and AcceptPageBreak()) if ((@y + h) > @page_break_trigger and !@in_footer and AcceptPageBreak())
#Automatic page break #Automatic page break
if @pages[@page+1].nil?
x = @x; x = @x;
ws = @ws; ws = @ws;
if (ws > 0) if (ws > 0)
@ -1673,7 +1696,12 @@ class TCPDF
@ws = ws; @ws = ws;
out(sprintf('%.3f Tw', ws * k)); out(sprintf('%.3f Tw', ws * k));
end end
else
@page += 1;
@y=@t_margin;
end end
end
if (w == 0) if (w == 0)
w = @w - @r_margin - @x; w = @w - @r_margin - @x;
end end
@ -1717,7 +1745,10 @@ class TCPDF
txt2 = escapetext(txt); txt2 = escapetext(txt);
s<<sprintf('BT %.2f %.2f Td (%s) Tj ET', (@x + dx) * k, (@h - (@y + 0.5 * h + 0.3 * @font_size)) * k, txt2); s<<sprintf('BT %.2f %.2f Td (%s) Tj ET', (@x + dx) * k, (@h - (@y + 0.5 * h + 0.3 * @font_size)) * k, txt2);
if (@underline) if (@underline)
s<<' ' + dounderline(@x + dx, @y + 0.5 * h + 0.3 * @font_size, txt); s<<' ' + dolinetxt(@x + dx, @y + 0.5 * h + 0.3 * @font_size, txt);
end
if (@deleted)
s<<' ' + dolinetxt(@x + dx, @y + 0.3 * h + 0.2 * @font_size, txt);
end end
if (@color_flag) if (@color_flag)
s<<' Q'; s<<' Q';
@ -1760,6 +1791,7 @@ class TCPDF
# save current position # save current position
prevx = @x; prevx = @x;
prevy = @y; prevy = @y;
prevpage = @page;
#Output text with automatic or explicit line breaks #Output text with automatic or explicit line breaks
@ -1876,6 +1908,7 @@ class TCPDF
@x = @l_margin; @x = @l_margin;
elsif (ln == 0) elsif (ln == 0)
# go to the top-right of the cell # go to the top-right of the cell
@page = prevpage;
@y = prevy; @y = prevy;
@x = prevx + w; @x = prevx + w;
elsif (ln == 2) elsif (ln == 2)
@ -2075,6 +2108,29 @@ class TCPDF
else else
@y += h; @y += h;
end end
k=@k;
if (@y > @page_break_trigger and !@in_footer and AcceptPageBreak())
#Automatic page break
if @pages[@page+1].nil?
x = @x;
ws = @ws;
if (ws > 0)
@ws = 0;
out('0 Tw');
end
AddPage(@cur_orientation);
@x = x;
if (ws > 0)
@ws = ws;
out(sprintf('%.3f Tw', ws * k));
end
else
@page += 1;
@y=@t_margin;
end
end
end end
alias_method :ln, :Ln alias_method :ln, :Ln
@ -2473,6 +2529,7 @@ class TCPDF
def putType0(font) def putType0(font)
#Type0 #Type0
newobj();
out('<</Type /Font') out('<</Type /Font')
out('/Subtype /Type0') out('/Subtype /Type0')
out('/BaseFont /'+font['name']+'-'+font['cMap']) out('/BaseFont /'+font['name']+'-'+font['cMap'])
@ -2525,7 +2582,7 @@ class TCPDF
out('/Width ' + info['w'].to_s); out('/Width ' + info['w'].to_s);
out('/Height ' + info['h'].to_s); out('/Height ' + info['h'].to_s);
if (info['cs']=='Indexed') if (info['cs']=='Indexed')
out('/ColorSpace [/Indexed /DeviceRGB ' + (info['pal'].length/3-1) + ' ' + (@n+1) + ' 0 R]'); out('/ColorSpace [/Indexed /DeviceRGB ' + (info['pal'].length/3-1).to_s + ' ' + (@n+1).to_s + ' 0 R]');
else else
out('/ColorSpace /' + info['cs']); out('/ColorSpace /' + info['cs']);
if (info['cs']=='DeviceCMYK') if (info['cs']=='DeviceCMYK')
@ -2553,7 +2610,7 @@ class TCPDF
#Palette #Palette
if (info['cs']=='Indexed') if (info['cs']=='Indexed')
newobj(); newobj();
pal=(@compress) ? gzcompress(info['pal']) : :info['pal']; pal=(@compress) ? gzcompress(info['pal']) : info['pal'];
out('<<' + filter + '/Length ' + pal.length.to_s + '>>'); out('<<' + filter + '/Length ' + pal.length.to_s + '>>');
putstream(pal); putstream(pal);
out('endobj'); out('endobj');
@ -2766,10 +2823,10 @@ class TCPDF
end end
# #
# Underline text # Underline and Deleted text
# @access protected # @access protected
# #
def dounderline(x, y, txt) def dolinetxt(x, y, txt)
up = @current_font['up']; up = @current_font['up'];
ut = @current_font['ut']; ut = @current_font['ut'];
w = GetStringWidth(txt) + @ws * txt.count(' '); w = GetStringWidth(txt) + @ws * txt.count(' ');
@ -3350,7 +3407,7 @@ class TCPDF
# #
# Allows to preserve some HTML formatting.<br /> # Allows to preserve some HTML formatting.<br />
# Supports: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small # Supports: h1, h2, h3, h4, h5, h6, b, u, i, a, img, p, br, strong, em, ins, del, font, blockquote, li, ul, ol, hr, td, th, tr, table, sup, sub, small
# @param string :html text to display # @param string :html text to display
# @param boolean :ln if true add a new line after text (default = true) # @param boolean :ln if true add a new line after text (default = true)
# @param int :fill Indicates if the background must be painted (1) or transparent (0). Default value: 0. # @param int :fill Indicates if the background must be painted (1) or transparent (0). Default value: 0.
@ -3364,9 +3421,35 @@ class TCPDF
end end
@href = nil @href = nil
@style = {} @style = "";
html.gsub!(/[\t\r\n\f]/, "")#\0\x0B @t_cells = [[]];
@table_id = 0;
# pre calculate
html.split(/(<[^>]+>)/).each do |element| html.split(/(<[^>]+>)/).each do |element|
if "<" == element[0,1]
#Tag
if (element[1, 1] == '/')
closedHTMLTagCalc(element[2..-2].downcase);
else
#Extract attributes
# get tag name
tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
tag = tag[0].downcase;
# get attributes
attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
attrs = {}
attr_array.each do |name, value|
attrs[name.downcase] = value;
end
openHTMLTagCalc(tag, attrs);
end
end
end
@table_id = 0;
html.split(/(<[A-Za-z!?\/][^>]*?>)/).each do |element|
if "<" == element[0,1] if "<" == element[0,1]
#Tag #Tag
if (element[1, 1] == '/') if (element[1, 1] == '/')
@ -3389,14 +3472,32 @@ class TCPDF
else else
#Text #Text
if (@href) if (@href)
element.gsub!(/[\t\r\n\f]/, "");
addHtmlLink(@href, element, fill); addHtmlLink(@href, element, fill);
elsif (@tdbegin) elsif (@tdbegin)
if ((element.strip.length > 0) and (element != "&nbsp;")) element.gsub!(/[\t\r\n\f]/, "");
Cell(@tdwidth, @tdheight, unhtmlentities(element.strip), @tableborder, 0, @tdalign, @tdfill); element.gsub!(/&nbsp;/, " ");
elsif (element == "&nbsp;") base_page = @page;
Cell(@tdwidth, @tdheight, '', @tableborder, 0, @tdalign, @tdfill); base_x = @x;
base_y = @y;
MultiCell(@tdwidth, @tdheight, unhtmlentities(element.strip), @tableborder, @tdalign, @tdfill, 1);
tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
if @max_td_page[tr_end].nil? or (@max_td_page[tr_end] < @page)
@max_td_page[tr_end] = @page
@max_td_y[tr_end] = @y
elsif (@max_td_page[tr_end] == @page)
@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y)
end
@page = base_page;
@x = base_x + @tdwidth;
@y = base_y;
elsif (element.strip.length > 0)
if @pre_state != true
element.gsub!(/[\t\r\n\f]/, "");
element.gsub!(/&nbsp;/, " ");
end end
elsif ((element.strip.length > 0) and (element != "&nbsp;"))
Write(@lasth, unhtmlentities(element), '', fill); Write(@lasth, unhtmlentities(element), '', fill);
end end
end end
@ -3422,7 +3523,7 @@ class TCPDF
# @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0. # @param int :fill Indicates if the cell background must be painted (1) or transparent (0). Default value: 0.
# @see Cell() # @see Cell()
# #
def writeHTMLCell(w, h, x, y, html='', border=0, ln=0, fill=0) def writeHTMLCell(w, h, x, y, html='', border=0, ln=1, fill=0)
if (@lasth == 0) if (@lasth == 0)
#set row height #set row height
@ -3446,6 +3547,24 @@ class TCPDF
w = @fw - x - @r_margin; w = @fw - x - @r_margin;
end end
b=0;
if (border)
if (border==1)
border='LTRB';
b='LRT';
b2='LR';
elsif border.is_a?(String)
b2='';
if (border.include?('L'))
b2<<'L';
end
if (border.include?('R'))
b2<<'R';
end
b=(border.include?('T')) ? b2 + 'T' : b2;
end
end
# store original margin values # store original margin values
l_margin = @l_margin; l_margin = @l_margin;
r_margin = @r_margin; r_margin = @r_margin;
@ -3461,36 +3580,187 @@ class TCPDF
currentY = GetY(); currentY = GetY();
@auto_page_break = false;
# check if a new page has been created # check if a new page has been created
if (@page > pagenum) if (@page > pagenum)
# design a cell around the text on first page # design a cell around the text on first page
currentpage = @page; currentpage = @page;
@page = pagenum; @page = pagenum;
SetY(GetPageHeight() - restspace - GetBreakMargin()); SetY(GetPageHeight() - restspace - GetBreakMargin());
h = restspace - 1; Cell(w, restspace - 1, "", b, 0, 'L', 0);
Cell(w, h, "", border, ln, 'L', 0); b = b2;
# design a cell around the text on last page @page += 1;
@page = currentpage; while @page < currentpage
h = currentY - @t_margin;
SetY(@t_margin); # put cursor at the beginning of text SetY(@t_margin); # put cursor at the beginning of text
Cell(w, h, "", border, ln, 'L', 0); Cell(w, @page_break_trigger - @t_margin, "", b, 0, 'L', 0);
@page += 1;
end
if (border.is_a?(String) and border.include?('B'))
b<<'B';
end
# design a cell around the text on last page
SetY(@t_margin); # put cursor at the beginning of text
Cell(w, currentY - @t_margin, "", b, 0, 'L', 0);
else else
h = [h, (currentY - y)].max;
SetY(y); # put cursor at the beginning of text SetY(y); # put cursor at the beginning of text
# design a cell around the text # design a cell around the text
Cell(w, h, "", border, ln, 'L', 0); Cell(w, [h, (currentY - y)].max, "", border, 0, 'L', 0);
end end
@auto_page_break = true;
# restore original margin values # restore original margin values
SetLeftMargin(l_margin); SetLeftMargin(l_margin);
SetRightMargin(r_margin); SetRightMargin(r_margin);
if (ln) @lasth = h
Ln(0);
# move cursor to specified position
if (ln == 0)
# go to the top-right of the cell
@x = x + w;
@y = y;
elsif (ln == 1)
# go to the beginning of the next line
@x = @l_margin;
@y = currentY;
elsif (ln == 2)
# go to the bottom-left of the cell (below)
@x = x;
@y = currentY;
end end
end end
alias_method :write_html_cell, :writeHTMLCell alias_method :write_html_cell, :writeHTMLCell
#
# Check html table tag position.
#
# @param array :table potision array
# @param int :current tr tag id number
# @param int :current td tag id number
# @access private
# @return int : next td_id position.
# value 0 mean that can use position.
#
def checkTableBlockingCellPosition(table, tr_id, td_id )
0.upto(tr_id) do |j|
0.upto(@t_cells[table][j].size - 1) do |i|
if @t_cells[table][j][i]['i0'] <= td_id and td_id <= @t_cells[table][j][i]['i1']
if @t_cells[table][j][i]['j0'] <= tr_id and tr_id <= @t_cells[table][j][i]['j1']
return @t_cells[table][j][i]['i1'] - td_id + 1;
end
end
end
end
return 0;
end
#
# Calculate opening tags.
#
# html table cell array : @t_cells
#
# i0: table cell start position
# i1: table cell end position
# j0: table row start position
# j1: table row end position
#
# +------+
# |i0,j0 |
# | i1,j1|
# +------+
#
# example html:
# <table>
# <tr><td></td><td></td><td></td></tr>
# <tr><td colspan=2></td><td></td></tr>
# <tr><td rowspan=2></td><td></td><td></td></tr>
# <tr><td></td><td></td></tr>
# </table>
#
# i: 0 1 2
# j+----+----+----+
# :|0,0 |1,0 |2,0 |
# 0| 0,0| 1,0| 2,0|
# +----+----+----+
# |0,1 |2,1 |
# 1| 1,1| 2,1|
# +----+----+----+
# |0,2 |1,2 |2,2 |
# 2| | 1,2| 2,2|
# + +----+----+
# | |1,3 |2,3 |
# 3| 0,3| 1,3| 2,3|
# +----+----+----+
#
# html table cell array :
# [[[i0=>0,j0=>0,i1=>0,j1=>0],[i0=>1,j0=>0,i1=>1,j1=>0],[i0=>2,j0=>0,i1=>2,j1=>0]],
# [[i0=>0,j0=>1,i1=>1,j1=>1],[i0=>2,j0=>1,i1=>2,j1=>1]],
# [[i0=>0,j0=>2,i1=>0,j1=>3],[i0=>1,j0=>2,i1=>1,j1=>2],[i0=>2,j0=>2,i1=>2,j1=>2]]
# [[i0=>1,j0=>3,i1=>1,j1=>3],[i0=>2,j0=>3,i1=>2,j1=>3]]]
#
# @param string :tag tag name (in upcase)
# @param string :attr tag attribute (in upcase)
# @access private
#
def openHTMLTagCalc(tag, attrs)
#Opening tag
case (tag)
when 'table'
@max_table_columns[@table_id] = 0;
@t_columns = 0;
@tr_id = -1;
when 'tr'
if @max_table_columns[@table_id] < @t_columns
@max_table_columns[@table_id] = @t_columns;
end
@t_columns = 0;
@tr_id += 1;
@td_id = -1;
@t_cells[@table_id].push []
when 'td', 'th'
@td_id += 1;
if attrs['colspan'].nil? or attrs['colspan'] == ''
colspan = 1;
else
colspan = attrs['colspan'].to_i;
end
if attrs['rowspan'].nil? or attrs['rowspan'] == ''
rowspan = 1;
else
rowspan = attrs['rowspan'].to_i;
end
i = 0;
while true
next_i_distance = checkTableBlockingCellPosition(@table_id, @tr_id, @td_id + i);
if next_i_distance == 0
@t_cells[@table_id][@tr_id].push "i0"=>@td_id + i, "j0"=>@tr_id, "i1"=>(@td_id + i + colspan - 1), "j1"=>@tr_id + rowspan - 1
break;
end
i += next_i_distance;
end
@t_columns += colspan;
end
end
#
# Calculate closing tags.
# @param string :tag tag name (in upcase)
# @access private
#
def closedHTMLTagCalc(tag)
#Closing tag
case (tag)
when 'table'
if @max_table_columns[@table_id] < @t_columns
@max_table_columns[@table_id] = @t_columns;
end
@table_id += 1;
@t_cells.push []
end
end
# #
# Process opening tags. # Process opening tags.
# @param string :tag tag name (in upcase) # @param string :tag tag name (in upcase)
@ -3501,20 +3771,56 @@ class TCPDF
def openHTMLTagHandler(tag, attrs, fill=0) def openHTMLTagHandler(tag, attrs, fill=0)
#Opening tag #Opening tag
case (tag) case (tag)
when 'pre'
@pre_state = true;
@l_margin += 5;
@r_margin += 5;
@x += 5;
when 'table' when 'table'
if @default_table_columns < @max_table_columns[@table_id]
@table_columns = @max_table_columns[@table_id];
else
@table_columns = @default_table_columns;
end
@l_margin += 5;
@r_margin += 5;
@x += 5;
if attrs['border'].nil? or attrs['border'] == '' if attrs['border'].nil? or attrs['border'] == ''
@tableborder = 0; @tableborder = 0;
else else
@tableborder = attrs['border']; @tableborder = attrs['border'];
end end
when 'tr', 'td', 'th' @tr_id = -1;
# SetStyle('b', true) if tag == 'th' @max_td_page[0] = @page;
@max_td_y[0] = @y;
when 'tr', 'td', 'th'
if tag == 'th'
SetStyle('b', true);
@tdalign = "C";
end
if ((!attrs['width'].nil?) and (attrs['width'] != '')) if ((!attrs['width'].nil?) and (attrs['width'] != ''))
@tdwidth = (attrs['width'].to_i/4); @tdwidth = (attrs['width'].to_i/4);
else else
@tdwidth = ((@w - @l_margin - @r_margin) / @default_table_columns); @tdwidth = ((@w - @l_margin - @r_margin) / @table_columns);
end end
if tag == 'tr'
@tr_id += 1;
@td_id = -1;
else
@td_id += 1;
@x = @l_margin + @tdwidth * @t_cells[@table_id][@tr_id][@td_id]['i0'];
end
if attrs['colspan'].nil? or attrs['border'] == ''
@colspan = 1;
else
@colspan = attrs['colspan'].to_i;
end
@tdwidth *= @colspan;
if ((!attrs['height'].nil?) and (attrs['height'] != '')) if ((!attrs['height'].nil?) and (attrs['height'] != ''))
@tdheight=(attrs['height'].to_i / @k); @tdheight=(attrs['height'].to_i / @k);
else else
@ -3538,17 +3844,14 @@ class TCPDF
@tdbegin=true; @tdbegin=true;
when 'hr' when 'hr'
Ln(); margin = 1;
if ((!attrs['width'].nil?) and (attrs['width'] != '')) if ((!attrs['width'].nil?) and (attrs['width'] != ''))
hrWidth = attrs['width']; hrWidth = attrs['width'];
else else
hrWidth = @w - @l_margin - @r_margin; hrWidth = @w - @l_margin - @r_margin - margin;
end end
x = GetX();
y = GetY();
SetLineWidth(0.2);
Line(x, y, x + hrWidth, y);
SetLineWidth(0.2); SetLineWidth(0.2);
Line(@x + margin, @y, @x + hrWidth, @y);
Ln(); Ln();
when 'strong' when 'strong'
@ -3557,6 +3860,12 @@ class TCPDF
when 'em' when 'em'
SetStyle('i', true); SetStyle('i', true);
when 'ins'
SetStyle('u', true);
when 'del'
SetStyle('d', true);
when 'b', 'i', 'u' when 'b', 'i', 'u'
SetStyle(tag, true); SetStyle(tag, true);
@ -3565,6 +3874,8 @@ class TCPDF
when 'img' when 'img'
if (!attrs['src'].nil?) 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 # replace relative path with real server path
attrs['src'] = attrs['src'].gsub(@@k_path_url_cache, @@k_path_cache); attrs['src'] = attrs['src'].gsub(@@k_path_url_cache, @@k_path_cache);
if (attrs['width'].nil?) if (attrs['width'].nil?)
@ -3577,37 +3888,70 @@ class TCPDF
Image(attrs['src'], GetX(),GetY(), pixelsToMillimeters(attrs['width']), pixelsToMillimeters(attrs['height'])); Image(attrs['src'], GetX(),GetY(), pixelsToMillimeters(attrs['width']), pixelsToMillimeters(attrs['height']));
#SetX(@img_rb_x); #SetX(@img_rb_x);
SetY(@img_rb_y); SetY(@img_rb_y);
=end
end end
when 'ul' when 'ul', 'ol'
@listordered = false; if @li_count == 0
@listcount = 0; Ln() if @prevquote_count == @quote_count; # insert Ln for keeping quote lines
@prevquote_count = @quote_count;
when 'ol' end
@listordered = true; if @li_state == true
@listcount = 0; Ln();
@li_state = false;
end
if tag == 'ul'
@list_ordered[@li_count] = false;
else
@list_ordered[@li_count] = true;
end
@list_count[@li_count] = 0;
@li_count += 1
when 'li' when 'li'
Ln(); Ln() if @li_state == true
if (@listordered) if (@list_ordered[@li_count - 1])
@listcount += 1 @list_count[@li_count - 1] += 1;
@lispacer = " " + (@listcount).to_s + ". "; @li_spacer = " " * @li_count + (@list_count[@li_count - 1]).to_s + ". ";
else else
#unordered list simbol #unordered list simbol
@lispacer = " - "; @li_spacer = " " * @li_count + "- ";
end end
Write(@lasth, @lispacer, '', fill); Write(@lasth, @spacer + @li_spacer, '', fill);
@li_state = true;
when 'blockquote', 'br' when 'blockquote'
if (@quote_count == 0)
SetStyle('i', true);
@l_margin += 5;
else
@l_margin += 5 / 2;
end
@x = @l_margin;
@quote_top[@quote_count] = @y;
@quote_page[@quote_count] = @page;
@quote_count += 1
when 'br'
Ln(); Ln();
if (@lispacer.length > 0)
@x += GetStringWidth(@lispacer); if (@li_spacer.length > 0)
@x += GetStringWidth(@li_spacer);
end end
when 'p' when 'p'
Ln(); Ln();
Ln(); 0.upto(@quote_count - 1) do |i|
if @quote_page[i] == @page;
if @quote_top[i] == @y - @lasth; # fix start line
@quote_top[i] = @y;
end
else
if @quote_page[i] == @page - 1;
@quote_page[i] = @page; # fix start line
@quote_top[i] = @t_margin;
end
end
end
when 'sup' when 'sup'
currentfont_size = @font_size; currentfont_size = @font_size;
@ -3648,6 +3992,7 @@ class TCPDF
@lasth = @font_size * @@k_cell_height_ratio; @lasth = @font_size * @@k_cell_height_ratio;
when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
Ln();
headsize = (4 - tag[1,1].to_f) * 2 headsize = (4 - tag[1,1].to_f) * 2
@tempfontsize = @font_size_pt; @tempfontsize = @font_size_pt;
SetFontSize(@font_size_pt + headsize); SetFontSize(@font_size_pt + headsize);
@ -3665,19 +4010,63 @@ class TCPDF
def closedHTMLTagHandler(tag) def closedHTMLTagHandler(tag)
#Closing tag #Closing tag
case (tag) case (tag)
when 'pre'
@pre_state = false;
@l_margin -= 5;
@r_margin -= 5;
@x = @l_margin;
Ln();
when 'td','th' when 'td','th'
@tdbegin = false; @tdbegin = false;
@tdwidth = 0; @tdwidth = 0;
@tdheight = 0; @tdheight = 0;
@tdalign = "L"; @tdalign = "L";
SetStyle('b', false);
@tdfill = 0; @tdfill = 0;
SetFillColor(@prevfill_color[0], @prevfill_color[1], @prevfill_color[2]); SetFillColor(@prevfill_color[0], @prevfill_color[1], @prevfill_color[2]);
when 'tr' when 'tr'
Ln(); @y = @max_td_y[@tr_id + 1];
@x = @l_margin;
@page = @max_td_page[@tr_id + 1];
when 'table' when 'table'
# Write Table Line
width = (@w - @l_margin - @r_margin) / @table_columns;
0.upto(@t_cells[@table_id].size - 1) do |j|
0.upto(@t_cells[@table_id][j].size - 1) do |i|
@page = @max_td_page[j]
i0=@t_cells[@table_id][j][i]['i0'];
j0=@t_cells[@table_id][j][i]['j0'];
i1=@t_cells[@table_id][j][i]['i1'];
j1=@t_cells[@table_id][j][i]['j1'];
Line(@l_margin + width * i0, @max_td_y[j0], @l_margin + width * (i1+1), @max_td_y[j0]) # top
if ( @page == @max_td_page[j1 + 1])
Line(@l_margin + width * i0, @max_td_y[j0], @l_margin + width * i0, @max_td_y[j1+1]) # left
Line(@l_margin + width * (i1+1), @max_td_y[j0], @l_margin + width * (i1+1), @max_td_y[j1+1]) # right
else
Line(@l_margin + width * i0, @max_td_y[j0], @l_margin + width * i0, @page_break_trigger) # left
Line(@l_margin + width * (i1+1), @max_td_y[j0], @l_margin + width * (i1+1), @page_break_trigger) # right
@page += 1;
while @page < @max_td_page[j1 + 1]
Line(@l_margin + width * i0, @t_margin, @l_margin + width * i0, @page_break_trigger) # left
Line(@l_margin + width * (i1+1), @t_margin, @l_margin + width * (i1+1), @page_break_trigger) # right
@page += 1;
end
Line(@l_margin + width * i0, @t_margin, @l_margin + width * i0, @max_td_y[j1+1]) # left
Line(@l_margin + width * (i1+1), @t_margin, @l_margin + width * (i1+1), @max_td_y[j1+1]) # right
end
Line(@l_margin + width * i0, @max_td_y[j1+1], @l_margin + width * (i1+1), @max_td_y[j1+1]) # bottom
end
end
@l_margin -= 5;
@r_margin -= 5;
@tableborder=0; @tableborder=0;
Ln();
@table_id += 1;
when 'strong' when 'strong'
SetStyle('b', false); SetStyle('b', false);
@ -3685,12 +4074,21 @@ class TCPDF
when 'em' when 'em'
SetStyle('i', false); SetStyle('i', false);
when 'ins'
SetStyle('u', false);
when 'del'
SetStyle('d', false);
when 'b', 'i', 'u' when 'b', 'i', 'u'
SetStyle(tag, false); SetStyle(tag, false);
when 'a' when 'a'
@href = nil; @href = nil;
when 'p'
Ln();
when 'sup' when 'sup'
currentfont_size = @font_size; currentfont_size = @font_size;
SetFontSize(@tempfontsize); SetFontSize(@tempfontsize);
@ -3725,14 +4123,47 @@ class TCPDF
#@text_color = @prevtext_color; #@text_color = @prevtext_color;
@lasth = @font_size * @@k_cell_height_ratio; @lasth = @font_size * @@k_cell_height_ratio;
when 'ul' when 'blockquote'
Ln(); @quote_count -= 1
if (@quote_page[@quote_count] == @page)
Line(@l_margin - 1, @quote_top[@quote_count], @l_margin - 1, @y) # quoto line
else
cur_page = @page;
cur_y = @y;
@page = @quote_page[@quote_count];
if (@quote_top[@quote_count] < @page_break_trigger)
Line(@l_margin - 1, @quote_top[@quote_count], @l_margin - 1, @page_break_trigger) # quoto line
end
@page += 1;
while @page < cur_page
Line(@l_margin - 1, @t_margin, @l_margin - 1, @page_break_trigger) # quoto line
@page += 1;
end
@y = cur_y;
Line(@l_margin - 1, @t_margin, @l_margin - 1, @y) # quoto line
end
if (@quote_count <= 0)
SetStyle('i', false);
@l_margin -= 5;
else
@l_margin -= 5 / 2;
end
@x = @l_margin;
Ln() if @quote_count == 0
when 'ol' when 'ul', 'ol'
@li_count -= 1
if @li_state == true
Ln(); Ln();
@li_state = false;
end
when 'li' when 'li'
@lispacer = ""; @li_spacer = "";
if @li_state == true
Ln();
@li_state = false;
end
when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
SetFontSize(@tempfontsize); SetFontSize(@tempfontsize);
@ -3741,6 +4172,16 @@ class TCPDF
Ln(); Ln();
@lasth = @font_size * @@k_cell_height_ratio; @lasth = @font_size * @@k_cell_height_ratio;
if tag == 'h1' or tag == 'h2' or tag == 'h3' or tag == 'h4'
margin = 1;
hrWidth = @w - @l_margin - @r_margin - margin;
if tag == 'h1' or tag == 'h2'
SetLineWidth(0.2);
else
SetLineWidth(0.1);
end
Line(@x + margin, @y, @x + hrWidth, @y);
end
end end
end end
@ -3752,11 +4193,16 @@ class TCPDF
# #
def SetStyle(tag, enable) def SetStyle(tag, enable)
#Modify style and select corresponding font #Modify style and select corresponding font
style=''; ['b', 'i', 'u', 'd'].each do |s|
['b', 'i', 'u'].each do |s| if tag.downcase == s
style << s if tag.downcase == s and enable if enable
@style << s if ! @style.include?(s)
else
@style = @style.gsub(s,'')
end end
SetFont('', style); end
end
SetFont('', @style);
end end
# #