From e0b25c8f51e06af77c0b4e07a164184ca972ff38 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Fri, 10 Jul 2015 09:13:19 +0000 Subject: [PATCH] fpspreadsheet: Fix WorksheetGrid hanging if cell text contains a manual line break. Fix reading of new subscript and superscript font properties for biff5 and biff8 (Rich-text support not yet fully working here). git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4208 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/fpspreadsheet/fpsvisualutils.pas | 8 +++---- components/fpspreadsheet/xlsbiff5.pas | 15 ++++++++++--- components/fpspreadsheet/xlsbiff8.pas | 24 ++++++++++++++++----- components/fpspreadsheet/xlscommon.pas | 11 +++++++--- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/components/fpspreadsheet/fpsvisualutils.pas b/components/fpspreadsheet/fpsvisualutils.pas index bb57b42bd..d8635b521 100644 --- a/components/fpspreadsheet/fpsvisualutils.pas +++ b/components/fpspreadsheet/fpsvisualutils.pas @@ -328,10 +328,10 @@ var end; #13, #10: begin - dec(p); - width := savedWidth; - numSpaces := savedspaces; - PendingRtpIndex := savedRtpIndex; + // dec(p); + //width := savedWidth; + //numSpaces := savedspaces; + //PendingRtpIndex := savedRtpIndex; exit; end; else begin diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas index 14cd0195d..e027a9727 100755 --- a/components/fpspreadsheet/xlsbiff5.pas +++ b/components/fpspreadsheet/xlsbiff5.pas @@ -643,7 +643,7 @@ begin // Font index i := WordLEToN(rec.FontIndex); - if i > 4 then dec(i); // Watch out for the nasty missing font #4... +// if i > 4 then dec(i); // Watch out for the nasty missing font #4... fmt.FontIndex := FixFontIndex(i); { fnt := TsFont(FFontList[i]); @@ -823,6 +823,7 @@ var lOptions: Word; lColor: Word; lWeight: Word; + lEsc: Word; Len: Byte; fontname: ansistring; font: TsFont; @@ -859,10 +860,15 @@ begin { Font weight } lWeight := WordLEToN(AStream.ReadWord); - if lWeight = 700 then Include(font.Style, fssBold); + if lWeight >= 700 then Include(font.Style, fssBold); { Escapement type } - AStream.ReadWord(); + lEsc := WordLEToN(AStream.ReadWord); + case lEsc of + 0: ; + 1: font.Position := fpSuperscript; + 2: font.Position := fpSubscript; + end; { Underline type } if AStream.ReadByte > 0 then Include(font.Style, fssUnderline); @@ -889,6 +895,9 @@ begin as the font index in the internal list may be different from the index in the workbook's list. } FFontList.Add(font); + + { Excel does not have zero-based font #4! } + if FFontList.Count = 4 then FFontList.Add(nil); end; // Read the FORMAT record for formatting numerical data diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas index acc3ef211..1fef0cbb7 100755 --- a/components/fpspreadsheet/xlsbiff8.pas +++ b/components/fpspreadsheet/xlsbiff8.pas @@ -924,6 +924,7 @@ var XF: Word; AStrValue: ansistring; cell: PCell; + rtfRuns: TsRichTextFormattingRuns; begin ReadRowColXF(AStream, ARow, ACol, XF); @@ -940,15 +941,18 @@ begin { Save the data } FWorksheet.WriteUTF8Text(cell, AStrValue); - //Read formatting runs (not supported) + + // Read rich-text formatting runs B := WordLEtoN(AStream.ReadWord); + SetLength(rtfRuns, B); for L := 0 to B-1 do begin - AStream.ReadWord; // First formatted character - AStream.ReadWord; // Index to FONT record + rtfRuns[L].FirstIndex := WordLEToN(AStream.ReadWord); // Index of first formatted character + rtfRuns[L].FontIndex := WordLEToN(AStream.ReadByte); // Index of font used end; {Add attributes} ApplyCellFormatting(cell, XF); + ApplyRichTextFormattingRuns(cell, rtfRuns); if FIsVirtualMode then Workbook.OnReadCellData(Workbook, ARow, ACol, cell); @@ -1235,7 +1239,7 @@ begin // Font index i := WordLEToN(rec.FontIndex); - if i > 4 then dec(i); // Watch out for the nasty missing font #4... +// if i > 4 then dec(i); // Watch out for the nasty missing font #4... fnt := TsFont(FFontList[i]); fmt.FontIndex := Workbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color); if fmt.FontIndex = -1 then @@ -1396,6 +1400,7 @@ var lOptions: Word; lColor: Word; lWeight: Word; + lEsc: Word; Len: Byte; font: TsFont; begin @@ -1434,7 +1439,13 @@ begin if lWeight = 700 then Include(font.Style, fssBold); { Escape type } - AStream.ReadWord(); + { Escapement type } + lEsc := WordLEToN(AStream.ReadWord); + case lEsc of + 0: ; + 1: font.Position := fpSuperscript; + 2: font.Position := fpSubscript; + end; { Underline type } if AStream.ReadByte > 0 then Include(font.Style, fssUnderline); @@ -1459,6 +1470,9 @@ begin the font index in the internal list (= index in file) is not the same as the index the font will have in the workbook's fontlist! } FFontList.Add(font); + + { Excel does not have zero-based font #4! } + if FFontList.Count = 4 then FFontList.Add(nil); end; {@@ ---------------------------------------------------------------------------- diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas index b67214496..ba63a16ac 100644 --- a/components/fpspreadsheet/xlscommon.pas +++ b/components/fpspreadsheet/xlscommon.pas @@ -988,9 +988,14 @@ var fnt: TsFont; begin fnt := TsFont(FFontList[AFontIndex]); - Result := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position); - if Result = -1 then - Result := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position); + if fnt = nil then // damned font 4! + Result := -1 + else + begin + Result := FWorkbook.FindFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position); + if Result = -1 then + Result := FWorkbook.AddFont(fnt.FontName, fnt.Size, fnt.Style, fnt.Color, fnt.Position); + end; end; {@@ ----------------------------------------------------------------------------