001package sec.web.render.utilities;
002
003import android.graphics.Paint;
004import android.graphics.Rect;
005import android.graphics.Typeface;
006
007import armyc2.c2sd.graphics2d.Point2D;
008import armyc2.c2sd.graphics2d.Rectangle;
009import armyc2.c2sd.renderer.utilities.RectUtilities;
010import armyc2.c2sd.renderer.utilities.RendererSettings;
011
012/**
013*
014 */
015public class SVGTextInfo {
016    protected String _text;
017    protected String _fontName;
018    protected int _fontSize = 0;
019    protected String _fontStyle;
020    protected Point2D _location;
021    protected Rectangle _bounds;
022    private String justification = "start";
023    private double angle = 0;
024    private String alignmentBaseline = "middle";
025
026    public SVGTextInfo(String text, Point2D position, String justification, double angle) {
027        RendererSettings RS = RendererSettings.getInstance();
028        this._fontName = RS.getMPModifierFontName();
029        this._fontSize = RS.getMPModifierFontSize();
030        this._fontStyle = RS.getMPModifierFontType() == Typeface.BOLD ? "bold" : "normal";
031
032        this._text = text;
033
034        this._location = new Point2D.Double(position.getX(), position.getY());
035
036        this.justification = justification;
037        this.angle = angle;
038
039        Paint p = new Paint();
040        p.setTypeface(Typeface.create(this._fontName, RS.getMPModifierFontType()));
041        p.setTextSize(this._fontSize);
042        Rect r = new Rect();
043        p.getTextBounds(text, 0, text.length(), r);
044        this._bounds = new Rectangle(0, 0, r.width(), _fontSize);
045        if (_fontStyle.equals("bold")) // paint.getTextBounds() not handling bold text well
046            this._bounds.width *= 1.2;
047
048
049        if (this.justification.equals("middle"))
050            this._bounds = new Rectangle((int) position.getX() - this._bounds.getWidth() / 2, (int) position.getY() - this._bounds.getHeight() / 2, this._bounds.getWidth(), this._bounds.getHeight());
051        else if (this.justification.equals("end"))
052            this._bounds = new Rectangle((int) position.getX() - this._bounds.getWidth(), (int) position.getY() - this._bounds.getHeight() / 2, this._bounds.getWidth(), this._bounds.getHeight());
053        else
054            this._bounds = new Rectangle((int) position.getX(), (int) position.getY() - this._bounds.getHeight() / 2, this._bounds.getWidth(), this._bounds.getHeight());
055
056        RectUtilities.grow(this._bounds, 1);
057
058        if (this.angle != 0)
059            this._bounds = SVGTextInfo.getRotatedRectangleBounds(this._bounds, position, this.angle, this.justification);
060    }
061
062
063    public Rectangle getTextBounds() {
064        return this._bounds;
065    }
066
067    public String toSVGElement(String textColor, String outlineColor, double outlineWidth) {
068        String fill = textColor;
069        String stroke = outlineColor;
070        double strokeWidth = outlineWidth;
071
072        double x = this._location.getX();
073        double y = this._location.getY();
074
075        String se = "<text";
076        if (this.angle == 0)
077            se += " x=\"" + x + "\" y=\"" + y + "\"";
078        else
079            se += " transform=\"translate(" + x + ',' + y + ") rotate(" + this.angle + ")\"";
080        se += " font-family=\"" + this._fontName + '"';
081        se += " font-size=\"" + this._fontSize + "px\"";
082        se += " font-weight=\"" + this._fontStyle + '"';
083        se += " alignment-baseline=\"" + this.alignmentBaseline + "\"";
084        se += " stroke-miterlimit=\"3\"";
085        se += " text-anchor=\"" + justification + '"';
086
087        /*if(this._angle)
088        {
089            se += ' transform="rotate(' + this._angle + ' ' + this._location.getX() + ' ' + this._location.getY() + ')"';
090        }//*/
091
092        String seStroke = null,
093                seFill = null;
094
095        String text = this._text;
096
097        if (stroke != null && strokeWidth > 0) {
098
099            seStroke = se + " stroke=\"" + stroke + '"';
100            /*else
101                seStroke = se + ' stroke="' + stroke.replace(/#/g,"&#35;") + '"';*/
102
103            if (strokeWidth != 0)
104                seStroke += " stroke-width=\"" + (strokeWidth + 2) + '"';
105            seStroke += " fill=\"none\"";
106            seStroke += ">";
107            seStroke += text;
108            seStroke += "</text>";
109        }
110
111        if (fill != null) {
112
113            seFill = se + " fill=\"" + fill + '"';
114            /*else
115                seFill = se + ' fill="' + fill.replace(/#/g,"%23") + '"';*/
116            seFill += ">";
117            seFill += text;
118            seFill += "</text>";
119        }
120
121        if (stroke != null && !stroke.isEmpty() && fill != null && !fill.isEmpty())
122            se = seStroke + seFill;
123        else if (fill != null && !fill.isEmpty())
124            se = seFill;
125        else
126            se = "";
127        return se;
128    }
129
130    public static Rectangle getRotatedRectangleBounds(Rectangle rectangle, Point2D pivotPt, double angle, String justification) {
131        double textWidth = rectangle.getWidth();
132
133        if (justification.equals("start"))
134            rectangle.setRect((int) (rectangle.getX() - textWidth / 2), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
135        else if (justification.equals("end"))
136            rectangle.setRect((int) (rectangle.getX() + textWidth / 2), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
137
138        Point2D ptTL = new Point2D.Double(rectangle.getMinX(), rectangle.getMinY());
139        Point2D ptTR = new Point2D.Double(rectangle.getMaxX(), rectangle.getMinY());
140        Point2D ptBL = new Point2D.Double(rectangle.getMinX(), rectangle.getMaxY());
141        Point2D ptBR = new Point2D.Double(rectangle.getMaxX(), rectangle.getMaxY());
142
143        SVGTextInfo.rotatePoint(ptTL, pivotPt, angle);
144        SVGTextInfo.rotatePoint(ptTR, pivotPt, angle);
145        SVGTextInfo.rotatePoint(ptBL, pivotPt, angle);
146        SVGTextInfo.rotatePoint(ptBR, pivotPt, angle);
147
148        rectangle = new Rectangle((int) ptTL.getX(), (int) ptTL.getY(), 0, 0);
149        rectangle.add(ptTR);
150        rectangle.add(ptBL);
151        rectangle.add(ptBR);
152
153        if (justification == "start") {
154            double s = Math.sin(angle * 2 * Math.PI / 360);
155            double c = Math.cos(angle * 2 * Math.PI / 360);
156            rectangle.setRect((int) (rectangle.getX() + textWidth / 2 * c), (int) (rectangle.getY() + textWidth / 2 * s), rectangle.getWidth(), rectangle.getHeight());
157        } else if (justification == "end") {
158            double s = Math.sin(angle * 2 * Math.PI / 360);
159            double c = Math.cos(angle * 2 * Math.PI / 360);
160            rectangle.setRect((int) (rectangle.getX() - textWidth / 2 * c), (int) (rectangle.getY() - textWidth / 2 * s), rectangle.getWidth(), rectangle.getHeight());
161
162        }
163
164        return rectangle;
165    }
166
167    static void rotatePoint(Point2D pt, Point2D pivotPt, double angle) {
168        final double s = Math.sin(-angle * 2 * Math.PI / 360);
169        final double c = Math.cos(-angle * 2 * Math.PI / 360);
170
171        pt.setLocation(pt.getX() - pivotPt.getX(), pt.getY() - pivotPt.getY());
172
173        double xnew = pt.getX() * c - pt.getY() * s;
174        double ynew = pt.getX() * s + pt.getY() * c;
175
176        pt.setLocation(xnew + pivotPt.getX(), ynew + pivotPt.getY());
177
178    }
179}