Method: TCPDF#Write

Defined in:
lib/tcpdf.rb

#Write(h, txt, link = nil, fill = 0, align = '', ln = false, stretch = 0, firstline = false, firstblock = false, maxh = 0) ⇒ Object Also known as: write

This method prints text from the current position.

@param float :h

Line height

@param string :txt

String to print

@param mixed :link

URL or identifier returned by AddLink()

@param int :fill

Indicates if the background must be painted (1) or transparent (0). Default value: 0.

@param string :align

Allows to center or align the text. Possible values are:

  • L or empty string: left align (default value)

  • C: center

  • R: right align

  • J: justify

@param boolean :ln

if true set cursor at the bottom of the line, otherwise set cursor at the top of the line.

@param int :stretch

stretch carachter mode:

  • 0 = disabled

  • 1 = horizontal scaling only if necessary

  • 2 = forced horizontal scaling

  • 3 = character spacing only if necessary

  • 4 = forced character spacing

@param boolean :firstline

if true prints only the first line and return the remaining string.

@param boolean :firstblock

if true the string is the starting of a line.

@param float :maxh

maximum height. The remaining unprinted text will be returned. It should be >= :h and less then remaining space to the bottom of the page, or 0 for disable this feature.

@return mixed

Return the number of cells or the remaining string if :firstline = true.

@access public
@since 1.5


4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
# File 'lib/tcpdf.rb', line 4197

