lazarus/components/tachart/tahtml.pas

534 lines
16 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit TAHtml;
{$H+}
interface
uses
fpimage, Classes;
function ReplaceHTMLEntities(const AText: String): String;
function HTMLToFontSize(AText: String): Integer;
function HTMLToFPColor(const AText: String): TFPColor;
implementation
uses
SysUtils, math, contnrs,
TAChartUtils, TAGeometry;
type
THtmlEntities = class(TFPStringHashTable)
public
procedure Add(const AEntName, AEntNum, AUtf8: String); reintroduce;
end;
var
HtmlEntities: THtmlEntities = nil;
procedure THtmlEntities.Add(const AEntName, AEntNum, AUtf8: String);
begin
inherited Add(AEntName, AUtf8);
inherited Add(AEntNum, AUtf8);
end;
// https://www.w3schools.com/charsets/ref_utf_basic_latin.asp
procedure PopulateHtmlEntities;
begin
if HtmlEntities <> nil then
exit;
HtmlEntities := THtmlEntities.Create;
with HtmlEntities do begin
// Latin Basic
Add('quot', '34', '"');
Add('amp', '38', '&');
Add('apos', '39', '''');
Add('lt', '60', '<');
Add('gt', '61', '>');
// Latin Supplement
Add('nbsp', '160', ' ');
Add('iexcl', '161', '¡');
Add('cent', '162', '¢');
Add('pound', '163', '£');
Add('curren', '164', '¤');
Add('yen', '165', '¥');
Add('brvbar', '166', '¦');
Add('sect', '167', '§');
Add('uml', '168', '¨');
Add('copy', '169', '©');
Add('ordf', '170', 'ª');
Add('laquo', '171', '«');
Add('not', '172', '¬');
Add('reg', '174', '®');
Add('macr', '175', '¯');
Add('deg', '176', '°');
Add('plusmn', '177', '±');
Add('sup2', '178', '²');
Add('sup3', '179', '³');
Add('acute', '180', '´');
Add('micro', '181', 'µ');
Add('para', '182', '¶');
Add('middot', '183', '·');
Add('cedil', '184', '¸');
Add('sup1', '185', '¹');
Add('ordm', '186', 'º');
Add('raquo', '187', '»');
Add('frac14', '188', '¼');
Add('frac12', '189', '½');
Add('frac34', '190', '¾');
Add('iquest', '191', '¿');
Add('Agrave', '192', 'À');
Add('Aacute', '193', 'Á');
Add('Acirc', '194', 'Â');
Add('Atilde', '195', 'Ã');
Add('Auml', '196', 'Ä');
Add('Aring', '197', 'Å');
Add('AElig', '198', 'Æ');
Add('Ccedil', '199', 'Ç');
Add('Egrave', '200', 'È');
Add('Eacute', '201', 'É');
Add('Ecirc', '202', 'Ê');
Add('Euml', '203', 'Ë');
Add('Igrave', '204', 'Ì');
Add('Iacute', '205', 'Í');
Add('Icirc', '206', 'Î');
Add('Iuml', '207', 'Ï');
Add('ETH', '208', 'Ð');
Add('Ntilde', '209', 'Ñ');
Add('Ograve', '210', 'Ò');
Add('Oacute', '211', 'Ó');
Add('Ocirc', '212', 'Ô');
Add('Otilde', '213', 'Õ');
Add('Ouml', '214', 'Ö');
Add('times', '215', '×');
Add('Oslash', '216', 'Ø');
Add('Ugrave', '217', 'Ù');
Add('Uacute', '218', 'Ú');
Add('Ucirc', '219', 'Û');
Add('Uuml', '220', 'Ü');
Add('Yacute', '221', 'Ý');
Add('THORN', '222', 'Þ');
Add('szlig', '223', 'ß');
Add('agrave', '224', 'à');
Add('aacute', '225', 'á');
Add('acirc', '226', 'â');
Add('atilde', '227', 'ã');
Add('auml', '228', 'ä');
Add('aring', '229', 'å');
Add('aelig', '230', 'æ');
Add('ccedil', '231', 'ç');
Add('egrave', '232', 'è');
Add('eacute', '233', 'é');
Add('ecirc', '234', 'ê');
Add('euml', '235', 'ë');
Add('igrave', '236', 'ì');
Add('iacute', '237', 'í');
Add('icircl', '238', 'î');
Add('iuml', '239', 'ï');
Add('eth', '240', 'ð');
Add('ntilde', '241', 'ñ');
Add('ograve', '242', 'ò');
Add('oacute', '243', 'ô');
Add('ocirc', '244', 'ô');
Add('otilde', '245', 'õ');
Add('ouml', '246', 'ö');
Add('divide', '247', '÷');
Add('oslash', '248', 'ø');
Add('ugrave', '249', 'ù');
Add('uacute', '250', 'ú');
Add('ucirc', '251', 'û');
Add('uuml', '252', 'ü');
Add('yacute', '253', 'ý');
Add('thorn', '254', 'þ');
Add('yuml', '255', 'ÿ');
// Latin Extended A
Add('Amacr', '256', 'Ā');
Add('amacr', '257', 'ā');
Add('Abreve', '258', 'Ă');
Add('abreve', '259', 'ă');
Add('Aogon', '260', 'Ą');
Add('aogon', '261', 'ą');
Add('Cacute', '262', 'Ć');
Add('cacute', '263', 'ć');
Add('Ccirc', '264', 'Ĉ');
Add('ccirc', '265', 'ĉ');
Add('Cdot', '266', 'Ċ');
Add('cdot', '267', 'ċ');
Add('Ccaron', '268', 'Č');
Add('ccaron', '269', 'č');
Add('Dcaron', '270', 'Ď');
Add('dcaron', '271', 'ď');
Add('Dstrok', '272', 'Đ');
Add('dstrok', '273', 'đ');
Add('Emacr', '274', 'Ē');
Add('emacr', '275', 'ē');
Add('Edot', '278', 'Ė');
Add('edot', '279', 'ė');
Add('Eogon', '280', 'Ę');
Add('eogon', '281', 'ę');
Add('Ecaron', '282', 'Ě');
Add('ecaron', '283', 'ě');
Add('Gcirc', '284', 'Ĝ');
Add('gcirc', '285', 'ĝ');
Add('Gbreve', '286', 'Ğ');
Add('gbreve', '287', 'ğ');
Add('Gdot', '288', 'Ġ');
Add('gdot', '289', 'ġ');
Add('Gcedil', '290', 'Ģ');
Add('gcedil', '291', 'ģ');
Add('Hcirc', '292', 'Ĥ');
Add('hcirc', '293', 'ĥ');
Add('Hstrok', '294', 'Ħ');
Add('hstrok', '295', 'ħ');
Add('Itilde', '296', 'Ĩ');
Add('itilde', '297', 'ĩ');
Add('Imacr', '298', 'Ī');
Add('imacr', '299', 'ī');
Add('Iogon', '302', 'Į');
Add('iogon', '303', 'į');
Add('Idot', '304', 'İ');
Add('inodot', '305', 'ı');
Add('IJlig', '306', 'IJ');
Add('ijlig', '307', 'ij');
Add('Jcirc', '308', 'Ĵ');
Add('jcirc', '309', 'ĵ');
Add('Kcedil', '310', 'Ķ');
Add('kcedil', '311', 'ķ');
Add('kgreen', '312', 'ĸ');
Add('Lacute', '313', 'Ĺ');
Add('lacute', '314', 'ĺ');
Add('Lcedil', '315', 'Ļ');
Add('lcedil', '316', 'ļ');
Add('Lcaron', '317', 'Ľ');
Add('lcaron', '318', 'ľ');
Add('Lmidot', '319', 'Ŀ');
Add('lmidot', '320', 'ŀ');
Add('Lstrok', '321', 'Ł');
Add('lstrok', '322', 'ł');
Add('Nacute', '323', 'Ń');
Add('nacute', '324', 'ń');
Add('Ncedil', '325', 'Ņ');
Add('ncedil', '326', 'ņ');
Add('Ncaron', '327', 'Ň');
Add('ncaron', '328', 'ň');
Add('napos', '329', 'ʼn');
Add('ENG', '330', 'Ŋ');
Add('eng', '331', 'ŋ');
Add('Omacr', '332', 'Ō');
Add('omacr', '333', 'ō');
Add('Odblac', '336', 'Ő');
Add('odblac', '337', 'ő');
Add('OElig', '338', 'Œ');
Add('oelig', '339', 'œ');
Add('Racute', '340', 'Ŕ');
Add('racute', '341', 'ŕ');
Add('Rcedil', '342', 'Ŗ');
Add('rcedil', '343', 'ŗ');
Add('Rcaron', '344', 'Ř');
Add('rcaron', '345', 'ř');
Add('Sacute', '346', 'Ś');
Add('sacute', '347', 'ś');
Add('Scirc', '348', 'Ŝ');
Add('scirc', '349', 'ŝ');
Add('Scedil', '350', 'Ş');
Add('scedil', '351', 'ş');
Add('Scaron', '352', 'Š');
Add('scaron', '353', 'š');
Add('Tcedil', '354', 'Ţ');
Add('tcedil', '355', 'ţ');
Add('Tcaron', '356', 'Ť');
Add('tcaron', '357', 'ť');
Add('Tstrok', '358', 'Ŧ');
Add('tstrok', '359', 'ŧ');
Add('Utilde', '360', 'Ũ');
Add('utilde', '361', 'ũ');
Add('Umacr', '362', 'Ū');
Add('umacr', '363', 'ū');
Add('Ubreve', '364', 'Ŭ');
Add('ubreve', '365', 'ŭ');
Add('Uring', '366', 'Ů');
Add('uring', '367', 'ů');
Add('Udblac', '368', 'Ű');
Add('udblac', '369', 'ű');
Add('Uogon', '370', 'Ų');
Add('uogon', '371', 'ų');
Add('Wcirc', '372', 'Ŵ');
Add('wcirc', '373', 'ŵ');
Add('Ycirc', '374', 'Ŷ');
Add('ycirc', '375', 'ŷ');
Add('Yuml', '376', 'Ÿ');
Add('Zacute', '377', 'Ź');
Add('zacute', '378', 'ź');
Add('Zdot', '379', 'Ż');
Add('zdot', '380', 'ż');
Add('Zcaron', '381', 'Ž');
Add('zcaron', '382', 'ž');
// Latin Extended B
Add('fnof', '402', 'ƒ');
Add('imped', '437', 'Ƶ');
Add('gacute', '501', 'ǵ');
Add('jmath', '567', 'ȷ');
// Modified letters
Add('circ', '710', 'ˆ');
Add('tilde', '732', '˜');
// Greek and coptic
Add('Alpha', '913', 'Α');
Add('Beta', '914', 'Β');
Add('Gamma', '915', 'Γ');
Add('Delta', '916', 'Δ');
Add('Epsilon', '917', 'Ε');
Add('Zeta', '918', 'Ζ');
Add('Eta', '919', 'Η');
Add('Theta', '920', 'Θ');
Add('Iota', '921', 'Ι');
Add('Kappa', '922', 'Κ');
Add('Lambda', '923', 'Λ');
Add('Mu', '924', 'Μ');
Add('Nu', '925', 'Ν');
Add('Xi', '926', 'Ξ');
Add('Omicron', '927', 'Ο');
Add('Pi', '928', 'Π');
Add('Rho', '929', 'Ρ');
Add('Sigma', '931', 'Σ');
Add('Tau', '932', 'Τ');
Add('Upsilon', '933', 'Υ');
Add('Phi', '934', 'Φ');
Add('Chi', '935', 'Χ');
Add('Psi', '936', 'Ψ');
Add('Omega', '937', 'Ω');
Add('alpha', '945', 'α');
Add('beta', '946', 'β');
Add('gamma', '947', 'γ');
Add('delta', '948', 'δ');
Add('epsilon', '949', 'ε');
Add('zeta', '950', 'ζ');
Add('eta', '951', 'η');
Add('theta', '952', 'θ');
Add('iota', '953', 'ι');
Add('kappa', '954', 'κ');
Add('lambda', '955', 'λ');
Add('mu', '956', 'μ');
Add('nu', '957', 'ν');
Add('xi', '958', 'ξ');
Add('omicron', '959', 'ο');
Add('pi', '960', 'π');
Add('rho', '961', 'ρ');
Add('sigmaf', '962', 'ς');
Add('sigma', '963', 'σ');
Add('tau', '964', 'τ');
Add('upsilon', '965', 'υ');
Add('phi', '966', 'φ');
Add('chi', '967', 'χ');
Add('psi', '968', 'ψ');
Add('omega', '969', 'ω');
Add('thetasym','977', 'ϑ');
Add('upsih', '978', 'ϒ');
Add('straightphi', '981', 'ϕ');
Add('piv', '982', 'ϖ'); // ??? should be vertical pi
Add('Gammad', '988', 'Ϝ');
Add('gammad', '987', 'ϝ');
Add('varkappa','1008', 'ϰ');
Add('varrho', '1009', 'ϱ');
Add('straightepsilon', '1013', 'ϵ');
Add('backepsilon', '1014', '϶');
// Currency
Add('euro', '8364', '€');
// Arrows
Add('larr', '8592', '←');
Add('uarr', '8593', '↑');
Add('rarr', '8594', '→');
Add('darr', '8595', '↓');
Add('harr', '8596', '↔');
Add('crarr', '8629', '↵');
Add('lArr', '8656', '⇐');
Add('uArr', '8657', '⇑');
Add('rArr', '8658', '⇒');
Add('dArr', '8659', '⇓');
Add('hArr', '8860', '⇔');
// Math operators
Add('forall', '8704', '∀');
Add('part', '8706', '∂');
Add('exist', '8707', '∃');
Add('empty', '8709', '∅');
Add('nabla', '8711', '∇');
Add('isin', '8712', '∈');
Add('notin', '8713', '∉');
Add('ni', '8715', '∋');
Add('prod', '8719', '∏');
Add('sum', '8721', '∑');
Add('minus', '8722', '');
Add('lowast', '8728', '');
Add('radic', '8730', '√');
Add('prop', '8733', '∝');
Add('infin', '8734', '∞');
Add('ang', '8736', '∠');
Add('and', '8743', '∧');
Add('or', '8744', '');
Add('cap', '8745', '∩');
Add('cup', '8746', '');
Add('int', '8747', '∫');
Add('there4', '8756', '∴');
Add('sim', '8764', '');
Add('cong', '8773', '≅');
Add('asymp', '9776', '≅');
Add('ne', '8800', '≠');
Add('equiv', '8801', '≡');
Add('le', '8804', '≤');
Add('ge', '8805', '≥');
Add('sub', '8834', '⊂');
Add('sup', '8835', '⊃');
Add('nsub', '8836', '⊄');
Add('sube', '8838', '⊆');
Add('supe', '8839', '⊇');
Add('oplus', '8853', '⊕');
Add('otimes', '8855', '⊗');
Add('perp', '8859', '⊥');
Add('sdot', '8901', '⋅');
// Geometric shapes
Add('loz', '9674', '◊');
// Misc symbols
Add('spades', '9824', '♠');
Add('clubs', '9827', '♣');
Add('hearts', '9829', '♥');
Add('diams', '9830', '♦');
end;
end;
function HTMLEntityToUTF8(s: String): String;
var
n: Integer;
begin
if s = '' then
exit('');
if HtmlEntities = nil then
PopulateHtmlEntities;
if (Length(s) > 1) and (s[1] = '#') then begin
Delete(s, 1, 1);
if (s[1] = 'x') then begin
s[1] := '$';
n := StrToInt(s);
s := IntToStr(n);
end;
end;
Result := HTMLEntities[s];
end;
function ReplaceHTMLEntities(const AText: String): String;
var
i: Integer;
s: String;
begin
Result := '';
i := 1;
while (i <= Length(AText)) do
begin
case AText[i] of
'&': begin
s := '';
inc(i);
while (i <= Length(AText)) and (AText[i] <> ';') do begin
s := s + AText[i];
inc(i);
end;
Result := Result + HTMLEntityToUTF8(s);
end;
else Result := Result + AText[i];
end;
inc(i);
end;
end;
function HTMLToFPColor(const AText: String): TFPColor;
var
i: Integer;
len: Integer;
begin
Result := colBlack;
// AText is already upper-cased by the calling routine.
case AText of
'AQUA' : Result := colAqua;
'BLACK' : Result := colBlack;
'BLUE' : Result := colBlue;
'CYAN' : Result := colCyan;
'FUCHSIA': Result := colFuchsia;
'GRAY' : Result := colGray;
'GREY' : Result := colGray;
'GREEN' : Result := colGreen;
'LIME' : Result := colLime;
'MAGENTA': Result := colMagenta;
'MAROON' : Result := colMaroon;
'NAVY' : Result := colNavy;
'OLIVE' : Result := colOlive;
'PURPLE' : Result := colPurple;
'RED' : Result := colRed;
'SILVER' : Result := colSilver;
'TEAL' : Result := colTeal;
'WHITE' : Result := colWhite;
'YELLOW' : Result := colYellow;
else if (pos('#', AText) = 1) then begin
len := Length(AText);
if not (len in [7, 4]) then
exit;
for i:=2 to len do
if not (AText[i] in ['0'..'9', 'A'..'F']) then
exit;
if len = 7 then begin
Result.Red := StrToInt('$' + copy(AText, 2, 2)) shl 8;
Result.Green := StrToInt('$' + copy(AText, 4, 2)) shl 8;
Result.Blue := StrToInt('$' + copy(AText, 6, 2)) shl 8;
end else
if len = 4 then begin
Result.Red := StrToInt('$' + AText[2] + AText[2]) shl 8;
Result.Green := StrToInt('$' + AText[3] + AText[3]) shl 8;
Result.Blue := StrToInt('$' + AText[4] + AText[4]) shl 8;
end;
end;
end;
end;
function HTMLToFontSize(AText: String): Integer;
begin
case AText of
'X-SMALL', '1' : Result := 7;
'SMALL', '2' : Result := 10;
'MEDIUM', '3' : Result := 12;
'LARGE', '4' : Result := 14;
'X-LARGE', '5' : Result := 18;
'XX-LARGE', '6' : Result := 24;
else
if Pos('PT', AText) = Length(AText)-1 then
Result := StrToInt(Copy(AText, 1, Length(AText) - 2))
else
if Pos('PX', AText) = Length(AText)-1 then
begin
Result := StrToInt(Copy(AText, 1, Length(AText) - 2));
Result := Result * 72 div 96; // Assuming a 96 ppi screen here!
end else
Result := 9;
end;
end;
initialization
finalization
HTMLEntities.Free;
end.