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