Page 1 of 1

Calculate table cell height.

Posted: Thu Mar 07, 2013 12:23 pm
by Michal
Hello,

I have upgraded TRichView to version 14 from 1.9.
A table generated using ver. 1.9 fills all page, but table generated using ver. 14.0 is sorter, does not fill all page, but contains this same contents. The table is only shorter. Due to this there are a margin on bottom of page.

I calculate cell height like this
Height:= Pixel_DPI+ //top frame of cell
TabCellPadding*Pixel_DPI+ //top padding
HeightOfFont+ //
TabCellPadding*Pixel_DPI+ //bottom padding
Pixel_DPI; //bottom frame

TabCellPadding := 2;
Pixel_DPI :=6.25 (calculated)

What does change ?

Regards
Michal

Posted: Wed Mar 13, 2013 8:03 am
by Sergey Tkachenko
A calculation of widths of table columns was changes several times, so, in some non-trivial cases, table width may be different for the same table.
Table width may affect table height because of line wrapping inside cells.

Otherwise, the only change I can remember is implementation of different cellpaddings: a horizontal and a vertical cellpadding (CellHPadding and CellVPadding).
It may be important if you import a table from MS Word-generated RTF, because by default MS Word's tables have different vertical and horizontal cellpaddings.
But if you generate your table yourself using table.CellPadding property, it must not affect the result.

I need a sample project to reproduce the problem.

Posted: Wed Mar 13, 2013 10:52 am
by Michal
Hello,

Thanks for your replay.

When I change

Height:= Pixel_DPI+ //top frame of cell
TabCellPadding*Pixel_DPI+ //top padding
HeightOfFont+ //
TabCellPadding*Pixel_DPI+ //bottom padding
Pixel_DPI *0.70 ; //bottom frame

the table height is better calculated. Usually a table has one row more and the bottom margin is smaller.

In my tables there are no wrapped lines. After upgrade to current version of TRichView tables are shorter like before. It seams to cell height is a bit smaller then before.

I make mixed prints. There are text, tables some times pictures on them. What is proper way to calculate size of elements before insert them ?

For example I insert a few lines of text with different styles. Then I want to insert a table, but before this I have to know how many space are available on the page. Next during build the table I have to know how many space are available inside a table. After this I insert this table on page and create new empty page for next part of a print.

For now I calculate all myself.

There are in TRichView any functions to calculate it all ?

Regards
Michal

Posted: Wed Mar 13, 2013 5:48 pm
by Sergey Tkachenko
Please send me a (simple) sample project where table heights are different in different versions.

TRichView cannot calculate sizes before formatting.

Posted: Wed Mar 13, 2013 6:54 pm
by Michal
Hello,

To reproduce this behaviour you can build a simple table:

Code: Select all


procedure TFPD.InicjujTabele(Styl:byte);  
var
 n,m:byte;
begin
  IncWiersz(0,0);                     //zapamietuje poprzedni tekst
  Inicjuj_WspT;
  NrWiersza:=NrWiersza+2*Pixel_DPI;   //obramowanie tabeli
  
  fillChar(Tab,sizeOf(Tab),0);
  for n:=0 to TAB_MAX_Wierszy-1 do begin
    for m:=0 to TAB_MAX_Kolumn-1 do begin
      Tab[n,m].RGora     :=false; //true;
      Tab[n,m].RDol      :=true;
      Tab[n,m].RLewa     :=false; //true;
      Tab[n,m].RPrawa    :=true;
      Tab[n,m].PolaczonaX:=m;      //sama ze soba, co znaczy ze nie jest polaczona
      Tab[n,m].PolaczonaY:=n;      //sama ze soba, co znaczy ze nie jest polaczona
      Tab[n,m].Kolor     :=clNone;
      Tab[n,m].Styl      :=Styl;
      Tab[n,m].Pad       :=D_PadL;
      Tab[n,m].NrObrazka :=0;
      if n=TAB_MAX_Wierszy-1 then Tab[n,m].RDol:=false;
      if m=TAB_MAX_Kolumn-1  then Tab[n,m].RPrawa:=false;
    end;
  end;
  CzyObrys    :=true;
  NrWierszaTab:=0;
end;

