rbpdf 1.18.3 → 1.18.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca9832fc7040403705b87fe67df785e4450cef00
4
- data.tar.gz: 31c6bee90f97b4ddc284f670b74eeb09c36d5a1d
3
+ metadata.gz: 5329616012db52c1743a298afb11aa835126a284
4
+ data.tar.gz: 6d92283c3fa55edaa59b68edab0b2db7f1311ae5
5
5
  SHA512:
6
- metadata.gz: aa5d54a75bba745946e90af5e31444efb9ce8a36e12cf6028d92508987dbd8e1d30bdfffe894677f98712921b90e7520d6009e36bb1a2085f9b632c0ec7c37eb
7
- data.tar.gz: c0b469c4c2544ea86297485535cda927c762019ed0b94d1661566b722a5febcd91d48bb5cea827c75337d0b6c8244415bdbc6a2baea7c6e2e686af4b4d80dd9f
6
+ metadata.gz: 74738ca0557dbe52a46177277d58b92ce1dc4e590fea0cfb6c4711e94f657db4359fe455aab918aeb67d55353fd4044d6bea4de05eaa7c1189b22e7daa05d918
7
+ data.tar.gz: f29d02d42ac883a7781314deed127c67216fc780b9df7d742cefeb8b839fc7e896fc2638a9459f6eb1010eb3a4b5e478450d523e6a55a9b55f045914efda2000
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ 1.18.4 2014-12-21
2
+ - utf8Bidi() Persion 0x200C(8204) and endedletter bug fixed.
3
+ - utf8Bidi() Bidirectional Algorithm X9/I1 rule BN(ZERO WIDTH NON-JOINER) bug fixed.
4
+ - utf8Bidi() Bidirectional Algorithm N1/N2 rule B/S/WS/ON bug fixed.
5
+ - utf8Bidi() Bidirectional Algorithm W2/W7 rule bug fixed.
6
+ - utf8Bidi() Bidirectional Algorithm N1/N2 rule multiple NIs bug fixed.
7
+ - RTL direction problem fixed. isRTLTextDir direction bug fixed.
8
+ - utf8Bidi() speed was improved.
9
+
1
10
  1.18.3 2014-12-06
2
11
  - fixed img and hr self html tag DOM problem.
3
12
  - fixed HTML table problem in writeHTMLCell function.
@@ -989,15 +989,33 @@ class RBPDF
989
989
 
990
990
  #
991
991
  # Return the current temporary RTL status
992
- # [@return boolean]
992
+ # [@return boolean] true: RTL, false: LTR
993
993
  # [@access public]
994
994
  # [@since 4.8.014 (2009-11-04)]
995
995
  #
996
996
  def isRTLTextDir()
997
- return (@rtl or (@tmprtl == 'R'))
997
+ if @tmprtl != false
998
+ return @tmprtl == 'R'
999
+ else
1000
+ return @rtl
1001
+ end
998
1002
  end
999
1003
  alias_method :is_rtl_text_dir, :isRTLTextDir
1000
1004
 
1005
+ #
1006
+ # Return the current text RTL status
1007
+ # [@return direction] 'R' : RTL, 'L' LTR
1008
+ # [@access protected]
1009
+ #
1010
+ def rtl_text_dir()
1011
+ if @tmprtl != false
1012
+ return @tmprtl # 'R' or 'L'
1013
+ else
1014
+ return @rtl ? 'R' : 'L'
1015
+ end
1016
+ end
1017
+ protected :rtl_text_dir
1018
+
1001
1019
  #
1002
1020
  # Set the last cell height.
1003
1021
  # [@param float :h] cell height.
@@ -2432,7 +2450,7 @@ class RBPDF
2432
2450
  # [@since 1.2]
2433
2451
  #
2434
2452
  def GetStringWidth(s, fontname='', fontstyle='', fontsize=0, getarray=false)
2435
- return GetArrStringWidth(utf8Bidi(UTF8StringToArray(s), s, @tmprtl), fontname, fontstyle, fontsize, getarray)
2453
+ return GetArrStringWidth(utf8Bidi(UTF8StringToArray(s), s, rtl_text_dir), fontname, fontstyle, fontsize, getarray)
2436
2454
  end
2437
2455
  alias_method :get_string_width, :GetStringWidth
2438
2456
 
@@ -3509,7 +3527,7 @@ class RBPDF
3509
3527
  txt2 = UTF8ToLatin1(txt2)
3510
3528
  else
3511
3529
  unicode = UTF8StringToArray(txt) # array of UTF-8 unicode values
3512
- unicode = utf8Bidi(unicode, '', @tmprtl)
3530
+ unicode = utf8Bidi(unicode, '', rtl_text_dir)
3513
3531
  if @@k_thai_topchars and @@k_thai_topchars == true
3514
3532
  # ---- Fix for bug #2977340 "Incorrect Thai characters position arrangement" ----
3515
3533
  # NOTE: this doesn't work with HTML justification
@@ -4078,7 +4096,7 @@ class RBPDF
4078
4096
  lines = 1
4079
4097
  sum = 0
4080
4098
  chars = UTF8StringToArray(txt)
4081
- chars = utf8Bidi(chars, txt, @tmprtl)
4099
+ chars = utf8Bidi(chars, txt, rtl_text_dir)
4082
4100
  charsWidth = GetArrStringWidth(chars, '', '', 0, true)
4083
4101
  if @rtl
4084
4102
  charsWidth.reverse!
@@ -4228,7 +4246,7 @@ class RBPDF
4228
4246
  end
4229
4247
 
4230
4248
  # check if string contains RTL text
4231
- if arabic or (@tmprtl == 'R') or (txt =~ @@k_re_pattern_rtl)
4249
+ if arabic or isRTLTextDir or (txt =~ @@k_re_pattern_rtl)
4232
4250
  rtlmode = true
4233
4251
  else
4234
4252
  rtlmode = false
@@ -4303,7 +4321,7 @@ class RBPDF
4303
4321
  startx = @x
4304
4322
  tmparr = chars[j, i - j]
4305
4323
  if rtlmode
4306
- tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
4324
+ tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
4307
4325
  end
4308
4326
  linew = GetArrStringWidth(tmparr)
4309
4327
  tmparr = ''
