{******************************************} { } { 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.