/** * Compute the bounds of the text, if necessary. * * @param dc the current DrawContext. */ protected void computeBoundsIfNeeded(DrawContext dc) { // Do not compute bounds if they are available. Computing text bounds is expensive, so only do // this // calculation if necessary. if (this.bounds != null) return; TextRenderer textRenderer = OGLTextRenderer.getOrCreateTextRenderer(dc.getTextRendererCache(), this.getFont()); int width = 0; int maxLineHeight = 0; this.lineBounds = new Rectangle2D[this.lines.length]; for (int i = 0; i < this.lines.length; i++) { Rectangle2D lineBounds = textRenderer.getBounds(lines[i]); width = (int) Math.max(lineBounds.getWidth(), width); double thisLineHeight = Math.abs(lineBounds.getY()); maxLineHeight = (int) Math.max(thisLineHeight, maxLineHeight); this.lineBounds[i] = lineBounds; } this.lineHeight = maxLineHeight; // Compute final height using maxLineHeight and number of lines this.bounds = new Rectangle( this.lines.length, maxLineHeight, width, this.lines.length * maxLineHeight + this.lines.length * this.lineSpacing); }
/** * Compute the amount of rotation to apply to a label in order to keep it oriented toward its * orientation position. * * @param screenPoint Geographic position of the text, projected onto the screen. * @param orientationScreenPoint Orientation position, projected onto the screen. * @return The rotation angle to apply when drawing the label. */ protected Angle computeRotation(Vec4 screenPoint, Vec4 orientationScreenPoint) { // Determine delta between the orientation position and the label position double deltaX = screenPoint.x - orientationScreenPoint.x; double deltaY = screenPoint.y - orientationScreenPoint.y; if (deltaX != 0) { double angle = Math.atan(deltaY / deltaX); return Angle.fromRadians(angle); } else { return Angle.POS90; // Vertical label } }