@@ -4362,7 +4380,7 @@ class RBPDF
4362
4380
  if ((@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')) and arabic
4363
4381
  # with bidirectional algorithm some chars may be changed affecting the line length
4364
4382
  # *** very slow ***
4365
- l = GetArrStringWidth(utf8Bidi(chars[j,i-j], '', @tmprtl))
4383
+ l = GetArrStringWidth(utf8Bidi(chars[j,i-j], '', rtl_text_dir))
4366
4384
  else
4367
4385
  l += GetCharWidth(c)
4368
4386
  end
@@ -4385,7 +4403,7 @@ class RBPDF
4385
4403
  startx = @x
4386
4404
  tmparr = chars[j, i - j]
4387
4405
  if rtlmode
4388
- tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
4406
+ tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
4389
4407
  end
4390
4408
  linew = GetArrStringWidth(tmparr)
4391
4409
  tmparr = ''
@@ -4439,7 +4457,7 @@ class RBPDF
4439
4457
  startx = @x
4440
4458
  tmparr = chars[j, sep + endspace - j]
4441
4459
  if rtlmode
4442
- tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
4460
+ tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
4443
4461
  end
4444
4462
  linew = GetArrStringWidth(tmparr)
4445
4463
  tmparr = ''
@@ -4514,7 +4532,7 @@ class RBPDF
4514
4532
  startx = @x
4515
4533
  tmparr = chars[j, nb - j]
4516
4534
  if rtlmode
4517
- tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
4535
+ tmparr = utf8Bidi(tmparr, tmpstr, rtl_text_dir)
4518
4536
  end
4519
4537
  linew = GetArrStringWidth(tmparr)
4520
4538
  tmparr = ''
@@ -5592,8 +5610,8 @@ protected
5592
5610
  if @is_unicode
5593
5611
  alias_b = escape(UTF8ToLatin1(@alias_nb_pages))
5594
5612
  alias_bu = escape(UTF8ToLatin1('{' + @alias_nb_pages + '}'))
5595
- alias_c = escape(utf8StrRev(@alias_nb_pages, false, @tmprtl))
5596
- alias_cu = escape(utf8StrRev('{' + @alias_nb_pages + '}', false, @tmprtl))
5613
+ alias_c = escape(utf8StrRev(@alias_nb_pages, false, rtl_text_dir))
5614
+ alias_cu = escape(utf8StrRev('{' + @alias_nb_pages + '}', false, rtl_text_dir))
5597
5615
  end
5598
5616
  end
5599
5617
  if @alias_num_page
@@ -5602,8 +5620,8 @@ protected
5602
5620
  if @is_unicode
5603
5621
  alias_pb = escape(UTF8ToLatin1(@alias_num_page))
5604
5622
  alias_pbu = escape(UTF8ToLatin1('{' + @alias_num_page + '}'))
5605
- alias_pc = escape(utf8StrRev(@alias_num_page, false, @tmprtl))
5606
- alias_pcu = escape(utf8StrRev('{' + @alias_num_page + '}', false, @tmprtl))
5623
+ alias_pc = escape(utf8StrRev(@alias_num_page, false, rtl_text_dir))
5624
+ alias_pcu = escape(utf8StrRev('{' + @alias_num_page + '}', false, rtl_text_dir))
5607
5625
  end
5608
5626
  end
5609
5627
  pagegroupnum = 0
@@ -5624,8 +5642,8 @@ protected
5624
5642
  if @is_unicode
5625
5643
  alias_gb = escape(UTF8ToLatin1(k))
5626
5644
  alias_gbu = escape(UTF8ToLatin1('{' + k + '}'))
5627
- alias_gc = escape(utf8StrRev(k.dup, false, @tmprtl))
5628
- alias_gcu = escape(utf8StrRev('{' + k + '}', false, @tmprtl))
5645
+ alias_gc = escape(utf8StrRev(k.dup, false, rtl_text_dir))
5646
+ alias_gcu = escape(utf8StrRev('{' + k + '}', false, rtl_text_dir))
5629
5647
  end
5630
5648
  temppage = temppage.gsub(alias_gau, vu)
5631
5649
  if @is_unicode
@@ -5644,8 +5662,8 @@ protected
5644
5662
  if @is_unicode
5645
5663
  alias_pgb = escape(UTF8ToLatin1(pk))
5646
5664
  alias_pgbu = escape(UTF8ToLatin1('{' + pk + '}'))
5647
- alias_pgc = escape(utf8StrRev(pk, false, @tmprtl))
5648
- alias_pgcu = escape(utf8StrRev('{' + pk + '}', false, @tmprtl))
5665
+ alias_pgc = escape(utf8StrRev(pk, false, rtl_text_dir))
5666
+ alias_pgcu = escape(utf8StrRev('{' + pk + '}', false, rtl_text_dir))
5649
5667
  end
5650
5668
  temppage = temppage.gsub(alias_pgau, pvu)
5651
5669
  if @is_unicode
@@ -7497,7 +7515,7 @@ protected
7497
7515
  s = UTF8ToLatin1(s)
7498
7516
  else
7499
7517
  # Convert string to UTF-16BE and reverse RTL language
7500
- s = utf8StrRev(s, false, @tmprtl)
7518
+ s = utf8StrRev(s, false, rtl_text_dir)
7501
7519
  end
7502
7520
  end
7503
7521
  return escape(s);
@@ -9048,7 +9066,7 @@ public
9048
9066
  else
9049
9067
  # P2. In each paragraph, find the first character of type L, AL, or R.
9050
9068
  # P3. If a character is found in P2 and it is of type AL or R, then set the paragraph embedding level to one; otherwise, set it to zero.
9051
- 0.upto(numchars -1) do |i|
9069
+ numchars.times do |i|
9052
9070
  type = @@unicode[ta[i]]
9053
9071
  if type == 'L'
9054
9072
  pel = 0
@@ -9074,63 +9092,78 @@ public
9074
9092
 
9075
9093
  # X1. Begin by setting the current embedding level to the paragraph embedding level. Set the directional override status to neutral. Process each character iteratively, applying rules X2 through X9. Only embedding levels from 0 to 61 are valid in this phase.
9076
9094
  # In the resolution of levels in rules I1 and I2, the maximum embedding level of 62 can be reached.
9077
- 0.upto(numchars-1) do |i|
9078
- if ta[i] == @@k_rle
9095
+ reg_KRP = /^(@@k_rle|@@k_lre|@@k_rlo|@@k_lro|@@k_pdf)$/
9096
+ reg_KR = /^(@@k_rle|@@k_lre|@@k_rlo|@@k_lro)$/
9097
+ numchars.times do |i|
9098
+ if ta[i] !~ reg_KRP
9099
+ # X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
9100
+ # a. Set the level of the current character to the current embedding level.
9101
+ # b. Whenever the directional override status is not neutral, reset the current character type to the directional override status.
9102
+ if dos != 'N'
9103
+ chardir = dos
9104
+ else
9105
+ chardir = @@unicode[ta[i]]
9106
+ chardir = 'L' if chardir.nil?
9107
+ end
9108
+ # stores string characters and other information
9109
+ chardata << {:char => ta[i], :level => cel, :type => chardir, :sor => sor, :eor => eor}
9110
+ next
9111
+ end
9112
+
9113
+ case ta[i]
9114
+ when @@k_rle
9079
9115
  # X2. With each RLE, compute the least greater odd embedding level.
9080
9116
  # a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral.
9081
9117
  # b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
9082
9118
  next_level = cel + (cel % 2) + 1
9083
9119
  if next_level < 62
9084
- remember.push :num => @@k_rle, :cel => cel, :dos => dos
9120
+ remember << {:num => @@k_rle, :cel => cel, :dos => dos}
9085
9121
  cel = next_level
9086
9122
  dos = 'N'
9087
9123
  sor = eor
9088
9124
  eor = (cel % 2 == 1) ? 'R' : 'L'
9089
9125
  end
9090
- elsif ta[i] == @@k_lre
9126
+ when @@k_lre
9091
9127
  # X3. With each LRE, compute the least greater even embedding level.
9092
9128
  # a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to neutral.
9093
9129
  # b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
9094
9130
  next_level = cel + 2 - (cel % 2)
9095
9131
  if next_level < 62
9096
- remember.push :num => @@k_lre, :cel => cel, :dos => dos
9132
+ remember << {:num => @@k_lre, :cel => cel, :dos => dos}
9097
9133
  cel = next_level
9098
9134
  dos = 'N'
9099
9135
  sor = eor
9100
9136
  eor = (cel % 2 == 1) ? 'R' : 'L'
9101
9137
  end
9102
- elsif ta[i] == @@k_rlo
9138
+ when @@k_rlo
9103
9139
  # X4. With each RLO, compute the least greater odd embedding level.
9104
9140
  # a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to right-to-left.
9105
9141
  # b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
9106
9142
  next_level = cel + (cel % 2) + 1
9107
9143
  if next_level < 62
9108
- remember.push :num => @@k_rlo, :cel => cel, :dos => dos
9144
+ remember << {:num => @@k_rlo, :cel => cel, :dos => dos}
9109
9145
  cel = next_level
9110
9146
  dos = 'R'
9111
9147
  sor = eor
9112
9148
  eor = (cel % 2 == 1) ? 'R' : 'L'
9113
9149
  end
9114
- elsif ta[i] == @@k_lro
9150
+ when @@k_lro
9115
9151
  # X5. With each LRO, compute the least greater even embedding level.
9116
9152
  # a. If this new level would be valid, then this embedding code is valid. Remember (push) the current embedding level and override status. Reset the current level to this new level, and reset the override status to left-to-right.
9117
9153
  # b. If the new level would not be valid, then this code is invalid. Do not change the current level or override status.
9118
9154
  next_level = cel + 2 - (cel % 2)
9119
9155
  if next_level < 62
9120
- remember.push :num => @@k_lro, :cel => cel, :dos => dos
9156
+ remember << {:num => @@k_lro, :cel => cel, :dos => dos}
9121
9157
  cel = next_level
9122
9158
  dos = 'L'
9123
9159
  sor = eor
9124
9160
  eor = (cel % 2 == 1) ? 'R' : 'L'
9125
9161
  end
9126
- elsif ta[i] == @@k_pdf
9162
+ when @@k_pdf
9127
9163
  # X7. With each PDF, determine the matching embedding or override code. If there was a valid matching code, restore (pop) the last remembered (pushed) embedding level and directional override.
9128
9164
  if remember.length
9129
9165
  last = remember.length - 1
9130
- if (remember[last][:num] == @@k_rle) or
9131
- (remember[last][:num] == @@k_lre) or
9132
- (remember[last][:num] == @@k_rlo) or
9133
- (remember[last][:num] == @@k_lro)
9166
+ if remember[last][:num] =~ reg_KR
9134
9167
  match = remember.pop
9135
9168
  cel = match[:cel]
9136
9169
  dos = match[:dos]
@@ -9138,25 +9171,6 @@ public
9138
9171
  eor = ((cel > match[:cel] ? cel : match[:cel]) % 2 == 1) ? 'R' : 'L'
9139
9172
  end
9140
9173
  end
9141
- elsif (ta[i] != @@k_rle) and
9142
- (ta[i] != @@k_lre) and
9143
- (ta[i] != @@k_rlo) and
9144
- (ta[i] != @@k_lro) and
9145
- (ta[i] != @@k_pdf)
9146
- # X6. For all types besides RLE, LRE, RLO, LRO, and PDF:
9147
- # a. Set the level of the current character to the current embedding level.
9148
- # b. Whenever the directional override status is not neutral, reset the current character type to the directional override status.
9149
- if dos != 'N'
9150
- chardir = dos
9151
- else
9152
- if !@@unicode[ta[i]].nil?
9153
- chardir = @@unicode[ta[i]]
9154
- else
9155
- chardir = 'L'
9156
- end
9157
- end
9158
- # stores string characters and other information
9159
- chardata.push :char => ta[i], :level => cel, :type => chardir, :sor => sor, :eor => eor
9160
9174
  end
9161
9175
  end # end for each char
9162
9176
 
@@ -9172,7 +9186,7 @@ public
9172
9186
  # W1. Examine each nonspacing mark (NSM) in the level run, and change the type of the NSM to the type of the previous character. If the NSM is at the start of the level run, it will get the type of sor.
9173
9187
  prevlevel = -1 # track level changes
9174
9188
  levcount = 0 # counts consecutive chars at the same level
9175
- 0.upto(numchars-1) do |i|
9189
+ numchars.times do |i|
9176
9190
  if chardata[i][:type] == 'NSM'
9177
9191
  if levcount
9178
9192
  chardata[i][:type] = chardata[i][:sor]
@@ -9191,8 +9205,8 @@ public
9191
9205
  # W2. Search backward from each instance of a European number until the first strong type (R, L, AL, or sor) is found. If an AL is found, change the type of the European number to Arabic number.
9192
9206
  prevlevel = -1
9193
9207
  levcount = 0
9194
- 0.upto(numchars-1) do |i|
9195
- if chardata[i][:char] == 'EN'
9208
+ numchars.times do |i|
9209
+ if chardata[i][:type] == 'EN'
9196
9210
  levcount.downto(0) do |j|
9197
9211
  if chardata[j][:type] == 'AL'
9198
9212
  chardata[i][:type] = 'AN'
@@ -9210,7 +9224,7 @@ public
9210
9224
  end
9211
9225
 
9212
9226
  # W3. Change all ALs to R.
9213
- 0.upto(numchars-1) do |i|
9227
+ numchars.times do |i|
9214
9228
  if chardata[i][:type] == 'AL'
9215
9229
  chardata[i][:type] = 'R'
9216
9230
  end
@@ -9219,7 +9233,7 @@ public
9219
9233
  # W4. A single European separator between two European numbers changes to a European number. A single common separator between two numbers of the same type changes to that type.
9220
9234
  prevlevel = -1
9221
9235
  levcount = 0
9222
- 0.upto(numchars-1) do |i|
9236
+ numchars.times do |i|
9223
9237
  if (levcount > 0) and (i+1 < numchars) and (chardata[i+1][:level] == prevlevel)
9224
9238
  if (chardata[i][:type] == 'ES') and (chardata[i-1][:type] == 'EN') and (chardata[i+1][:type] == 'EN')
9225
9239
  chardata[i][:type] = 'EN'
@@ -9240,7 +9254,7 @@ public
9240
9254
  # W5. A sequence of European terminators adjacent to European numbers changes to all European numbers.
9241
9255
  prevlevel = -1
9242
9256
  levcount = 0
9243
- 0.upto(numchars-1) do |i|
9257
+ numchars.times do |i|
9244
9258
  if chardata[i][:type] == 'ET'
9245
9259
  if (levcount > 0) and (chardata[i-1][:type] == 'EN')
9246
9260
  chardata[i][:type] = 'EN'
@@ -9268,8 +9282,9 @@ public
9268
9282
  # W6. Otherwise, separators and terminators change to Other Neutral.
9269
9283
  prevlevel = -1
9270
9284
  levcount = 0
9271
- 0.upto(numchars-1) do |i|
9272
- if (chardata[i][:type] == 'ET') or (chardata[i][:type] == 'ES') or (chardata[i][:type] == 'CS')
9285
+ reg_ET_ES_CS = /^(ET|ES|CS)$/
9286
+ numchars.times do |i|
9287
+ if chardata[i][:type] =~ reg_ET_ES_CS
9273
9288
  chardata[i][:type] = 'ON'
9274
9289
  end
9275
9290
  if chardata[i][:level] != prevlevel
@@ -9283,8 +9298,8 @@ public
9283
9298
  # W7. Search backward from each instance of a European number until the first strong type (R, L, or sor) is found. If an L is found, then change the type of the European number to L.
9284
9299
  prevlevel = -1
9285
9300
  levcount = 0
9286
- 0.upto(numchars-1) do |i|
9287
- if chardata[i][:char] == 'EN'
9301
+ numchars.times do |i|
9302
+ if chardata[i][:type] == 'EN'
9288
9303
  levcount.downto(0) do |j|
9289
9304
  if chardata[j][:type] == 'L'
9290
9305
  chardata[i][:type] = 'L'
@@ -9304,45 +9319,62 @@ public
9304
9319
  # N1. A sequence of neutrals takes the direction of the surrounding strong text if the text on both sides has the same direction. European and Arabic numbers act as if they were R in terms of their influence on neutrals. Start-of-level-run (sor) and end-of-level-run (eor) are used at level run boundaries.
9305
9320
  prevlevel = -1
9306
9321
  levcount = 0
9307
- 0.upto(numchars-1) do |i|
9308
- if (levcount > 0) and (i+1 < numchars) and (chardata[i+1][:level] == prevlevel)
9309
- if (chardata[i][:type] == 'N') and (chardata[i-1][:type] == 'L') and (chardata[i+1][:type] == 'L')
9310
- chardata[i][:type] = 'L'
9311
- elsif (chardata[i][:type] == 'N') and
9312
- ((chardata[i-1][:type] == 'R') or (chardata[i-1][:type] == 'EN') or (chardata[i-1][:type] == 'AN')) and
9313
- ((chardata[i+1][:type] == 'R') or (chardata[i+1][:type] == 'EN') or (chardata[i+1][:type] == 'AN'))
9314
- chardata[i][:type] = 'R'
9315
- elsif chardata[i][:type] == 'N'
9316
- # N2. Any remaining neutrals take the embedding direction
9317
- chardata[i][:type] = chardata[i][:sor]
9318
- end
9319
- elsif (levcount == 0) and (i+1 < numchars) and (chardata[i+1][:level] == prevlevel)
9320
- # first char
9321
- if (chardata[i][:type] == 'N') and (chardata[i][:sor] == 'L') and (chardata[i+1][:type] == 'L')
9322
- chardata[i][:type] = 'L'
9323
- elsif (chardata[i][:type] == 'N') and
9324
- ((chardata[i][:sor] == 'R') or (chardata[i][:sor] == 'EN') or (chardata[i][:sor] == 'AN')) and
9325
- ((chardata[i+1][:type] == 'R') or (chardata[i+1][:type] == 'EN') or (chardata[i+1][:type] == 'AN'))
9326
- chardata[i][:type] = 'R'
9327
- elsif chardata[i][:type] == 'N'
9328
- # N2. Any remaining neutrals take the embedding direction
9329
- chardata[i][:type] = chardata[i][:sor]
9330
- end
9331
- elsif (levcount > 0) and ((i+1 == numchars) or ((i+1 < numchars) and (chardata[i+1][:level] != prevlevel)))
9332
- # last char
9333
- if (chardata[i][:type] == 'N') and (chardata[i-1][:type] == 'L') and (chardata[i][:eor] == 'L')
9334
- chardata[i][:type] = 'L'
9335
- elsif (chardata[i][:type] == 'N') and
9336
- ((chardata[i-1][:type] == 'R') or (chardata[i-1][:type] == 'EN') or (chardata[i-1][:type] == 'AN')) and
9337
- ((chardata[i][:eor] == 'R') or (chardata[i][:eor] == 'EN') or (chardata[i][:eor] == 'AN'))
9338
- chardata[i][:type] = 'R'
9339
- elsif chardata[i][:type] == 'N'
9322
+ reg_NI = /^(B|S|WS|ON)$/
9323
+ reg_R_EN_AN = /^(R|EN|AN)$/
9324
+ reg_EN_AN = /^(EN|AN)$/
9325
+ ni = nil
9326
+ numchars.times do |i|
9327
+ if (chardata[i][:type] =~ reg_NI)
9328
+ if (levcount > 0) and (i+1 < numchars) and (chardata[i+1][:level] == prevlevel)
9329
+ if !ni.nil? and ni > i
9330
+ next_non_space_char = chardata[ni][:type]
9331
+ else
9332
+ ni = chardata[i+1..-1].index {|item| item[:type] !~ reg_NI}
9333
+ unless ni.nil?
9334
+ ni += i+1
9335
+ next_non_space_char = chardata[ni][:type]
9336
+ end
9337
+ end
9338
+ if (chardata[i-1][:type] == 'L') and (next_non_space_char == 'L')
9339
+ chardata[i][:type] = 'L'
9340
+ elsif ((chardata[i-1][:type] == 'R') and (next_non_space_char =~ reg_R_EN_AN) or
9341
+ (chardata[i-1][:type] =~ reg_EN_AN) and (next_non_space_char == 'R'))
9342
+ chardata[i][:type] = 'R'
9343
+ else
9344
+ # N2. Any remaining neutrals take the embedding direction
9345
+ chardata[i][:type] = chardata[i][:sor]
9346
+ end
9347
+ elsif (levcount == 0) and (i+1 < numchars) and (chardata[i+1][:level] == prevlevel)
9348
+ ni = chardata[i+1..-1].index {|item| item[:type] !~ reg_NI}
9349
+ unless ni.nil?
9350
+ ni += i+1
9351
+ next_non_space_char = chardata[ni][:type]
9352
+ end
9353
+ # first char
9354
+ if (chardata[i][:sor] == 'L') and (next_non_space_char == 'L')
9355
+ chardata[i][:type] = 'L'
9356
+ elsif ((chardata[i][:sor] == 'R') and (next_non_space_char =~ reg_R_EN_AN) or
9357
+ (chardata[i][:sor] =~ reg_EN_AN) and (next_non_space_char == 'R'))
9358
+ chardata[i][:type] = 'R'
9359
+ else
9360
+ # N2. Any remaining neutrals take the embedding direction
9361
+ chardata[i][:type] = chardata[i][:sor]
9362
+ end
9363
+ elsif (levcount > 0) and ((i+1 == numchars) or ((i+1 < numchars) and (chardata[i+1][:level] != prevlevel)))
9364
+ # last char
9365
+ if (chardata[i-1][:type] == 'L') and (chardata[i][:eor] == 'L')
9366
+ chardata[i][:type] = 'L'
9367
+ elsif ((chardata[i-1][:type] == 'R') and (chardata[i][:eor] =~ reg_R_EN_AN) or
9368
+ (chardata[i-1][:type] =~ reg_EN_AN) and (chardata[i][:eor] == 'R'))
9369
+ chardata[i][:type] = 'R'
9370
+ else
9371
+ # N2. Any remaining neutrals take the embedding direction
9372
+ chardata[i][:type] = chardata[i][:sor]
9373
+ end
9374
+ else
9340
9375
  # N2. Any remaining neutrals take the embedding direction
9341
9376
  chardata[i][:type] = chardata[i][:sor]
9342
9377
  end
9343
- elsif chardata[i][:type] == 'N'
9344
- # N2. Any remaining neutrals take the embedding direction
9345
- chardata[i][:type] = chardata[i][:sor]
9346
9378
  end
9347
9379
  if chardata[i][:level] != prevlevel
9348
9380
  levcount = 0
@@ -9354,19 +9386,26 @@ public
9354
9386
 
9355
9387
  # I1. For all characters with an even (left-to-right) embedding direction, those of type R go up one level and those of type AN or EN go up two levels.
9356
9388
  # I2. For all characters with an odd (right-to-left) embedding direction, those of type L, EN or AN go up one level.
9357
- 0.upto(numchars-1) do |i|
9389
+ prevlevel = -1
9390
+ reg_L_AN_EN = /^(L|AN|EN)$/
9391
+ reg_AN_EN = /^(AN|EN)$/
9392
+
9393
+ numchars.times do |i|
9358
9394
  odd = chardata[i][:level] % 2
9359
- if odd == 1
9360
- if (chardata[i][:type] == 'L') or (chardata[i][:type] == 'AN') or (chardata[i][:type] == 'EN')
9395
+ if odd == 1 # I2.
9396
+ if chardata[i][:type] =~ reg_L_AN_EN
9361
9397
  chardata[i][:level] += 1
9362
9398
  end
9363
- else
9399
+ else # I1.
9364
9400
  if chardata[i][:type] == 'R'
9365
9401
  chardata[i][:level] += 1
9366
- elsif (chardata[i][:type] == 'AN') or (chardata[i][:type] == 'EN')
9402
+ elsif chardata[i][:type] == 'BN' and prevlevel != -1
9403
+ chardata[i][:level] = prevlevel
9404
+ elsif chardata[i][:type] =~ reg_AN_EN
9367
9405
  chardata[i][:level] += 2
9368
9406
  end
9369
9407
  end
9408
+ prevlevel = chardata[i][:level]
9370
9409
  maxlevel = [chardata[i][:level],maxlevel].max
9371
9410
  end
9372
9411
 
@@ -9375,13 +9414,14 @@ public
9375
9414
  # 2. Paragraph separators,
9376
9415
  # 3. Any sequence of whitespace characters preceding a segment separator or paragraph separator, and
9377
9416
  # 4. Any sequence of white space characters at the end of the line.
9378
- 0.upto(numchars-1) do |i|
9379
- if (chardata[i][:type] == 'B') or (chardata[i][:type] == 'S')
9417
+ reg_B_S = /^(B|S)$/
9418
+ numchars.times do |i|
9419
+ if chardata[i][:type] =~ reg_B_S
9380
9420
  chardata[i][:level] = pel
9381
9421
  elsif chardata[i][:type] == 'WS'
9382
9422
  j = i+1
9383
9423
  while j < numchars
9384
- if ((chardata[j][:type] == 'B') or (chardata[j][:type] == 'S')) or
9424
+ if (chardata[j][:type] =~ reg_B_S) or
9385
9425
  ((j == numchars-1) and (chardata[j][:type] == 'WS'))
9386
9426
  chardata[i][:level] = pel
9387
9427
  break
@@ -9402,16 +9442,18 @@ public
9402
9442
  laaletter = false
9403
9443
  charAL = []
9404
9444
  x = 0
9405
- 0.upto(numchars-1) do |i|
9406
- if (@@unicode[chardata[i][:char]] == 'AL') or (chardata[i][:char] == 32) or (chardata[i]['char'] == 8204) # 4.0.008 - Arabic shaping for "Zero-Width Non-Joiner" character (U+200C) was fixed.
9407
- charAL[x] = chardata[i]
9445
+ numchars.times do |i|
9446
+ c = chardata[i][:char]
9447
+ if (@@unicode[c] == 'AL') or (c == 32) or (c == 8204) # Unicode Character 'ZERO WIDTH NON-JOINER' (U+200C)
9448
+ charAL[x] = chardata[i].dup
9408
9449
  charAL[x][:i] = i
9409
9450
  chardata[i][:x] = x
9410
9451
  x += 1
9411
9452
  end
9412
9453
  end
9413
9454
  numAL = x
9414
- 0.upto(numchars-1) do |i|
9455
+ reg_AL_NSM = /^(AL|NSM)$/
9456
+ numchars.times do |i|
9415
9457
  thischar = chardata[i]
9416
9458
  if i > 0
9417
9459
  prevchar = chardata[i-1]
@@ -9449,8 +9491,8 @@ public
9449
9491
  laaletter = false
9450
9492
  end
9451
9493
  if (prevchar != false) and (nextchar != false) and
9452
- ((@@unicode[prevchar[:char]] == 'AL') or (@@unicode[prevchar[:char]] == 'NSM')) and
9453
- ((@@unicode[nextchar[:char]] == 'AL') or (@@unicode[nextchar[:char]] == 'NSM')) and
9494
+ (@@unicode[prevchar[:char]] =~ reg_AL_NSM) and
9495
+ (@@unicode[nextchar[:char]] =~ reg_AL_NSM) and
9454
9496
  (nextchar[:type] == thischar[:type]) and
9455
9497
  (nextchar[:char] != 1567)
9456
9498
  # medial
@@ -9466,7 +9508,7 @@ public
9466
9508
  end
9467
9509
  end
9468
9510
  elsif (nextchar != false) and
9469
- ((@@unicode[nextchar[:char]] == 'AL') or (@@unicode[nextchar[:char]] == 'NSM')) and
9511
+ (@@unicode[nextchar[:char]] =~ reg_AL_NSM) and
9470
9512
  (nextchar[:type] == thischar[:type]) and
9471
9513
  (nextchar[:char] != 1567)
9472
9514
  if !arabicarr[thischar[:char]].nil? and !arabicarr[thischar[:char]][2].nil?
@@ -9474,7 +9516,7 @@ public
9474
9516
  chardata2[i][:char] = arabicarr[thischar[:char]][2]
9475
9517
  end
9476
9518
  elsif ((prevchar != false) and
9477
- ((@@unicode[prevchar[:char]] == 'AL') or (@@unicode[prevchar[:char]] == 'NSM')) and
9519
+ (@@unicode[prevchar[:char]] =~ reg_AL_NSM) and
9478
9520
  (prevchar[:type] == thischar[:type])) or
9479
9521
  ((nextchar != false) and (nextchar[:char] == 1567))
9480
9522
  # final
@@ -9516,7 +9558,7 @@ public
9516
9558
  # Putting the combining mark and shadda in the same glyph allows us to avoid the two marks overlapping each other in an illegible manner.
9517
9559
  #
9518
9560
  cw = @current_font['cw']
9519
- 0.upto(numchars-2) do |i|
9561
+ (numchars-1).times do |i|
9520
9562
  if (chardata2[i][:char] == 1617) and !@@diacritics[chardata2[i+1][:char]].nil?
9521
9563
  # check if the subtitution font is defined on current font
9522
9564
  unless cw[@@diacritics[chardata2[i+1][:char]]].nil?
@@ -9544,14 +9586,15 @@ public
9544
9586
  ordarray = []
9545
9587
  revarr = []
9546
9588
  onlevel = false
9547
- 0.upto(numchars-1) do |i|
9589
+ numchars.times do |i|
9548
9590
  if chardata[i][:level] >= j
9549
9591
  onlevel = true
9550
- unless @@unicode_mirror[chardata[i][:char]].nil?
9592
+ um = @@unicode_mirror[chardata[i][:char]]
9593
+ if um
9551
9594
  # L4. A character is depicted by a mirrored glyph if and only if (a) the resolved directionality of that character is R, and (b) the Bidi_Mirrored property value of that character is true.
9552
- chardata[i][:char] = @@unicode_mirror[chardata[i][:char]]
9595
+ chardata[i][:char] = um
9553
9596
  end
9554
- revarr.push chardata[i]
9597
+ revarr << chardata[i]
9555
9598
  else
9556
9599
  if onlevel
9557
9600
  revarr.reverse!
@@ -9559,7 +9602,7 @@ public
9559
9602
  revarr = []
9560
9603
  onlevel = false
9561
9604
  end
9562
- ordarray.push chardata[i]
9605
+ ordarray << chardata[i]
9563
9606
  end
9564
9607
  end
9565
9608
  if onlevel
@@ -9570,7 +9613,7 @@ public
9570
9613
  end
9571
9614
 
9572
9615
  ordarray = []
9573
- 0.upto(numchars-1) do |i|
9616
+ numchars.times do |i|
9574
9617
  ordarray.push chardata[i][:char]
9575
9618
  end
9576
9619
 
@@ -14124,8 +14167,8 @@ public
14124
14167
  if @is_unicode
14125
14168
  alias_b = escape(UTF8ToLatin1(k))
14126
14169
  alias_bu = escape(UTF8ToLatin1(ku))
14127
- alias_c = escape(utf8StrRev(k, false, @tmprtl))
14128
- alias_cu = escape(utf8StrRev(ku, false, @tmprtl))
14170
+ alias_c = escape(utf8StrRev(k, false, rtl_text_dir))
14171
+ alias_cu = escape(utf8StrRev(ku, false, rtl_text_dir))
14129
14172
  end
14130
14173
  if n >= page
14131
14174
  np = n + numpages
@@ -14226,8 +14269,8 @@ public
14226
14269
  if @is_unicode
14227
14270
  alias_b = escape(UTF8ToLatin1(k))
14228
14271
  alias_bu = escape(UTF8ToLatin1(ku))
14229
- alias_c = escape(utf8StrRev(k, false, @tmprtl))
14230
- alias_cu = escape(utf8StrRev(ku, false, @tmprtl))
14272
+ alias_c = escape(utf8StrRev(k, false, rtl_text_dir))
14273
+ alias_cu = escape(utf8StrRev(ku, false, rtl_text_dir))
14231
14274
  end
14232
14275
  if n >= page
14233
14276
  np = n + numpages
@@ -1,3 +1,3 @@
1
1
  module Rbpdf
2
- VERSION = "1.18.3"
2
+ VERSION = "1.18.4"
3
3
  end
@@ -12,6 +12,42 @@ class RbpdfTest < ActiveSupport::TestCase
12
12
  def cache_utf8_string_to_array(str)
13
13
  @cache_utf8_string_to_array[str]
14
14
  end
15
+ def rtl_text_dir
16
+ super
17
+ end
18
+ end
19
+
20
+ test "RTL test" do
21
+ pdf = MYPDF.new
22
+
23
+ # LTR
24
+ rtl = pdf.get_rtl
25
+ assert_equal rtl, false
26
+ rtl = pdf.is_rtl_text_dir
27
+ assert_equal rtl, false
28
+ rtl = pdf.rtl_text_dir
29
+ assert_equal rtl, 'L'
30
+
31
+ pdf.set_temp_rtl('rtl')
32
+ rtl = pdf.is_rtl_text_dir
33
+ assert_equal rtl, true
34
+ rtl = pdf.rtl_text_dir
35
+ assert_equal rtl, 'R'
36
+
37
+ # RTL
38
+ pdf.set_rtl(true)
39
+ rtl = pdf.get_rtl
40
+ assert_equal rtl, true
41
+ rtl = pdf.is_rtl_text_dir
42
+ assert_equal rtl, true
43
+ rtl = pdf.rtl_text_dir
44
+ assert_equal rtl, 'R'
45
+
46
+ pdf.set_temp_rtl('ltr')
47
+ rtl = pdf.is_rtl_text_dir
48
+ assert_equal rtl, false
49
+ rtl = pdf.rtl_text_dir
50
+ assert_equal rtl, 'L'
15
51
  end
16
52
 
17
53
  test "Bidi" do
@@ -65,6 +101,99 @@ class RbpdfTest < ActiveSupport::TestCase
65
101
  assert_equal [0x61, 0x62, 0x63, 0x5ea, 0x5d9, 0x5e8, 0x5d1, 0x5e2], ary_str
66
102
  end
67
103
 
104
+ test "Bidi ascii space test" do
105
+ pdf = MYPDF.new
106
+
107
+ ascii_str = "abc def"
108
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
109
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x64, 0x65, 0x66]
110
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
111
+ assert_equal ary_ucs4_2, ary_ucs4_1
112
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
113
+ assert_equal ary_ucs4_2, ary_ucs4_1
114
+
115
+ ascii_str = "abc def"
116
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
117
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x20, 0x64, 0x65, 0x66]
118
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
119
+ assert_equal ary_ucs4_2, ary_ucs4_1
120
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
121
+ assert_equal ary_ucs4_2, ary_ucs4_1
122
+
123
+ ascii_str = "abc "
124
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
125
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x20]
126
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
127
+ assert_equal ary_ucs4_2, ary_ucs4_1
128
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
129
+ assert_equal ary_ucs4_2, [0x20, 0x20, 0x61, 0x62, 0x63]
130
+
131
+ ascii_str = "abc_def"
132
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
133
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x5f, 0x64, 0x65, 0x66]
134
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
135
+ assert_equal ary_ucs4_2, ary_ucs4_1
136
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
137
+ assert_equal ary_ucs4_2, ary_ucs4_1
138
+ end
139
+
140
+ test "Bidi ascii numeric space test" do
141
+ pdf = MYPDF.new
142
+
143
+ ascii_str = "abc 123 def"
144
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
145
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x31, 0x32, 0x33, 0x20, 0x64, 0x65, 0x66]
146
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
147
+ assert_equal ary_ucs4_2, ary_ucs4_1
148
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
149
+ assert_equal ary_ucs4_2, ary_ucs4_1
150
+
151
+ ascii_str = "abc_123_def"
152
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
153
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x5f, 0x31, 0x32, 0x33, 0x5f, 0x64, 0x65, 0x66]
154
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
155
+ assert_equal ary_ucs4_2, ary_ucs4_1
156
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
157
+ assert_equal ary_ucs4_2, ary_ucs4_1
158
+ end
159
+
160
+ test "Bidi ascii colon test" do
161
+ pdf = MYPDF.new
162
+
163
+ ascii_str = "abc:def"
164
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
165
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x3a, 0x64, 0x65, 0x66]
166
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
167
+ assert_equal ary_ucs4_2, ary_ucs4_1
168
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
169
+ assert_equal ary_ucs4_2, ary_ucs4_1
170
+
171
+ ascii_str = "abc: def"
172
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
173
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x3a, 0x20, 0x64, 0x65, 0x66]
174
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
175
+ assert_equal ary_ucs4_2, ary_ucs4_1
176
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
177
+ assert_equal ary_ucs4_2, ary_ucs4_1
178
+
179
+ ascii_str = "abc : def"
180
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
181
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x3a, 0x20, 0x64, 0x65, 0x66]
182
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
183
+ assert_equal ary_ucs4_2, ary_ucs4_1
184
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
185
+ assert_equal ary_ucs4_2, ary_ucs4_1
186
+
187
+ ascii_str = "abc :: def"
188
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str))
189
+ assert_equal ary_ucs4_1, [0x61, 0x62, 0x63, 0x20, 0x20, 0x3a, 0x3a, 0x20, 0x20, 0x64, 0x65, 0x66]
190
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'R')
191
+ assert_equal ary_ucs4_2, ary_ucs4_1
192
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(ascii_str), '', 'L')
193
+ assert_equal ary_ucs4_2, ary_ucs4_1
194
+ end
195
+
196
+
68
197
  test "Bidi arabic test" do
