001/*
002 * ============================================================================
003 * Copyright © 2002-2023 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.Arrays.stream;
021import static java.util.stream.Collectors.joining;
022import static org.apiguardian.api.API.Status.INTERNAL;
023import static org.tquadrat.foundation.lang.Objects.nonNull;
024import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_LengthAdjust;
025import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_Rotate;
026import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_TextLength;
027import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_dx;
028import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_dy;
029import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_x;
030import static org.tquadrat.foundation.svg.SVGUtils.SVGATTRIBUTE_y;
031import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.ALLOWS_CHILDREN;
032import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.ALLOWS_TEXT;
033import static org.tquadrat.foundation.xml.builder.XMLElement.Flags.VALIDATES_ATTRIBUTES;
034
035import org.apiguardian.api.API;
036import org.tquadrat.foundation.annotation.ClassVersion;
037import org.tquadrat.foundation.svg.type.SVGNumber;
038import org.tquadrat.foundation.svg.type.SVGNumber.SVGDegree;
039
040/**
041 *  The abstract common base class for the implementation of interfaces
042 *  {@link org.tquadrat.foundation.svg.SVGText}
043 *  and
044 *  {@link org.tquadrat.foundation.svg.SVGTSpan}.
045 *
046 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
047 *  @version $Id: SVGTextBase.java 1074 2023-10-02 12:05:06Z tquadrat $
048 *  @since 0.0.5
049 *
050 *  @UMLGraph.link
051 */
052@SuppressWarnings( "AbstractClassExtendsConcreteClass" )
053@ClassVersion( sourceVersion = "$Id: SVGTextBase.java 1074 2023-10-02 12:05:06Z tquadrat $" )
054@API( status = INTERNAL, since = "0.0.5" )
055public abstract sealed class SVGTextBase extends SVGElementImpl
056    permits SVGTSpanImpl, SVGTextImpl
057{
058        /*--------------*\
059    ====** Constructors **=====================================================
060        \*--------------*/
061    /**
062     *  Creates a new {@code SVGTextBase} instance.
063     *
064     *  @param  elementName The element name.
065     */
066    protected SVGTextBase( final String elementName )
067    {
068        super( elementName, ALLOWS_CHILDREN, ALLOWS_TEXT, VALIDATES_ATTRIBUTES );
069    }   //  SVGTextBase()
070
071        /*---------*\
072    ====** Methods **==========================================================
073        \*---------*/
074    /**
075     *  Sets a list of lengths which move the characters relative to the
076     *  absolute position of the last glyph drawn. The n<sup>th</sup> length is
077     *  given to n<sup>th</sup> character in the text. If there are additional
078     *  characters after the positions run out, the last length is applied to
079     *  them.
080     *
081     *  @param  values  The lengths.
082     */
083    public final void setDx( @SuppressWarnings( "UseOfConcreteClass" ) final SVGNumber... values )
084    {
085        final var value = nonNull( values ) && (values.length != 0) ? stream( values ).map( SVGNumber::toString ).collect( joining( "," ) ) : null;
086        setAttribute( SVGATTRIBUTE_dx, value );
087    }   //  setDx()
088
089    /**
090     *  Sets a list of heights which move the characters relative to the
091     *  absolute position of the last glyph drawn. The n<sup>th</sup> height is
092     *  given to n<sup>th</sup> character in the text. If there are additional
093     *  characters after the positions run out, the last height is applied to
094     *  them.
095     *
096     *  @param  values  The heights.
097     */
098    public final void setDy( @SuppressWarnings( "UseOfConcreteClass" ) final SVGNumber... values )
099    {
100        final var value = nonNull( values ) && (values.length != 0) ? stream( values ).map( SVGNumber::toString ).collect( joining( "," ) ) : null;
101        setAttribute( SVGATTRIBUTE_dy, value );
102    }   //  setDy()
103
104    /**
105     *  Sets the way the text length will be adjusted in order to meet the
106     *  target length set by
107     *  {@link #setTextLength(SVGNumber)}.
108     *
109     *  @param  flag    {@code true} means that both, spacing and glyph size
110     *      will be adjusted to match, {@code false} indicates that only the
111     *      spacing will be changed.
112     */
113    public final void setLengthAdjust( final boolean flag )
114    {
115        final var value = flag ? "spacingAndGlyphs" : "spacing";
116        setAttribute( SVGATTRIBUTE_LengthAdjust, value );
117    }   //  setLengthAdjust()
118
119    /**
120     *  Sets a list of rotations for the glyphs. The n<sup>th</sup> rotation is
121     *  given to n<sup>th</sup> character in the text. Additional characters
122     *  are <em>not</em> given the last rotation (although some browsers may
123     *  handle that differently).
124     *
125     *  @param  values  The rotations.
126     */
127    public final void setRotate( @SuppressWarnings( "UseOfConcreteClass" ) final SVGDegree... values )
128    {
129        final var value = nonNull( values ) && (values.length != 0) ? stream( values ).map( SVGDegree::toString ).collect( joining( "," ) ) : null;
130        setAttribute( SVGATTRIBUTE_Rotate, value );
131    }   //  setRotate()
132
133    /**
134     *  Sets the target length for the text that an SVG viewer will attempt to
135     *  display the text between by adjusting the spacing and/or the glyphs.
136     *
137     *  @param  value   The intended text length.
138     */
139    public final void setTextLength( @SuppressWarnings( "UseOfConcreteClass" ) final SVGNumber value ) { setAttribute( SVGATTRIBUTE_TextLength, value ); }
140
141    /**
142     *  Sets a list of x-axis position. The n<sup>th</sup> x-axis position is
143     *  given to n<sup>th</sup> character in the text. If there are additional
144     *  characters after the positions run out, they are placed after the last
145     *  character.
146     *
147     *  @param  values  The x-axis positions.
148     */
149    public final void setX( @SuppressWarnings( "UseOfConcreteClass" ) final SVGNumber... values )
150    {
151        final var value = nonNull( values ) && (values.length != 0) ? stream( values ).map( SVGNumber::toString ).collect( joining( "," ) ) : null;
152        setAttribute( SVGATTRIBUTE_x, value );
153    }   //  setX()
154
155    /**
156     *  Sets a list of y-axis position. The n<sup>th</sup> y-axis position is
157     *  given to n<sup>th</sup> character in the text. If there are additional
158     *  characters after the positions run out, they are placed after the last
159     *  character.
160     *
161     *  @param  values  The y-axis positions.
162     */
163    public final void setY( @SuppressWarnings( "UseOfConcreteClass" ) final SVGNumber... values )
164    {
165        final var value = nonNull( values ) && (values.length != 0) ? stream( values ).map( SVGNumber::toString ).collect( joining( "," ) ) : null;
166        setAttribute( SVGATTRIBUTE_y, value );
167    }   //  setY()
168}
169//  class SVGTextBase
170
171/*
172 *  End of File
173 */