2018-03-18 17:49:53 +00:00
|
|
|
{-----------------------------------------------------------------------------
|
|
|
|
The contents of this file are subject to the Mozilla Public License
|
|
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
|
|
|
|
The Original Code is: JvMarkupLabel.PAS, released on 2002-06-15.
|
|
|
|
|
|
|
|
The Initial Developer of the Original Code is Jan Verhoeven [jan1 dott verhoeven att wxs dott nl]
|
|
|
|
Portions created by Jan Verhoeven are Copyright (C) 2002 Jan Verhoeven.
|
|
|
|
All Rights Reserved.
|
|
|
|
|
|
|
|
Contributor(s):
|
|
|
|
Robert Love [rlove att slcdug dott org].
|
|
|
|
Lionel Reynaud
|
|
|
|
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
|
|
located at http://jvcl.delphi-jedi.org
|
|
|
|
|
|
|
|
Known Issues:
|
|
|
|
-----------------------------------------------------------------------------}
|
|
|
|
// $Id$
|
|
|
|
|
|
|
|
unit JvMarkupLabel;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2018-03-23 08:46:50 +00:00
|
|
|
Graphics, Controls, SysUtils, Classes,
|
2018-03-18 17:49:53 +00:00
|
|
|
JvMarkupCommon;
|
|
|
|
|
|
|
|
type
|
|
|
|
TJvMarkupLabel = class(TGraphicControl) //TJvPubGraphicControl)
|
|
|
|
private
|
|
|
|
FElementStack: TJvHTMLElementStack;
|
|
|
|
FTagStack: TJvHTMLElementStack;
|
|
|
|
FMarginLeft: Integer;
|
|
|
|
FMarginRight: Integer;
|
|
|
|
FMarginTop: Integer;
|
|
|
|
FAlignment: TAlignment;
|
|
|
|
FText: TCaption;
|
2020-01-01 18:33:32 +00:00
|
|
|
procedure RefreshLabel;
|
2018-03-18 17:49:53 +00:00
|
|
|
procedure ParseHTML(S: string);
|
|
|
|
procedure RenderHTML;
|
|
|
|
procedure HTMLClearBreaks;
|
|
|
|
procedure HTMLElementDimensions;
|
|
|
|
procedure SetMarginLeft(const Value: Integer);
|
|
|
|
procedure SetMarginRight(const Value: Integer);
|
|
|
|
procedure SetMarginTop(const Value: Integer);
|
|
|
|
procedure SetAlignment(const Value: TAlignment);
|
|
|
|
// procedure DoReadBackColor(Reader: TReader);
|
|
|
|
protected
|
|
|
|
// procedure FontChanged; override;
|
2020-01-01 18:33:32 +00:00
|
|
|
procedure Loaded; override;
|
2018-03-18 17:49:53 +00:00
|
|
|
procedure SetText(const Value: TCaption);
|
|
|
|
procedure SetAutoSize(Value: Boolean); override;
|
|
|
|
// procedure DefineProperties(Filer: TFiler); override;
|
|
|
|
public
|
|
|
|
constructor Create(AOwner: TComponent); override;
|
|
|
|
destructor Destroy; override;
|
|
|
|
procedure Paint; override;
|
|
|
|
published
|
|
|
|
property Height default 100;
|
|
|
|
property Width default 200;
|
|
|
|
property MarginLeft: Integer read FMarginLeft write SetMarginLeft default 5;
|
|
|
|
property MarginRight: Integer read FMarginRight write SetMarginRight default 5;
|
|
|
|
property MarginTop: Integer read FMarginTop write SetMarginTop default 5;
|
|
|
|
property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
|
|
|
|
property Text: TCaption read FText write SetText;
|
|
|
|
property AutoSize;
|
|
|
|
property Align;
|
|
|
|
property Font;
|
|
|
|
property Anchors;
|
|
|
|
property BorderSpacing;
|
|
|
|
property Constraints;
|
|
|
|
property Enabled;
|
|
|
|
property Color default clBtnFace; // Duplicates BackColor
|
|
|
|
property ParentColor default True;
|
|
|
|
property ParentFont;
|
|
|
|
property ParentShowHint;
|
|
|
|
property PopupMenu;
|
|
|
|
property ShowHint;
|
|
|
|
property Visible;
|
|
|
|
property OnClick;
|
|
|
|
property OnContextPopup;
|
|
|
|
property OnDblClick;
|
|
|
|
property OnDragDrop;
|
|
|
|
property OnDragOver;
|
|
|
|
property OnEndDrag;
|
|
|
|
property OnMouseDown;
|
|
|
|
property OnMouseMove;
|
|
|
|
property OnMouseUp;
|
|
|
|
property OnMouseEnter;
|
|
|
|
property OnMouseLeave;
|
|
|
|
property OnStartDrag;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2019-05-29 16:06:12 +00:00
|
|
|
Themes;
|
2018-03-18 17:49:53 +00:00
|
|
|
|
|
|
|
constructor TJvMarkupLabel.Create(AOwner: TComponent);
|
|
|
|
begin
|
|
|
|
inherited Create(AOwner);
|
|
|
|
//IncludeThemeStyle(Self, [csParentBackground]);
|
|
|
|
FElementStack := TJvHTMLElementStack.Create;
|
|
|
|
FTagStack := TJvHTMLElementStack.Create;
|
|
|
|
FAlignment := taLeftJustify;
|
|
|
|
Width := 200;
|
|
|
|
Height := 100;
|
|
|
|
FMarginLeft := 5;
|
|
|
|
FMarginRight := 5;
|
|
|
|
FMarginTop := 5;
|
|
|
|
Color := clBtnFace;
|
|
|
|
ParentColor := True;
|
|
|
|
end;
|
|
|
|
|
|
|
|
destructor TJvMarkupLabel.Destroy;
|
|
|
|
begin
|
|
|
|
FElementStack.Free;
|
|
|
|
FTagStack.Free;
|
|
|
|
inherited Destroy;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.HTMLClearBreaks;
|
|
|
|
var
|
|
|
|
I, C: Integer;
|
|
|
|
El: TJvHTMLElement;
|
|
|
|
begin
|
|
|
|
C := FElementStack.Count;
|
|
|
|
if C = 0 then
|
|
|
|
Exit;
|
|
|
|
for I := 0 to C - 1 do
|
|
|
|
begin
|
|
|
|
El := TJvHTMLElement(FElementStack.Items[I]);
|
|
|
|
El.SolText := '';
|
|
|
|
El.EolText := '';
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.HTMLElementDimensions;
|
|
|
|
var
|
|
|
|
I, C: Integer;
|
|
|
|
El: TJvHTMLElement;
|
|
|
|
H, A, W: Integer;
|
|
|
|
tm: TLCLTextMetric;
|
|
|
|
//m: TTextMetric;
|
|
|
|
S: string;
|
|
|
|
begin
|
|
|
|
C := FElementStack.Count;
|
|
|
|
if C = 0 then
|
|
|
|
Exit;
|
|
|
|
for I := 0 to C - 1 do
|
|
|
|
begin
|
|
|
|
El := TJvHTMLElement(FElementStack.Items[I]);
|
|
|
|
S := El.Text;
|
|
|
|
Canvas.Font.Name := El.FontName;
|
|
|
|
Canvas.Font.Size := El.FontSize;
|
|
|
|
Canvas.Font.Style := El.FontStyle;
|
|
|
|
Canvas.Font.Color := El.FontColor;
|
|
|
|
Canvas.GetTextMetrics(tm);
|
|
|
|
// GetTextMetrics(Canvas.Handle, Tm);
|
|
|
|
H := tm.Height;
|
|
|
|
A := tm.Ascender;
|
|
|
|
W := Canvas.TextWidth(S);
|
|
|
|
El.Height := H;
|
|
|
|
El.Ascent := A;
|
|
|
|
El.Width := W;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2020-01-01 18:33:32 +00:00
|
|
|
procedure TJvMarkupLabel.RefreshLabel;
|
2018-03-18 17:49:53 +00:00
|
|
|
begin
|
2020-01-01 18:33:32 +00:00
|
|
|
if csLoading in ComponentState then
|
|
|
|
exit;
|
|
|
|
|
2018-03-18 17:49:53 +00:00
|
|
|
ParseHTML(FText);
|
|
|
|
HTMLElementDimensions;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.Paint;
|
|
|
|
begin
|
|
|
|
RenderHTML;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{
|
|
|
|
procedure TJvMarkupLabel.FontChanged;
|
|
|
|
begin
|
|
|
|
inherited FontChanged;
|
2020-01-01 18:33:32 +00:00
|
|
|
RefreshLabel;
|
2018-03-18 17:49:53 +00:00
|
|
|
end;
|
|
|
|
}
|
|
|
|
|
2020-01-01 18:33:32 +00:00
|
|
|
procedure TJvMarkupLabel.Loaded;
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
RefreshLabel;
|
|
|
|
end;
|
|
|
|
|
2018-03-18 17:49:53 +00:00
|
|
|
procedure TJvMarkupLabel.ParseHTML(S: string);
|
|
|
|
var
|
|
|
|
P: Integer;
|
|
|
|
SE, ST: string;
|
|
|
|
lText: string;
|
|
|
|
lStyle: TFontStyles;
|
|
|
|
lName: string;
|
|
|
|
lSize: Integer;
|
|
|
|
lBreakLine: Boolean;
|
2022-05-07 15:47:09 +00:00
|
|
|
lPosition: TJvHtmlTextPos;
|
2018-03-18 17:49:53 +00:00
|
|
|
AColor, lColor: TColor;
|
|
|
|
Element: TJvHTMLElement;
|
|
|
|
|
|
|
|
function HTMLStringToColor(V: string; var Col: TColor): Boolean;
|
|
|
|
var
|
|
|
|
VV: string;
|
|
|
|
begin
|
|
|
|
Result := False;
|
|
|
|
if Length(V) < 2 then
|
|
|
|
Exit;
|
|
|
|
if not CharInSet(V[1], ['#', '$']) then
|
|
|
|
begin
|
|
|
|
// allow the use of both "clBlack" and "Black"
|
|
|
|
if Pos('cl', AnsiLowerCase(V)) = 1 then
|
|
|
|
VV := V
|
|
|
|
else
|
|
|
|
VV := 'cl' + V;
|
|
|
|
try
|
|
|
|
Col := StringToColor(VV);
|
|
|
|
Result := True;
|
|
|
|
except
|
|
|
|
Result := False;
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
// this is either #FFFFFF or $FFFFFF - we treat them the same
|
|
|
|
begin
|
|
|
|
try
|
|
|
|
VV := '$' + Copy(V, 6, 2) + Copy(V, 4, 2) + Copy(V, 2, 2);
|
|
|
|
Col := StringToColor(VV);
|
|
|
|
Result := True;
|
|
|
|
except
|
|
|
|
Result := False;
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure PushTag;
|
|
|
|
begin
|
|
|
|
Element := TJvHTMLElement.Create;
|
|
|
|
Element.FontName := lName;
|
|
|
|
Element.FontSize := lSize;
|
|
|
|
Element.FontStyle := lStyle;
|
|
|
|
Element.FontColor := lColor;
|
|
|
|
FTagStack.Push(Element);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure PopTag;
|
|
|
|
begin
|
|
|
|
Element := FTagStack.Pop;
|
|
|
|
if Element <> nil then
|
|
|
|
begin
|
|
|
|
lName := Element.FontName;
|
|
|
|
lSize := Element.FontSize;
|
|
|
|
lStyle := Element.FontStyle;
|
|
|
|
lColor := Element.FontColor;
|
|
|
|
Element.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure PushElement;
|
|
|
|
begin
|
|
|
|
Element := TJvHTMLElement.Create;
|
|
|
|
Element.Text := lText;
|
|
|
|
Element.FontName := lName;
|
|
|
|
Element.FontSize := lSize;
|
|
|
|
Element.FontStyle := lStyle;
|
|
|
|
Element.FontColor := lColor;
|
2022-05-07 15:47:09 +00:00
|
|
|
Element.Position := lPosition;
|
2018-03-18 17:49:53 +00:00
|
|
|
Element.BreakLine := lBreakLine;
|
|
|
|
lBreakLine := False;
|
|
|
|
FElementStack.Push(Element);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure ParseTag(SS: string);
|
|
|
|
var
|
|
|
|
PP: Integer;
|
|
|
|
ATag, APar, AVal: string;
|
|
|
|
HaveParams: Boolean;
|
|
|
|
begin
|
|
|
|
SS := Trim(SS);
|
|
|
|
HaveParams := False;
|
|
|
|
PP := Pos(' ', SS);
|
|
|
|
if PP = 0 then
|
|
|
|
ATag := SS // tag only
|
|
|
|
else
|
|
|
|
begin // tag + attributes
|
|
|
|
ATag := Copy(SS, 1, PP - 1);
|
|
|
|
SS := Trim(Copy(SS, PP + 1, Length(SS)));
|
|
|
|
HaveParams := True;
|
|
|
|
end;
|
|
|
|
// handle ATag
|
|
|
|
ATag := LowerCase(ATag);
|
|
|
|
if ATag = 'br' then
|
|
|
|
lBreakLine := True
|
|
|
|
else
|
|
|
|
if ATag = 'b' then
|
|
|
|
begin // bold
|
|
|
|
PushTag;
|
|
|
|
lStyle := lStyle + [fsBold];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = '/b' then
|
|
|
|
begin // cancel bold
|
|
|
|
lStyle := lStyle - [fsBold];
|
|
|
|
PopTag;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = 'i' then
|
|
|
|
begin // italic
|
|
|
|
PushTag;
|
|
|
|
lStyle := lStyle + [fsItalic];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = '/i' then
|
|
|
|
begin // cancel italic
|
|
|
|
lStyle := lStyle - [fsItalic];
|
|
|
|
PopTag;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = 'u' then
|
|
|
|
begin // underline
|
|
|
|
PushTag;
|
|
|
|
lStyle := lStyle + [fsUnderline];
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = '/u' then
|
|
|
|
begin // cancel underline
|
|
|
|
lStyle := lStyle - [fsUnderline];
|
|
|
|
PopTag;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if ATag = 'font' then
|
|
|
|
PushTag
|
|
|
|
else
|
|
|
|
if ATag = '/font' then
|
2022-05-07 15:47:09 +00:00
|
|
|
PopTag
|
|
|
|
else
|
|
|
|
if ATag = 'sub' then
|
|
|
|
lPosition := tpSubscript
|
|
|
|
else
|
|
|
|
if ATag = 'sup' then
|
|
|
|
lPosition := tpSuperscript
|
|
|
|
else if (ATag = '/sub') or (ATag = '/sup') then
|
|
|
|
lPosition := tpNormal
|
|
|
|
else
|
2018-03-18 17:49:53 +00:00
|
|
|
if HaveParams then
|
|
|
|
begin
|
|
|
|
repeat
|
|
|
|
PP := Pos('="', SS);
|
|
|
|
if PP > 0 then
|
|
|
|
begin
|
|
|
|
APar := LowerCase(Trim(Copy(SS, 1, PP - 1)));
|
|
|
|
Delete(SS, 1, PP + 1);
|
|
|
|
PP := Pos('"', SS);
|
|
|
|
if PP > 0 then
|
|
|
|
begin
|
|
|
|
AVal := Copy(SS, 1, PP - 1);
|
|
|
|
Delete(SS, 1, PP);
|
|
|
|
if APar = 'face' then
|
|
|
|
lName := AVal
|
|
|
|
else
|
|
|
|
if APar = 'size' then
|
|
|
|
try
|
|
|
|
lSize := StrToInt(AVal);
|
|
|
|
except
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if APar = 'color' then
|
|
|
|
try
|
|
|
|
if HTMLStringToColor(AVal, AColor) then
|
|
|
|
lColor := AColor;
|
|
|
|
except
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
until PP = 0;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
FElementStack.Clear;
|
|
|
|
FTagStack.Clear;
|
|
|
|
lStyle := Font.Style;
|
|
|
|
lName := Font.Name;
|
|
|
|
lSize := Font.Size;
|
|
|
|
lColor := Font.Color;
|
|
|
|
lBreakLine := False;
|
2022-05-07 15:47:09 +00:00
|
|
|
lPosition := tpNormal;
|
2018-03-18 17:49:53 +00:00
|
|
|
repeat
|
|
|
|
P := Pos('<', S);
|
|
|
|
if P = 0 then
|
|
|
|
begin
|
|
|
|
lText := S;
|
|
|
|
PushElement;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
if P > 1 then
|
|
|
|
begin
|
|
|
|
SE := Copy(S, 1, P - 1);
|
|
|
|
lText := SE;
|
|
|
|
PushElement;
|
|
|
|
Delete(S, 1, P - 1);
|
|
|
|
end;
|
|
|
|
P := Pos('>', S);
|
|
|
|
if P > 0 then
|
|
|
|
begin
|
|
|
|
ST := Copy(S, 2, P - 2);
|
|
|
|
Delete(S, 1, P);
|
|
|
|
ParseTag(ST);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
until P = 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.RenderHTML;
|
|
|
|
var
|
|
|
|
R: TRect;
|
2022-05-07 14:51:41 +00:00
|
|
|
I, C, X, Y, W: Integer;
|
2018-03-18 17:49:53 +00:00
|
|
|
ATotalWidth, AClientWidth, ATextWidth, BaseLine: Integer;
|
|
|
|
iSol, iEol, PendingCount, MaxHeight, MaxAscent: Integer;
|
|
|
|
El: TJvHTMLElement;
|
|
|
|
Eol: Boolean;
|
|
|
|
PendingBreak: Boolean;
|
|
|
|
lSolText: string;
|
|
|
|
MaxWidth: Integer;
|
|
|
|
|
|
|
|
procedure SetFont(EE: TJvHTMLElement);
|
|
|
|
begin
|
|
|
|
with Canvas do
|
|
|
|
begin
|
|
|
|
Font.Name := EE.FontName;
|
|
|
|
Font.Size := EE.FontSize;
|
|
|
|
Font.Style := EE.FontStyle;
|
|
|
|
Font.Color := EE.FontColor;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure RenderString(EE: TJvHTMLElement; Test: Boolean);
|
|
|
|
var
|
|
|
|
SS: string;
|
|
|
|
WW: Integer;
|
2022-05-07 15:47:09 +00:00
|
|
|
yy: Integer;
|
|
|
|
oldFontHeight: Integer;
|
|
|
|
fd: TFontData;
|
2018-03-18 17:49:53 +00:00
|
|
|
begin
|
|
|
|
SetFont(EE);
|
|
|
|
if EE.SolText <> '' then
|
|
|
|
begin
|
2022-05-07 15:47:09 +00:00
|
|
|
oldFontHeight := Canvas.Font.Height;
|
|
|
|
|
2018-03-18 17:49:53 +00:00
|
|
|
SS := TrimLeft(EE.SolText);
|
2022-05-07 15:47:09 +00:00
|
|
|
|
|
|
|
case EE.Position of
|
|
|
|
tpNormal:
|
|
|
|
yy := Y + BaseLine - EE.Ascent;
|
|
|
|
tpSubscript:
|
|
|
|
begin
|
|
|
|
fd := GetFontData(Canvas.Font.Reference.Handle);
|
|
|
|
Canvas.Font.Height := fd.Height * 7 div 10;
|
|
|
|
yy := Y + MaxHeight - abs(fd.Height);
|
|
|
|
end;
|
|
|
|
tpSuperscript:
|
|
|
|
begin
|
|
|
|
fd := GetFontData(Canvas.Font.Reference.Handle);
|
|
|
|
Canvas.Font.Height := fd.Height * 7 div 10;
|
|
|
|
yy := Y;
|
|
|
|
end;
|
|
|
|
end;
|
2018-03-18 17:49:53 +00:00
|
|
|
WW := Canvas.TextWidth(SS);
|
|
|
|
if not Test then
|
2022-05-07 15:47:09 +00:00
|
|
|
Canvas.TextOut(X, yy, SS);
|
2018-03-18 17:49:53 +00:00
|
|
|
X := X + WW;
|
2022-05-07 15:47:09 +00:00
|
|
|
|
|
|
|
if EE.Position <> tpNormal then
|
|
|
|
Canvas.Font.Height := oldFontHeight;
|
2018-03-18 17:49:53 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
iEol := 0; // Not Needed but removes warning.
|
|
|
|
R := ClientRect;
|
|
|
|
Canvas.Brush.Color := Color;
|
|
|
|
Canvas.FillRect(R);
|
|
|
|
//DrawThemedBackground(Self, Canvas, R);
|
|
|
|
C := FElementStack.Count;
|
|
|
|
if C = 0 then
|
|
|
|
Exit;
|
|
|
|
HTMLClearBreaks;
|
|
|
|
if AutoSize then
|
|
|
|
AClientWidth := 10000
|
|
|
|
else
|
|
|
|
AClientWidth := ClientWidth - MarginLeft - MarginRight;
|
|
|
|
|
|
|
|
Canvas.Brush.Style := bsClear;
|
|
|
|
Y := MarginTop;
|
|
|
|
iSol := 0;
|
|
|
|
PendingBreak := False;
|
|
|
|
PendingCount := -1;
|
|
|
|
MaxWidth := 0;
|
|
|
|
repeat
|
|
|
|
I := iSol;
|
|
|
|
ATotalWidth := AClientWidth;
|
|
|
|
ATextWidth := 0;
|
|
|
|
MaxHeight := 0;
|
|
|
|
MaxAscent := 0;
|
|
|
|
Eol := False;
|
|
|
|
repeat // scan line
|
|
|
|
El := TJvHTMLElement(FElementStack.Items[I]);
|
|
|
|
if El.BreakLine then
|
|
|
|
begin
|
|
|
|
if not PendingBreak and (PendingCount <> I) then
|
|
|
|
begin
|
|
|
|
PendingBreak := True;
|
|
|
|
PendingCount := I;
|
|
|
|
iEol := I;
|
|
|
|
Break;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
PendingBreak := False;
|
|
|
|
end;
|
|
|
|
if El.Height > MaxHeight then
|
|
|
|
MaxHeight := El.Height;
|
|
|
|
if El.Ascent > MaxAscent then
|
|
|
|
MaxAscent := El.Ascent;
|
|
|
|
if El.Text <> '' then
|
|
|
|
begin
|
|
|
|
lSolText := El.SolText;
|
|
|
|
// (Lionel) If Breakup can do something, I increase a bit the space until
|
|
|
|
// it can do the break ...
|
|
|
|
repeat
|
|
|
|
El.Breakup(Canvas, ATotalWidth);
|
|
|
|
Inc(ATotalWidth, 5);
|
|
|
|
until lSolText <> El.SolText;
|
|
|
|
end;
|
|
|
|
if El.SolText <> '' then
|
|
|
|
begin
|
2022-05-07 14:51:41 +00:00
|
|
|
W := Canvas.TextWidth(El.SolText);
|
|
|
|
ATotalWidth := ATotalWidth - W - 5;
|
|
|
|
ATextWidth := ATextWidth + W;
|
2018-03-18 17:49:53 +00:00
|
|
|
if El.EolText = '' then
|
|
|
|
begin
|
|
|
|
if I >= C - 1 then
|
|
|
|
begin
|
|
|
|
Eol := True;
|
|
|
|
iEol := I;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
Inc(I);
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
Eol := True;
|
|
|
|
iEol := I;
|
|
|
|
end;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin // Eol
|
|
|
|
Eol := True;
|
|
|
|
iEol := I;
|
|
|
|
end;
|
|
|
|
until Eol;
|
|
|
|
|
|
|
|
// render line
|
|
|
|
BaseLine := MaxAscent;
|
|
|
|
|
|
|
|
if AutoSize then
|
|
|
|
begin
|
|
|
|
X := MarginLeft;
|
|
|
|
if (ATextWidth + MarginLeft + MarginRight) > MaxWidth then
|
|
|
|
MaxWidth := (ATextWidth + MarginLeft + MarginRight);
|
|
|
|
end
|
|
|
|
else
|
|
|
|
case Alignment of
|
|
|
|
taLeftJustify:
|
|
|
|
X := MarginLeft;
|
|
|
|
taRightJustify:
|
|
|
|
X := Width - MarginRight - ATextWidth;
|
|
|
|
taCenter:
|
|
|
|
X := MarginLeft + (Width - MarginLeft - MarginRight - ATextWidth) div 2;
|
|
|
|
end;
|
|
|
|
|
|
|
|
for I := iSol to iEol do
|
|
|
|
begin
|
|
|
|
El := TJvHTMLElement(FElementStack.Items[I]);
|
|
|
|
RenderString(El, False);
|
|
|
|
end;
|
|
|
|
|
|
|
|
Y := Y + MaxHeight;
|
|
|
|
iSol := iEol;
|
|
|
|
until (iEol >= C - 1) and (El.EolText = '');
|
|
|
|
if AutoSize then
|
|
|
|
begin
|
|
|
|
Width := MaxWidth;
|
|
|
|
Height := Y + 5;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetAlignment(const Value: TAlignment);
|
|
|
|
begin
|
|
|
|
if Value <> FAlignment then
|
|
|
|
begin
|
|
|
|
FAlignment := Value;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetAutoSize(Value: Boolean);
|
|
|
|
begin
|
|
|
|
inherited SetAutoSize(Value);
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetMarginLeft(const Value: Integer);
|
|
|
|
begin
|
|
|
|
FMarginLeft := Value;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetMarginRight(const Value: Integer);
|
|
|
|
begin
|
|
|
|
FMarginRight := Value;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetMarginTop(const Value: Integer);
|
|
|
|
begin
|
|
|
|
FMarginTop := Value;
|
|
|
|
Invalidate;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetText(const Value: TCaption);
|
|
|
|
var
|
|
|
|
S: string;
|
|
|
|
begin
|
|
|
|
if Value = FText then
|
|
|
|
Exit;
|
|
|
|
S := Value;
|
|
|
|
S := StringReplace(S, SLineBreak, ' ', [rfReplaceAll]);
|
|
|
|
S := TrimRight(S);
|
|
|
|
FText := S;
|
2020-01-01 18:33:32 +00:00
|
|
|
RefreshLabel;
|
2018-03-18 17:49:53 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{function TJvMarkupLabel.GetBackColor: TColor;
|
|
|
|
begin
|
|
|
|
Result := Color;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.SetBackColor(const Value: TColor);
|
|
|
|
begin
|
|
|
|
Color := Value;
|
|
|
|
end;}
|
|
|
|
{
|
|
|
|
procedure TJvMarkupLabel.DoReadBackColor(Reader: TReader);
|
|
|
|
begin
|
|
|
|
if Reader.NextValue = vaIdent then
|
|
|
|
Color := StringToColor(Reader.ReadIdent)
|
|
|
|
else
|
|
|
|
Color := Reader.ReadInteger;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TJvMarkupLabel.DefineProperties(Filer: TFiler);
|
|
|
|
begin
|
|
|
|
inherited DefineProperties(Filer);
|
|
|
|
Filer.DefineProperty('BackColor', @DoReadBackColor, nil, False);
|
|
|
|
end;
|
|
|
|
}
|
|
|
|
|
|
|
|
end.
|