{---------------------------------------------------------------------------}
procedure TFPD.Tabela(IleWierszy,IleKolumn:word;Szerokosc,PAD:SmallInt; PlikTla:string);
var
  table : TRVTableItemInfo;
  ramki : TRVBooleanRect;
  m,n,o : byte;
  ByloPolaczenieX:boolean;
  IlePolaczycX:byte;
  ByloPolaczenieY:boolean;
  IlePolaczycY:byte;
  AktualnyStylTmp:byte;
  bmp,bmpTlo:TBitmap;
  ss:string;
  xxx:integer;
  Szer,Wys:longint;
  CzyBMP:boolean;
  JPG:TJPEGImage;
  MS:TStream;


begin
  AktualnyStylTmp:=AktualnyStyl;

  if IleWierszy>0 then
  for n:=0 to IleWierszy-1 do begin
    if IleKolumn>0 then
    for m:=0 to IleKolumn-1 do begin
      if n=IleWierszy-1 then Tab[n,m].RDol:=false;
      if m=IleKolumn-1  then Tab[n,m].RPrawa:=false;
      if Tab[n,0].Blok_Start then Tab[n,m].RGora:=true;
      if Tab[n,0].Blok_End   then Tab[n,m].RDol:=true;
    end;
  end;

// Stale definiujace wyglad tabeli - raczej nie zmienic !!!
  table := TRVTableItemInfo.CreateEx(IleWierszy,IleKolumn, RVE.RVData);
  table.ParaNo    := PAD;

  table.Color                := clWhite; //clNone;      //clWhite;
  table.BorderLightColor     := clNone;  //=trnsparent   //clWhite;
  if CzyObrys
  then table.BorderColor     := clBlack
  else table.BorderColor     := clNone;
  table.CellBorderColor      := clGray;
  table.CellBorderLightColor := clNone; //clWhite;

  table.BorderStyle     :=  rvtbColor; // rvtbRaisedColor;
  table.CellBorderStyle :=  rvtbColor; //rvtbLoweredColor;
  // TRVTableBorderStyle = (rvtbRaised, rvtbLowered, rvtbColor, rvtbRaisedColor, rvtbLoweredColor);

  table.VRuleWidth:=0;
  table.VRuleColor:=clYellow;
  table.VOutermostRule:=False;
  table.HRuleWidth:=0;
  table.HRuleColor:=clYellow;
  table.HOutermostRule:=False;

  table.BorderWidth    := 1;  //0 - oznacza ze bez ramki
  table.BorderVSpacing := 0;
  table.BorderHSpacing := 0;

  table.CellBorderWidth := 1; //0 - oznacza ze nie ma ramek komorek;
  table.CellPadding     := 2; //2 - oznacza szerokosc ramki wkolo tekstu wewnatrz komorki ;
  table.CellVSpacing    := 0;
  table.CellHSpacing    := 0;

  if Pokaz_Siatke_Tabel
  then table.Options:=table.Options-[rvtoHideGridLines]
  else table.Options:=table.Options+[rvtoHideGridLines];


  //Ustawienie szerokosci kolumn tabeli i polaczen komorek w wierszu oraz koloru komorek
  if IleWierszy>0 then
  for n:=0 to IleWierszy-1 do begin
    if IleKolumn>0 then
    for m:=0 to IleKolumn-1 do begin
      table.Cells[n,m].BestWidth        := Tab[0,m].Szerokosc;
      table.Cells[n,m].BorderLightColor := Tab[n,m].Kolor;
      table.Cells[n,m].Color            := Tab[n,m].Kolor;
      { TODO : Komponent nie obsluguje prawidlowo tej wlasciwosci troche lepiej jest dla rvtbRaised}
      //2007.07
      case Tab[n,m].Pad_V of
      D_PAD_G: table.Cells[n,m].VAlign := rvcTop;
      D_PAD_S: table.Cells[n,m].VAlign := rvcMiddle;
      D_PAD_D: table.Cells[n,m].VAlign := rvcBottom;
      else     table.Cells[n,m].VAlign := rvcVDefault;
      end;
    end;

    m:=0;
    ByloPolaczenieX:=false;
    ByloPolaczenieY:=false;
    IlePolaczycX:=0;
    IlePolaczycY:=0;
    while m<=IleKolumn-1 do begin
      // dla X
      if (Tab[n,m].PolaczonaX<>m) then begin
        inc(IlePolaczycX);
        ByloPolaczenieX:=true;
      end else begin
        if ByloPolaczenieX then begin
          inc(IlePolaczycX);
          table.MergeCells(n,m-IlePolaczycX,IlePolaczycX,1,FALSE);
        end;
        IlePolaczycX:=0;
        ByloPolaczenieX:=false
      end;
      //Dla Y
      if (Tab[n,m].PolaczonaY<>n) then begin
        table.MergeCells(Tab[n,m].PolaczonaY,m,1,1+n-Tab[n,m].PolaczonaY,FALSE);
      end;
      inc(m);
    end;
    if ByloPolaczenieX then begin
      inc(IlePolaczycX);
      table.MergeCells(n,m-IlePolaczycX,IlePolaczycX,1,FALSE);
    end;
  end;

