From 8c90f30c66b8a51dd1f358591c50f933fafe10ed Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sun, 20 Apr 2014 14:57:23 +0000 Subject: [PATCH] fpspreadsheet: Add reading of row heights for biff8. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2952 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpspreadsheet/fpspreadsheet.pas | 5 ++-- .../fpspreadsheet/fpspreadsheetgrid.pas | 25 +++++++++++++++++++ components/fpspreadsheet/fpsutils.pas | 16 ++++++++++++ components/fpspreadsheet/wikitable.pas | 2 -- components/fpspreadsheet/xlsbiff8.pas | 3 ++- components/fpspreadsheet/xlscommon.pas | 25 +++++++++++++++++++ 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index dd8059a3c..7b43aadad 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -240,7 +240,7 @@ type TRow = record Row: Cardinal; - Height: Single; // in milimeters + Height: Single; // in millimeters end; PRow = ^TRow; @@ -310,6 +310,7 @@ type { Properties } property Cells: TAVLTree read FCells; property Cols: TIndexedAVLTree read FCols; + property Rows: TIndexedAVLTree read FRows; end; { TsWorkbook } @@ -358,7 +359,7 @@ type TsCustomSpreadReader = class protected FWorkbook: TsWorkbook; - FCurrentWorksheet: TsWorksheet; + FWorksheet: TsWorksheet; public constructor Create; virtual; // To allow descendents to override it { General writing methods } diff --git a/components/fpspreadsheet/fpspreadsheetgrid.pas b/components/fpspreadsheet/fpspreadsheetgrid.pas index 2964f5538..5e6aa13a0 100644 --- a/components/fpspreadsheet/fpspreadsheetgrid.pas +++ b/components/fpspreadsheet/fpspreadsheetgrid.pas @@ -25,6 +25,7 @@ type FWorksheet: TsWorksheet; FDisplayFixedColRow: Boolean; function CalcColWidth(AWidth: Single): Integer; + function CalcRowHeight(AHeight: Single): Integer; procedure SetDisplayFixedColRow(const AValue: Boolean); { Private declarations } protected @@ -175,6 +176,9 @@ begin inherited Destroy; end; +// Converts the column width, given in "characters", to pixels +// All chars are assumed to have the same width defined by the "0". +// Therefore, this calculation is only approximate. function TsCustomWorksheetGrid.CalcColWidth(AWidth: Single): Integer; var w0: Integer; @@ -183,6 +187,12 @@ begin Result := Round(AWidth * w0); end; +// Converts the row height, given in mm, to pixels +function TsCustomWorksheetGrid.CalcRowHeight(AHeight: Single): Integer; +begin + Result := round(AHeight / 25.4 * Screen.PixelsPerInch); +end; + procedure TsCustomWorksheetGrid.DoPrepareCanvas(ACol, ARow: Integer; AState: TGridDrawState); var @@ -309,6 +319,7 @@ procedure TsCustomWorksheetGrid.Setup; var i: Integer; lCol: PCol; + lRow: PRow; begin if (FWorksheet = nil) or (FWorksheet.GetCellCount = 0) then begin if FDisplayFixedColRow then begin @@ -351,6 +362,20 @@ begin ColWidths[i] := DefaultColWidth; end; end; + if FWorksheet <> nil then begin + RowHeights[0] := DefaultRowHeight; + for i := FixedRows to RowCount-1 do begin + lRow := FWorksheet.FindRow(i - FixedRows); + if (lRow <> nil) then + RowHeights[i] := CalcRowHeight(lRow^.Height) + else + RowHeights[i] := DefaultRowHeight; + end + end + else + for i:=0 to RowCount-1 do begin + RowHeights[i] := DefaultRowHeight; + end; Invalidate; end; diff --git a/components/fpspreadsheet/fpsutils.pas b/components/fpspreadsheet/fpsutils.pas index c63925141..feb3317a8 100644 --- a/components/fpspreadsheet/fpsutils.pas +++ b/components/fpspreadsheet/fpsutils.pas @@ -54,6 +54,9 @@ function GetColString(AColIndex: Integer): String; function UTF8TextToXMLText(AText: ansistring): ansistring; +function TwipsToMillimeters(AValue: Integer): Single; +function MillimetersToTwips(AValue: Single): Integer; + implementation { @@ -431,5 +434,18 @@ begin Result:=WrkStr; end; +{ Excel's unit of row heights is "twips", i.e. 1/20 point. 72 pts = 1 inch = 25.4 mm + The procedure TwipsToMillimeters performs the conversion to millimeters. } +function TwipsToMillimeters(AValue: Integer): Single; +begin + Result := 25.4 * AValue / (20 * 72); +end; + +{ Converts Millimeters to Twips, i.e. 1/20 pt } +function MillimetersToTwips(AValue: Single): Integer; +begin + Result := Round((AValue * 20 * 72) / 25.4); +end; + end. diff --git a/components/fpspreadsheet/wikitable.pas b/components/fpspreadsheet/wikitable.pas index 732dcd8b2..4392cc9ec 100644 --- a/components/fpspreadsheet/wikitable.pas +++ b/components/fpspreadsheet/wikitable.pas @@ -59,8 +59,6 @@ type { TsWikiTableReader } TsWikiTableReader = class(TsCustomSpreadReader) - private - FWorksheet: TsWorksheet; public SubFormat: TsSpreadsheetFormat; { General reading methods } diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index 2f95e2b6b..463d0ea7a 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -93,7 +93,6 @@ type private RecordSize: Word; PendingRecordSize: SizeInt; - FWorksheet: TsWorksheet; FWorksheetNames: TStringList; FCurrentWorksheet: Integer; FSharedStringTable: TStringList; @@ -202,6 +201,7 @@ const INT_EXCEL_ID_INDEX = $020B; INT_EXCEL_ID_LABEL = $0204; INT_EXCEL_ID_NUMBER = $0203; + INT_EXCEL_ID_ROWINFO = $0208; INT_EXCEL_ID_STYLE = $0293; INT_EXCEL_ID_WINDOW1 = $003D; INT_EXCEL_ID_WINDOW2 = $023E; @@ -1922,6 +1922,7 @@ begin INT_EXCEL_ID_MULRK: ReadMulRKValues(AStream); INT_EXCEL_ID_LABELSST:ReadLabelSST(AStream); //BIFF8 only INT_EXCEL_ID_COLINFO: ReadColInfo(AStream); + INT_EXCEL_ID_ROWINFO: ReadRowInfo(AStream); INT_EXCEL_ID_BOF: ; INT_EXCEL_ID_EOF: SectionEOF := True; else diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas index bb5ed3695..0c54c269d 100644 --- a/components/fpspreadsheet/xlscommon.pas +++ b/components/fpspreadsheet/xlscommon.pas @@ -289,6 +289,8 @@ type procedure ReadCodePage(AStream: TStream); // Figures out what the base year for dates is for this file procedure ReadDateMode(AStream: TStream); + // Read row info + procedure ReadRowInfo(const AStream: TStream); virtual; end; { TsSpreadBIFFWriter } @@ -461,6 +463,29 @@ begin end; end; +// Read the part of the ROW record that is common to all BIFF versions +procedure TsSpreadBIFFReader.ReadRowInfo(const AStream: TStream); +type + TRowRecord = packed record + RowIndex: Word; + Col1: Word; + Col2: Word; + Height: Word; + end; +var + rowrec: TRowRecord; + lRow: PRow; + h: word; +begin + AStream.ReadBuffer(rowrec, SizeOf(TRowRecord)); + h := WordLEToN(rowrec.Height); + if h and $8000 = 0 then begin // if this bit were set, rowheight would be default + lRow := FWorksheet.GetRow(WordLEToN(rowrec.RowIndex)); + // Row height is encoded into the 15 remaining bits in units "twips" (1/20 pt) + lRow^.Height := TwipsToMillimeters(h and $7FFF); + end; +end; + function TsSpreadBIFFWriter.FPSColorToExcelPalette(AColor: TsColor): Word; begin case AColor of