def Write(h, txt, link=nil, fill=0, align='', ln=false, stretch=0, firstline=false, firstblock=false, maxh=0)
  txt.force_encoding('ASCII-8BIT') if txt.respond_to?(:force_encoding)
  if txt.length == 0
    txt = ' '
  end

  # remove carriage returns
  s = txt.gsub("\r", '');

  # check if string contains arabic text
  if s =~ @@k_re_pattern_arabic
    arabic = true
  else
    arabic = false
  end

  # check if string contains RTL text
  if arabic or (@tmprtl == 'R') or (txt =~ @@k_re_pattern_rtl)
    rtlmode = true
  else
    rtlmode = false
  end

  # get a char width
  chrwidth = GetCharWidth('.')
  # get array of unicode values
  chars = UTF8StringToArray(s)
  # get array of chars
  uchars = UTF8ArrayToUniArray(chars)

  # get the number of characters
  nb = chars.size

  # replacement for SHY character (minus symbol)
  shy_replacement = 45
  shy_replacement_char = unichr(shy_replacement)
  # widht for SHY replacement
  shy_replacement_width = GetCharWidth(shy_replacement)

  # store current position
  prevx = @x
  prevy = @y

  # max Y
  maxy = @y + maxh - h - (2 * @c_margin)

  # calculating remaining line width (w)
  if @rtl
    w = @x - @l_margin
  else
    w = @w - @r_margin - @x
  end
  
  # max column width
  wmax = w - (2 * @c_margin)
  if !firstline and (chrwidth > wmax or (GetCharWidth(chars[0]) > wmax))
    # a single character do not fit on column
    return ''
  end

  i = 0    # character position
  j = 0    # current starting position
  sep = -1 # position of the last blank space
  shy = false # true if the last blank is a soft hypen (SHY)
  l = 0    # current string length
  nl = 0   # number of lines
  linebreak = false

  pc = 0 # previous character
  # for each character
  while(i<nb)
    if (maxh > 0) and (@y >= maxy)
      break
    end
    # Get the current character
    c = chars[i]
    if (c == 10) # 10 = "\n" = new line
      #Explicit line break
      if align == 'J'
        if @rtl
          talign = 'R'
        else
          talign = 'L'
        end
      else
        talign = align
      end
      tmpstr = UniArrSubString(uchars, j, i)
      if firstline
        startx = @x
        tmparr = chars[j, i - j]
        if rtlmode
          tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
        end
        linew = GetArrStringWidth(tmparr)
        tmparr = ''
        if @rtl
          @endlinex = startx - linew
        else
          @endlinex = startx + linew
        end
        w = linew
        tmpcmargin = @c_margin
        if maxh == 0
          @c_margin = 0
        end
      end
      if firstblock and isRTLTextDir()
        tmpstr = tmpstr.rstrip
      end
      Cell(w, h, tmpstr, 0, 1, talign, fill, link, stretch)
      tmpstr = ''
      if firstline
        @c_margin = tmpcmargin
        return UniArrSubString(uchars, i)
      end
      nl += 1
      j = i + 1
      l = 0
      sep = -1
      shy = false;
      # account for margin changes
      if ((@y + @lasth) > @page_break_trigger) and !@in_footer
        AcceptPageBreak()
      end
      w = getRemainingWidth()
      wmax = w - (2 * @c_margin)
    else 
      # 160 is the non-breaking space, 173 is SHY (Soft Hypen)
      if (c != 160) and ((unichr(c) =~ /\s/) or (c == 173))
        # update last blank space position
        sep = i
        # check if is a SHY
        if c == 173
          shy = true
          if pc == 45
            tmp_shy_replacement_width = 0
            tmp_shy_replacement_char = ''
          else
            tmp_shy_replacement_width = shy_replacement_width
            tmp_shy_replacement_char = shy_replacement_char
          end
        else 
          shy = false
        end
      end

      # update string length
      if ((@current_font['type'] == 'TrueTypeUnicode') or (@current_font['type'] == 'cidfont0')) and arabic
        # with bidirectional algorithm some chars may be changed affecting the line length
        # *** very slow ***
        l = GetArrStringWidth(utf8Bidi(chars[j..i-1], '', @tmprtl))
      else
        l += GetCharWidth(c)
      end

      if (l > wmax) or ((c == 173) and ((l + tmp_shy_replacement_width) > wmax))
        # we have reached the end of column
        if (sep == -1)
          # check if the line was already started
          if (@rtl and (@x <= @w - @r_margin - chrwidth)) or (!@rtl and (@x >= @l_margin + chrwidth))
            # print a void cell and go to next line
            Cell(w, h, '', 0, 1)
            linebreak = true
            if firstline
              return UniArrSubString(uchars, j)
            end
          else
            # truncate the word because do not fit on column
            tmpstr = UniArrSubString(uchars, j, i)
            if firstline
              startx = @x
              tmparr = chars[j, i - j]
              if rtlmode
                tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
              end
              linew = GetArrStringWidth(tmparr)
              tmparr = ''
              if @rtl
                @endlinex = startx - linew
              else
                @endlinex = startx + linew
              end
              w = linew
              tmpcmargin = @c_margin
              if maxh == 0
                @c_margin = 0
              end
            end
            if firstblock and isRTLTextDir()
              tmpstr = tmpstr.rstrip
            end
            Cell(w, h, tmpstr, 0, 1, align, fill, link, stretch)
            tmpstr = ''
            if firstline
              @c_margin = tmpcmargin
              return UniArrSubString(uchars, i)
            end
            j = i
            i -= 1
          end
        else
          # word wrapping
          if @rtl and !firstblock
            endspace = 1
          else
            endspace = 0
          end
          if shy
            # add hypen (minus symbol) at the end of the line
            shy_width = tmp_shy_replacement_width
            if @rtl
              shy_char_left = tmp_shy_replacement_char
              shy_char_right = ''
            else
              shy_char_left = ''
              shy_char_right = tmp_shy_replacement_char
            end
          else
            shy_width = 0
            shy_char_left = ''
            shy_char_right = ''
          end
          tmpstr = UniArrSubString(uchars, j, sep + endspace)
          if firstline
            startx = @x
            tmparr = chars[j, sep + endspace - j]
            if rtlmode
              tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
            end
            linew = GetArrStringWidth(tmparr)
            tmparr = ''
            if @rtl
              @endlinex = startx - linew - shy_width
            else
              @endlinex = startx + linew + shy_width
            end
            w = linew
            tmpcmargin = @c_margin
            if maxh == 0
              @c_margin = 0
            end
          end
          # print the line
          if firstblock and isRTLTextDir()
            tmpstr = tmpstr.rstrip
          end
          Cell(w, h, shy_char_left + tmpstr + shy_char_right, 0, 1, align, fill, link, stretch)
          tmpstr = ''
          if firstline
            # return the remaining text
            @c_margin = tmpcmargin
            return UniArrSubString(uchars, sep + endspace)
          end
          i = sep
          sep = -1
          shy = false
          j = i + 1
        end
        # account for margin changes
        if (@y + @lasth > @page_break_trigger) and !@in_footer
          AcceptPageBreak()
        end
        w = getRemainingWidth()
        wmax = w - (2 * @c_margin)
        if linebreak
          linebreak = false
        else
          nl += 1
          l = 0
        end
      end
    end
    # save last character
    pc = c
    i +=1
  end # end while i < nb

  # print last substring (if any)
  if l > 0
    case align
    when 'J' , 'C'
      w = w
    when 'L'
      if @rtl
        w = w
      else
        w = l
      end
    when 'R'
      if @rtl
        w = l
      else
        w = w
      end
    else
      w = l
    end
    tmpstr = UniArrSubString(uchars, j, nb)
    if firstline
      startx = @x
      tmparr = chars[j, nb - j]
      if rtlmode
        tmparr = utf8Bidi(tmparr, tmpstr, @tmprtl)
      end
      linew = GetArrStringWidth(tmparr)
      tmparr = ''
      if @rtl
        @endlinex = startx - linew
      else
        @endlinex = startx + linew
      end
      w = linew
      tmpcmargin = @c_margin
      if maxh == 0
        @c_margin = 0
      end
    end
    if firstblock and isRTLTextDir()
      tmpstr = tmpstr.rstrip
    end
    Cell(w, h, tmpstr, 0, (ln ? 1 : 0), align, fill, link, stretch)
    tmpstr = ''
    if firstline
      @c_margin = tmpcmargin
      return UniArrSubString(uchars, nb)
    end
    nl += 1
  end

  if firstline
    return ''
  end
  return nl
end