Font tasszalációja

Top  Previous  Next

         final char glyphChar = text.charAt(i);

          final Rectangle2D glyphBounds = gv.getGlyphOutline(i).getBounds2D();

          final int indexChar = i;

          GL11.glPushMatrix();

          GL11.glTranslated(glyphBounds.getX(), glyphBounds.getY(), 0);

          GLList gllist = new GLGlyph(glyphChar, font.getSize()) {

 

              @Override

              public Runnable getList() {

                  return new Runnable() {

 

                      public void run() {

                          Shape glyph = gv.getGlyphOutline(indexChar, -(float) glyphBounds.getX(), -(float) glyphBounds.getY());

                          PathIterator pi = glyph.getPathIterator(null);

                          GLUtessellator tess = GLUtessellatorImpl.gluNewTess();

                          GLUtessellatorCallbackAdapter tessCb = new GLUtessellatorCallbackAdapter() {

 

                              @Override

                              public void begin(int type) {

                                  GL11.glBegin(type);

                              }

 

                              @Override

                              public void vertex(Object vertexData) {

                                  float[] vert = (float[]) vertexData;

                                  GL11.glVertex2f(vert[0], vert[1]);

                              }

 

                              public void combine(double[] coords, Object[] data, float[] weight, Object[] outData) {

                                  for (int i = 0; i < outData.length; i++) {

                                      float[] combined = new float[6];

                                      combined[0] = (float) coords[0];

                                      combined[1] = (float) coords[1];

                                      /*combined[2] = (float) coords[2];

                                      for (int j = 3; j < 6; j++) {

                                      for(int d = 0; d < data.length; d++)

                                      combined[j] = weight[d] * data[d][j];

                                      }*/

                                      outData[i] = combined;

                                  }

                              }

 

                              @Override

                              public void end() {

                                  GL11.glEnd();

                              }

                          };

                          tess.gluTessCallback(GLU.GLU_TESS_BEGIN, tessCb);

                          tess.gluTessCallback(GLU.GLU_TESS_VERTEX, tessCb);

                          tess.gluTessCallback(GLU.GLU_TESS_COMBINE, tessCb);

                          tess.gluTessCallback(GLU.GLU_TESS_END, tessCb);

                          Point2D.Float current = new Point2D.Float();

                          tess.gluTessBeginPolygon(null);

                          while (!pi.isDone()) {

                              float[] coords = new float[6];

                              int path = pi.currentSegment(coords);

                              switch (pi.getWindingRule()) {

                                  case PathIterator.WIND_EVEN_ODD:

                                      tess.gluTessProperty(GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_ODD);

                                      break;

                                  case PathIterator.WIND_NON_ZERO:

                                      tess.gluTessProperty(GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NONZERO);

                                      break;

                                  default:

                                      if (JXAenvUtils._debug) {

                                          System.err.println(JXAenvUtils._JXAEnvOutput("no winding rule", JXAenvUtils.APP_WARNING));

                                      }

                                      break;

                              }

 

                              switch (path) {

                                  case PathIterator.SEG_MOVETO:

                                      /*System.err.println("PaIt begin move"); */

                                      /*GL11.glBegin(GL11.GL_LINE_LOOP);*/

                                      tess.gluTessBeginContour();

                                      /*GL11.glVertex2f(coords[0], coords[1]);*/

                                      tess.gluTessVertex(new double[]{coords[0], coords[1], 0.}, 0, new float[]{coords[0], coords[1], 0f});

                                      current.x = coords[0];

                                      current.y = coords[1];

                                      break;

                                  case PathIterator.SEG_CLOSE:

                                      /*System.err.println("PaIt close");*/

                                      /*GL11.glEnd();*/

                                      tess.gluTessEndContour();

                                      break;

                                  case PathIterator.SEG_LINETO:

                                      /*System.err.println("PaIt line");*/

                                      /*GL11.glVertex2f(coords[0], coords[1]);*/

                                      tess.gluTessVertex(new double[]{coords[0], coords[1], 0.}, 0, new float[]{coords[0], coords[1], 0f});

                                      current.x = coords[0];

                                      current.y = coords[1];

                                      break;

                                  case PathIterator.SEG_CUBICTO:

                                      /*System.err.println("PaIt cubic");*/

                                      for (Point2D.Float p : GLGeom._computeBezierCurve(new Point2D.Float[]{current, new Point2D.Float(coords[0], coords[1]), new Point.Float(coords[2], coords[3]), new Point.Float(coords[4], coords[5])}, font.getSize())) {

                                          /*GL11.glVertex2f(p.x, p.y);*/

                                          tess.gluTessVertex(new double[]{p.x, p.y, 0.}, 0, new float[]{p.x, p.y, 0f});

                                      }

                                      current.x = coords[4];

                                      current.y = coords[5];

                                      break;

                                  case PathIterator.SEG_QUADTO:

                                      /*System.err.println("PaIt quad");*/

                                      for (Point2D.Float p : GLGeom._computeBezierCurve(new Point2D.Float[]{current, new Point2D.Float(coords[0], coords[1]), new Point.Float(coords[2], coords[3])}, font.getSize())) {

                                          /*GL11.glVertex2f(p.x, p.y);*/

                                          tess.gluTessVertex(new double[]{p.x, p.y, 0.}, 0, new float[]{p.x, p.y, 0f});

                                      }

                                      current.x = coords[2];

                                      current.y = coords[3];

                                      break;

                                  default:

                                      break;

                              }

                              pi.next();

                          }

                          tess.gluTessEndPolygon();

                          tess.gluDeleteTess();

                      }

                  };

              }

          };