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,"#") + '"';*/ 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}