JOGL v2.6.0
JOGL, High-Performance Graphics Binding for Java™ (public API).
FontView01.java
Go to the documentation of this file.
1/**
2 * Copyright 2023-2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.demos.graph.ui;
29
30import java.io.File;
31import java.io.IOException;
32import java.util.ArrayList;
33import java.util.Arrays;
34import java.util.List;
35import java.util.Locale;
36
37import com.jogamp.common.os.Clock;
38import com.jogamp.common.util.IOUtil;
39import com.jogamp.graph.curve.OutlineShape;
40import com.jogamp.graph.curve.Region;
41import com.jogamp.graph.curve.opengl.RenderState;
42import com.jogamp.graph.font.Font;
43import com.jogamp.graph.font.Font.Glyph;
44import com.jogamp.graph.font.FontFactory;
45import com.jogamp.graph.ui.Group;
46import com.jogamp.graph.ui.Scene;
47import com.jogamp.graph.ui.Shape;
48import com.jogamp.graph.ui.TooltipShape;
49import com.jogamp.graph.ui.TooltipText;
50import com.jogamp.graph.ui.layout.Alignment;
51import com.jogamp.graph.ui.layout.BoxLayout;
52import com.jogamp.graph.ui.layout.Gap;
53import com.jogamp.graph.ui.layout.GridLayout;
54import com.jogamp.graph.ui.layout.Margin;
55import com.jogamp.graph.ui.layout.Padding;
56import com.jogamp.graph.ui.shapes.GlyphShape;
57import com.jogamp.graph.ui.shapes.Label;
58import com.jogamp.graph.ui.shapes.Rectangle;
59import com.jogamp.graph.ui.widgets.RangeSlider;
60import com.jogamp.graph.ui.widgets.RangedGroup;
61import com.jogamp.graph.ui.widgets.RangedGroup.SliderParam;
62import com.jogamp.math.FloatUtil;
63import com.jogamp.math.Vec2f;
64import com.jogamp.math.Vec3f;
65import com.jogamp.math.Vec4f;
66import com.jogamp.math.geom.AABBox;
67import com.jogamp.newt.MonitorDevice;
68import com.jogamp.newt.Window;
69import com.jogamp.newt.event.KeyAdapter;
70import com.jogamp.newt.event.KeyEvent;
71import com.jogamp.newt.event.MouseEvent;
72import com.jogamp.newt.event.WindowAdapter;
73import com.jogamp.newt.event.WindowEvent;
74import com.jogamp.newt.opengl.GLWindow;
75import com.jogamp.opengl.GL;
76import com.jogamp.opengl.GL2ES2;
77import com.jogamp.opengl.GLAutoDrawable;
78import com.jogamp.opengl.GLCapabilities;
79import com.jogamp.opengl.GLCapabilitiesImmutable;
80import com.jogamp.opengl.GLEventListener;
81import com.jogamp.opengl.GLPipelineFactory;
82import com.jogamp.opengl.GLProfile;
83import com.jogamp.opengl.JoglVersion;
84import com.jogamp.opengl.demos.graph.FontSetDemos;
85import com.jogamp.opengl.demos.graph.MSAATool;
86import com.jogamp.opengl.demos.util.CommandlineOptions;
87import com.jogamp.opengl.demos.util.MiscUtils;
88import com.jogamp.opengl.util.Animator;
89import com.jogamp.opengl.util.caps.NonFSAAGLCapsChooser;
90
91/**
92 * This may become a little font viewer application, having FontForge as its role model.
93 *
94 * This UISceneDemo* implements as a GLEventListener, capable to be used with any GLAutoDrawable.
95 *
96 * Notable: The actual {@link GlyphShape} created for the glyph-grid {@link Group}
97 * is reused as-is in the top-right info-box as well as in the {@link TooltipShape}.
98 *
99 * This is possible only when not modifying the scale or position of the {@link GlyphShape},
100 * achieved by simply wrapping it in a {@link Group}.
101 * The latter gets scaled and translated when dropped
102 * into each target {@link Group} with a {@link Group.Layout}.<br/>
103 *
104 * This is also good example using GraphUI with a Directed Acyclic Graph (DAG) arrangement.
105 */
106public class FontView01 implements GLEventListener {
107 // static CommandlineOptions options = new CommandlineOptions(1280, 720, Region.MSAA_RENDERING_BIT, Region.DEFAULT_AA_QUALITY, 4);
108 // static CommandlineOptions options = new CommandlineOptions(1280, 720, Region.NORM_RENDERING_BIT, 0, 0, 8);
109 static CommandlineOptions options = new CommandlineOptions(1280, 720, Region.VBAA_RENDERING_BIT);
110
111 public static void main(final String[] args) throws IOException {
112 boolean showUnderline = false;
113 boolean showLabel = false;
114 boolean perfanal = false;
115 float mmPerCell = 8f;
116 String fontFilename = null;
117 int gridColumns = -1;
118
119 if( 0 != args.length ) {
120 final int[] idx = { 0 };
121 for (idx[0] = 0; idx[0] < args.length; ++idx[0]) {
122 if( options.parse(args, idx) ) {
123 continue;
124 } else if(args[idx[0]].equals("-font")) {
125 idx[0]++;
126 fontFilename = args[idx[0]];
127 } else if(args[idx[0]].equals("-mmPerCell")) {
128 idx[0]++;
129 mmPerCell = MiscUtils.atof(args[idx[0]], mmPerCell);
130 } else if(args[idx[0]].equals("-gridCols")) {
131 idx[0]++;
132 gridColumns = MiscUtils.atoi(args[idx[0]], gridColumns);
133 } else if(args[idx[0]].equals("-showUnderline")) {
134 showUnderline = true;
135 } else if(args[idx[0]].equals("-showLabel")) {
136 showLabel = true;
137 } else if(args[idx[0]].equals("-perf")) {
138 perfanal = true;
139 } else if(args[idx[0]].equals("-max")) {
140 idx[0]++;
141 max_glyph_count = MiscUtils.atoi(args[idx[0]], max_glyph_count);
142 }
143 }
144 }
145 System.err.println(JoglVersion.getInstance().toString());
146 System.err.println(options);
147
148 final FontView01 demo = new FontView01(fontFilename, options.renderModes, false, false);
149 demo.showUnderline = showUnderline;
150 demo.showLabel = showLabel;
151 demo.mmPerCell = mmPerCell;
152 demo.gridColumns = gridColumns;
153
154 final GLCapabilities caps = options.getGLCaps();
155 System.out.println("Requested: " + caps);
156
157 final GLWindow window = GLWindow.create(caps);
158 if( 0 == options.sceneMSAASamples ) {
160 }
161 window.setSize(options.surface_width, options.surface_height);
162 window.setTitle(FontView01.class.getSimpleName()+": "+demo.font.getFullFamilyName()+", "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight());
163
164 window.addGLEventListener(demo);
165
166 final Animator animator = new Animator(0 /* w/o AWT */);
167 animator.setUpdateFPSFrames(5*60, null);
168 animator.add(window);
169 animator.setExclusiveContext(options.exclusiveContext);
170
171 window.addWindowListener(new WindowAdapter() {
172 @Override
173 public void windowResized(final WindowEvent e) {
174 window.setTitle(FontView01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight());
175 }
176 @Override
177 public void windowDestroyNotify(final WindowEvent e) {
178 animator.stop();
179 }
180 });
181
182 if( options.wait_to_start ) {
183 System.err.println("Press enter to continue");
184 MiscUtils.waitForKey("Start");
185 }
186
187 window.setVisible(true);
188 System.out.println("Chosen: " + window.getChosenGLCapabilities());
189
190 animator.start();
191 }
192
193 private static final float GlyphGridWidth = 3/4f; // FBO AA: 3/4f = 0.75f dropped fine grid lines @ 0.2f thickness; 0.70f OK
194 private static final float GlyphGridBorderThickness = 0.02f; // thickness 0.2f dropping
195 private static final Vec4f GlyphGridBorderColorComplex = new Vec4f(0.2f, 0.2f, 0.2f, 1);
196 private static final Vec4f GlyphGridBorderColorSimple = new Vec4f(0.2f, 0.2f, 0.7f, 1);
197
198 private static int max_glyph_count = 10000;
199
200 private static boolean VERBOSE_GLYPHS = false;
201 private static boolean VERBOSE_UI = false;
202
203 private boolean showUnderline = false;
204 private boolean showLabel = false;
205 private boolean debug = false;
206 private boolean trace = false;
207 private final Font font, fontStatus, fontInfo;
208 private float dpiY = 96;
209 private float pixPerMMY;
210
211 private final Scene scene;
212
213 private int maxGlyphCount = Integer.MAX_VALUE;
214 private float mmPerCell = 8f;
215 private int gridColumns = -1;
216 private boolean firstReshape = true;
217
218 Group mainView = null;
219 Label infoLabel = null;
220 int lastCodepoint = 0;
221
222 /**
223 * @param renderModes
224 */
225 public FontView01(final int renderModes) {
226 this(null, renderModes, false, false);
227 }
228
229 private FontView01(final String fontFilename, final int renderModes, final boolean debug, final boolean trace) {
230 this.debug = debug;
231 this.trace = trace;
232
233 FontView01.options.renderModes = renderModes;
234
235 try {
236 if( null == fontFilename ) {
237 font = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerif.ttf",
238 FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
239 } else {
240 font = FontFactory.get( new File( fontFilename ) );
241 }
242 System.err.println("Font "+font.getFullFamilyName());
243
244 fontStatus = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeMono.ttf", FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true);
245 fontInfo = FontFactory.get(FontFactory.UBUNTU).getDefault();
246 System.err.println("Status Font "+fontStatus.getFullFamilyName());
247 System.err.println("Info Font "+fontInfo.getFullFamilyName());
248 } catch (final IOException ioe) {
249 throw new RuntimeException(ioe);
250 }
251
252 scene = new Scene(options.graphAASamples);
253 scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
254 scene.setPMvCullingEnabled(true);
255 scene.getRenderer().setHintBits(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
256 }
257
258 public float getMMPerCell() { return mmPerCell; }
259 public void setMMPerCell(final float v) { mmPerCell = v; }
260
261 public int getMaxGlyphCount() { return maxGlyphCount; }
262 public void setMaxGlyphCount(final int v) { maxGlyphCount = v; }
263
264 @Override
265 public void init(final GLAutoDrawable glad) {
266 // Resolution independent, no screen size
267 //
268 final int glyphGridRowsPerPage;
269
270 final Object upObj = glad.getUpstreamWidget();
271 final float[] pixPerMMXY, dpiXY;
272 if( upObj instanceof Window ) {
273 final Window win = (Window)upObj;
275 @Override
276 public void mouseWheelMoved(final MouseEvent e) {
277 if( null == mainView || e.getX() >= win.getSurfaceWidth() / 2f ) {
278 return;
279 }
280 if( e.isControlDown() ) {
281 // Scale and move back to center
282 final float[] rot = e.getRotation();
283 final float r = e.isShiftDown() ? rot[0] : rot[1];
284 final float s = 1f+r/200f;
285 final AABBox b0 = mainView.getBounds();
286 final AABBox bs = new AABBox(b0).scale(s, s, 1);
287 final float dw = b0.getWidth() - bs.getWidth();
288 final float dh = b0.getHeight() - bs.getHeight();
289 mainView.scale(s, s, 1);
290 final Vec3f s1 = mainView.getScale();
291 mainView.move(s1.x()*dw/2f, s1.y()*dh/2f, 0);
292 System.err.println("scale +"+s+" = "+s1);
293 e.setConsumed(true);
294 } else {
295 final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f );
296 // swap axis for onscreen rotation matching natural feel
297 final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp );
298 mainView.setRotation( mainView.getRotation().rotateByEuler( rot.scale( 2f ) ) );
299 e.setConsumed(true);
300 }
301 } } );
302 win.addKeyListener(new KeyAdapter() {
303 @Override
304 public void keyReleased(final KeyEvent e) {
305 final short keySym = e.getKeySymbol();
306 if( keySym == KeyEvent.VK_F4 || keySym == KeyEvent.VK_ESCAPE || keySym == KeyEvent.VK_Q ) {
308 } else if( keySym == KeyEvent.VK_S ) {
309 printScreenOnGLThread(scene, glad.getChosenGLCapabilities(), font, lastCodepoint);
310 }
311 }
312 });
313 final MonitorDevice monitor = win.getMainMonitor();
314 final float[] monitorDPI = MonitorDevice.mmToInch( monitor.getPixelsPerMM(new float[2]) );
315 pixPerMMXY = win.getPixelsPerMM(new float[2]);
316 pixPerMMY = pixPerMMXY[1]; // [px]/[mm]
317 dpiXY = MonitorDevice.mmToInch(new float[2], pixPerMMXY);
318 dpiY = dpiXY[1];
319 final float[] hasSurfacePixelScale1 = win.getCurrentSurfaceScale(new float[2]);
320 System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
321 System.err.println("Monitor detected: "+monitor);
322 System.err.println("Monitor dpi: "+monitorDPI[0]+" x "+monitorDPI[1]);
323 System.err.println("Surface scale: native "+Arrays.toString(win.getMaximumSurfaceScale(new float[2]))+", current "+Arrays.toString(win.getCurrentSurfaceScale(new float[2])));
324 System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
325 } else {
326 dpiY = 96;
327 dpiXY = new float[] { dpiY, dpiY };
328 pixPerMMY = MonitorDevice.inchToMM(dpiY); // [px]/[mm]
329 pixPerMMXY = new float[] { pixPerMMY, pixPerMMY };
330 System.err.println("Using default DPI of "+dpiY);
331 }
332 glyphGridRowsPerPage = (int)( ( glad.getSurfaceHeight() / pixPerMMXY[1] ) / mmPerCell );
333 if( 0 >= gridColumns ) {
334 gridColumns = (int)( ( glad.getSurfaceWidth() * GlyphGridWidth / pixPerMMXY[0] ) / mmPerCell );
335 }
336
337 System.err.println("Surface "+glad.getSurfaceWidth()+"x"+glad.getSurfaceHeight());
338 System.err.println("Surface dpi "+dpiXY[0]+" x "+dpiXY[1]);
339 System.err.println("Surface pixPerMM: "+pixPerMMXY[0]+" x "+pixPerMMXY[1]);
340 System.err.println("mmPerCell "+mmPerCell+", glyphGridRowsPerPage "+glyphGridRowsPerPage+", gridColumns "+gridColumns);
341
342 {
343 final int o = options.fixDefaultAARenderModeWithDPIThreshold(dpiY);
344 System.err.println("AUTO RenderMode: dpi "+dpiY+", threshold "+options.noAADPIThreshold+
345 ", mode "+Region.getRenderModeString(o)+" -> "+
347 }
348 if(glad instanceof GLWindow) {
349 System.err.println("FontView01: init (1.1)");
350 final GLWindow glw = (GLWindow) glad;
351 scene.attachInputListenerTo(glw);
352 } else {
353 System.err.println("FontView01: init (1.0)");
354 }
355
356 GL2ES2 gl = glad.getGL().getGL2ES2();
357 if(debug) {
358 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ).getGL2ES2();
359 }
360 if(trace) {
361 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2();
362 }
363 System.err.println(JoglVersion.getGLInfo(gl, null, false /* withCapsAndExts */).toString());
364 System.err.println("VSync Swap Interval: "+gl.getSwapInterval());
365 System.err.println("Chosen: "+glad.getChosenGLCapabilities());
366 MSAATool.dump(glad);
367
368 gl.setSwapInterval(1);
369 gl.glEnable(GL.GL_DEPTH_TEST);
370 // gl.glDepthFunc(GL.GL_LEQUAL);
371 // gl.glEnable(GL.GL_BLEND);
372
373 final float glyphGridCellSize = GlyphGridWidth / gridColumns;
374 final Vec2f glyphGridSize = new Vec2f(GlyphGridWidth, glyphGridRowsPerPage * glyphGridCellSize);
375
376 final long t0 = Clock.currentNanos();
377
378 final GridDim gridDim = new GridDim(font, gridColumns, glyphGridRowsPerPage, 1, maxGlyphCount);
379 final Vec2f glyphGridTotalSize = new Vec2f(glyphGridSize.x(), gridDim.rows * glyphGridCellSize);
380 System.err.println(gridDim);
381 System.err.println("GlyphGrid[pgsz "+glyphGridSize+", totsz "+glyphGridTotalSize+", cellSz "+glyphGridCellSize+"]");
382
383 lastCodepoint = gridDim.contourChars.get(0);
384 final Shape.PointerListener glyphHoverListener;
385 {
386 final Group glyphShapeBox = new Group( new BoxLayout( 1f, 1f, Alignment.FillCenter, new Margin(0.01f) ) );
387 final Group glyphShapeHolder = new Group();
388 glyphShapeHolder.setName("GlyphShapeHolderInfo");
389 glyphShapeBox.addShape( glyphShapeHolder );
390
391 final Group glyphInfoBox = new Group( new BoxLayout( 1f, 1f, Alignment.FillCenter, new Margin(0.025f, 0.025f, 0.025f, 0.025f) ) );
392 final Label glyphInfo = new Label(options.renderModes, fontStatus, "Nothing there yet");
393 setGlyphInfo(fontStatus, glyphInfo, font.getGlyph( 'A' ));
394 glyphInfo.setColor(0.1f, 0.1f, 0.1f, 1.0f);
395 glyphInfoBox.addShape(glyphInfo);
396 glyphInfoBox.setRelayoutOnDirtyShapes(false); // avoid group re-validate on info text changes
397
398 glyphHoverListener = (final Shape s, final Vec3f pos, final MouseEvent e) -> {
399 System.err.println("XXX: Hover: "+s+", event "+e);
400 final GlyphShape g0 = getGlyphShape(s);
401
402 e.setConsumed(true);
403
404 // Selected Glyph g0
405 scene.invoke(false, (final GLAutoDrawable d) -> {
406 // Handle old one
407 if( 1 == glyphShapeHolder.getShapeCount() ) {
408 final GlyphShape old = (GlyphShape) glyphShapeHolder.getShapeByIdx(0);
409 if( null != old ) {
410 if( old.getGlyph().getCodepoint() == g0.getGlyph().getCodepoint() ) {
411 // System.err.println("GlyphShape Same: "+old);
412 return true; // abort - no change
413 } else {
414 glyphShapeHolder.removeShape(old);
415 }
416 } else {
417 // System.err.println("GlyphShape Old: Null");
418 }
419 } else {
420 // System.err.println("GlyphShape Old: None");
421 }
422 // New Glyph
423 glyphShapeHolder.addShape(g0);
424 setGlyphInfo(fontStatus, glyphInfo, g0.getGlyph());
425 lastCodepoint = g0.getGlyph().getCodepoint();
426 return true;
427 });
428 };
429
430 final GLCapabilitiesImmutable reqCaps = glad.getRequestedGLCapabilities();
431 final Group glyphInfoView = new Group(new GridLayout(2, 0f, 0f, Alignment.None));
432 {
433 // final float gapSizeX = ( gridDim.rawSize.x() - 1 ) * cellSize * 0.1f;
434 final Group glyphGrid = new Group(new GridLayout(gridDim.columns, glyphGridCellSize*0.9f, glyphGridCellSize*0.9f, Alignment.FillCenter,
435 new Gap(glyphGridCellSize*0.1f)));
436 glyphGrid.setInteractive(true).setDragAndResizable(false).setToggleable(false).setName("GlyphGrid");
437 addGlyphs(reqCaps.getGLProfile(), font, glyphGrid, gridDim, showUnderline, showLabel, fontStatus, fontInfo, glyphHoverListener);
438 glyphGrid.setRelayoutOnDirtyShapes(false); // avoid group re-validate to ease load in Group.isShapeDirty() w/ thousands of glyphs
439 if( VERBOSE_UI ) {
440 glyphGrid.validate(reqCaps.getGLProfile());
441 System.err.println("GlyphGrid "+glyphGrid);
442 System.err.println("GlyphGrid "+glyphGrid.getLayout());
443 }
444 {
445 final GlyphShape gs = getGlyphShape( glyphGrid );
446 if( null != gs ) {
447 glyphShapeHolder.addShape(gs);
448 }
449 }
450 final RangedGroup glyphView = new RangedGroup( options.renderModes, glyphGrid, glyphGridSize,
451 null,
452 new SliderParam( new Vec2f(glyphGridCellSize/4f, glyphGridSize.y()), glyphGridCellSize/10f, true ) );
453 glyphView.getVertSlider().setColor(0.3f, 0.3f, 0.3f, 0.7f).setName("GlyphView");
454 if( VERBOSE_UI ) {
455 glyphView.getVertSlider().addChangeListener((final RangeSlider w, final float old_val, final float val, final float old_val_pct, final float val_pct, final Vec3f pos, final MouseEvent e) -> {
456 final Vec2f minmax = w.getMinMax();
457 final float row_f = val / glyphGridCellSize;
458 System.err.println("VertSlider: row["+row_f+".."+(row_f+gridDim.rowsPerPage-1)+"]/"+gridDim.rows+
459 ", val["+old_val+" -> "+val+"]/"+minmax.y()+", pct["+(100*old_val_pct)+"% -> "+(100*val_pct)+"%], cellSz "+glyphGridCellSize);
460 System.err.println("VertSlider: "+w.getDescription());
461 });
462 }
463 glyphView.getVertSlider().receiveKeyEvents(glyphGrid);
464 // glyphView.getVertSlider().receiveMouseEvents(glyphGrid);
465 if( VERBOSE_UI ) {
466 glyphView.validate(reqCaps.getGLProfile());
467 System.err.println("GlyphView "+glyphView);
468 }
469 glyphInfoView.addShape(glyphView);
470 }
471 {
472 final float infoCellWidth = ( 1f - glyphGridSize.x() ) * 1.15f; // FIXME: Layout issues to force 15% more width to use more size?
473 final float infoCellHeight = glyphGridSize.y() * 0.5f;
474 final Group infoGrid = new Group( new GridLayout(1, infoCellWidth, infoCellHeight * 1f, Alignment.FillCenter, new Gap(infoCellHeight*0.001f, 0)) );
475 infoGrid.setPaddding( new Padding(0, 0, 0, 0.01f) );
476 infoGrid.addShape(glyphShapeBox.setBorder(0.005f).setBorderColor(0, 0, 0, 1));
477 infoGrid.addShape(glyphInfoBox.setBorder(0.005f).setBorderColor(0, 0, 0, 1));
478 if( VERBOSE_UI ) {
479 infoGrid.validate(reqCaps.getGLProfile());
480 System.err.println("InfoGrid "+infoGrid);
481 System.err.println("InfoGrid "+infoGrid.getLayout());
482 System.err.println("GlyphShapeBox "+glyphShapeBox);
483 }
484 glyphInfoView.addShape(infoGrid);
485 }
486 glyphInfoView.setPaddding(new Padding(glyphGridCellSize/6f, 0, 0));
487 if( VERBOSE_UI ) {
488 glyphInfoView.validate(reqCaps.getGLProfile());
489 System.err.println("GlyphInfoGrid "+glyphInfoView);
490 System.err.println("GlyphInfoGrid "+glyphInfoView.getLayout());
491 }
492
493 mainView = new Group(new GridLayout(1, 0f, 0f, Alignment.None));
494 mainView.addShape(glyphInfoView);
495 {
496 final String infoHelp = "Click on a Glyph for a big tooltip view.\n"+
497 "Key-Up/Down or Slider-Mouse-Scroll to move through glyphs.\n"+
498 "Page-Up/Down or Control + Slider-Mouse-Scroll to page faster.\n"+
499 "Mouse-Scroll over left-half of Window rotates and holding control zooms.";
500 infoLabel = new Label(options.renderModes, fontInfo, "Not yet");
501 infoLabel.setColor(0.1f, 0.1f, 0.1f, 1f);
502 infoLabel.setTooltip(new TooltipText(infoHelp, fontInfo, 8f));
503
504 final float h = glyphGridCellSize * 0.4f;
505 final Group labelBox = new Group(new BoxLayout(1.0f, h, new Alignment(Alignment.Bit.Fill.value | Alignment.Bit.CenterVert.value),
506 new Margin(0, 0.005f)));
507 labelBox.addShape(infoLabel);
508 mainView.addShape(labelBox);
509 }
510 if( VERBOSE_UI ) {
511 mainView.validate(reqCaps.getGLProfile());
512 System.err.println("MainView "+mainView);
513 System.err.println("MainView "+mainView.getLayout());
514 }
515 }
516 scene.addShape(mainView);
517 scene.setAAQuality(options.graphAAQuality);
518 scene.init(glad);
519
520 firstReshape = true;
521
522 {
523 final long t1 = Clock.currentNanos();
524 final long total = t1 - t0;
525 final float nsPerGlyph = total / gridDim.glyphCount;
526 System.err.println("PERF: Total took "+(total/1000000.0)+"ms, per-glyph "+(nsPerGlyph/1000000.0)+"ms, glyphs "+gridDim.glyphCount);
527 }
528 // printScreenOnGLThread(scene, glad.getChosenGLCapabilities(), font, lastCodepoint);
529
530 // stay open ..
531 OutlineShape.printPerf(System.err);
532 }
533
534 @Override
535 public void dispose(final GLAutoDrawable drawable) {
536 mainView.destroy(drawable.getGL().getGL2ES2(), scene.getRenderer());
537 mainView = null;
538 infoLabel = null;
539
540 scene.dispose(drawable);
541 }
542
543 @Override
544 public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
545 scene.reshape(glad, x, y, width, height);
546 if( firstReshape ) {
547 firstReshape = false;
548 final AABBox sceneBox = scene.getBounds();
549 mainView.validate(glad.getGL().getGL2ES2());
550 final AABBox mainViewBox = mainView.getBounds();
551 final float sx = sceneBox.getWidth() / mainViewBox.getWidth();
552 final float sy = sceneBox.getHeight() / mainViewBox.getHeight();
553 final float sxy = Math.min(sx, sy);
554 System.err.println("SceneBox "+sceneBox);
555 System.err.println("MainViewBox "+mainViewBox);
556 System.err.println("scale sx "+sx+", sy "+sy+", sxy "+sxy);
557 mainView.scale(sxy, sxy, 1f).moveTo(sceneBox.getLow());
558 }
559 }
560
561 @Override
562 public void display(final GLAutoDrawable drawable) {
563 infoLabel.setText( scene.getStatusText(drawable, options.renderModes, dpiY) + " (Hover over 1s for help)" );
564 scene.display(drawable);
565 }
566
567 static void printScreenOnGLThread(final Scene scene, final GLCapabilitiesImmutable caps, final Font font, final int codepoint) {
568 final String fn = font.getFullFamilyName().replace(' ', '_').replace('-', '_');
569 scene.screenshot(true, scene.nextScreenshotFile(null, FontView01.class.getSimpleName(), options.renderModes, caps, fn+"_cp"+Integer.toHexString(codepoint)));
570 }
571
572 static class GridDim {
573 final List<Character> contourChars;
574 final int glyphCount;
575 final int columns;
576 final int columnsNet;
577 final int rows;
578 final int rowsPerPage;
579 final int elemCount;
580 int complexGlyphCount;
581 int maxNameLen;
582
583 public GridDim(final Font font, final int columns, final int rowsPerPage, final int xReserved, final int maxGlyphCount) {
584 this.contourChars = new ArrayList<Character>();
585 this.glyphCount = Math.min(maxGlyphCount, scanContourGlyphs(font));
586 this.columns = columns;
587 this.columnsNet = columns - xReserved;
588 this.rows = (int)Math.ceil((double)glyphCount / (double)columnsNet);
589 this.rowsPerPage = rowsPerPage;
590 this.elemCount = glyphCount + ( rows * xReserved );
591 this.maxNameLen=10;
592 }
593
594 public int reserverColumns() { return columns - columnsNet; }
595
596 private int scanContourGlyphs(final Font font) {
597 final long t0 = Clock.currentNanos();
598 contourChars.clear();
599 complexGlyphCount = 0;
600 maxNameLen = 1;
601 final int[] max = { max_glyph_count };
602 font.forAllGlyphs((final Glyph fg) -> {
603 if( !fg.isNonContour() && max[0]-- > 0 ) {
604 contourChars.add( fg.getCodepoint() );
605 if( null != fg.getShape() && fg.getShape().isComplex() ) {
606 ++complexGlyphCount;
607 }
608 maxNameLen = Math.max(maxNameLen, fg.getName().length());
609 }
610 });
611 final long t1 = Clock.currentNanos();
612 final long total = t1 - t0;
613 final float nsPerGlyph = total / contourChars.size();
614 System.err.println("PERF: GlyphScan took "+(total/1000000.0)+"ms, per-glyph "+(nsPerGlyph/1000000.0)+"ms, glyphs "+contourChars.size());
615 return contourChars.size();
616 }
617 @Override
618 public String toString() { return "GridDim[contours "+glyphCount+", complex "+complexGlyphCount+" ("+((float)complexGlyphCount/(float)glyphCount)*100+"%), "+columns+"x"+rows+"="+(columns*rows)+">="+elemCount+", rows/pg "+rowsPerPage+"]"; }
619 }
620
621 static Group getGlyphShapeHolder(final Shape shape0) {
622 if( !( shape0 instanceof Group ) ) {
623 return null;
624 }
625 return (Group)((Group)shape0).getShapeByName("GlyphHolder");
626 }
627 static GlyphShape getGlyphShape(final Shape shape0) {
628 final Group gsh = getGlyphShapeHolder(shape0);
629 if( null != gsh && gsh.getShapeCount() > 0 ) {
630 return (GlyphShape) gsh.getShapeByIdx(0);
631 }
632 return null;
633 }
634
635 /**
636 * Fill given Group sink with glyph shapes wrapped as {@code Group2[Group1[GlyphShape]]},
637 * with Group1 having the name 'GlyphHolder'.
638 */
639 static void addGlyphs(final GLProfile glp, final Font font, final Group sink,
640 final GridDim gridDim, final boolean showUnderline, final boolean showLabel,
641 final Font fontStatus, final Font fontInfo, final Shape.PointerListener hoverHandler) {
642 final AABBox tmpBox = new AABBox();
643 final long t0 = Clock.currentNanos();
644
645 for(int idx = 0; idx < gridDim.glyphCount; ++idx) {
646 final char codepoint = gridDim.contourChars.get(idx);
647 final Font.Glyph fg = font.getGlyph(codepoint);
648 final boolean isComplex = null != fg.getShape() ? fg.getShape().isComplex() : false;
649
650 final GlyphShape g = new GlyphShape(options.renderModes, fg, 0, 0);
651 g.setColor(0.1f, 0.1f, 0.1f, 1).setName("GlyphShape");
652 g.setInteractive(false).setDragAndResizable(false);
653 g.setName( "cp_0x"+Integer.toHexString(fg.getCodepoint()) );
654
655 final Group c0 = new Group("GlyphHolder", null, null, g);
656 c0.setInteractive(false).setDragAndResizable(false);
657
658 // Group each GlyphShape with its bounding box Rectangle
659 final AABBox gbox = fg.getBounds(tmpBox); // g.getBounds(glp);
660 final boolean addUnderline = showUnderline && gbox.getMinY() < 0f;
661 final Group c1 = new Group( new BoxLayout( 1f, 1f, addUnderline ? Alignment.None : Alignment.Center) );
662 c1.setBorder(GlyphGridBorderThickness).setBorderColor(isComplex ? GlyphGridBorderColorComplex : GlyphGridBorderColorSimple)
663 .setInteractive(true).setDragAndResizable(false).setName("GlyphHolder2");
664 if( addUnderline ) {
665 final Shape underline = new Rectangle(options.renderModes, 1f, gbox.getMinY(), 0.01f).setInteractive(false).setColor(0f, 0f, 1f, 0.25f);
666 c1.addShape(underline);
667 }
668
669 c1.addShape( c0 );
670 c1.onHover(hoverHandler);
671 sink.receiveKeyEvents(c1);
672 // sink.receiveMouseEvents(c1);
673 c1.setTooltip( new TooltipShape(new Vec4f(1, 1, 1, 1), new Vec4f(0, 0, 0, 1), 0.01f,
674 new Padding(0.05f), new Vec2f(14,14), 0, options.renderModes,
675 g, TooltipShape.NoOpDtor) );
676 c1.onClicked((final Shape s, final Vec3f pos, final MouseEvent e) -> {
677 System.err.println("XXX: Clicked: "+s+", event "+e);
678 if( e.getPointerType(0).getPointerClass() == MouseEvent.PointerClass.Onscreen ) {
679 hoverHandler.run(s, pos, e);
680 } else {
681 c1.getTooltip().now();
682 }
683 });
684
685 if( 0 < gridDim.reserverColumns() && 0 == idx % gridDim.columnsNet ) {
686 addLabel(sink, fontStatus, String.format("%04x", (int)codepoint));
687 }
688 if( showLabel ) {
689 final Group c2 = new Group( new GridLayout( 1, 0, 0, Alignment.None) ); // Alignment(Alignment.Bit.CenterHoriz) ) );
690 c2.addShape(c1.setName("GlyphHolder3"));
691 {
692 final Label l = new Label(options.renderModes, fontInfo, fg.getName());
693 // final AABBox lbox = l.getUnscaledGlyphBounds();
694 final float sxy = 1f/7f; // gridDim.maxNameLen; // 0.10f; // Math.min(sx, sy);
695 c2.addShape( l.scale(sxy, sxy, 1).setColor(0, 0, 0, 1).setInteractive(false).setDragAndResizable(false) );
696 }
697 sink.addShape(c2);
698 // System.err.println("Add.2: "+c2);
699 } else {
700 sink.addShape(c1);
701 // System.err.println("Add.1: "+c1);
702 }
703 }
704 final long t1 = Clock.currentNanos();
705 final long total = t1 - t0;
706 final float nsPerGlyph = total / gridDim.glyphCount;
707 System.err.println("PERF: GlyphAdd took "+(total/1000000.0)+"ms, per-glyph "+(nsPerGlyph/1000000.0)+"ms, glyphs "+gridDim.glyphCount);
708 }
709 static void addLabel(final Group c, final Font font, final String text) {
710 c.addShape( new Label(options.renderModes, font, text).setColor(0, 0, 0, 1).setInteractive(false).setDragAndResizable(false) );
711 }
712
713 static void setGlyphInfo(final Font font, final Label label, final Font.Glyph g) {
714 label.setText( getGlyphInfo(g) );
715 if( VERBOSE_GLYPHS ) {
716 System.err.println( label.getText() );
717 }
718 }
719
720 static String getGlyphInfo(final Font.Glyph g) {
721 final OutlineShape os = g.getShape();
722 final boolean isComplex = null != os ? os.isComplex() : false;
723 final int osVertices = null != os ? os.getVertexCount() : 0;
724 final String name_s = null != g.getName() ? g.getName() : "";
725 final AABBox bounds = g.getBounds();
726 final String box_s = String.format("Box %+.3f/%+.3f%n %+.3f/%+.3f", bounds.getLow().x(), bounds.getLow().y(), bounds.getHigh().x(), bounds.getHigh().y());
727 return String.format((Locale)null, "%s%nHeight: %1.3f%nLine Height: %1.3f%n%nSymbol: %04x, id %04x%nName: '%s'%nDim %1.3f x %1.3f%n%s%nAdvance %1.3f%nLS Bearings: %1.3f%nVertices: %03d%n%s",
728 g.getFont().getFullFamilyName(),
729 g.getFont().getMetrics().getAscent() - g.getFont().getMetrics().getDescent(), // font hhea table
730 g.getFont().getLineHeight(), // font hhea table
731 (int)g.getCodepoint(), g.getID(), name_s,
732 bounds.getWidth(), bounds.getHeight(), box_s,
733 g.getAdvanceWidth(),
734 g.getLeftSideBearings(),
735 osVertices, isComplex?"Complex Shape":"Simple Shape");
736 }
737}
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
static final int VBAA_RENDERING_BIT
Rendering-Mode bit for Region.
Definition: Region.java:115
The optional property jogamp.graph.font.ctor allows user to specify the FontConstructor implementatio...
static final FontSet get(final int font)
Group of Shapes, optionally utilizing a Group.Layout.
Definition: Group.java:61
int getShapeCount()
Returns number of Shapes, see getShapes().
Definition: Group.java:216
void addShape(final Shape s)
Adds a Shape.
Definition: Group.java:225
Layout getLayout()
Return current Group.Layout.
Definition: Group.java:150
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
Definition: Group.java:686
void setRelayoutOnDirtyShapes(final boolean v)
Set relayout on dirty shapes mode, defaults to true.
Definition: Group.java:514
GraphUI Scene.
Definition: Scene.java:103
void addShape(final Shape s)
Adds a Shape.
Definition: Scene.java:292
final void setClearParams(final float[] clearColor, final int clearMask)
Sets the clear parameter for glClearColor(..) and glClear(..) to be issued at display(GLAutoDrawable)...
Definition: Scene.java:226
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
Definition: Scene.java:412
RegionRenderer getRenderer()
Returns the associated RegionRenderer.
Definition: Scene.java:213
final void setPMvCullingEnabled(final boolean v)
Enable or disable Project-Modelview (PMv) frustum culling per Shape for this container.
Definition: Scene.java:235
int setAAQuality(final int v)
Sets RegionRenderer#setAAQuality(int).
Definition: Scene.java:388
void dispose(final GLAutoDrawable drawable)
Disposes all added Shapes.
Definition: Scene.java:610
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
Definition: Scene.java:683
synchronized void attachInputListenerTo(final GLWindow window)
Definition: Scene.java:251
boolean invoke(final boolean wait, final GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next GLAutoDrawable#display() call ...
Definition: Scene.java:433
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
Definition: Scene.java:492
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Reshape scene using setupMatrix(PMVMatrix4f, int, int, int, int) using PMVMatrixSetup.
Definition: Scene.java:463
String getStatusText(final GLAutoDrawable glad, final int renderModes, final float dpi)
Return a formatted status string containing avg fps and avg frame duration.
Definition: Scene.java:1392
File nextScreenshotFile(final String dir, final String prefix, final int renderModes, final GLCapabilitiesImmutable caps, final String contentDetail)
Return the unique next technical screenshot PNG File instance as follows:
Definition: Scene.java:1445
Convenient adapter combining dummy implementation for MouseListener and GestureListener.
Definition: Shape.java:1884
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Definition: Shape.java:87
Shape setColor(final float r, final float g, final float b, final float a)
Set base color.
Definition: Shape.java:1389
Shape setName(final String name)
Set a symbolic name for this shape for identification.
Definition: Shape.java:339
final Shape move(final float dtx, final float dty, final float dtz)
Move about scaled distance.
Definition: Shape.java:557
final Vec3f getScale()
Returns scale Vec3f reference.
Definition: Shape.java:682
final Shape moveTo(final float tx, final float ty, final float tz)
Move to scaled position.
Definition: Shape.java:543
final Quaternion getRotation()
Returns Quaternion for rotation.
Definition: Shape.java:595
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
Definition: Shape.java:850
final Shape setRotation(final Quaternion q)
Sets the rotation Quaternion.
Definition: Shape.java:604
final void destroy(final GL2ES2 gl, final RegionRenderer renderer)
Destroys all data.
Definition: Shape.java:457
final Shape scale(final Vec3f s)
Multiply current scale factor by given scale.
Definition: Shape.java:661
Tooltip setTooltip(final Tooltip newTooltip)
Set's a new Tooltip for this shape.
Definition: Shape.java:1653
final Shape setBorderColor(final float r, final float g, final float b, final float a)
Set border color.
Definition: Shape.java:1489
final Shape setBorder(final float thickness)
Sets the thickness of the border, which is included in getBounds() and is outside of getPadding().
Definition: Shape.java:402
Immutable layout alignment options, including Bit#Fill.
Definition: Alignment.java:35
static final Alignment FillCenter
Bit#Fill, Bit#CenterHoriz and Bit#CenterVert alignment constant.
Definition: Alignment.java:45
GraphUI Stack Group.Layout.
Definition: BoxLayout.java:53
GraphUI CSS property Margin, scaled space between or around elements and not included in the element'...
Definition: Margin.java:41
Representing a single Font.Glyph as a GraphShape.
Definition: GlyphShape.java:53
Glyph getGlyph()
Returns the Font.Glyph to be rendered.
A GraphUI text label GraphShape.
Definition: Label.java:50
boolean setText(final CharSequence text)
Set the text to be rendered.
Definition: Label.java:94
Basic Float math utility functions.
Definition: FloatUtil.java:83
static final float PI
The value PI, i.e.
final Quaternion rotateByEuler(final Vec3f angradXYZ)
Rotates this quaternion from the given Euler rotation array angradXYZ in radians.
2D Vector based upon two float components.
Definition: Vec2f.java:37
3D Vector based upon three float components.
Definition: Vec3f.java:37
void setX(final float x)
Definition: Vec3f.java:158
Vec3f scale(final float s)
this = this * s, returns this.
Definition: Vec3f.java:218
void setY(final float y)
Definition: Vec3f.java:159
4D Vector based upon four float components.
Definition: Vec4f.java:37
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final float getWidth()
Definition: AABBox.java:879
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
Definition: AABBox.java:140
final float getHeight()
Definition: AABBox.java:883
final AABBox scale(final float s)
Scale this AABBox by a constant around fixed center.
Definition: AABBox.java:750
Visual output device, i.e.
static float[] mmToInch(final float[] result, final float[] ppmm)
Converts [1/mm] to [1/inch] from ppmm into result.
static float[] inchToMM(final float[] result, final float[] ppinch)
Converts [1/inch] to [1/mm] in place.
final float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter value according to the current mode's surface resolution.
final boolean isShiftDown()
getModifiers() contains SHIFT_MASK.
final boolean isControlDown()
getModifiers() contains CTRL_MASK.
static final short VK_F4
Constant for the F4 function key.
Definition: KeyEvent.java:686
static final short VK_ESCAPE
Constant for the ESCAPE function key.
Definition: KeyEvent.java:485
final short getKeySymbol()
Returns the virtual key symbol reflecting the current keyboard layout.
Definition: KeyEvent.java:176
static final short VK_S
See VK_A.
Definition: KeyEvent.java:631
static final short VK_Q
See VK_A.
Definition: KeyEvent.java:627
Pointer event of type PointerType.
Definition: MouseEvent.java:74
final float[] getRotation()
Returns a 3-component float array filled with the values of the rotational axis in the following orde...
final int getX()
See details for multiple-pointer events.
final void setConsumed(final boolean consumed)
If consumed is true, this event is marked as consumed, ie.
Definition: NEWTEvent.java:126
NEWT Window events are provided for notification purposes ONLY.
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Definition: GLWindow.java:466
final void setTitle(final String title)
Definition: GLWindow.java:297
final int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
Definition: GLWindow.java:461
final void setSize(final int width, final int height)
Sets the size of the window's client area in window units, excluding decorations.
Definition: GLWindow.java:625
final void setVisible(final boolean visible)
Calls setVisible(true, visible), i.e.
Definition: GLWindow.java:615
final void addWindowListener(final WindowListener l)
Appends the given com.jogamp.newt.event.WindowListener to the end of the list.
Definition: GLWindow.java:882
CapabilitiesChooser setCapabilitiesChooser(final CapabilitiesChooser chooser)
Set the CapabilitiesChooser to help determine the native visual type.
Definition: GLWindow.java:261
static GLWindow create(final GLCapabilitiesImmutable caps)
Creates a new GLWindow attaching a new Window referencing a new default Screen and default Display wi...
Definition: GLWindow.java:169
Specifies a set of OpenGL capabilities.
abstract GL setGL(GL gl)
Sets the GL pipeline object for this GLContext.
Factory for pipelining GL instances.
static final GL create(final String pipelineClazzBaseName, final Class<?> reqInterface, final GL downstream, final Object[] additionalArgs)
Creates a pipelined GL instance using the given downstream downstream and optional arguments addition...
static JoglVersion getInstance()
static StringBuilder getGLInfo(final GL gl, final StringBuilder sb)
StringBuilder toString(final GL gl, StringBuilder sb)
static void dump(final GLAutoDrawable drawable)
Definition: MSAATool.java:51
This may become a little font viewer application, having FontForge as its role model.
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
void init(final GLAutoDrawable glad)
Called by the drawable immediately after the OpenGL context is initialized.
void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height)
Called by the drawable during the first repaint after the component has been resized.
static void main(final String[] args)
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
int fixDefaultAARenderModeWithDPIThreshold(final float dpiV)
Changes default AA rendering bit if not modified via parse(), i.e.
int graphAASamples
Sample count for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT or Region#MSAA_RENDERING_BIT...
int graphAAQuality
Pass2 AA-quality rendering for Graph Region AA render-modes: VBAA_RENDERING_BIT.
static void waitForKey(final String preMessage)
Definition: MiscUtils.java:167
static int atoi(final String str, final int def)
Definition: MiscUtils.java:60
static void destroyWindow(final GLAutoDrawable glad)
Definition: MiscUtils.java:269
static float atof(final String str, final float def)
Definition: MiscUtils.java:78
final synchronized void add(final GLAutoDrawable drawable)
Adds a drawable to this animator's list of rendering drawables.
final synchronized Thread setExclusiveContext(final Thread t)
Dedicate all GLAutoDrawable's context to the given exclusive context thread.
final void setUpdateFPSFrames(final int frames, final PrintStream out)
final synchronized boolean start()
Starts this animator, if not running.
Definition: Animator.java:344
final synchronized boolean stop()
Stops this animator.
Definition: Animator.java:368
Custom GLCapabilitiesChooser, filtering out all full screen anti-aliasing (FSAA, multisample) capabil...
char getCodepoint()
Returns this glyph's mapped (unicode) codepoint symbol.
Interface wrapper for font implementation.
Definition: Font.java:60
Glyph getGlyph(final String name)
Returns the Glyph mapped to given name.
String getFullFamilyName()
Shall return the family and subfamily name, separated a dash.
int getSurfaceWidth()
Returns the width of the client area excluding insets (window decorations) in pixel units.
float[] getMaximumSurfaceScale(final float[] result)
Returns the maximum pixel scale of the associated NativeSurface.
float[] getCurrentSurfaceScale(final float[] result)
Returns the current pixel scale of the associated NativeSurface.
Specifying NEWT's Window functionality:
Definition: Window.java:115
void addKeyListener(KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter of this window's NativeSurface according to the main monitor's curr...
void addMouseListener(MouseListener l)
Appends the given MouseListener to the end of the list.
MonitorDevice getMainMonitor()
Returns the MonitorDevice with the highest viewport coverage of this window.
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
Object getUpstreamWidget()
Method may return the upstream UI toolkit object holding this GLAutoDrawable instance,...
void addGLEventListener(GLEventListener listener)
Adds the given listener to the end of this drawable queue.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
GLContext getContext()
Returns the GLContext associated which this GL object.
Specifies an immutable set of OpenGL capabilities.
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
static final int GL_DEPTH_TEST
GL_ES_VERSION_2_0, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_TEST" with expression '0x0B71',...
Definition: GL.java:43