69
198
  pdf = MYPDF.new
70
199
 
@@ -98,7 +227,108 @@ class RbpdfTest < ActiveSupport::TestCase
98
227
  assert_equal [0xfea9], ary_ucs4
99
228
 
100
229
  ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_arabic_str_1))
101
- assert_equal [0xfeae, 0xfeee, 0xfea9], ary_ucs4
230
+ assert_equal [0xfead, 0xfeed, 0xfea9], ary_ucs4
231
+ end
232
+
233
+ test "Bidi Persian Sunday test" do
234
+ pdf = MYPDF.new
235
+
236
+ utf8_persian_str_1 = "\xdb\x8c"
237
+ utf8_persian_str_2 = "\xdb\x8c\xda\xa9"
238
+ utf8_persian_str_3 = "\xdb\x8c\xda\xa9\xe2\x80\x8c"
239
+ utf8_persian_str_4 = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4"
240
+ utf8_persian_str_5 = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86"
241
+ utf8_persian_str_6 = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8"
242
+ utf8_persian_str_7 = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87" # Sunday
243
+
244
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_1))
245
+ assert_equal ary_ucs4, [0xfbfc]
246
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_2))
247
+ assert_equal ary_ucs4, [0xfb8f, 0xfbfe]
248
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_3))
249
+ assert_equal ary_ucs4, [0x200C, 0xfb8f, 0xfbfe]
250
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_4))
251
+ assert_equal ary_ucs4, [0xfeb5, 0x200C, 0xfb8f, 0xfbfe]
252
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_5))
253
+ assert_equal ary_ucs4, [0xfee6, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe]
254
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_6))
255
+ assert_equal ary_ucs4, [0xfe90, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe]
256
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_7))
257
+ assert_equal ary_ucs4, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe]
258
+ end
259
+
260
+ test "Bidi Persian Sunday forcertl test" do
261
+ pdf = MYPDF.new
262
+ utf8_persian_str_sunday = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
263
+
264
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_sunday), '', 'R')
265
+ assert_equal ary_ucs4_1, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe]
266
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_sunday), '', 'L')
267
+ assert_equal ary_ucs4_2, ary_ucs4_1
268
+ end
269
+
270
+ test "Bidi Persian Monday test" do
271
+ pdf = MYPDF.new
272
+
273
+ utf8_persian_str_1 = "\xd8\xaf"
274
+ utf8_persian_str_2 = "\xd8\xaf\xd9\x88"
275
+ utf8_persian_str_3 = "\xd8\xaf\xd9\x88\xd8\xb4"
276
+ utf8_persian_str_4 = "\xd8\xaf\xd9\x88\xd8\xb4\xd9\x86"
277
+ utf8_persian_str_5 = "\xd8\xaf\xd9\x88\xd8\xb4\xd9\x86\xd8\xa8"
278
+ utf8_persian_str_6 = "\xd8\xaf\xd9\x88\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87" # Monday
279
+
280
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_1))
281
+ assert_equal ary_ucs4, [0xfea9]
282
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_2))
283
+ assert_equal ary_ucs4, [0xfeed, 0xfea9]
284
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_3))
285
+ assert_equal ary_ucs4, [0xfeb5, 0xfeed, 0xfea9]
286
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_4))
287
+ assert_equal ary_ucs4, [0xfee6, 0xfeb7, 0xfeed, 0xfea9]
288
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_5))
289
+ assert_equal ary_ucs4, [0xfe90, 0xfee8, 0xfeb7, 0xfeed, 0xfea9]
290
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_6))
291
+ assert_equal ary_ucs4, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0xfeed, 0xfea9]
292
+ end
293
+
294
+ test "Bidi Persian Monday forcertl test" do
295
+ pdf = MYPDF.new
296
+ utf8_persian_str_monday = "\xd8\xaf\xd9\x88\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
297
+
298
+ ary_ucs4_1 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_monday), '', 'R')
299
+ assert_equal ary_ucs4_1, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0xfeed, 0xfea9]
300
+ ary_ucs4_2 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_monday), '', 'L')
301
+ assert_equal ary_ucs4_2, ary_ucs4_1
302
+ end
303
+
304
+ test "Bidi Persian and English test" do
305
+ pdf = MYPDF.new
306
+
307
+ utf8_persian_str_sunday = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
308
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_sunday + ' abc'))
309
+ assert_equal ary_ucs4, [0x61, 0x62, 0x63, 0x20, # 'abc '
310
+ 0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe] # Sunday
311
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_sunday + ' abc'), '', 'R')
312
+ assert_equal ary_ucs4, [0x61, 0x62, 0x63, 0x20, # 'abc '
313
+ 0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe] # Sunday
314
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray(utf8_persian_str_sunday + ' abc'), '', 'L')
315
+ assert_equal ary_ucs4, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe, # Sunday
316
+ 0x20, 0x61, 0x62, 0x63] # 'abc '
317
+ end
318
+
319
+ test "Bidi English and Persian test" do
320
+ pdf = MYPDF.new
321
+
322
+ utf8_persian_str_sunday = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
323
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray('abc ' + utf8_persian_str_sunday))
324
+ assert_equal ary_ucs4, [0x61, 0x62, 0x63, 0x20, # 'abc '
325
+ 0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe] # Sunday
326
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray('abc ' + utf8_persian_str_sunday), '', 'L')
327
+ assert_equal ary_ucs4, [0x61, 0x62, 0x63, 0x20, # 'abc '
328
+ 0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe] # Sunday
329
+ ary_ucs4 = pdf.utf8Bidi(pdf.UTF8StringToArray('abc ' + utf8_persian_str_sunday), '', 'R')
330
+ assert_equal ary_ucs4, [0xfeea, 0xfe92, 0xfee8, 0xfeb7, 0x200C, 0xfb8f, 0xfbfe, # Sunday
331
+ 0x20, 0x61, 0x62, 0x63] # 'abc '
102
332
  end
