You've already forked lazarus-ccr
jvcllaz: Support all html entities, and improved painting of subscripts in HTML output (e.g. for TJvHTLabel)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8274 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -871,7 +871,7 @@ function Scale96ToForm(ASize: Integer): Integer;
|
||||
implementation
|
||||
|
||||
uses
|
||||
sysutils, LCLIntf, GraphType, GraphUtil, FPImage, IntfGraphics, Math,
|
||||
sysutils, LCLIntf, GraphType, GraphUtil, FPImage, IntfGraphics, Math, htmldefs, StrUtils,
|
||||
{$IFDEF MSWINDOWS}
|
||||
CommCtrl,
|
||||
{$ENDIF}
|
||||
@ -7125,6 +7125,7 @@ end;
|
||||
const
|
||||
cBR = '<BR>';
|
||||
cBR2 = '<BR/>';
|
||||
cBR3 = '<BR />';
|
||||
cHR = '<HR>';
|
||||
cTagBegin = '<';
|
||||
cTagEnd = '>';
|
||||
@ -7138,34 +7139,83 @@ const
|
||||
cCOLOR = 'COLOR';
|
||||
cBGCOLOR = 'BGCOLOR';
|
||||
|
||||
// moved from JvHTControls and renamed
|
||||
function HTMLPrepareText(const Text: string): string;
|
||||
type
|
||||
THtmlCode = record
|
||||
Html: string;
|
||||
Text: UTF8String;
|
||||
end;
|
||||
const
|
||||
Conversions: array [0..6] of THtmlCode = (
|
||||
(Html: '&'; Text: '&'),
|
||||
(Html: '"'; Text: '"'),
|
||||
(Html: '®'; Text: #$C2#$AE),
|
||||
(Html: '©'; Text: #$C2#$A9),
|
||||
(Html: '™'; Text: #$E2#$84#$A2),
|
||||
(Html: '€'; Text: #$E2#$82#$AC),
|
||||
(Html: ' '; Text: ' ')
|
||||
);
|
||||
// moved from JvHTControls and refactored to support all html entities
|
||||
function HTMLPrepareText(const Text: String): String;
|
||||
var
|
||||
I: Integer;
|
||||
i, j, len, p: Integer;
|
||||
sEntity: String;
|
||||
wEntity: WideString;
|
||||
wChar: WideChar;
|
||||
|
||||
procedure AddCurrentChar;
|
||||
begin
|
||||
Result[j] := Text[i];
|
||||
inc(j);
|
||||
inc(i);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := Text;
|
||||
for I := Low(Conversions) to High(Conversions) do
|
||||
Result := StringReplace(Result, Conversions[I].Html, Utf8ToAnsi(Conversions[I].Text), [rfReplaceAll, rfIgnoreCase]);
|
||||
Result := StringReplace(Result, #13, '', [rfReplaceAll]); // only <BR> can be new line
|
||||
Result := StringReplace(Result, #10, '', [rfReplaceAll]); // only <BR> can be new line
|
||||
Result := StringReplace(Result, cBR, sLineBreak, [rfReplaceAll, rfIgnoreCase]);
|
||||
Result := StringReplace(Result, cBR2, sLineBreak, [rfReplaceAll, rfIgnoreCase]); // Fixes <BR/>, but not <BR />!
|
||||
Result := StringReplace(Result, cHR, cHR + sLineBreak, [rfReplaceAll, rfIgnoreCase]); // fixed <HR><BR>
|
||||
Result := '';
|
||||
if Text = '' then
|
||||
exit;
|
||||
|
||||
len := Length(Text);
|
||||
SetLength(Result, len*4);
|
||||
j := 1;
|
||||
i := 1;
|
||||
while i <= len do begin
|
||||
if (Text[i] in [#10, #13]) then // only <br> is allowed for new line here
|
||||
inc(i)
|
||||
else
|
||||
if Text[i] = '<' then
|
||||
begin
|
||||
if SameText(Copy(Text, i, Length(cBR)), cBR) then // Fixes <br>
|
||||
begin
|
||||
Move(LineEnding, Result[j], Length(LineEnding));
|
||||
inc(j, Length(LineEnding));
|
||||
inc(i, Length(cBR));
|
||||
end else
|
||||
if SameText(Copy(Text, i, Length(cBR2)), cBR2) then // Fixes <br/>
|
||||
begin
|
||||
Move(LineEnding, Result[j], Length(LineEnding));
|
||||
inc(j, Length(LineEnding));
|
||||
inc(i, Length(cBR2));
|
||||
end else
|
||||
if SameText(Copy(Text, i, Length(cBR3)), cBR3) then // Fixes <br />
|
||||
begin
|
||||
Move(LineEnding, Result[j], Length(LineEnding));
|
||||
inc(j, Length(LineEnding));
|
||||
inc(i, Length(cBR3));
|
||||
end else
|
||||
if SameText(Copy(Text, i, Length(cHR)), cHR) then // Fixes <hr>
|
||||
begin
|
||||
Move(cHR + LineEnding, Result[j], Length(cHR + LineEnding));
|
||||
inc(j, Length(cHR + LineEnding));
|
||||
inc(i, Length(cHR));
|
||||
end else
|
||||
AddCurrentChar;
|
||||
end else
|
||||
if Text[i] = '&' then
|
||||
begin
|
||||
p := PosEx(';', Text, i);
|
||||
if p > 0 then
|
||||
begin
|
||||
sEntity := Copy(Text, i+1, p-i-1);
|
||||
wEntity := WideString(sEntity);
|
||||
if ResolveHTMLEntityReference(wEntity, wChar) then
|
||||
begin
|
||||
sEntity := UTF8Encode(wChar);
|
||||
Move(sEntity[1], Result[j], Length(sEntity));
|
||||
inc(j, Length(sEntity));
|
||||
i := p+1;
|
||||
end else
|
||||
AddCurrentChar;
|
||||
end else
|
||||
AddCurrentChar;
|
||||
end else
|
||||
AddCurrentChar;
|
||||
end;
|
||||
SetLength(Result, j-1);
|
||||
end;
|
||||
|
||||
function HTMLStringToColor(AText: String; ADefColor: TColor = clBlack): TColor;
|
||||
@ -7351,8 +7401,12 @@ var
|
||||
Width := Canvas.TextWidth(M);
|
||||
Height := CanvasMaxTextHeight(Canvas);
|
||||
|
||||
if ScriptPosition = spSubscript then
|
||||
R.Top := R.Top + lineHeight - Height - 1;
|
||||
case ScriptPosition of
|
||||
spSubscript:
|
||||
R.Top := R.Top + lineHeight - abs(Canvas.Font.Height);
|
||||
spSuperScript:
|
||||
R.Top := R.Top + (Canvas.Font.Size - abs(Canvas.Font.Height));
|
||||
end;
|
||||
|
||||
if IsLink and not MouseOnLink then
|
||||
if (MouseY >= R.Top) and (MouseY <= R.Top + Height) and
|
||||
|
Reference in New Issue
Block a user