//  table.MergeCells(0,0,6,1,FALSE);
//  table.MergeCells(0,6,5,1,FALSE);

//  table.MergeCells(3,1,3,1,FALSE);
//  table.MergeCells(3,4,2,1,FALSE);

//  table.Select(3,1,1,1);
//  table.SplitSelectedCellsVertically(3);
  o:=0;
  if Tab[0,0].NrObrazka<>0 then begin 
    o:=1;
  end;

  if IleWierszy>0 then
  for n:=0 to IleWierszy-1 do begin
    InicjujStyle;

    if IleKolumn>0 then
    for m:=o to IleKolumn-1 do begin
      with Table.Cells[n,m] do begin
        try
          if (Tab[n,m].PolaczonaX=m) and
             (Tab[n,m].PolaczonaY=n)
          then begin
            Clear;
            ramki:=VisibleBorders;
            ramki.SetValues(Tab[n,m].RLewa,  Tab[n,m].RGora,
                            Tab[n,m].RPrawa, Tab[n,m].RDol  );
            VisibleBorders:=ramki;

            //AddNL(Tab[n,m].Tresc,Tab[n,m].Styl,Tab[n,m].Pad);
            if Tab[n,m].SzerTXT>0 then begin  {2004.08.17}
              Szer:=0;
              Wys :=0;
              ss:=trim(Tab[n,m].Tresc);
              WymiarTXT(ss,Tab[n,m].Styl,Szer,Wys);
              if Szer > Tab[n,m].SzerTXT then begin
                repeat
                  ss:=trim(ss);
                  if ss<>'' then delete(ss,length(ss),1);
                  ss:=trim(ss);
                  WymiarTXT(ss+'...',Tab[n,m].Styl,Szer,Wys);
                until Szer <= Tab[n,m].SzerTXT;
                ss:=ss+'...';
              end;

              AddNL(ss ,Tab[n,m].Styl,Tab[n,m].Pad); 
            end else begin
              AddNL(Tab[n,m].Tresc,Tab[n,m].Styl,Tab[n,m].Pad); 
            end;
            
            AktualnyStyl:=Tab[n,m].Styl;
            AktualizujWystepowanieStylow;
          end;
        except
          on E:Exception do begin end;
        end;
      end;  
    end;

    // IncWiersz(1,0);
  end;


  if Tab[0,0].NrObrazka<>0 then begin
    table.MergeCells(0,0,1,IleWierszy,FALSE);
    bmp:=TBitmap.Create;
    bmp.Assign(TabBmp[Tab[0,0].NrObrazka].Obrazek);
    table.cells[0,0].Clear;
    table.cells[0,0].AddPictureEx('',bmp,D_PadC,rvvaMiddle);
    table.BorderWidth     := 0;
    table.CellBorderWidth := 0;
    table.CellBorderColor :=clNone;
    //bmp.Free; - powoduje blad
  end;


//  table.InsertRows(3,10,1,false);
//  with table.Cells[2,0] do begin
//    Clear;
//    AddNL('Another example.',0,0);
//    SetItemExtraIntProperty(ItemCount-1, rvepResizable, 1);
//    AddNL('Width of table = 90% of document width. Widths of cells = 16%',0,0);
//  end;