103
333
 
104
334
  test "Bidi date test" do
@@ -128,4 +358,10 @@ class RbpdfTest < ActiveSupport::TestCase
128
358
  rtn = pdf.cache_utf8_string_to_array('1234')
129
359
  assert_equal rtn, [0x31, 0x32, 0x33, 0x34]
130
360
  end
361
+
362
+ test "UniArrSubString test" do
363
+ pdf = RBPDF.new
364
+ str = pdf.uni_arr_sub_string(['a', 'b', 'c', ' ', 'd', 'e', 'f'])
365
+ assert_equal str, 'abc def'
366
+ end
131
367
  end
@@ -1,3 +1,4 @@
1
+ # coding: ASCII-8BIT
1
2
  require 'test_helper'
2
3
 
3
4
  class RbpdfPageTest < ActiveSupport::TestCase
@@ -112,6 +113,84 @@ class RbpdfPageTest < ActiveSupport::TestCase
112
113
  assert_equal content[12], '340.88 141.17 370.62 158.34 392.04 183.86 c' # 8/9 circle
113
114
  assert_equal content[13], '413.45 209.38 425.20 241.65 425.20 274.96 c' # 9/9 circle
114
115
  assert_equal content[14], 'S'
116
+ end
117
+
118
+ test "write content test" do
119
+ pdf = MYPDF.new
120
+ pdf.add_page()
121
+ page = pdf.get_page
122
+ assert_equal 1, page
123
+
124
+ content = []
125
+ line = pdf.write(0, "abc def")
126
+ contents = pdf.getPageBuffer(page)
127
+ contents.each_line {|line| content.push line.chomp }
128
+ assert_equal content.length, 22
129
+ assert_equal content[21], "BT 31.19 801.84 Td 0 Tr 0.00 w [(abc def)] TJ ET"
130
+ end
131
+
132
+ test "write content RTL test" do
133
+ pdf = MYPDF.new
134
+ pdf.set_rtl(true)
135
+ pdf.add_page()
136
+ page = pdf.get_page
137
+ assert_equal 1, page
138
+
139
+ content = []
140
+ line = pdf.write(0, "abc def")
141
+ contents = pdf.getPageBuffer(page)
142
+ contents.each_line {|line| content.push line.chomp }
143
+ assert_equal content.length, 22
144
+ assert_equal content[21], "BT 524.73 801.84 Td 0 Tr 0.00 w [(abc def)] TJ ET"
145
+ end
146
+
147
+ test "write Persian Sunday content test" do
148
+ pdf = MYPDF.new
149
+ pdf.set_font('dejavusans', '', 18)
150
+ pdf.add_page()
151
+ page = pdf.get_page
152
+ assert_equal 1, page
115
153
 
