FastReport_2022_VCL/Source/frxSVGComponents.pas
2024-01-01 16:13:08 +01:00

427 lines
16 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport VCL }
{ SVG Components }
{ }
{ Copyright (c) 1998-2021 }
{ by Fast Reports Inc. }
{ }
{******************************************}
unit frxSVGComponents;
interface
{$I frx.inc}
//uses
type
TSVGSpecificWord = (
frx_noMater, frx_RGBA, frx_URI,
css_font,
svg_align, svg_alphabetic, svg_arcs, svg_auto,
svg_bevel, svg_bold, svg_bolder, svg_butt,
svg_catch_all, svg_central, svg_collapse, svg_context_fill, svg_context_stroke, svg_currentcolor,
svg_end, svg_evenodd, svg_exact,
svg_hanging, svg_hidden,
svg_ideographic, svg_inherit, svg_italic,
svg_left, svg_lighter, svg_line_through,
svg_mathematical, svg_meet, svg_middle, svg_miter, svg_miter_clip,
svg_none, svg_nonzero, svg_normal,
svg_objectBoundingBox, svg_oblique, svg_overline,
svg_pad,
svg_reflect, svg_repeat, svg_right, svg_round,
svg_slice, svg_square, svg_start, svg_stretch,
svg_text_bottom, svg_text_top, svg_transparent,
svg_underline, svg_userSpaceOnUse,
svg_visible,
svg_xMinYMin, svg_xMinYMid, svg_xMinYMax, svg_xMidYMin, svg_xMidYMid, svg_xMidYMax, svg_xMaxYMin, svg_xMaxYMid, svg_xMaxYMax
);
TSVGSpecificWordSet = set of TSVGSpecificWord;
function IsInSWSet(S: string; SWSet: TSVGSpecificWordSet): boolean;
const
SVGSpecificWord: array[TSVGSpecificWord] of string = (
'', '', '',
'font',
'align', 'alphabetic', 'arcs', 'auto',
'bevel', 'bold', 'bolder', 'butt',
'catch-all', 'central', 'collapse', 'context-fill', 'context-stroke', 'currentcolor',
'end', 'evenodd', 'exact',
'hanging', 'hidden',
'ideographic', 'inherit', 'italic',
'left', 'lighter', 'line-through',
'mathematical', 'meet', 'middle', 'miter', 'miter-clip',
'none', 'nonzero', 'normal',
'objectBoundingBox', 'oblique', 'overline',
'pad',
'reflect', 'repeat', 'right', 'round',
'slice', 'square', 'start', 'stretch',
'text-bottom', 'text-top', 'transparent',
'underline', 'userSpaceOnUse',
'visible',
'xMinYMin', 'xMinYMid', 'xMinYMax', 'xMidYMin', 'xMidYMid', 'xMidYMax', 'xMaxYMin', 'xMaxYMid', 'xMaxYMax'
);
type
TSVGAttribute = (
at_class,
at_clip_path,
at_clip_rule,
at_clipPathUnits,
at_color,
at_cx,
at_cy,
at_d,
at_display,
at_dominant_baseline,
at_dx,
at_dy,
at_fill,
at_fill_opacity,
at_fill_rule,
at_font_family,
at_font_size,
at_font_style,
at_font_weight,
at_fr,
at_fx,
at_fy,
at_gradientTransform,
at_gradientUnits,
at_height,
at_href,
at_id,
at_method,
at_offset,
at_opacity,
at_path,
at_points,
at_preserveAspectRatio,
at_r,
at_rx,
at_ry,
at_side,
at_spacing,
at_spreadMethod,
at_startOffset,
at_stop_color,
at_stop_opacity,
at_stroke,
at_stroke_dasharray,
at_stroke_dashoffset,
at_stroke_linecap,
at_stroke_linejoin,
at_stroke_miterlimit,
at_stroke_opacity,
at_stroke_width,
at_style,
at_systemLanguage,
at_transform,
at_text_anchor,
at_text_decoration,
at_viewBox,
at_visibility,
at_width,
at_x,
at_x1,
at_x2,
at_y,
at_y1,
at_y2
);
TSVGAttributeSet = set of TSVGAttribute;
TSVGElement = (
el_PathElement,
el_PlainText,
el_a,
el_circle,
el_clipPath,
el_defs,
el_ellipse,
el_g,
el_image,
el_line,
el_linearGradient,
el_path,
el_polygon,
el_polyline,
el_radialGradient,
el_rect,
el_stop,
el_style,
el_svg,
el_switch,
el_text,
el_textPath,
el_tspan,
el_use
);
TSVGElementSet = set of TSVGElement;
TSVGDirection = (sdNo, sdHorizontal, sdVertical, sdDiagonal);
TSVGDirectionArray = array of TSVGDirection;
TSVGAttributeData = record
Name: string;
Direction: TSVGDirection;
CSS: TSVGElementSet;
end;
const
AnySVGElement = [Low(TSVGElement) .. High(TSVGElement)];
SVGAttribute: array[TSVGAttribute] of TSVGAttributeData = (
(Name: 'class'; Direction: sdNo; CSS: []),
(Name: 'clip-path'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'clip-rule'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'clipPathUnits'; Direction: sdNo; CSS: []),
(Name: 'color'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'cx'; Direction: sdHorizontal; CSS: [el_circle, el_ellipse]),
(Name: 'cy'; Direction: sdVertical; CSS: [el_circle, el_ellipse]),
(Name: 'd'; Direction: sdNo; CSS: []),
(Name: 'display'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'dominant-baseline'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'dx'; Direction: sdHorizontal; CSS: []),
(Name: 'dy'; Direction: sdVertical; CSS: []),
(Name: 'fill'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'fill-opacity'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'fill-rule'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'font-family'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'font-size'; Direction: sdDiagonal; CSS: AnySVGElement),
(Name: 'font-style'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'font-weight'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'fr'; Direction: sdDiagonal; CSS: []),
(Name: 'fx'; Direction: sdHorizontal; CSS: []),
(Name: 'fy'; Direction: sdVertical; CSS: []),
(Name: 'gradientTransform'; Direction: sdNo; CSS: []),
(Name: 'gradientUnits'; Direction: sdNo; CSS: []),
(Name: 'height'; Direction: sdVertical; CSS: [el_image, el_rect, el_svg, el_use]),
(Name: 'href'; Direction: sdNo; CSS: []),
(Name: 'id'; Direction: sdNo; CSS: []),
(Name: 'method'; Direction: sdNo; CSS: []),
(Name: 'offset'; Direction: sdNo; CSS: []),
(Name: 'opacity'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'path'; Direction: sdNo; CSS: []),
(Name: 'points'; Direction: sdNo; CSS: []),
(Name: 'preserveAspectRatio'; Direction: sdNo; CSS: []),
(Name: 'r'; Direction: sdDiagonal; CSS: [el_circle]),
(Name: 'rx'; Direction: sdHorizontal; CSS: [el_ellipse, el_rect]),
(Name: 'ry'; Direction: sdVertical; CSS: [el_ellipse, el_rect]),
(Name: 'side'; Direction: sdNo; CSS: []),
(Name: 'spacing'; Direction: sdNo; CSS: []),
(Name: 'spreadMethod'; Direction: sdNo; CSS: []),
(Name: 'startOffset'; Direction: sdDiagonal; CSS: []),
(Name: 'stop-color'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stop-opacity'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stroke'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stroke-dasharray'; Direction: sdDiagonal; CSS: AnySVGElement),
(Name: 'stroke-dashoffset'; Direction: sdDiagonal; CSS: AnySVGElement),
(Name: 'stroke-linecap'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stroke-linejoin'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stroke-miterlimit'; Direction: sdDiagonal; CSS: AnySVGElement),
(Name: 'stroke-opacity'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'stroke-width'; Direction: sdDiagonal; CSS: AnySVGElement),
(Name: 'style'; Direction: sdNo; CSS: []),
(Name: 'systemLanguage'; Direction: sdNo; CSS: []),
(Name: 'transform'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'text-anchor'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'text-decoration'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'viewBox'; Direction: sdNo; CSS: []),
(Name: 'visibility'; Direction: sdNo; CSS: AnySVGElement),
(Name: 'width'; Direction: sdHorizontal; CSS: [el_image, el_rect, el_svg, el_use]),
(Name: 'x'; Direction: sdHorizontal; CSS: [el_image, el_rect, el_svg, el_use]),
(Name: 'x1'; Direction: sdHorizontal; CSS: []),
(Name: 'x2'; Direction: sdHorizontal; CSS: []),
(Name: 'y'; Direction: sdVertical; CSS: [el_image, el_rect, el_svg, el_use]),
(Name: 'y1'; Direction: sdVertical; CSS: []),
(Name: 'y2'; Direction: sdVertical; CSS: [])
);
BaseAttributes: TSVGAttributeSet = [
at_clip_path,
at_clip_rule,
at_color,
at_display,
at_font_family,
at_font_size,
at_font_style,
at_font_weight,
at_fill,
at_fill_opacity,
at_fill_rule,
at_opacity,
at_stroke,
at_stroke_dasharray,
at_stroke_dashoffset,
at_stroke_linecap,
at_stroke_linejoin,
at_stroke_miterlimit,
at_stroke_opacity,
at_stroke_width,
at_transform,
at_text_anchor,
at_text_decoration,
at_visibility];
type
TSVGElementOptions = (eoHaveChild, eoSelfBounds, eoChildBounds, eoPaint, eoMatrix, eoBaseSet);
TSVGElementOptionsSet = set of TSVGElementOptions;
TSVGElementData = record
Name: string;
Options: TSVGElementOptionsSet;
Attributes: TSVGAttributeSet;
end;
const
SVGElement: array[TSVGElement] of TSVGElementData = (
(Name: '#pathelement'; Options: [];
Attributes: []),
(Name: '#text'; Options: [];
Attributes: []),
(Name: 'a'; Options: [eoHaveChild , eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_href,
at_systemLanguage]),
(Name: 'circle'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_cx,
at_cy,
at_r,
at_systemLanguage]),
(Name: 'clipPath'; Options: [eoHaveChild , eoMatrix, eoBaseSet];
Attributes: [at_clipPathUnits,
at_systemLanguage]),
(Name: 'defs'; Options: [eoHaveChild , eoMatrix, eoBaseSet];
Attributes: [at_systemLanguage]),
(Name: 'ellipse'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_cx,
at_cy,
at_rx,
at_ry,
at_systemLanguage]),
(Name: 'g'; Options: [eoHaveChild , eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_systemLanguage]),
(Name: 'image'; Options: [ eoSelfBounds , eoPaint, eoMatrix ];
Attributes: [at_clip_path,
at_display,
at_height,
at_href,
at_opacity,
at_preserveAspectRatio,
at_systemLanguage,
at_transform,
at_visibility,
at_width,
at_x,
at_y]),
(Name: 'line'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_systemLanguage,
at_x1,
at_y1,
at_x2,
at_y2]),
(Name: 'linearGradient'; Options: [eoHaveChild , eoMatrix, eoBaseSet];
Attributes: [at_gradientTransform,
at_gradientUnits,
at_href,
at_spreadMethod,
at_x1,
at_y1,
at_x2,
at_y2]),
(Name: 'path'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_d,
at_systemLanguage]),
(Name: 'polygon'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_points,
at_systemLanguage]),
(Name: 'polyline'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_points,
at_systemLanguage]),
(Name: 'radialGradient'; Options: [eoHaveChild , eoMatrix, eoBaseSet];
Attributes: [at_cx,
at_cy,
at_fr,
at_fx,
at_fy,
at_gradientTransform,
at_gradientUnits,
at_href,
at_spreadMethod,
at_r]),
(Name: 'rect'; Options: [ eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_height,
at_rx,
at_ry,
at_systemLanguage,
at_x,
at_y,
at_width]),
(Name: 'stop'; Options: [];
Attributes: [at_color,
at_offset,
at_stop_color,
at_stop_opacity]),
(Name: 'style'; Options: [];
Attributes: []),
(Name: 'svg'; Options: [eoHaveChild, eoSelfBounds , eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_height,
at_preserveAspectRatio,
at_systemLanguage,
at_x,
at_y,
at_viewBox,
at_width]),
(Name: 'switch'; Options: [eoHaveChild , eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_systemLanguage]),
(Name: 'text'; Options: [eoHaveChild, eoSelfBounds, eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_dx,
at_dy,
at_systemLanguage,
at_x,
at_y]),
(Name: 'textPath'; Options: [eoHaveChild, eoSelfBounds, eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_href,
at_startOffset,
at_systemLanguage]),
(Name: 'tspan'; Options: [eoHaveChild, eoSelfBounds, eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_dx,
at_dy,
at_systemLanguage,
at_x,
at_y]),
(Name: 'use'; Options: [ eoChildBounds, eoPaint, eoMatrix, eoBaseSet];
Attributes: [at_height,
at_href,
at_systemLanguage,
at_x,
at_y,
at_width])
);
implementation
//uses
function IsInSWSet(S: string; SWSet: TSVGSpecificWordSet): boolean;
var
sw: TSVGSpecificWord;
begin
Result := False;
if S <> '' then
for sw := Low(sw) to High(sw) do
if S = SVGSpecificWord[sw] then
begin
Result := True;
Break;
end;
end;
end.