//  table.BackgroundImageFileName:='d:\BDS2006\Apl\FVat\#\Polecenie.bmp';
  if FileExists(PlikTla) then begin
    bmpTlo := TBitmap.Create;

    CzyBMP:=(FileExt(UpStr(PlikTla))='BMP');

    if CzyBMP then begin
      try
        bmpTlo.LoadFromFile(PlikTla);
      except
        msgBox({self,}'Problem z za³adowaniem pliku:'+#13+#13+PlikTla, mfOK);
      end;
    end else begin
      try
        JPG := TJPEGImage.Create;
        JPG.LoadFromFile(PlikTla);
        bmpTlo.Assign(JPG);
//        MS:=TMemoryStream.Create;
//        JPG.SaveToStream(MS);
//        bmpTlo.LoadFromStream(MS);
//        MS.Free;
        JPG.Free;
      except
        msgBox({self,}'Problem z za³adowaniem pliku:'+#13+#13+PlikTla, mfOK);
      end;
    end;

    table.BackgroundImage := bmpTlo;
    table.BackgroundStyle := rvbsStretched; //rvbsTiled;//rvbsCentered;//rvbsStretched;
    bmpTlo.Free;
  end;

  table.BestWidth := Szerokosc;
  RVE.AddItem('', table);

  InicjujStyle;
end;

{---------------------------------------------------------------------------}
  procedure  TworzTabele(Styl:byte);
  var
    Wsp:double;
    x,y:byte;
  begin
    Wsp:=1.00;
    case Styl of
    Arial_3:   Wsp:=WspT_Arial3;
    Arial_3b:  Wsp:=WspT_Arial3b;
    Arial_3i:  Wsp:=WspT_Arial3i;
    Arial_3bi: Wsp:=WspT_Arial3bi;
    Arial_3u:  Wsp:=WspT_Arial3u;

    Arial_6:   Wsp:=WspT_Arial6;
    Arial_6b:  Wsp:=WspT_Arial6b;
    Arial_6i:  Wsp:=WspT_Arial6i;
    Arial_6bi: Wsp:=WspT_Arial6bi;
    Arial_6u:  Wsp:=WspT_Arial6u;

    Arial_7:   Wsp:=WspT_Arial7;
    Arial_7b:  Wsp:=WspT_Arial7b;
    Arial_7i:  Wsp:=WspT_Arial7i;
    Arial_7bi: Wsp:=WspT_Arial7bi;
    Arial_7u:  Wsp:=WspT_Arial7u;

    Arial_8:   Wsp:=WspT_Arial8;
    Arial_8b:  Wsp:=WspT_Arial8b;
    Arial_8i:  Wsp:=WspT_Arial8i;
    Arial_8bi: Wsp:=WspT_Arial8bi;
    Arial_8u:  Wsp:=WspT_Arial8u;

    Arial_9:   Wsp:=WspT_Arial9;
    Arial_9b:  Wsp:=WspT_Arial9b;
    Arial_9i:  Wsp:=WspT_Arial9i;
    Arial_9bi: Wsp:=WspT_Arial9bi;
    Arial_9u:  Wsp:=WspT_Arial9u;

    Arial_10:   Wsp:=WspT_Arial10;
    Arial_10b:  Wsp:=WspT_Arial10b;
    Arial_10i:  Wsp:=WspT_Arial10i;
    Arial_10bi: Wsp:=WspT_Arial10bi;
    Arial_10u:  Wsp:=WspT_Arial10u;
    
    Arial_12:   Wsp:=WspT_Arial12;
    Arial_12b:  Wsp:=WspT_Arial12b;
    Arial_12i:  Wsp:=WspT_Arial12i;
    Arial_12bi: Wsp:=WspT_Arial12bi;
    Arial_12u:  Wsp:=WspT_Arial12u;

    Arial_14:   Wsp:=WspT_Arial14;
    Arial_14b:  Wsp:=WspT_Arial14b;
    Arial_14i:  Wsp:=WspT_Arial14i;
    Arial_14bi: Wsp:=WspT_Arial14bi;
    Arial_14u:  Wsp:=WspT_Arial14u;

    Curier_7:   Wsp:=WspT_Curier7;
    Curier_7b:  Wsp:=WspT_Curier7b;
    Curier_7i:  Wsp:=WspT_Curier7i;
    Curier_7bi: Wsp:=WspT_Curier7bi;
    Curier_7u:  Wsp:=WspT_Curier7u;

    Curier_10:   Wsp:=WspT_Curier10;
    Curier_10b:  Wsp:=WspT_Curier10b;
    Curier_10i:  Wsp:=WspT_Curier10i;
    Curier_10bi: Wsp:=WspT_Curier10bi;
    Curier_10u:  Wsp:=WspT_Curier10u;
    end;

    NowaStrona(false);
    InicjujTabele(Styl);
    Zostalo:=0;
    for x:=0 to 73 do begin
      
      if CzyNowaStrona(Wsp,1,NrWierszaTab,Zostalo) and CzyPodzial
      then begin
        Tabela(NrWierszaTab,10,-100, D_PADL);
        NowaStrona(False);
        InicjujTabele(Styl);
      end;

      if NrWierszaTab=0 then begin
        Tab[0,0].Szerokosc:=-5;
        Tab[0,1].Szerokosc:=-15;
        Tab[0,2].Szerokosc:=-12;
        Tab[0,3].Szerokosc:=-12;
        Tab[0,4].Szerokosc:=-10;
        for y:=5 to 9 do begin
          Tab[0,y].Szerokosc:=-5;
        end;
      end;
        
      Tab[NrWierszaTab,0].Tresc:=intToStr(x+1);
      Tab[NrWierszaTab,1].Tresc:=RVStyle1.TextStyles.Items[Styl].StyleName{+#182+#222};
      Tab[NrWierszaTab,0].Pad  :=D_PADR;
      IncWiersz(1,NrWierszaTab);
      Tab[NrWierszaTab,2].Tresc := realToStr(NrWiersza,2);
      Tab[NrWierszaTab,3].Tresc := realToStr(Zostalo-Wsp,2);
      Tab[NrWierszaTab,4].Tresc := realToStr(Wsp,2);
      inc(NrWierszaTab);
    end;  
    if NrWierszaTab>0 then Tabela(NrWierszaTab,10,-100, D_PADL);
  
  end;
I can't separate the code, but I'm sending you the main procedures

Michal

Posted: Thu Mar 14, 2013 9:16 am
by Sergey Tkachenko
Sorry, it's too complicated to reproduce the problem by these procedures :(

Posted: Fri Mar 15, 2013 4:44 pm
by Michal
Hello,

You may insert a simple table of about 60 rows and 4 columns. In first cell of each row you can write number of the row using Arial 9 font.
Probably 60 rows will fill a A4 page.

Then you can create the page using RVE 1.9 and 14. On RVE 14 table should have more rows then on 1.9, because height of each row is a bit shorter.

Michal

Posted: Thu Mar 21, 2013 2:59 pm
by Sergey Tkachenko
I made this test, compared version 14.3 and 1.9.0.4

Code: Select all

var table : TRVTableItemInfo;
    r: Integer;
begin
  RVStyle1.TextStyles.Clear;
  with RVStyle1.TextStyles.Add do begin
    FontName := 'Arial';
    Size := 9;
  end;

  table := TRVTableItemInfo.CreateEx(60, 4, RichView1.RVData);

  table.Color                := clWhite; //clNone;      //clWhite;
  table.BorderLightColor     := clNone;  //=trnsparent   //clWhite;
  table.BorderColor     := clBlack;
  table.CellBorderColor      := clGray;
  table.CellBorderLightColor := clNone; //clWhite;

  table.BorderStyle     :=  rvtbColor; // rvtbRaisedColor;
  table.CellBorderStyle :=  rvtbColor; //rvtbLoweredColor;
  // TRVTableBorderStyle = (rvtbRaised, rvtbLowered, rvtbColor, rvtbRaisedColor, rvtbLoweredColor);

  table.VRuleWidth:=0;
  table.VRuleColor:=clYellow;
  table.VOutermostRule:=False;
  table.HRuleWidth:=0;
  table.HRuleColor:=clYellow;
  table.HOutermostRule:=False;

  table.BorderWidth    := 1;  //0 - oznacza ze bez ramki
  table.BorderVSpacing := 0;
  table.BorderHSpacing := 0;

  table.CellBorderWidth := 1; //0 - oznacza ze nie ma ramek komorek;
  table.CellPadding     := 2; //2 - oznacza szerokosc ramki wkolo tekstu wewnatrz komorki ;
  table.CellVSpacing    := 0;
  table.CellHSpacing    := 0;
  RichView1.AddItem('', table);

  for r := 0 to table.Rows.Count-1 do begin
    table.Cells[r, 0].Clear;
    table.Cells[r, 0].AddFmt('%d', [r], 0, 0);
  end;

  RichView1.AddNL(RVVersion, 0, 0);
  RichView1.Format;
  
  Caption := IntToStr(table.GetHeight(RVStyle1)); -- for 14.3
  Caption := IntToStr(table.Height); -- for 1.9.0.4
end;
As a result, the both versions show the same table height in Caption (1262).
I compared screenshots in a graphical editor. While column widths are different (because the old version made a filled column wider than empty columns), row heights are exactly the same.

Posted: Tue Mar 26, 2013 8:25 pm
by Michal
Hello,

Thanks for replay.

I have sent you examples of this differences.

Regards
Michal

Posted: Wed Mar 27, 2013 10:48 am
by Sergey Tkachenko
Please send me this document as RVF file too.

Posted: Wed Mar 27, 2013 12:14 pm
by Michal
Hello,

I have sent you these RVE files.

Regards
Michal