154
+ utf8_persian_str_sunday = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
155
+ content = []
156
+ line = pdf.write(0, utf8_persian_str_sunday)
157
+ contents = pdf.getPageBuffer(page)
158
+
159
+ contents.each_line {|line| content.push line.chomp }
160
+ assert_equal content.length, 22
161
+ assert_equal content[21], "BT 31.19 796.06 Td 0 Tr 0.00 w [(\xFE\xEA\xFE\x92\xFE\xE8\xFE\xB7 \f\xFB\x8F\xFB\xFE)] TJ ET"
162
+
163
+ pdf.set_rtl(true)
164
+ line = pdf.write(0, utf8_persian_str_sunday)
165
+ contents = pdf.getPageBuffer(page)
166
+
167
+ contents.each_line {|line| content.push line.chomp }
168
+ assert_equal content.length, 46
169
+ assert_equal content[45], "BT 507.38 796.06 Td 0 Tr 0.00 w [(\xFE\xEA\xFE\x92\xFE\xE8\xFE\xB7 \f\xFB\x8F\xFB\xFE)] TJ ET"
170
+ end
171
+
172
+ test "write English and Persian Sunday content test" do
173
+ pdf = MYPDF.new
174
+ pdf.set_font('dejavusans', '', 18)
175
+ pdf.add_page()
176
+ page = pdf.get_page
177
+ assert_equal 1, page
178
+
179
+ utf8_persian_str_sunday = "\xdb\x8c\xda\xa9\xe2\x80\x8c\xd8\xb4\xd9\x86\xd8\xa8\xd9\x87"
180
+ content = []
181
+ line = pdf.write(0, 'abc def ' + utf8_persian_str_sunday)
182
+ contents = pdf.getPageBuffer(page)
183
+
184
+ contents.each_line {|line| content.push line.chomp }
185
+ assert_equal content.length, 22
186
+ assert_equal content[21], "BT 31.19 796.06 Td 0 Tr 0.00 w [(\x00a\x00b\x00c\x00 \x00d\x00e\x00f\x00 \xFE\xEA\xFE\x92\xFE\xE8\xFE\xB7 \f\xFB\x8F\xFB\xFE)] TJ ET"
187
+
188
+ pdf.set_rtl(true)
189
+ line = pdf.write(0, 'abc def ' + utf8_persian_str_sunday)
190
+ contents = pdf.getPageBuffer(page)
191
+
192
+ contents.each_line {|line| content.push line.chomp }
193
+ assert_equal content.length, 46
194
+ assert_equal content[45], "BT 434.73 796.06 Td 0 Tr 0.00 w [(\xFE\xEA\xFE\x92\xFE\xE8\xFE\xB7 \f\xFB\x8F\xFB\xFE\x00 \x00a\x00b\x00c\x00 \x00d\x00e\x00f)] TJ ET"
116
195
  end
