// // PlotText.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2002 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* History: 04 July 2003: Extended the render_font and render_label methods to allow rotation of individual characters, scaling, and offsets. (Sylvain Letourneau) */ package visad; import java.awt.*; import java.awt.font.*; import java.awt.geom.*; import java.util.Vector; import visad.browser.Convert; import visad.util.HersheyFont; /** PlotText calculates an array of points to be plotted to the screen as vector pairs, given a String and location, orientation and size in space.

The font is a simple one, and includes characters from the ASCII collating sequence from 0x20 thru 0x7E. Most of this was taken from the original visad.PlotText. */ public class PlotText extends Object { static final double XMIN = -1.0; static final double YMIN = -1.0; static final double ZMIN = -1.0; static final double WIDTH = .8; /* base line and up vectors */ static double[] bx = { 0.07, 0.0, 0.0 }, ux = { 0.0, 0.07, 0.07 }; static double[] by = { 0.0, 0.07, 0.0 }, uy = { -0.07, 0.0, -0.07 }; static double[] bz = { 0.0, 0.0, -0.07 }, uz = { 0.07, 0.07, 0.0 }; /* vector characters -- (100 + x) value indicates beginning of segment */ /* characters are ordered by ASCII collating sequence, starting at 0x20 */ static float[][] charCodes = { {100f,0f}, // sp {101f,8f,1f,3f,3f,3f,3f,8f,1f,8f,101f,1f,1f,0f,3f,0f,3f,1f,1f,1f}, // ! {101f,8f,0f,5f,104f,8f,3f,5f}, // " {101.5f,8f,1.5f,0f,103.5f,8f,3.5f,0f,100f,5f,5f,5f,100f,3f,5f,3f}, // # {101.5f,8f,1.5f,0f,102.5f,8f,2.5f,0f,104f,5.5f,3f,7f,1f,7f,0f,5.5f,0f,4.5f,4f,3.5f,4f,2.5f,3f,1f,1f,1f,0f,2.5f}, // $ {100f,8f,0f,7f,1f,7f,1f,8f,0f,8f,105f,8f,0f,0f,104f,1f,4f,0f,5f,0f,5f,1f,4f,1f}, // % {105f,0f,0f,5f,0f,7f,1f,8f,3f,8f,4f,7f,4f,5f,0f,3f,0f,1f,1f,0f,3f,0f,5f,3f,5f,4f}, // & {101f,8f,0f,5f}, // ' {104f,8f,2f,6f,2f,2f,4f,0f}, // ( {101f,8f,3f,6f,3f,2f,1f,0f}, // ) {100f,7f,5f,1f,102.5f,7f,2.5f,1f,100f,1f,5f,7f,105f,4f,0f,4f}, // * {102.5f,7f,2.5f,1f,100f,4f,5f,4f}, // + {103f,0f,2f,0f,2f,1f,3f,1f,3f,0f,2.1f,-2f}, // , {100f,4f,5f,4f}, // - {102f,0f,3f,0f,3f,1f,2f,1f,2f,0f}, // . {100f,0f,5f,8f}, // / {102f,8f,0f,6f,0f,2f,2f,0f,3f,0f,5f,2f,5f,6f,3f,8f,2f,8f}, // 0 {101f,7f,2.5f,8f,2.5f,0f,1f,0f,4f,0f}, // 1 {100f,7f,1f,8f,4f,8f,5f,7f,5f,5f,0f,0f,5f,0f}, // 2 {100f,7f,1f,8f,4f,8f,5f,7f,5f,5f,4f,4f,3f,4f,4f,4f,5f,3f,5f,1f,4f,0f,1f,0f,0f,1f}, // 3 {103f,8f,0f,4f,5f,4f,5f,8f,5f,0f}, // 4 {100f,1f,1f,0f,4f,0f,5f,1f,5f,4f,4f,5f,0f,5f,0f,8f,5f,8f}, // 5 {105f,7f,4f,8f,1f,8f,0f,7f,0f,1f,1f,0f,4f,0f,5f,1f,5f,3f,4f,4f,0f,4f}, // 6 {100f,8f,5f,8f,3f,0f}, // 7 {101f,8f,0f,7f,0f,5f,1f,4f,4f,4f,5f,5f,5f,7f,4f,8f,1f,8f,101f,4f,0f,3f,0f,1f,1f,0f,4f,0f,5f,1f,5f,3f,4f,4f}, // 8 {101f,0f,1f,0f,4f,0f,5f,1f,5f,7f,4f,8f,1f,8f,0f,7f,0f,5f,1f,4f,5f,4f}, // 9 {102f,7f,2f,5f,3f,5f,3f,7f,2f,7f,102f,3f,2f,1f,3f,1f,3f,3f,2f,3f}, // : {100f,7f,0f,5f,1f,5f,1f,7f,0f,7f,100f,0f,1f,1f,1f,3f,0f,3f,0f,1f,1f,1f}, // ; {105f,7f,0f,4f,5f,1f}, // < {100f,5f,5f,5f,100f,3f,5f,3f}, // = {100f,7f,5f,4f,0f,1f}, // > {100f,7f,1f,8f,4f,8f,5f,7f,5f,5f,4f,4f,2.5f,4f,2.5f,2f,102.5f,1f,2.5f,0f}, // ? {104f,0f,1f,0f,0f,1f,0f,7f,1f,8f,4f,8f,5f,7f,5f,3f,4f,1.5f,3f,2f,1.5f,4f,1.5f,5f,2.5f,6f,4f,5f,3f,2f}, // @ {100f,0f,0f,7f,1f,8f,4f,8f,5f,7f,5f,0f,5f,4f,0f,4f}, // A {100f,8f,0f,0f,4f,0f,5f,1f,5f,3f,4f,4f,5f,5f,5f,7f,4f,8f,0f,8f,0f,4f,4f,4f}, // B {105f,7f,4f,8f,1f,8f,0f,7f,0f,1f,1f,0f,4f,0f,5f,1f}, // C {100f,8f,0f,0f,4f,0f,5f,1f,5f,7f,4f,8f,0f,8f}, // D {105f,8f,0f,8f,0f,4f,3f,4f,0f,4f,0f,0f,5f,0f}, // E {105f,8f,0f,8f,0f,4f,3f,4f,0f,4f,0f,0f}, // F {105f,7f,4f,8f,1f,8f,0f,7f,0f,1f,1f,0f,4f,0f,5f,1f,5f,4f,3f,4f}, // G {100f,8f,0f,0f,0f,4f,5f,4f,5f,8f,5f,0f}, // H {100f,8f,5f,8f,2.5f,8f,2.5f,0f,0f,0f,5f,0f}, // I {105f,8f,5f,1f,4f,0f,1f,0f,0f,1f,0f,3f}, // J {100f,8f,0f,0f,0f,4f,5f,8f,0f,4f,5f,0f}, // K {100f,8f,0f,0f,5f,0f}, // L {100f,0f,0f,8f,2.5f,4f,5f,8f,5f,0f}, // M {100f,0f,0f,8f,5f,0f,5f,8f}, // N {101f,8f,0f,7f,0f,1f,1f,0f,4f,0f,5f,1f,5f,7f,4f,8f,1f,8f}, // O {100f,0f,0f,8f,4f,8f,5f,7f,5f,5f,4f,4f,0f,4f}, // P {101f,8f,0f,7f,0f,1f,1f,0f,4f,0f,5f,1f,5f,7f,4f,8f,1f,8f,103f,3f,5f,0f}, // Q {100f,0f,0f,8f,4f,8f,5f,7f,5f,5f,4f,4f,0f,4f,3f,4f,5f,0f}, // R {105f,7f,4f,8f,1f,8f,0f,7f,0f,5f,1f,4f,4f,4f,5f,3f,5f,1f,4f,0f,1f,0f,0f,1f}, // S {100f,8f,5f,8f,2.5f,8f,2.5f,0f}, // T {100f,8f,0f,1f,1f,0f,4f,0f,5f,1f,5f,8f}, // U {100f,8f,2.5f,0f,5f,8f}, // V {100f,8f,0f,0f,2.5f,4f,5f,0f,5f,8f}, // W {100f,8f,5f,0f,100f,0f,5f,8f}, // X {100f,8f,2.5f,4f,5f,8f,2.5f,4f,2.5f,0f}, // Y {100f,8f,5f,8f,0f,0f,5f,0f}, // Z {104f,8f,2f,8f,2f,0f,4f,0f}, // [ {100f,8f,5f,0f}, // \ {101f,8f,3f,8f,3f,0f,1f,0f}, // ] {102f,6f,3f,8f,4f,6f}, // ^ {100f,-2f,5f,-2f}, // _ {102f,8f,4f,6f}, // ` {104f,5f,4f,1f,3f,0f,1f,0f,0f,1f,0f,4f,1f,5f,3f,5f,4f,4f,4f,1f,5f,0f}, // a {100f,8f,0f,0f,0f,1f,1f,0f,4f,0f,5f,1f,5f,4f,4f,5f,3f,5f,0f,3f}, // b {105f,0f,1f,0f,0f,1f,0f,4f,1f,5f,4f,5f,5f,4f}, // c {105f,3f,3f,5f,1f,5f,0f,4f,0f,1f,1f,0f,4f,0f,5f,1f,5f,0f,5f,8f}, // d {105f,0f,1f,0f,0f,1f,0f,4f,1f,5f,4f,5f,5f,4f,4f,3f,0f,3f}, // e {103f,0f,3f,7f,4f,8f,5f,8f,5f,7f,101f,4f,4f,4f}, // f {105f,5f,5f,-3f,4f,-4f,1f,-4f,105f,1f,4f,0f,1f,0f,0f,1f,0f,4f,1f,5f,3f,5f,5f,3f}, // g {100f,8f,0f,0f,0f,3f,3f,5f,4f,5f,5f,4f,5f,0f}, // h {103f,4f,3f,0f,4f,0f,1f,0f,103f,6.5f,3f,5.5f}, // i {104f,4f,4f,-3f,3f,-4f,1f,-4f,0f,-3f,0f,-1f,1f,0f,104f,6.5f,4f,5.5f}, // j {101f,8f,1f,0f,101f,3f,5f,5f,101f,3f,5f,0f}, // k {102f,8f,3f,8f,3f,0f}, // l {100f,0f,0f,5f,0f,4f,1f,5f,4f,5f,5f,4f,5f,0f,102.5f,5f,2.5f,2.0f}, // m {100f,0f,0f,5f,0f,4f,1f,5f,4f,5f,5f,3f,5f,0f}, // n {101f,0f,0f,1f,0f,4f,1f,5f,4f,5f,5f,4f,5f,1f,4f,0f,1f,0f}, // o {100f,-4f,0f,1f,1f,0f,4f,0f,5f,1f,5f,4f,4f,5f,3f,5f,0f,3f,0f,1f,0f,5f}, // p {105f,-4f,5f,1f,4f,0f,1f,0f,0f,1f,0f,4f,1f,5f,3f,5f,5f,3f,5f,1f,5f,5f}, // q {100f,5f,0f,0f,0f,3f,3f,5f,4f,5f,5f,4f}, // r {105f,4f,3f,5f,2f,5f,0f,4f,0f,3f,5f,2f,5f,1f,3f,0f,2f,0f,0f,1f}, // s // {105f,4f,4f,5f,3f,5f,1f,3.5f,3f,3f,4f,3f,5f,1f,4f,0f,3f,0f,1f,1f}, // s {102.5f,8f,2.5f,0f,100.5f,5f,4.5f,5f}, // t {100f,5f,0f,1f,1f,0f,3f,0f,5f,3f,5f,5f,5f,0f}, // u {100f,5f,0f,3f,2.5f,0f,5f,3f,5f,5f}, // v {100f,5f,0f,0f,2.5f,3f,5f,0f,5f,5f}, // w {100f,5f,5f,0f,105f,5f,0f,0f}, // x {100f,5f,0f,3f,3f,0f,5f,3f,5f,5f,5f,-3f,3f,-4f}, // y {100f,5f,5f,5f,0f,0f,5f,0f}, // z {104f,8f,3f,8f,2f,4.5f,1f,4.5f,2f,4.5f,3f,0f,4f,0f}, // { {103.5f,8f,3.5f,0f}, // | {102f,8f,3f,8f,4f,4.5f,5f,4.5f,4f,4.5f,3f,0f,2f,0f}, // } {100f,4f,1f,5f,3f,4f,4f,5f}, // ~ {100f,0f} // RO }; /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param axis [=0 (x), =1 (y), or =2 (z) * @param pos position along axis to put label in [-1,1] * @param str the text string to "print" * @param line line number for multi-line text (0 = first line) * @param c color (not used yet) * * @return VisADLineArray of all the vectors needed to draw the * characters in this string */ public static VisADLineArray render_label(int axis, double pos, String str, int line, long c) { double XMIN = -1.0; double YMIN = -1.0; double ZMIN = -1.0; /* base line and up vectors */ double[] bx = { 0.07, 0.0, 0.0 }, ux = { 0.0, 0.07, 0.07 }; double[] by = { 0.0, 0.07, 0.0 }, uy = { -0.07, 0.0, -0.07 }; double[] bz = { 0.0, 0.0, -0.07 }, uz = { 0.07, 0.07, 0.0 }; double[] base = null; double[] up = null; double[] start = new double[3]; if (axis==0) { // x base = bx; up = ux; start[0] = pos; start[1] = YMIN * (1.1 + 0.07*line); start[2] = ZMIN * (1.1 + 0.07*line); } else if (axis==1) { // y base = by; up = uy; start[0] = XMIN * (1.1 + 0.07*line); start[1] = pos; start[2] = ZMIN * (1.1 + 0.07*line); } else if (axis==2) { // z base = bz; up = uz; start[0] = XMIN * (1.1 + 0.07*line); start[1] = YMIN * (1.1 + 0.07*line); start[2] = pos; } // abcd 5 February 2001 return render_label(str, start, base, up, TextControl.Justification.CENTER, TextControl.Justification.BOTTOM, 0.0,1.0, null); // return render_label(str, start, base, up, true); } /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param str String to use * @param start point (x,y,z) * @param base (x,y,z) of baseline vector * @param up (x,y,z) of "up" direction vector * @param center is true if string is to be centered * * @return VisADLineArray of all the vectors needed to draw the * characters in this string */ public static VisADLineArray render_label(String str, double[] start, double[] base, double[] up, boolean center) { return render_label(str, start, base, up, (center ? TextControl.Justification.CENTER : TextControl.Justification.LEFT), TextControl.Justification.BOTTOM, 0.0, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param str String to use * @param start point (x,y,z) * @param base (x,y,z) of baseline vector * @param up (x,y,z) of "up" direction vector * @param justification is one of:

* @param verticalJustification is one of: * * @return VisADLineArray of all the vectors needed to draw the * characters in this string */ public static VisADLineArray render_label(String str, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification) { return render_label(str, start, base, up, justification, verticalJustification, 0.0, 1.0, null); } // abcd 5 February 2001 // was // * @param center is true if string is to be centered /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param str String to use * @param start point (x,y,z) * @param base (x,y,z) of baseline vector * @param up (x,y,z) of "up" direction vector * @param justification is one of: * * @return VisADLineArray of all the vectors needed to draw the * characters in this string */ public static VisADLineArray render_label(String str, double[] start, double[] base, double[] up, TextControl.Justification justification) { return render_label(str, start, base, up, justification, TextControl.Justification.BOTTOM, 0.0, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param str String to use * @param start point (x,y,z) * @param base (x,y,z) of baseline vector * @param up (x,y,z) of "up" direction vector * @param justification is one of: * @param verticalJustification is one of: * @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * * @return VisADLineArray of all the vectors needed to draw the * characters in this string */ public static VisADLineArray render_label(String str, double[] start, double[] base, double[] up, TextControl.Justification justification, double characRotation) { return render_label(str, start, base, up, justification, TextControl.Justification.BOTTOM, characRotation, 1.0, null); } // abcd 5 February 2001 // was // * @param center is true if string is to be centered /** * Convert a string of characters (ASCII collating sequence) into a * series of vectors for drawing. * * @param str String to use * @param start point (x,y,z) * @param base (x,y,z) of baseline vector * @param up (x,y,z) of "up" direction vector * @param justification is one of: * @param verticalJustification is one of: * @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * @param scale is the scaling factor. * @param offsets is a 1x3 array defining the offsets in X, Y, Z, respectively. * * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_label(String str, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification, double characRotation, double scale, double[] offsets) { if (offsets == null) { offsets = new double[]{0.0, 0.0, 0.0}; } if (scale <= 0.0) { scale = 1.0; } /* System.out.println("in render_label:" + " characRotation= " + characRotation + " scale=" + scale + " offset=[" + offsets[0] + ", " + offsets[1] + ", " + offsets[2] + "]"); */ double []start_off = new double[3]; start_off[0] = start[0] + offsets[0]; start_off[1] = start[1] + offsets[1]; start_off[2] = start[2] + offsets[2]; double[] base_scaled = new double[3]; base_scaled[0] = base[0] * scale; base_scaled[1] = base[1] * scale; base_scaled[2] = base[2] * scale; double[] up_scaled = new double[3]; up_scaled[0] = up[0] * scale; up_scaled[1] = up[1] * scale; up_scaled[2] = up[2] * scale; double[] temp; double cx, cy, cz; double startx = 0.0; double starty = 0.0; double startz = 0.0; double sw; int i, j, k, v2, len; cx = start_off[0]; cy = start_off[1]; cz = start_off[2]; len = str.length(); // allow 20 2-point 3-component strokes per character float[] plot = new float[120 * len]; int plot_index = 0; double angle = Math.toRadians(-characRotation); float angle2 = (float) (angle + Math.PI/2.0); double w, h, x, y; /* draw left justified text */ for (i=0; i 127) continue; // invalid - just skip int verts = charCodes[k].length/2; /* make the vertex array for this character */ /* points with x>9 are 'start new segment' flag */ int plot_index_begin = plot_index; float maxX = 0.f; float maxY = 0.f, minY = 10.f; int temp_index = 0; for (j=0; j 9.0) { if (j != 0) plot_index -= 3; // reset pointer to remove last point w = w - 10.0; dup_point = false; } temp_index++; h = (double) charCodes[k][temp_index]*.1; temp_index++; if (w > maxX) maxX = (float) w; if (h > maxY) maxY = (float) h; if (h < minY) minY = (float) h; // System.out.println(i + " " + j + " " + cur_char + ". w=" + w + " h=" + h); x = (float) (w * Math.cos(angle) - h * Math.sin(angle)); y = (float) (w * Math.sin(angle) + h * Math.cos(angle)); // System.out.println(i + ". " + k + ". " + j + ". x=" + x + ", y="+ y); px = (float) (cx + x * base_scaled[0] + y * up_scaled[0]); py = (float) (cy + x * base_scaled[1] + y * up_scaled[1]); pz = (float) (cz + x * base_scaled[2] + y * up_scaled[2]); plot[plot_index] = px; plot[plot_index + 1] = py; plot[plot_index + 2] = pz; if (dup_point) { // plot points are in pairs -- set up for next pair plot[plot_index + 3] = plot[plot_index]; plot[plot_index + 4] = plot[plot_index + 1]; plot[plot_index + 5] = plot[plot_index + 2]; plot_index += 3; } plot_index += 3; } if (minY > maxY) { minY = maxY; // no vertice } // System.out.println(i + ". " + cur_char + ". maxX=" + maxX + ", minY="+ minY + ", maxY="+ maxY); // Calculate offsets due to rotations of characters x = maxX; y = (float)(maxY-minY + 0.1); float x_plus = (float) (x * Math.abs(Math.cos(angle)) + y * Math.abs(Math.cos(angle2))); float cur_x_off = 0.0f; if (Math.cos(angle) < 0) { cur_x_off = (float) (x * Math.abs(Math.cos(angle))); } if (Math.cos(angle2) < 0) { cur_x_off += (float) ((maxY+.05) * Math.abs(Math.cos(angle2))); } else if (minY < 0) { cur_x_off += (float) ((-minY+0.05) * Math.abs(Math.cos(angle2))); } // System.out.println(i + ". " + cur_char + ". x=" + x + " y=" + y + " x_plus=" + x_plus + " cur_x_off=" + cur_x_off); // Apply offsets for (j=plot_index_begin;jtrue if string is to be centered * * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_font(String str, HersheyFont font, double[] start, double[] base, double[] up, boolean center) { return render_font(str, font, start, base, up, (center ? TextControl.Justification.CENTER : TextControl.Justification.LEFT), TextControl.Justification.BOTTOM, 0.0, 1, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of lines for drawing. * * @param str String to use * @param font non-null HersheyFont name * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_font(String str, HersheyFont font, double[] start, double[] base, double[] up, TextControl.Justification justification) { return render_font(str, font, start, base, up, justification, TextControl.Justification.BOTTOM, 0.0, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of lines for drawing. * * @param str String to use * @param font non-null HersheyFont name * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_font(String str, HersheyFont font, double[] start, double[] base, double[] up, TextControl.Justification justification, double characRotation) { return render_font(str, font, start, base, up, justification, TextControl.Justification.BOTTOM, characRotation, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of lines for drawing. * * @param str String to use * @param font non-null HersheyFont name * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param verticalJustification is one of:
    *
  • TextControl.Justification.TOP - Top justified text *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.BOTTOM - Bottom justified text (normal) *
* * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_font(String str, HersheyFont font, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification) { return render_font(str, font, start, base, up, justification, verticalJustification, 0.0, 1.0, null); } // abcd, 3 March 2003 /** * Convert a string of characters (ASCII collating sequence) into a * series of lines for drawing. * * @param str String to use * @param font non-null HersheyFont name * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param verticalJustification is one of:
    *
  • TextControl.Justification.TOP - Top justified text *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.BOTTOM - Bottom justified text (normal) *
* @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * @param scale is the scaling factor. * @param offsets is a 1x3 array defining the offsets in X, Y, Z, respectively. * * @return VisADLineArray of all the lines needed to draw the * characters in this string */ public static VisADLineArray render_font(String str, HersheyFont font, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification, double characRotation, double scale, double[] offsets) { /* System.out.println("in render_font with HersheyFont font:" + " characRotation= " + characRotation + " scale=" + scale + " offset=[" + offsets[0] + ", " + offsets[1] + ", " + offsets[2] + "]" ); */ if (offsets == null) { offsets = new double[]{0.0, 0.0, 0.0}; } double []start_off = new double[3]; start_off[0] = start[0] + offsets[0]; start_off[1] = start[1] + offsets[1]; start_off[2] = start[2] + offsets[2]; if (scale <= 0.0) { scale = 1.0; } double[] base_scaled = new double[3]; base_scaled[0] = base[0] * scale; base_scaled[1] = base[1] * scale; base_scaled[2] = base[2] * scale; double[] up_scaled = new double[3]; up_scaled[0] = up[0] * scale; up_scaled[1] = up[1] * scale; up_scaled[2] = up[2] * scale; int maxChars = font.getCharactersInSet(); double width = 0; double startx = 0.0; double starty = 0.0; double startz = 0.0; double cx = start_off[0]; double cy = start_off[1]; double cz = start_off[2]; int len = str.length(); boolean isFixed = font.getFixedWidth(); // allow 2-point 3-component strokes per character int maxSeg = font.getMaxPoints(); float[] plot = new float[maxSeg * 6 * len]; int plot_index = 0; int [] charMinX = font.getCharacterMinX(); int [] charMaxX = font.getCharacterMaxX(); int charMinY = font.getCharacterSetMinY(); int charMaxY = font.getCharacterSetMaxY(); int charSetMinX = font.getCharacterSetMinX(); int charSetMaxX = font.getCharacterSetMaxX(); boolean isCursive = font.getIsCursive(); float oldpx = 0.f; float oldpy = 0.f; float oldpz = 0.f; float x,y, px, py, pz; float w,h; // look at each character in the string double angle = Math.toRadians(-characRotation); float angle2 = (float) (angle + Math.PI/2.0); for (int i=0; i maxChars) continue; // invalid - just skip char [][] charVector = font.getCharacterVector(k); int verts = font.getNumberOfPoints(k); /* calculate position for start of this char - about .08 seems right*/ if (i > 0) { width = .08; if (isCursive) width = -.08; cx += width * base_scaled[0]; cy += width * base_scaled[1]; cz += width * base_scaled[2]; } // System.out.println(i + ". " + cur_char + ". charMinY=" + charMinY + " charMaxY=" + charMaxY); // System.out.println(i + ". " + cur_char + " cx=" + cx + " cy=" + cy + " cz=" + cz); int plot_index_begin = plot_index; boolean skip = true; float maxX = 0.f; float maxY = 0.f, minY = (float)charMaxY; for (int j=1; j maxX) maxX = w; if (h > maxY) maxY = h; if (h < minY) minY = h; // System.out.println(i + " " + j + " " + cur_char + ". w=" + w + " h=" + h); x = (float) (w * Math.cos(angle) - h * Math.sin(angle)); y = (float) (w * Math.sin(angle) + h * Math.cos(angle)); // System.out.println(i + ". " + k + ". " + j + ". x=" + x + ", y="+ y); px = (float) (cx + x * base_scaled[0] + y * up_scaled[0]); py = (float) (cy + x * base_scaled[1] + y * up_scaled[1]); pz = (float) (cz + x * base_scaled[2] + y * up_scaled[2]); // System.out.println(i + ". " + k + ". " + j + ". px=" + px + ", py="+ py + ", pz=" + pz); // need pairs of points if (!skip) { plot[plot_index] = oldpx; plot[plot_index + 1] = oldpy; plot[plot_index + 2] = oldpz; plot[plot_index + 3] = px; plot[plot_index + 4] = py; plot[plot_index + 5] = pz; plot_index += 6; } skip = false; oldpx = px; oldpy = py; oldpz = pz; } } if (verts == 1) maxX = .5f; if (minY > maxY) { minY = maxY; // no vertice } // System.out.println(i + ". " + cur_char + ". maxX=" + maxX + ", minY="+ minY + ", maxY="+ maxY); // Calculate offsets due to rotations of characters x = maxX; y = (float)Math.max((maxY - minY + 0.3), 0.5); float x_plus = (float) (x * Math.abs(Math.cos(angle)) + y * Math.abs(Math.cos(angle2))); float cur_x_off = 0.0f; if (Math.cos(angle) < 0) { cur_x_off = (float) (x * Math.abs(Math.cos(angle))); } if (Math.cos(angle2) < 0) { cur_x_off += (float) (y * Math.abs(Math.cos(angle2))); } // The space required to center horizontally float y1 = (float) ((minY + .30)/2.0 - minY); cur_x_off += (float) (y1 * Math.cos(angle2)); // System.out.println(i + ". " + cur_char + ". x=" + x + " y=" + y + " y1=" + y1 + " x_plus=" + x_plus + " cur_x_off=" + cur_x_off); // Apply offsets for (int j=plot_index_begin;jtrue if string is to be centered * * @return VisADTriangleArray of all the triangles needed to draw the * characters in this string */ public static VisADTriangleArray render_font(String str, Font font, double[] start, double[] base, double[] up, boolean center) { return render_font(str, font, start, base, up, (center ? TextControl.Justification.CENTER : TextControl.Justification.LEFT), TextControl.Justification.BOTTOM, 0.0, 1.0, null); } // abcd 19 March 2003 /** * Convert a string of characters (ASCII collating sequence) into a * series of triangles for drawing. * * @param str String to use * @param font non-null font * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* * @return VisADTriangleArray of all the triangles needed to draw the * characters in this string */ public static VisADTriangleArray render_font(String str, Font font, double[] start, double[] base, double[] up, TextControl.Justification justification) { return render_font(str, font, start, base, up, justification, TextControl.Justification.BOTTOM, 0.0, 0.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of triangles for drawing. * * @param str String to use * @param font non-null font * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * * @return VisADTriangleArray of all the triangles needed to draw the * characters in this string */ public static VisADTriangleArray render_font(String str, Font font, double[] start, double[] base, double[] up, TextControl.Justification justification, double characRotation) { return render_font(str, font, start, base, up, justification, TextControl.Justification.BOTTOM, characRotation, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of triangles for drawing. * * @param str String to use * @param font non-null font * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param verticalJustification is one of:
    *
  • TextControl.Justification.TOP - Top justified text *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.BOTTOM - Bottom justified text (normal) *
* * @return VisADTriangleArray of all the triangles needed to draw the * characters in this string */ public static VisADTriangleArray render_font(String str, Font font, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification) { return render_font(str, font, start, base, up, justification, verticalJustification, 0.0, 1.0, null); } /** * Convert a string of characters (ASCII collating sequence) into a * series of triangles for drawing. * * @param str String to use * @param font non-null font * ?param start * ?param base * ?param up * @param justification is one of:
    *
  • TextControl.Justification.LEFT - Left justified text (ie: normal text) *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.RIGHT - Right justified text *
* @param verticalJustification is one of:
    *
  • TextControl.Justification.TOP - Top justified text *
  • TextControl.Justification.CENTER - Centered text *
  • TextControl.Justification.BOTTOM - Bottom justified text (normal) *
* @param characRotation is the angle (in degrees) at which each character * in str is rotated with respect to the base line of the text. A positive * value rotates the characters clockwise; a negative value * rotates them counterclockwise. * @param scale is the scaling factor. * @param offsets is a 1x3 array defining the offsets in X, Y, Z, respectively. * * @return VisADTriangleArray of all the triangles needed to draw the * characters in this string */ public static VisADTriangleArray render_font(String str, Font font, double[] start, double[] base, double[] up, TextControl.Justification justification, TextControl.Justification verticalJustification, double characRotation, double scale, double[] offsets) { VisADTriangleArray array = null; // System.out.println("x, y, z = " + x + " " + y + " " + z); // System.out.println("center = " + center); /* System.out.println("in render_font with Java font:" + " characRotation= " + characRotation + " scale=" + scale + " offset=[" + offsets[0] + ", " + offsets[1] + ", " + offsets[2] + "]"); */ if (offsets == null) { offsets = new double[]{0.0, 0.0, 0.0}; } double []start_off = new double[3]; start_off[0] = start[0] + offsets[0]; start_off[1] = start[1] + offsets[1]; start_off[2] = start[2] + offsets[2]; if (scale < 0.0) { scale = 1.0; } float fsize = font.getSize(); float fsize_inv = (float)(scale / fsize); //float fsize_inv = (float)(1.0 / fsize); // ?? // Graphics2D g2 = null; // FontRenderContext frc = g2.getFontRenderContext(); int str_len = str.length(); AffineTransform at = null; boolean isAntiAliased = false; boolean usesFractionalMetrics = false; FontRenderContext frc = new FontRenderContext(at, isAntiAliased, usesFractionalMetrics); GlyphVector gv = font.createGlyphVector(frc, "M"); float maxW = (float) (fsize_inv * gv.getGlyphMetrics(0). getBounds2D().getWidth()); double flatness = 0.05; // ?? Vector big_vector = new Vector(); int big_len = 1000; float[][] big_samples = new float[2][big_len]; float[] seg = new float[6]; float x_offset = 0.0f; for (int str_index=0; str_index 1) { // System.out.println("path_count = " + path_count + // " for char = " + chars[0]); float[][][] ss = new float[path_count][][]; for (int i=0; i