You've already forked lazarus-ccr
fpspreadsheet: Improved worksheet grid row height and col width calculation taking care of rich text formatted cells.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4207 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -891,16 +891,26 @@ end;
|
||||
procedure TsCustomWorksheetGrid.AutoAdjustColumn(ACol: Integer);
|
||||
var
|
||||
gRow: Integer; // row in grid coordinates
|
||||
r: Cardinal;
|
||||
lastRow: Cardinal;
|
||||
w, maxw: Integer;
|
||||
txt: String;
|
||||
cell: PCell;
|
||||
begin
|
||||
if Worksheet = nil then
|
||||
exit;
|
||||
|
||||
lastRow := Worksheet.GetLastOccupiedRowIndex;
|
||||
maxw := -1;
|
||||
for cell in Worksheet.Cells.GetColEnumerator(GetWorkSheetCol(ACol)) do
|
||||
begin
|
||||
gRow := GetGridRow(cell^.Row);
|
||||
txt := GetCellText(ACol, gRow);
|
||||
if txt = '' then
|
||||
Continue;
|
||||
w := RichTextWidth(Canvas, Workbook, Rect(0, 0, MaxInt, MaxInt), txt,
|
||||
Worksheet.ReadCellFontIndex(cell), cell^.RichTextParams,
|
||||
Worksheet.ReadTextRotation(cell), false);
|
||||
if w > maxw then maxw := w;
|
||||
end;
|
||||
{
|
||||
for r := 0 to lastRow do
|
||||
begin
|
||||
gRow := GetGridRow(r);
|
||||
@ -909,6 +919,7 @@ begin
|
||||
w := Canvas.TextWidth(txt);
|
||||
if (txt <> '') and (w > maxw) then maxw := w;
|
||||
end;
|
||||
}
|
||||
if maxw > -1 then
|
||||
maxw := maxw + 2*constCellPadding
|
||||
else
|
||||
@ -2635,11 +2646,11 @@ var
|
||||
lCell: PCell;
|
||||
s: String;
|
||||
wrapped: Boolean;
|
||||
txtR: TRect;
|
||||
cellR: TRect;
|
||||
flags: Cardinal;
|
||||
r1,c1,r2,c2: Cardinal;
|
||||
fmt: PsCellFormat;
|
||||
fntIndex: Integer;
|
||||
txtRot: TsTextRotation;
|
||||
begin
|
||||
Result := 0;
|
||||
if ShowHeaders and ((ACol = 0) or (ARow = 0)) then
|
||||
@ -2650,6 +2661,7 @@ begin
|
||||
lCell := Worksheet.FindCell(ARow-FHeaderCount, ACol-FHeaderCount);
|
||||
if lCell <> nil then
|
||||
begin
|
||||
cellR := CellRect(ACol, ARow);
|
||||
if Worksheet.IsMerged(lCell) then
|
||||
begin
|
||||
Worksheet.FindMergedRange(lCell, r1, c1, r2, c2);
|
||||
@ -2658,12 +2670,38 @@ begin
|
||||
// determination since only the height of the first row of the block
|
||||
// (containing the merge base cell) would change which is very confusing.
|
||||
exit;
|
||||
cellR := CellRect(c1+FHeaderCount, ARow);
|
||||
cellR.Right := CellRect(c2+FHeaderCount, ARow).Right;
|
||||
end;
|
||||
InflateRect(cellR, -constCellPadding, -constCellPadding);
|
||||
|
||||
s := GetCellText(ACol, ARow);
|
||||
if s = '' then
|
||||
exit;
|
||||
|
||||
DoPrepareCanvas(ACol, ARow, []);
|
||||
|
||||
fmt := Workbook.GetPointerToCellFormat(lCell^.FormatIndex);
|
||||
if (uffFont in fmt^.UsedFormattingFields) then
|
||||
fntIndex := fmt^.FontIndex else fntIndex := DEFAULT_FONTINDEX;
|
||||
if (uffTextRotation in fmt^.UsedFormattingFields) then
|
||||
txtRot := fmt^.TextRotation else txtRot := trHorizontal;
|
||||
wrapped := (uffWordWrap in fmt^.UsedFormattingFields);
|
||||
|
||||
case txtRot of
|
||||
trHorizontal: ;
|
||||
rt90DegreeClockwiseRotation,
|
||||
rt90DegreeCounterClockwiseRotation:
|
||||
cellR := Rect(0, 0, MaxInt, MaxInt);
|
||||
rtStacked:
|
||||
cellR := Rect(0, 0, MaxInt, MaxInt);
|
||||
end;
|
||||
|
||||
Result := RichTextHeight(Canvas, Workbook, cellR, s, fntIndex,
|
||||
lCell^.RichTextParams, txtRot, wrapped)
|
||||
+ 2 * constCellPadding;
|
||||
|
||||
(*
|
||||
wrapped := (uffWordWrap in fmt^.UsedFormattingFields)
|
||||
or (fmt^.TextRotation = rtStacked);
|
||||
// *** multi-line text ***
|
||||
@ -2700,6 +2738,7 @@ begin
|
||||
then
|
||||
Result := Canvas.TextWidth(s) + 2*constCellPadding;
|
||||
end;
|
||||
*)
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2760,8 +2799,7 @@ end;
|
||||
function TsCustomWorksheetGrid.GetCellText(ACol, ARow: Integer): String;
|
||||
var
|
||||
cell: PCell;
|
||||
r, c, i: Integer;
|
||||
s: String;
|
||||
r, c: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
|
||||
|
@ -21,9 +21,18 @@ procedure DrawRichText(ACanvas: TCanvas; AWorkbook: TsWorkbook; const ARect: TRe
|
||||
AWordwrap: Boolean; AHorAlignment: TsHorAlignment; AVertAlignment: TsVertAlignment;
|
||||
ARotation: TsTextRotation);
|
||||
|
||||
function RichTextWidth(ACanvas: TCanvas; AWorkbook: TsWorkbook; AMaxRect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
ATextRotation: TsTextRotation; AWordWrap: Boolean): Integer;
|
||||
|
||||
function RichTextHeight(ACanvas: TCanvas; AWorkbook: TsWorkbook; AMaxRect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
ATextRotation: TsTextRotation; AWordWrap: Boolean): Integer;
|
||||
|
||||
{
|
||||
function RichTextWidth(ACanvas: TCanvas; AWorkbook: TsWorkbook; const AText: String;
|
||||
AFontIndex: Integer; ARichTextParams: TsRichTextParams): Integer;
|
||||
|
||||
}
|
||||
|
||||
implementation
|
||||
|
||||
@ -163,10 +172,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure DrawRichText(ACanvas: TCanvas; AWorkbook: TsWorkbook; const ARect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
AWordwrap: Boolean; AHorAlignment: TsHorAlignment; AVertAlignment: TsVertAlignment;
|
||||
ARotation: TsTextRotation);
|
||||
procedure InternalDrawRichText(ACanvas: TCanvas; AWorkbook: TsWorkbook;
|
||||
const ARect: TRect; const AText: String; AFontIndex: Integer;
|
||||
ARichTextParams: TsRichTextParams; AWordwrap: Boolean;
|
||||
AHorAlignment: TsHorAlignment; AVertAlignment: TsVertAlignment;
|
||||
ARotation: TsTextRotation; var Width,Height: Integer; AMeasureOnly: Boolean);
|
||||
type
|
||||
TLineInfo = record
|
||||
pStart, pEnd: PChar;
|
||||
@ -183,7 +193,7 @@ var
|
||||
iRtp: Integer;
|
||||
lineInfo: TLineInfo;
|
||||
lineInfos: Array of TLineInfo = nil;
|
||||
totalHeight, stackPeriod: Integer;
|
||||
totalHeight, linelen, stackPeriod: Integer;
|
||||
|
||||
procedure InitFont(P: PChar; out rtState: TRtState;
|
||||
PendingRtpIndex: Integer; out AHeight: Integer);
|
||||
@ -426,6 +436,7 @@ begin
|
||||
else
|
||||
iRtp := -1;
|
||||
totalHeight := 0;
|
||||
linelen := 0;
|
||||
|
||||
Convert_sFont_to_Font(AWorkbook.GetFont(AFontIndex), ACanvas.Font);
|
||||
if ARotation = rtStacked then
|
||||
@ -444,6 +455,7 @@ begin
|
||||
NextRtpIndex := iRtp;
|
||||
ScanLine(pEnd, NumSpaces, NextRtpIndex, Width, Height);
|
||||
totalHeight := totalHeight + Height;
|
||||
linelen := Max(linelen, Width);
|
||||
iRtp := NextRtpIndex;
|
||||
p := pEnd;
|
||||
case p^ of
|
||||
@ -457,6 +469,14 @@ begin
|
||||
end;
|
||||
until p^ = #0;
|
||||
|
||||
Width := linelen;
|
||||
if ARotation = rtStacked then
|
||||
Height := Length(lineinfos) * stackperiod
|
||||
else
|
||||
Height := totalHeight;
|
||||
if AMeasureOnly then
|
||||
exit;
|
||||
|
||||
// Draw lines
|
||||
// 1/ get starting point of line
|
||||
case ARotation of
|
||||
@ -540,12 +560,59 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function RichTextWidth(ACanvas: TCanvas; AWorkbook: TsWorkbook; const AText: String;
|
||||
AFontIndex: Integer; ARichTextParams: TsRichTextParams): Integer;
|
||||
procedure DrawRichText(ACanvas: TCanvas; AWorkbook: TsWorkbook; const ARect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
AWordwrap: Boolean; AHorAlignment: TsHorAlignment; AVertAlignment: TsVertAlignment;
|
||||
ARotation: TsTextRotation);
|
||||
var
|
||||
w,h: Integer;
|
||||
begin
|
||||
InternalDrawRichText(ACanvas, AWorkbook, ARect, AText, AFontIndex,
|
||||
ARichTextParams, AWordWrap, AHorAlignment, AVertAlignment, ARotation,
|
||||
w, h, false);
|
||||
end;
|
||||
|
||||
function RichTextWidth(ACanvas: TCanvas; AWorkbook: TsWorkbook; AMaxRect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
ATextRotation: TsTextRotation; AWordWrap: Boolean): Integer;
|
||||
var
|
||||
h, w: Integer;
|
||||
begin
|
||||
InternalDrawRichText(ACanvas, AWorkbook, AMaxRect, AText, AFontIndex,
|
||||
ARichTextParams, AWordWrap, haLeft, vaTop, ATextRotation,
|
||||
w, h, true);
|
||||
case ATextRotation of
|
||||
trHorizontal, rtStacked:
|
||||
Result := w;
|
||||
rt90DegreeClockwiseRotation, rt90DegreeCounterClockwiseRotation:
|
||||
Result := h;
|
||||
end;
|
||||
end;
|
||||
|
||||
function RichTextHeight(ACanvas: TCanvas; AWorkbook: TsWorkbook; AMaxRect: TRect;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
ATextRotation: TsTextRotation; AWordWrap: Boolean): Integer;
|
||||
var
|
||||
h, w: Integer;
|
||||
begin
|
||||
InternalDrawRichText(ACanvas, AWorkbook, AMaxRect, AText, AFontIndex,
|
||||
ARichTextParams, AWordWrap, haLeft, vaTop, ATextRotation,
|
||||
w, h, true);
|
||||
case ATextRotation of
|
||||
trHorizontal, rtStacked:
|
||||
Result := h;
|
||||
rt90DegreeClockwiseRotation, rt90DegreeCounterClockwiseRotation:
|
||||
Result := w;
|
||||
end;
|
||||
end;
|
||||
(*
|
||||
function GetRichTextExtent(ACanvas: TCanvas; AWorkbook: TsWorkbook;
|
||||
const AText: String; AFontIndex: Integer; ARichTextParams: TsRichTextParams;
|
||||
ATextRotation: TsTextRotation): TSize;
|
||||
var
|
||||
s: String;
|
||||
p: Integer;
|
||||
w, n: Integer;
|
||||
len, height: Integer;
|
||||
rtp, next_rtp: TsRichTextParam;
|
||||
fnt, fnt0: TsFont;
|
||||
begin
|
||||
@ -557,9 +624,24 @@ begin
|
||||
|
||||
if Length(ARichTextParams) = 0 then
|
||||
begin
|
||||
Result := ACanvas.TextWidth(AText);
|
||||
if fnt0.Position <> fpNormal then
|
||||
Result := Round(Result * SUBSCRIPT_SUPERSCRIPT_FACTOR);
|
||||
Result := ACanvas.TextExtent(AText);
|
||||
if ATextRotation = trHorizontal then
|
||||
exit;
|
||||
len := Result.cx;
|
||||
height := Result.cy;
|
||||
case ATextRotation of
|
||||
rt90DegreeClockwiseRotation,
|
||||
rt90DegreeCounterClockwiseRotation:
|
||||
begin
|
||||
Result.CX := height;
|
||||
Result.CY := len;
|
||||
end;
|
||||
rtStacked:
|
||||
begin
|
||||
Result.CX := ACanvas.TextWidth('M');
|
||||
Restul.CY := UTF8Length(AText) * height;
|
||||
end;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -602,5 +684,5 @@ begin
|
||||
inc(p);
|
||||
end;
|
||||
end;
|
||||
|
||||
*)
|
||||
end.
|
||||
|
Reference in New Issue
Block a user