117
196
  end
@@ -8,6 +8,9 @@ class RbpdfTest < ActiveSupport::TestCase
8
8
  def openHTMLTagHandler(dom, key, cell)
9
9
  super
10
10
  end
11
+ def get_temp_rtl
12
+ @tmprtl
13
+ end
11
14
  end
12
15
 
13
16
  test "Dom Basic" do
@@ -179,6 +182,89 @@ class RbpdfTest < ActiveSupport::TestCase
179
182
  assert_equal dom1, dom2
180
183
  end
181
184
 
185
+ test "Dom HTMLTagHandler DIR RTL test" do
186
+ pdf = MYPDF.new
187
+ pdf.add_page
188
+ temprtl = pdf.get_temp_rtl
189
+ assert_equal temprtl, false
190
+
191
+ # LTR, ltr
192
+ htmlcontent = '<p dir="ltr">HTML Example</p>'
193
+ dom = pdf.getHtmlDomArray(htmlcontent)
194
+ dom = pdf.openHTMLTagHandler(dom, 1, false)
195
+
196
+ assert_equal dom[1]['tag'], true
197
+ assert_equal dom[1]['opening'], true
198
+ assert_equal dom[1]['value'], 'p'
199
+ assert_equal dom[1]['attribute']['dir'], 'ltr'
200
+
201
+ temprtl = pdf.get_temp_rtl
202
+ assert_equal temprtl, false
203
+
204
+ # LTR, rtl
205
+ htmlcontent = '<p dir="rtl">HTML Example</p>'
206
+ dom = pdf.getHtmlDomArray(htmlcontent)
207
+ dom = pdf.openHTMLTagHandler(dom, 1, false)
208
+ assert_equal dom.length, 4
209
+
210
+ assert_equal dom[1]['tag'], true
211
+ assert_equal dom[1]['opening'], true
212
+ assert_equal dom[1]['value'], 'p'
213
+ assert_equal dom[1]['attribute']['dir'], 'rtl'
214
+
215
+ temprtl = pdf.get_temp_rtl
216
+ assert_equal temprtl, 'R'
217
+
218
+ # LTR, ltr
219
+ htmlcontent = '<p dir="ltr">HTML Example</p>'
220
+ dom = pdf.getHtmlDomArray(htmlcontent)
221
+ dom = pdf.openHTMLTagHandler(dom, 1, false)
222
+
223
+ assert_equal dom[1]['tag'], true
224
+ assert_equal dom[1]['opening'], true
225
+ assert_equal dom[1]['value'], 'p'
226
+ assert_equal dom[1]['attribute']['dir'], 'ltr'
227
+
228
+ temprtl = pdf.get_temp_rtl
229
+ assert_equal temprtl, false
230
+ end
231
+
232
+ test "Dom HTMLTagHandler DIR LTR test" do
233
+ pdf = MYPDF.new
234
+ pdf.add_page
235
+ temprtl = pdf.get_temp_rtl
236
+ assert_equal temprtl, false
237
+ pdf.set_rtl(true)
238
+
239
+ # RTL, ltr
240
+ htmlcontent = '<p dir="ltr">HTML Example</p>'
241
+ dom = pdf.getHtmlDomArray(htmlcontent)
242
+ dom = pdf.openHTMLTagHandler(dom, 1, false)
243
+ assert_equal dom.length, 4
244
+
245
+ assert_equal dom[1]['tag'], true
246
+ assert_equal dom[1]['opening'], true
247
+ assert_equal dom[1]['value'], 'p'
248
+ assert_equal dom[1]['attribute']['dir'], 'ltr'
249
+
250
+ temprtl = pdf.get_temp_rtl
251
+ assert_equal temprtl, 'L'
252
+
253
+ # RTL, rtl
254
+ htmlcontent = '<p dir="rtl">HTML Example</p>'
255
+ dom = pdf.getHtmlDomArray(htmlcontent)
256
+ dom = pdf.openHTMLTagHandler(dom, 1, false)
257
+ assert_equal dom.length, 4
258
+
259
+ assert_equal dom[1]['tag'], true
260
+ assert_equal dom[1]['opening'], true
261
+ assert_equal dom[1]['value'], 'p'
262
+ assert_equal dom[1]['attribute']['dir'], 'rtl'
263
+
264
+ temprtl = pdf.get_temp_rtl
265
+ assert_equal temprtl, false
266
+ end
267
+
182
268
  test "Dom HTMLTagHandler img test" do
183
269
  pdf = MYPDF.new
184
270
  pdf.add_page
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbpdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.18.3
4
+ version: 1.18.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - NAITOH Jun
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-06 00:00:00.000000000 Z
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler