001/*
002 * ============================================================================
003 * Copyright © 2002-2021 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 * Licensed to the public under the agreements of the GNU Lesser General Public
007 * License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *      http://www.gnu.org/licenses/lgpl.html
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017
018package org.tquadrat.foundation.svg.internal;
019
020import static java.util.Collections.emptyList;
021import static org.apiguardian.api.API.Status.INTERNAL;
022import static org.tquadrat.foundation.lang.CommonConstants.XMLATTRIBUTE_Id;
023import static org.tquadrat.foundation.lang.CommonConstants.XMLATTRIBUTE_Language;
024import static org.tquadrat.foundation.lang.CommonConstants.XMLATTRIBUTE_Whitespace;
025import static org.tquadrat.foundation.lang.Objects.nonNull;
026import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
027import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_AlignmentBaseline;
028import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_BaseProfile;
029import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_BaselineShift;
030import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Class;
031import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Clip;
032import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ClipPath;
033import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ClipRule;
034import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Color;
035import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ColorInterpolation;
036import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ColorInterpolationFilters;
037import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ColorProfile;
038import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ColorRendering;
039import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ContentScriptType;
040import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Cursor;
041import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Direction;
042import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Display;
043import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_DominantBaseline;
044import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_EnableBackground;
045import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ExternalResourcesRequired;
046import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Fill;
047import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FillOpacity;
048import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FillRule;
049import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Filter;
050import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FloodColor;
051import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FloodOpacity;
052import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontFamily;
053import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontSize;
054import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontSizeAdjust;
055import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontStretch;
056import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontStyle;
057import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontVariant;
058import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_FontWeight;
059import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_GlyphOrientationHorizontal;
060import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_GlyphOrientationVertical;
061import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Height;
062import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Id;
063import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ImageRendering;
064import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Kerning;
065import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Lang;
066import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_LetterSpacing;
067import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_LightingColor;
068import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_MarkerEnd;
069import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_MarkerMid;
070import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_MarkerStart;
071import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Mask;
072import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnAbort;
073import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnActivate;
074import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnError;
075import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnFocusIn;
076import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnFocusOut;
077import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnResize;
078import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnScroll;
079import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_OnUnload;
080import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Opacity;
081import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Overflow;
082import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_PointerEvents;
083import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_PreserveAspectRatio;
084import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_RequiredExtensions;
085import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_RequiredFeatures;
086import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ShapeRendering;
087import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StopColor;
088import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StopOpacity;
089import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Stroke;
090import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeDashArray;
091import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeDashOffset;
092import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeLineCap;
093import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeLineJoin;
094import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeMiterLimit;
095import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeOpacity;
096import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_StrokeWidth;
097import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Style;
098import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_SystemLanguage;
099import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_TabIndex;
100import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_TextAnchor;
101import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_TextDecoration;
102import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_TextRendering;
103import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Transform;
104import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_UnicodeBidi;
105import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_VectorEffect;
106import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Version;
107import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ViewBox;
108import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Visibility;
109import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Width;
110import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_WordSpacing;
111import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_WritingMode;
112import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_ZoomAndPan;
113import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_x;
114import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_y;
115import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_AltGlyphDef;
116import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Anchor;
117import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_ClipPath;
118import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_ColorProfile;
119import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Cursor;
120import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Defs;
121import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Filter;
122import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Font;
123import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_FontFace;
124import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_ForeignObject;
125import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Image;
126import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Marker;
127import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Mask;
128import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Pattern;
129import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Root;
130import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Script;
131import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Style;
132import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Switch;
133import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_Text;
134import static org.tquadrat.foundation.svg.SVGUtils.SVGELEMENT_View;
135import static org.tquadrat.foundation.svg.SVGUtils.XMLATTRIBUTE_Base;
136import static org.tquadrat.foundation.svg.SVGUtils.createStyle;
137import static org.tquadrat.foundation.svg.type.SVGElementCategory.ANIMATION;
138import static org.tquadrat.foundation.svg.type.SVGElementCategory.DESCRIPTIVE;
139import static org.tquadrat.foundation.svg.type.SVGElementCategory.GRADIENT;
140import static org.tquadrat.foundation.svg.type.SVGElementCategory.SHAPE;
141import static org.tquadrat.foundation.svg.type.SVGElementCategory.STRUCTURAL;
142import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.ALLOWS_CHILDREN;
143import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.VALIDATES_ATTRIBUTES;
144import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.VALIDATES_CHILDREN;
145
146import java.util.ArrayList;
147import java.util.Collection;
148import java.util.HashSet;
149import java.util.List;
150import java.util.Optional;
151
152import org.apiguardian.api.API;
153import org.tquadrat.foundation.annotation.ClassVersion;
154import org.tquadrat.foundation.lang.Lazy;
155import org.tquadrat.foundation.svg.AllowsDocumentElementEventAttributes;
156import org.tquadrat.foundation.svg.AllowsDocumentEventAttributes;
157import org.tquadrat.foundation.svg.SVG;
158import org.tquadrat.foundation.svg.SVGElement;
159import org.tquadrat.foundation.svg.SVGStyle;
160import org.tquadrat.foundation.xml.builder.spi.Element;
161import jakarta.activation.MimeType;
162
163/**
164 *  The implementation for the interface
165 *  {@link SVG}
166 *  for the {@code <svg>} element.
167 *
168 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
169 *  @version $Id: SVGImpl.java 1074 2023-10-02 12:05:06Z tquadrat $
170 *  @since 0.0.5
171 *
172 *  @UMLGraph.link
173 */
174@ClassVersion( sourceVersion = "$Id: SVGImpl.java 1074 2023-10-02 12:05:06Z tquadrat $" )
175@API( status = INTERNAL, since = "0.0.5" )
176public final class SVGImpl extends SVGElementImpl implements SVG
177{
178        /*------------*\
179    ====** Attributes **=======================================================
180        \*------------*/
181    /**
182     *  The optional {@code <defs>} element for this {@code <svg>} element.
183     */
184    private final Lazy<SVGElementImpl> m_Definitions = Lazy.use( this::createDefinitionsElement );
185
186    /**
187     *  The style sheet for this {@code <svg>} element.
188     */
189    @SuppressWarnings( "OptionalUsedAsFieldOrParameterType" )
190    private Optional<SVGStyle> m_StyleSheet = Optional.empty();
191
192        /*--------------*\
193    ====** Constructors **=====================================================
194        \*--------------*/
195    /**
196     *  Creates a new {@code SVGImpl} instance.
197     */
198    public SVGImpl()
199    {
200        super( SVGELEMENT_Root, ALLOWS_CHILDREN, VALIDATES_CHILDREN, VALIDATES_ATTRIBUTES );
201
202        //---* The children and attributes for the <svg> element *-------------
203        final var childElements = validChildElements();
204
205        final Collection<String> attributes = new ArrayList<>();
206        attributes.addAll( List.of( SVGATTRIBUTE_Id, SVGATTRIBUTE_Version,
207            SVGATTRIBUTE_BaseProfile, SVGATTRIBUTE_ContentScriptType,
208            SVGATTRIBUTE_x, SVGATTRIBUTE_y, SVGATTRIBUTE_Width,
209            SVGATTRIBUTE_Height, SVGATTRIBUTE_ViewBox,
210            SVGATTRIBUTE_PreserveAspectRatio, SVGATTRIBUTE_ZoomAndPan,
211            SVGATTRIBUTE_Class, SVGATTRIBUTE_Style, SVGATTRIBUTE_Lang,
212            SVGATTRIBUTE_TabIndex, SVGATTRIBUTE_ExternalResourcesRequired,
213            SVGATTRIBUTE_RequiredExtensions, SVGATTRIBUTE_RequiredFeatures,
214            SVGATTRIBUTE_SystemLanguage, XMLATTRIBUTE_Id, XMLATTRIBUTE_Base,
215            XMLATTRIBUTE_Language, XMLATTRIBUTE_Whitespace, SVGATTRIBUTE_OnAbort,
216            SVGATTRIBUTE_OnActivate, SVGATTRIBUTE_OnError,
217            SVGATTRIBUTE_OnFocusIn, SVGATTRIBUTE_OnFocusOut,
218            SVGATTRIBUTE_OnResize, SVGATTRIBUTE_OnScroll,
219            SVGATTRIBUTE_OnUnload, SVGATTRIBUTE_AlignmentBaseline,
220            SVGATTRIBUTE_BaselineShift, SVGATTRIBUTE_Clip,
221            SVGATTRIBUTE_ClipPath, SVGATTRIBUTE_ClipRule, SVGATTRIBUTE_Color,
222            SVGATTRIBUTE_ColorInterpolation,
223            SVGATTRIBUTE_ColorInterpolationFilters, SVGATTRIBUTE_ColorProfile,
224            SVGATTRIBUTE_ColorRendering, SVGATTRIBUTE_Cursor,
225            SVGATTRIBUTE_Direction, SVGATTRIBUTE_Display,
226            SVGATTRIBUTE_DominantBaseline, SVGATTRIBUTE_EnableBackground,
227            SVGATTRIBUTE_Fill, SVGATTRIBUTE_FillOpacity, SVGATTRIBUTE_FillRule,
228            SVGATTRIBUTE_Filter, SVGATTRIBUTE_FloodColor,
229            SVGATTRIBUTE_FloodOpacity, SVGATTRIBUTE_FontFamily,
230            SVGATTRIBUTE_FontSize, SVGATTRIBUTE_FontSizeAdjust,
231            SVGATTRIBUTE_FontStretch, SVGATTRIBUTE_FontStyle,
232            SVGATTRIBUTE_FontVariant, SVGATTRIBUTE_FontWeight,
233            SVGATTRIBUTE_GlyphOrientationHorizontal,
234            SVGATTRIBUTE_GlyphOrientationVertical, SVGATTRIBUTE_ImageRendering,
235            SVGATTRIBUTE_Kerning, SVGATTRIBUTE_LetterSpacing,
236            SVGATTRIBUTE_LightingColor, SVGATTRIBUTE_MarkerEnd,
237            SVGATTRIBUTE_MarkerMid, SVGATTRIBUTE_MarkerStart,
238            SVGATTRIBUTE_Mask, SVGATTRIBUTE_Opacity, SVGATTRIBUTE_Overflow,
239            SVGATTRIBUTE_PointerEvents, SVGATTRIBUTE_ShapeRendering,
240            SVGATTRIBUTE_StopColor, SVGATTRIBUTE_StopOpacity,
241            SVGATTRIBUTE_Stroke, SVGATTRIBUTE_StrokeDashArray,
242            SVGATTRIBUTE_StrokeDashOffset, SVGATTRIBUTE_StrokeLineCap,
243            SVGATTRIBUTE_StrokeLineJoin, SVGATTRIBUTE_StrokeMiterLimit,
244            SVGATTRIBUTE_StrokeOpacity, SVGATTRIBUTE_StrokeWidth,
245            SVGATTRIBUTE_TextAnchor, SVGATTRIBUTE_TextDecoration,
246            SVGATTRIBUTE_TextRendering, SVGATTRIBUTE_Transform,
247            SVGATTRIBUTE_UnicodeBidi, SVGATTRIBUTE_VectorEffect,
248            SVGATTRIBUTE_Visibility, SVGATTRIBUTE_WordSpacing,
249            SVGATTRIBUTE_WritingMode ) );
250        attributes.addAll( AllowsDocumentEventAttributes.DOCUMENTEVENT_ATTRIBUTES );
251        attributes.addAll( AllowsDocumentElementEventAttributes.DOCUMENTELEMENTEVENT_ATTRIBUTES );
252
253        updateRegistries( childElements, attributes );
254    }   //  SVGImpl()
255
256        /*---------*\
257    ====** Methods **==========================================================
258        \*---------*/
259    /**
260     *  {@inheritDoc}
261     */
262    @Override
263    public final <E extends SVGElement> void addDefinition( final E child ) throws IllegalArgumentException, IllegalStateException
264    {
265        /*
266         * The class of the instance is only sufficient when it is a native
267         * SVG object. But everything that is derived from SVGElementAdapter is
268         * everything (including an SVGStyle), therefore we need to check the
269         * element name, too.
270         */
271        if( requireNonNullArgument( child, "child" ) instanceof final SVGStyle style && child.getElementName().equals( SVGELEMENT_Style ) )
272        {
273            addStyle( style );
274        }
275        else
276        {
277            child.getAttribute( SVGATTRIBUTE_Id ).orElseThrow( () -> new IllegalArgumentException( "Id is missing" ) );
278            m_Definitions.get().addChild( child );
279        }
280    }   //  addDefinition()
281
282    /**
283     *  {@inheritDoc}
284     */
285    @Override
286    public final void addStyle( final SVGStyle style ) throws IllegalArgumentException, IllegalStateException
287    {
288        requireNonNullArgument( style, "style" );
289
290        /*
291         * <style> elements will be merged if possible, and they do not need an
292         * id.
293         */
294        if( m_StyleSheet.isPresent() )
295        {
296            m_StyleSheet.get().merge( style );
297        }
298        else
299        {
300            m_StyleSheet = Optional.of( style );
301            m_Definitions.get().addChild( style );
302        }
303    }   //  addDefinition()
304
305    /**
306     *  Creates the element for the definitions.
307     *
308     *  @return The {@code <defs>} element.
309     */
310    private final  SVGElementImpl createDefinitionsElement()
311    {
312        final var retValue = new SVGElementImpl( SVGELEMENT_Defs, ALLOWS_CHILDREN );
313
314        //---* The children and attributes for the <defs> element *-------------
315        /*
316         * The valid children for the <defs> element are the same as for the
317         * <svg> element - excluding the <defs> element itself.
318         */
319        final var childElements = validChildElements();
320        childElements.remove( SVGELEMENT_Defs );
321
322        /*
323         * The specification allows attributes for the <defs> element, but as
324         * we don't provide an API to set them, we do not configure them ...
325         */
326        retValue.updateRegistries( childElements, emptyList() );
327
328        //---* Done *----------------------------------------------------------
329        return retValue;
330    }   //  createDefinitionsElement()
331
332    /**
333     *  {@inheritDoc}
334     */
335    @Override
336    public final Collection<? extends Element> getChildren()
337    {
338        final Collection<? extends Element> retValue;
339        if( m_Definitions.isPresent() )
340        {
341            final Collection<Element> children = new ArrayList<>();
342            children.add( m_Definitions.get() );
343            children.addAll( super.getChildren() );
344            retValue = List.copyOf( children );
345        }
346        else
347        {
348            retValue = super.getChildren();
349        }
350
351        //---* Done *----------------------------------------------------------
352        return retValue;
353    }   //  getChildren()
354
355    /**
356     *  {@inheritDoc}
357     */
358    @Override
359    public final boolean hasChildren()
360    {
361        final var retValue = m_Definitions.isPresent() || super.hasChildren();
362
363        //---* Done *----------------------------------------------------------
364        return retValue;
365    }   //  hasChildren()
366    /**
367     *  {@inheritDoc}
368     */
369    @Override
370    public final void setContentScriptType( final MimeType value )
371    {
372        setAttribute( SVGATTRIBUTE_ContentScriptType, nonNull( value ) ? value.toString() : null );
373    }   //  setContentScriptType()
374
375    /**
376     *  {@inheritDoc}
377     */
378    @SuppressWarnings( "OptionalGetWithoutIsPresent" )
379    @Override
380    public final SVGStyle setStyleSheet( final CharSequence... styles )
381    {
382        /*
383         * After this call, m_StyleSheet is definitely no longer empty; it
384         * will be set as a side effect of SVG.addStyle(). Not nice, but
385         * efficient.
386         */
387        m_StyleSheet.ifPresentOrElse( style -> style.addStyle( styles ), () -> addStyle( createStyle( styles ) ) );
388
389        //---* Done *----------------------------------------------------------
390        return m_StyleSheet.get();
391    }   //  setStyleSheet()
392
393    /**
394     *  {@inheritDoc}
395     */
396    @Override
397    public final void setZoomAndPan( final boolean flag )
398    {
399        setAttribute( SVGATTRIBUTE_ZoomAndPan, flag ? "magnify" : "disable" );
400    }   //  setZoomAndPan()
401
402    /**
403     *  Composes the list of the valid child elements for the {@code <svg>}
404     *  element.
405     *
406     *  @return The valid child elements.
407     */
408    private final Collection<String> validChildElements()
409    {
410        //---* The valid child elements the <svg> element *--------------------
411        final Collection<String> retValue = new HashSet<>();
412        retValue.addAll( ANIMATION.getElements() );
413        retValue.addAll( DESCRIPTIVE.getElements() );
414        retValue.addAll( SHAPE.getElements() );
415        retValue.addAll( STRUCTURAL.getElements() );
416        retValue.addAll( GRADIENT.getElements() );
417        retValue.addAll( List.of( SVGELEMENT_AltGlyphDef,
418            SVGELEMENT_Anchor, SVGELEMENT_ClipPath, SVGELEMENT_ColorProfile,
419            SVGELEMENT_Cursor, SVGELEMENT_Filter, SVGELEMENT_Font,
420            SVGELEMENT_FontFace, SVGELEMENT_ForeignObject, SVGELEMENT_Image,
421            SVGELEMENT_Marker, SVGELEMENT_Mask, SVGELEMENT_Pattern,
422            SVGELEMENT_Script, SVGELEMENT_Style, SVGELEMENT_Switch,
423            SVGELEMENT_Text, SVGELEMENT_View ) );
424
425        //---* Done *----------------------------------------------------------
426        return retValue;
427    }   //  validChildElements()
428}
429//  class SVGImpl
430
431/*
432 *  End of File
433 */