1 package org.jmol.util; 2 3 4 import javajs.util.AU; 5 import javajs.util.M3; 6 import javajs.util.P3; 7 import javajs.util.T3; 8 import javajs.util.V3; 9 10 11 import org.jmol.api.GenericPlatform; 12 import org.jmol.api.JmolGraphicsInterface; 13 import org.jmol.api.JmolRendererInterface; 14 import org.jmol.c.STER; 15 import org.jmol.viewer.Viewer; 16 17 public class GData implements JmolGraphicsInterface { 18 19 public GenericPlatform apiPlatform; 20 public boolean translucentCoverOnly; 21 public boolean currentlyRendering; 22 public boolean antialiasEnabled; 23 24 protected int windowWidth, windowHeight; 25 protected int displayMinX, displayMaxX, displayMinY, displayMaxY; 26 protected int displayMinX2, displayMaxX2, displayMinY2, displayMaxY2; 27 protected boolean antialiasThisFrame; 28 29 protected boolean inGreyscaleMode; 30 31 protected short[] changeableColixMap = new short[16]; 32 33 protected Object backgroundImage; 34 35 protected int newWindowWidth, newWindowHeight; 36 protected boolean newAntialiasing; 37 38 public int bgcolor; 39 public int xLast, yLast; 40 public int slab, depth; 41 public int width, height; 42 public int ambientOcclusion; 43 44 protected short colixCurrent; 45 public int argbCurrent; 46 protected int ht3; // ht * 3, for cylinders 47 public boolean isPass2; 48 protected int textY; 49 50 public int bufferSize; 51 52 public Shader shader; 53 54 protected Viewer vwr; 55 56 public final static byte ENDCAPS_NONE = 0; 57 public final static byte ENDCAPS_HIDDEN = 1; // no cap, but interior 58 public final static byte ENDCAPS_FLAT = 2; 59 public final static byte ENDCAPS_SPHERICAL = 3; 60 public final static byte ENDCAPS_OPEN_TO_SPHERICAL = 4; 61 public final static byte ENDCAPS_FLAT_TO_SPHERICAL = 5; 62 63 /** 64 * It is possible to instantiate this class with no Graphics3D. 65 * This will happen in the case of WebGL. 66 */ GData()67 public GData() { 68 shader = new Shader(); 69 } 70 initialize(Viewer vwr, GenericPlatform apiPlatform)71 public void initialize(Viewer vwr, GenericPlatform apiPlatform) { 72 this.vwr = vwr; 73 this.apiPlatform = apiPlatform; 74 } 75 76 /** 77 * clipping from the front and the back 78 *<p> 79 * the plane is defined as a percentage from the back of the image to the 80 * front 81 *<p> 82 * for depth values: 83 * <ul> 84 * <li>0 means 100% is shown 85 * <li>25 means the back 25% is <i>not</i> shown 86 * <li>50 means the back half is <i>not</i> shown 87 * <li>100 means that nothing is shown 88 * </ul> 89 *<p> 90 * 91 * @param depthValue 92 * rear clipping percentage [0,100] 93 */ setDepth(int depthValue)94 public void setDepth(int depthValue) { 95 depth = depthValue < 0 ? 0 : depthValue; 96 } 97 98 /** 99 * clipping from the front and the back 100 *<p> 101 * the plane is defined as a percentage from the back of the image to the 102 * front 103 *<p> 104 * For slab values: 105 * <ul> 106 * <li>100 means 100% is shown 107 * <li>75 means the back 75% is shown 108 * <li>50 means the back half is shown 109 * <li>0 means that nothing is shown 110 * </ul> 111 *<p> 112 * 113 * @param slabValue 114 * front clipping percentage [0,100] 115 */ 116 @Override 117 public void setSlab(int slabValue) { 118 slab = Math.max(0, slabValue); 119 } 120 121 /** 122 * @param zSlab 123 * for zShade 124 * @param zDepth 125 * for zShade 126 * @param zPower 127 */ 128 @Override 129 public void setSlabAndZShade(int slab, int depth,int zSlab, int zDepth, int zPower) { 130 setSlab(slab); 131 setDepth(depth); 132 } 133 134 135 protected Object graphicsForMetrics; 136 137 public final static int EXPORT_RAYTRACER = 2; 138 139 public final static int EXPORT_CARTESIAN = 1; 140 141 public final static int EXPORT_NOT = 0; 142 143 public void setAmbientOcclusion(int value) { 144 ambientOcclusion = value; 145 } 146 147 148 /** 149 * is full scene / oversampling antialiasing in effect 150 * 151 * @return the answer 152 */ 153 @Override 154 public boolean isAntialiased() { 155 return antialiasThisFrame; 156 } 157 158 public short getChangeableColix(int id, int argb) { 159 if (id >= changeableColixMap.length) 160 changeableColixMap = AU.arrayCopyShort(changeableColixMap, id + 16); 161 if (changeableColixMap[id] == 0) 162 changeableColixMap[id] = C.getColix(argb); 163 return (short) (id | C.CHANGEABLE_MASK); 164 } 165 changeColixArgb(int id, int argb)166 public void changeColixArgb(int id, int argb) { 167 if (id < changeableColixMap.length && changeableColixMap[id] != 0) 168 changeableColixMap[id] = C.getColix(argb); 169 } 170 getColorArgbOrGray(short colix)171 public int getColorArgbOrGray(short colix) { 172 if (colix < 0) 173 colix = changeableColixMap[colix & C.UNMASK_CHANGEABLE_TRANSLUCENT]; 174 return (inGreyscaleMode ? C.getArgbGreyscale(colix) : C.getArgb(colix)); 175 } 176 getShades(short colix)177 public int[] getShades(short colix) { 178 if (colix < 0) 179 colix = changeableColixMap[colix & C.UNMASK_CHANGEABLE_TRANSLUCENT]; 180 return (inGreyscaleMode ? shader.getShadesG(colix) : shader 181 .getShades(colix)); 182 } 183 184 /** 185 * controls greyscale rendering 186 * 187 * @param greyscaleMode 188 * Flag for greyscale rendering 189 */ setGreyscaleMode(boolean greyscaleMode)190 public void setGreyscaleMode(boolean greyscaleMode) { 191 this.inGreyscaleMode = greyscaleMode; 192 } 193 getSpecularPower()194 public int getSpecularPower() { 195 return shader.specularPower; 196 } 197 198 /** 199 * fractional distance to white for specular dot 200 * 201 * @param val 202 */ setSpecularPower(int val)203 public synchronized void setSpecularPower(int val) { 204 if (val < 0) { 205 setSpecularExponent(-val); 206 return; 207 } 208 if (shader.specularPower == val) 209 return; 210 shader.specularPower = val; 211 shader.intenseFraction = val / 100f; 212 shader.flushCaches(); 213 } 214 getSpecularPercent()215 public int getSpecularPercent() { 216 return shader.specularPercent; 217 } 218 219 /** 220 * sf in I = df * (N dot L) + sf * (R dot V)^p not a percent of anything, 221 * really 222 * 223 * @param val 224 */ setSpecularPercent(int val)225 public synchronized void setSpecularPercent(int val) { 226 if (shader.specularPercent == val) 227 return; 228 shader.specularPercent = val; 229 shader.specularFactor = val / 100f; 230 shader.flushCaches(); 231 } 232 getSpecularExponent()233 public int getSpecularExponent() { 234 return shader.specularExponent; 235 } 236 237 /** 238 * log_2(p) in I = df * (N dot L) + sf * (R dot V)^p for faster calculation of 239 * shades 240 * 241 * @param val 242 */ setSpecularExponent(int val)243 public synchronized void setSpecularExponent(int val) { 244 if (shader.specularExponent == val) 245 return; 246 shader.specularExponent = val; 247 shader.phongExponent = (int) Math.pow(2, val); 248 shader.usePhongExponent = false; 249 shader.flushCaches(); 250 } 251 getPhongExponent()252 public int getPhongExponent() { 253 return shader.phongExponent; 254 } 255 256 /** 257 * p in I = df * (N dot L) + sf * (R dot V)^p 258 * 259 * @param val 260 */ setPhongExponent(int val)261 public synchronized void setPhongExponent(int val) { 262 if (shader.phongExponent == val && shader.usePhongExponent) 263 return; 264 shader.phongExponent = val; 265 float x = (float) (Math.log(val) / Math.log(2)); 266 shader.usePhongExponent = (x != (int) x); 267 if (!shader.usePhongExponent) 268 shader.specularExponent = (int) x; 269 shader.flushCaches(); 270 } 271 getDiffusePercent()272 public int getDiffusePercent() { 273 return shader.diffusePercent; 274 } 275 276 /** 277 * df in I = df * (N dot L) + sf * (R dot V)^p 278 * 279 * @param val 280 */ setDiffusePercent(int val)281 public synchronized void setDiffusePercent(int val) { 282 if (shader.diffusePercent == val) 283 return; 284 shader.diffusePercent = val; 285 shader.diffuseFactor = val / 100f; 286 shader.flushCaches(); 287 } 288 getAmbientPercent()289 public int getAmbientPercent() { 290 return shader.ambientPercent; 291 } 292 293 /** 294 * fractional distance from black for ambient color 295 * 296 * @param val 297 */ setAmbientPercent(int val)298 public synchronized void setAmbientPercent(int val) { 299 if (shader.ambientPercent == val) 300 return; 301 shader.ambientPercent = val; 302 shader.ambientFraction = val / 100f; 303 shader.flushCaches(); 304 } 305 getSpecular()306 public boolean getSpecular() { 307 return shader.specularOn; 308 } 309 setSpecular(boolean val)310 public synchronized void setSpecular(boolean val) { 311 if (shader.specularOn == val) 312 return; 313 shader.specularOn = val; 314 shader.flushCaches(); 315 } 316 setCel(boolean val)317 public void setCel(boolean val) { 318 shader.setCel(val, shader.celPower, bgcolor); 319 } 320 getCel()321 public boolean getCel() { 322 return shader.celOn; 323 } 324 getCelPower()325 public int getCelPower() { 326 return shader.celPower; 327 } 328 setCelPower(int celPower)329 public void setCelPower(int celPower) { 330 shader.setCel(shader.celOn || shader.celPower == 0, celPower, bgcolor); 331 } 332 getLightSource()333 public V3 getLightSource() { 334 return shader.lightSource; 335 } 336 isClipped3(int x, int y, int z)337 public boolean isClipped3(int x, int y, int z) { 338 // this is the one that could be augmented with slabPlane 339 return (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth); 340 } 341 isClipped(int x, int y)342 public boolean isClipped(int x, int y) { 343 return (x < 0 || x >= width || y < 0 || y >= height); 344 } 345 346 @Override isInDisplayRange(int x, int y)347 public boolean isInDisplayRange(int x, int y) { 348 return (x >= displayMinX && x < displayMaxX && y >= displayMinY && y < displayMaxY); 349 } 350 351 @Override isClippedXY(int diameter, int x, int y)352 public boolean isClippedXY(int diameter, int x, int y) { 353 int r = (diameter + 1) >> 1; 354 return (x < -r || x >= width + r || y < -r || y >= height + r); 355 } 356 isClippedZ(int z)357 public boolean isClippedZ(int z) { 358 return (z != Integer.MIN_VALUE && (z < slab || z > depth)); 359 } 360 361 final public static int yGT = 1; 362 final public static int yLT = 2; 363 final public static int xGT = 4; 364 final public static int xLT = 8; 365 final public static int zGT = 16; 366 final public static int zLT = 32; 367 final public static int HUGE = -1; 368 clipCode3(int x, int y, int z)369 public int clipCode3(int x, int y, int z) { 370 int code = 0; 371 if (x < 0) 372 code |= (x < displayMinX2 ? HUGE : xLT); 373 else if (x >= width) 374 code |= (x > displayMaxX2 ? HUGE : xGT); 375 if (y < 0) 376 code |= (y < displayMinY2 ? HUGE : yLT); 377 else if (y >= height) 378 code |= (y > displayMaxY2 ? HUGE : yGT); 379 if (z < slab) 380 code |= zLT; 381 else if (z > depth) // note that this is .GT., not .GE. 382 code |= zGT; 383 384 return code; 385 } 386 clipCode(int z)387 public int clipCode(int z) { 388 int code = 0; 389 if (z < slab) 390 code |= zLT; 391 else if (z > depth) // note that this is .GT., not .GE. 392 code |= zGT; 393 return code; 394 } 395 396 /* *************************************************************** 397 * fontID stuff 398 * a fontID is a byte that contains the size + the face + the style 399 * ***************************************************************/ 400 getFont3D(float fontSize)401 public Font getFont3D(float fontSize) { 402 return Font.createFont3D(Font.FONT_FACE_SANS, Font.FONT_STYLE_PLAIN, 403 fontSize, fontSize, apiPlatform, graphicsForMetrics); 404 } 405 getFont3DFS(String fontFace, float fontSize)406 public Font getFont3DFS(String fontFace, float fontSize) { 407 return Font.createFont3D(Font.getFontFaceID(fontFace), 408 Font.FONT_STYLE_PLAIN, fontSize, fontSize, apiPlatform, graphicsForMetrics); 409 } 410 getFontFidFS(String fontFace, float fontSize)411 public byte getFontFidFS(String fontFace, float fontSize) { 412 return getFont3DFSS(fontFace, "Bold", fontSize).fid; 413 } 414 getFont3DFSS(String fontFace, String fontStyle, float fontSize)415 public Font getFont3DFSS(String fontFace, String fontStyle, float fontSize) { 416 int iStyle = Font.getFontStyleID(fontStyle); 417 if (iStyle < 0) 418 iStyle = 0; 419 return Font.createFont3D(Font.getFontFaceID(fontFace), iStyle, fontSize, 420 fontSize, apiPlatform, graphicsForMetrics); 421 } 422 getFont3DScaled(Font font, float scale)423 public Font getFont3DScaled(Font font, float scale) { 424 // TODO: problem here is that we are assigning a bold font, then not DEassigning it 425 float newScale = font.fontSizeNominal * scale; 426 return (newScale == font.fontSize ? font : Font.createFont3D( 427 font.idFontFace, font.idFontStyle, newScale, font.fontSizeNominal, apiPlatform, graphicsForMetrics)); 428 } 429 getFontFid(float fontSize)430 public byte getFontFid(float fontSize) { 431 return getFont3D(fontSize).fid; 432 } 433 434 /** 435 * @param TF 436 */ setBackgroundTransparent(boolean TF)437 public void setBackgroundTransparent(boolean TF) { 438 } 439 440 /** 441 * sets background color to the specified argb value 442 * 443 * @param argb an argb value with alpha channel 444 */ setBackgroundArgb(int argb)445 public void setBackgroundArgb(int argb) { 446 bgcolor = argb; 447 setCel(shader.celOn); 448 // background of Jmol transparent in front of certain applications (VLC Player) 449 // when background [0,0,1]. 450 } 451 setBackgroundImage(Object image)452 public void setBackgroundImage(Object image) { 453 backgroundImage = image; 454 } 455 setWindowParameters(int width, int height, boolean antialias)456 public void setWindowParameters(int width, int height, boolean antialias) { 457 setWinParams(width, height, antialias); 458 } 459 setWinParams(int width, int height, boolean antialias)460 protected void setWinParams(int width, int height, boolean antialias) { 461 newWindowWidth = width; 462 newWindowHeight = height; 463 newAntialiasing = antialias; 464 } 465 setNewWindowParametersForExport()466 public void setNewWindowParametersForExport() { 467 windowWidth = newWindowWidth; 468 windowHeight = newWindowHeight; 469 setWidthHeight(false); 470 } 471 setWidthHeight(boolean isAntialiased)472 protected void setWidthHeight(boolean isAntialiased) { 473 width = windowWidth; 474 height = windowHeight; 475 if (isAntialiased) { 476 width <<= 1; 477 height <<= 1; 478 } 479 xLast = width - 1; 480 yLast = height - 1; 481 displayMinX = -(width >> 1); 482 displayMaxX = width - displayMinX; 483 displayMinY = -(height >> 1); 484 displayMaxY = height - displayMinY; 485 displayMinX2 = displayMinX<<2; 486 displayMaxX2 = displayMaxX<<2; 487 displayMinY2 = displayMinY<<2; 488 displayMaxY2 = displayMaxY<<2; 489 ht3 = height * 3; 490 bufferSize = width * height; 491 } 492 493 /** 494 * @param stereoRotationMatrix 495 * @param translucentMode 496 * @param isImageWrite 497 * @param renderLow TODO 498 */ beginRendering(M3 stereoRotationMatrix, boolean translucentMode, boolean isImageWrite, boolean renderLow)499 public void beginRendering(M3 stereoRotationMatrix, boolean translucentMode, boolean isImageWrite, boolean renderLow) { 500 } 501 endRendering()502 public void endRendering() { 503 } 504 snapshotAnaglyphChannelBytes()505 public void snapshotAnaglyphChannelBytes() { 506 } 507 508 /** 509 * @param isImageWrite 510 * @return image object 511 */ getScreenImage(boolean isImageWrite)512 public Object getScreenImage(boolean isImageWrite) { 513 return null; 514 } 515 releaseScreenImage()516 public void releaseScreenImage() { 517 } 518 519 /** 520 * @param stereoMode 521 * @param stereoColors 522 */ applyAnaglygh(STER stereoMode, int[] stereoColors)523 public void applyAnaglygh(STER stereoMode, int[] stereoColors) { 524 } 525 526 /** 527 * @param antialias 528 * @return true if need a second (translucent) pass 529 */ setPass2(boolean antialias)530 public boolean setPass2(boolean antialias) { 531 return false; 532 } 533 destroy()534 public void destroy() { 535 } 536 clearFontCache()537 public void clearFontCache() { 538 } 539 drawQuadrilateralBits(JmolRendererInterface jmolRenderer, short colix, P3 screenA, P3 screenB, P3 screenC, P3 screenD)540 public void drawQuadrilateralBits(JmolRendererInterface jmolRenderer, short colix, P3 screenA, P3 screenB, 541 P3 screenC, P3 screenD) { 542 //mesh only -- translucency has been checked 543 jmolRenderer.drawLineBits(colix, colix, screenA, screenB); 544 jmolRenderer.drawLineBits(colix, colix, screenB, screenC); 545 jmolRenderer.drawLineBits(colix, colix, screenC, screenD); 546 jmolRenderer.drawLineBits(colix, colix, screenD, screenA); 547 } 548 drawTriangleBits(JmolRendererInterface renderer, P3 screenA, short colixA, P3 screenB, short colixB, P3 screenC, short colixC, int check)549 public void drawTriangleBits(JmolRendererInterface renderer, P3 screenA, short colixA, P3 screenB, 550 short colixB, P3 screenC, short colixC, int check) { 551 // primary method for mapped Mesh 552 if ((check & 1) == 1) 553 renderer.drawLineBits(colixA, colixB, screenA, screenB); 554 if ((check & 2) == 2) 555 renderer.drawLineBits(colixB, colixC, screenB, screenC); 556 if ((check & 4) == 4) 557 renderer.drawLineBits(colixC, colixA, screenC, screenA); 558 } 559 560 /** 561 * @param x 562 * @param y 563 * @param z 564 * @param image 565 * @param jmolRenderer 566 * @param bgcolix 567 * @param width 568 * @param height 569 * 570 */ plotImage(int x, int y, int z, Object image, JmolRendererInterface jmolRenderer, short bgcolix, int width, int height)571 public void plotImage(int x, int y, int z, Object image, 572 JmolRendererInterface jmolRenderer, short bgcolix, 573 int width, int height) { 574 } 575 576 /** 577 * @param x 578 * @param y 579 * @param z 580 * @param colorArgbOrGray 581 * @param bgColor TODO 582 * @param text 583 * @param font3d 584 * @param jmolRenderer 585 * 586 */ plotText(int x, int y, int z, int colorArgbOrGray, int bgColor, String text, Font font3d, JmolRendererInterface jmolRenderer)587 public void plotText(int x, int y, int z, int colorArgbOrGray, int bgColor, 588 String text, Font font3d, JmolRendererInterface jmolRenderer) { 589 } 590 591 /** 592 * @param jmolRenderer 593 */ renderBackground(JmolRendererInterface jmolRenderer)594 public void renderBackground(JmolRendererInterface jmolRenderer) { 595 } 596 597 /** 598 * @param font3d 599 */ setFont(Font font3d)600 public void setFont(Font font3d) { 601 } 602 603 /** 604 * @param fid 605 */ setFontFid(byte fid)606 public void setFontFid(byte fid) { 607 } 608 609 public int argbNoisyUp, argbNoisyDn; 610 setColor(int argb)611 public void setColor(int argb) { 612 argbCurrent = argbNoisyUp = argbNoisyDn = argb; 613 } 614 615 /** 616 * @param colix 617 * @return TRUE if correct pass (translucent or opaque) 618 */ setC(short colix)619 public boolean setC(short colix) { 620 return true; 621 } 622 623 /** 624 * @param normix 625 * @return true if front 626 */ isDirectedTowardsCamera(short normix)627 public boolean isDirectedTowardsCamera(short normix) { 628 // normix < 0 means a double sided normix, so always visible 629 return (normix < 0) || (transformedVectors[normix].z > 0); 630 } 631 632 /** 633 * JavaScript won't really have an integer here after integer division. 634 * So we need to round it to the integer between it and zero. 635 * 636 * @param a 637 * @return number closest to zero 638 */ roundInt(int a)639 public static int roundInt(int a) { 640 /** 641 * @z2sNative 642 * 643 * return a < 0 ? Math.ceil(a) : Math.floor(a); 644 * 645 */ 646 { 647 return a; 648 } 649 } 650 clear()651 public void clear() { 652 // only in Graphics3D 653 } 654 655 @Override renderAllStrings(Object jmolRenderer)656 public void renderAllStrings(Object jmolRenderer) { 657 // only in Graphics3D 658 } 659 660 /** 661 * @param tok 662 */ addRenderer(int tok)663 public void addRenderer(int tok) { 664 // needed for JavaScript implementation to avoid unnecessary core loading 665 } 666 667 /** 668 * Used by Navigator, BioShapeRenderer, and DrawRenderer 669 * 670 * @param tension 671 * @param p0 672 * @param p1 673 * @param p2 674 * @param p3 675 * @param p4 676 * @param list 677 * @param index0 678 * @param n 679 * @param isPt 680 */ getHermiteList(int tension, T3 p0, T3 p1, T3 p2, T3 p3, T3 p4, T3[] list, int index0, int n, boolean isPt)681 public static void getHermiteList(int tension, T3 p0, T3 p1, 682 T3 p2, T3 p3, T3 p4, 683 T3[] list, int index0, int n, boolean isPt) { 684 //always deliver ONE MORE than one might expect, to provide a normal 685 int nPoints = n + 1; 686 float fnPoints = n - 1; 687 float x1 = p1.x, y1 = p1.y, z1 = p1.z; 688 float x2 = p2.x, y2 = p2.y, z2 = p2.z; 689 float xT1 = ((x2 - p0.x) * tension) / 8; 690 float yT1 = ((y2 - p0.y) * tension) / 8; 691 float zT1 = ((z2 - p0.z) * tension) / 8; 692 float xT2 = ((p3.x - x1) * tension) / 8; 693 float yT2 = ((p3.y - y1) * tension) / 8; 694 float zT2 = ((p3.z - z1) * tension) / 8; 695 float xT3 = ((p4.x - x2) * tension) / 8; 696 float yT3 = ((p4.y - y2) * tension) / 8; 697 float zT3 = ((p4.z - z2) * tension) / 8; 698 list[index0] = p1; 699 for (int i = 0; i < nPoints; i++) { 700 double s = i / fnPoints; 701 if (i == nPoints - 1) { 702 x1 = x2; 703 y1 = y2; 704 z1 = z2; 705 x2 = p3.x; 706 y2 = p3.y; 707 z2 = p3.z; 708 xT1 = xT2; 709 yT1 = yT2; 710 zT1 = zT2; 711 xT2 = xT3; 712 yT2 = yT3; 713 zT2 = zT3; 714 s -= 1; 715 } 716 double s2 = s * s; 717 double s3 = s2 * s; 718 double h1 = 2 * s3 - 3 * s2 + 1; 719 double h2 = -2 * s3 + 3 * s2; 720 double h3 = s3 - 2 * s2 + s; 721 double h4 = s3 - s2; 722 float x = (float) (h1 * x1 + h2 * x2 + h3 * xT1 + h4 * xT2); 723 float y = (float) (h1 * y1 + h2 * y2 + h3 * yT1 + h4 * yT2); 724 float z = (float) (h1 * z1 + h2 * z2 + h3 * zT1 + h4 * zT2); 725 list[index0 + i] = (isPt ? P3.new3(x, y, z) : V3.new3(x, y, z)); 726 } 727 } 728 setTextPosition(int y)729 public void setTextPosition(int y) { 730 textY = y; 731 } 732 getTextPosition()733 public int getTextPosition() { 734 return textY; 735 } 736 737 protected V3[] transformedVectors = new V3[normixCount]; 738 getTransformedVertexVectors()739 public V3[] getTransformedVertexVectors() { 740 return transformedVectors; 741 } 742 743 protected static short normixCount = Normix.getNormixCount(); 744 745 protected Font currentFont; 746 getFont3DCurrent()747 public Font getFont3DCurrent() { 748 return currentFont; 749 } 750 751 752 753 } 754