diff options
Diffstat (limited to 'src')
9 files changed, 116 insertions, 58 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java index 0fef325bd..d8f75610f 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java @@ -112,7 +112,7 @@ public class FontView01 { public static void main(final String[] args) throws IOException { float mmPerCell = 8f; - String fontfilename = null; + String fontFilename = null; int gridColumns = -1; boolean showUnderline = false; boolean showLabel = false; @@ -125,7 +125,7 @@ public class FontView01 { continue; } else if(args[idx[0]].equals("-font")) { idx[0]++; - fontfilename = args[idx[0]]; + fontFilename = args[idx[0]]; } else if(args[idx[0]].equals("-mmPerCell")) { idx[0]++; mmPerCell = MiscUtils.atof(args[idx[0]], mmPerCell); @@ -147,11 +147,11 @@ public class FontView01 { System.err.println(options); Font font; - if( null == fontfilename ) { + if( null == fontFilename ) { font = FontFactory.get(IOUtil.getResource("fonts/freefont/FreeSerif.ttf", FontSetDemos.class.getClassLoader(), FontSetDemos.class).getInputStream(), true); } else { - font = FontFactory.get( new File( fontfilename ) ); + font = FontFactory.get( new File( fontFilename ) ); } System.err.println("Font "+font.getFullFamilyName()); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java index 888a5bd28..c41604af0 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid00.java @@ -34,6 +34,7 @@ import java.util.List; import com.jogamp.common.net.Uri; import com.jogamp.graph.curve.Region; import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.font.FontScale; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Scene; @@ -213,7 +214,7 @@ public class UIMediaGrid00 { final List<Shape> customCtrls = new ArrayList<Shape>(); { - final Font fontSymbols = Scene.getSymbolsFont(); + final Font fontSymbols = FontFactory.getSymbolsFont(); if( null == fontSymbols ) { grid.addShape( new Rectangle(options.renderModes, 16f/9f, 1, 0.10f) ); return; diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java index ffba565f5..60366ac45 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UIMediaGrid01.java @@ -37,6 +37,7 @@ import java.util.List; import com.jogamp.common.net.Uri; import com.jogamp.graph.curve.Region; import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.font.FontScale; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Scene; @@ -53,8 +54,8 @@ import com.jogamp.graph.ui.shapes.MediaButton; import com.jogamp.graph.ui.shapes.Rectangle; import com.jogamp.graph.ui.widgets.MediaPlayer; import com.jogamp.graph.ui.widgets.RangeSlider; -import com.jogamp.graph.ui.widgets.RangedGroup; import com.jogamp.graph.ui.widgets.RangeSlider.SliderAdapter; +import com.jogamp.graph.ui.widgets.RangedGroup; import com.jogamp.graph.ui.widgets.RangedGroup.SliderParam; import com.jogamp.math.Vec2f; import com.jogamp.math.Vec2i; @@ -97,6 +98,7 @@ public class UIMediaGrid01 { float mmPerCellWidth = 50f; int maxMediaFiles = 10000; // Integer.MAX_VALUE; int gridColumns = -1; + String subFallbackFontFilename = null; String mediaDir = null; if( 0 != args.length ) { final int[] idx = { 0 }; @@ -129,12 +131,18 @@ public class UIMediaGrid01 { } else if(args[idx[0]].equals("-col")) { idx[0]++; gridColumns = MiscUtils.atoi(args[idx[0]], gridColumns); + } else if(args[idx[0]].equals("-fallbackFont")) { + idx[0]++; + subFallbackFontFilename = args[idx[0]]; } else if(args[idx[0]].equals("-texCount")) { idx[0]++; texCount = MiscUtils.atoi(args[idx[0]], texCount); } } } + if( null != subFallbackFontFilename ) { + FontFactory.setFallbackFont( FontFactory.get( new File( subFallbackFontFilename ) ) ); + } System.err.println(options); System.err.println("mediaDir "+mediaDir); System.err.println("maxMediaFiles "+maxMediaFiles); @@ -143,6 +151,7 @@ public class UIMediaGrid01 { System.err.println("boxRatio "+videoAspectRatio); System.err.println("letterBox "+letterBox); System.err.println("columns "+gridColumns); + System.err.println("FallbackFont "+FontFactory.getFallbackFont()); final List<Uri> mediaFiles = new ArrayList<Uri>(); if( null != mediaDir && mediaDir.length() > 0 ) { @@ -284,7 +293,7 @@ public class UIMediaGrid01 { mainGrid.setName("MainGrid"); mainGrid.addShape(mediaView); { - final Font fontInfo = Scene.getDefaultFont(); + final Font fontInfo = FontFactory.getDefaultFont(); final Label infoLabel = new Label(options.renderModes, fontInfo, "Not yet"); infoLabel.setColor(0.1f, 0.1f, 0.1f, 1f); final Group labelBox = new Group(new BoxLayout(mediaGridSize.x(), mediaCellHeight / 10, new Alignment(Alignment.Bit.Fill.value | Alignment.Bit.CenterVert.value), @@ -348,7 +357,7 @@ public class UIMediaGrid01 { final List<Shape> customCtrls = new ArrayList<Shape>(); if( true ) { - final Font fontSymbols = Scene.getSymbolsFont(); + final Font fontSymbols = FontFactory.getSymbolsFont(); if( null == fontSymbols ) { grid.addShape( new Rectangle(options.renderModes, defRatio, 1, 0.10f) ); return; @@ -380,7 +389,6 @@ public class UIMediaGrid01 { customCtrls.add(button); } final MediaPlayer graphMPlayer = new MediaPlayer(options.renderModes, scene, glMPlayer, medium, defRatio, letterBox, zoomSize, customCtrls); - // graphMPlayer.setSubtitleParams(MiscUtils.getSerifFont(), 0.1f); grid.addShape( graphMPlayer ); glMPlayer.playStream(medium, GLMediaPlayer.STREAM_ID_AUTO, aid, sid, texCount); if( start_pos > 0 ) { diff --git a/src/graphui/classes/com/jogamp/graph/ui/Scene.java b/src/graphui/classes/com/jogamp/graph/ui/Scene.java index 9ebacf2ec..7f47b2d98 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Scene.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Scene.java @@ -28,7 +28,6 @@ package com.jogamp.graph.ui; import java.io.File; -import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -54,8 +53,6 @@ import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.curve.opengl.RenderState; -import com.jogamp.graph.font.Font; -import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.ui.Shape.Visitor2; import com.jogamp.math.FloatUtil; import com.jogamp.math.Matrix4f; @@ -130,25 +127,6 @@ public final class Scene implements Container, GLEventListener { return FloatUtil.getZBufferEpsilon(zBits, setup.getSceneDist(), setup.getZNear()); } - /** Returns {@link FontFactory#getDefault()} font or null if n/a */ - public static Font getDefaultFont() { - try { - return FontFactory.getDefault().getDefault(); - } catch(final IOException ioe) { - ioe.printStackTrace(); - return null; - } - } - /** Returns the default symbols font or null if n/a */ - public static Font getSymbolsFont() { - try { - return FontFactory.get(FontFactory.SYMBOLS).getDefault(); - } catch(final IOException ioe) { - ioe.printStackTrace(); - return null; - } - } - private static final boolean DEBUG = false; private final List<Shape> shapes = new CopyOnWriteArrayList<Shape>(); diff --git a/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java b/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java index bbf1d7b66..54b23ba6a 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java +++ b/src/graphui/classes/com/jogamp/graph/ui/shapes/MediaButton.java @@ -39,8 +39,8 @@ import com.jogamp.common.util.InterruptSource; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.RegionRenderer; import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.ui.GraphShape; -import com.jogamp.graph.ui.Scene; import com.jogamp.graph.ui.layout.Alignment; import com.jogamp.math.Vec2f; import com.jogamp.math.Vec4f; @@ -78,6 +78,8 @@ public class MediaButton extends TexSeqButton { private static final boolean DEBUG_PGS_POSSZ = false; private boolean verbose = false; + private Font subFont; + private Font subFallbackFont; private final Label subLabel; private final float subZOffset; private boolean subEnabled; @@ -106,18 +108,19 @@ public class MediaButton extends TexSeqButton { private final List<SubtitleEvent> subEventQueue = new ArrayList<SubtitleEvent>(); private final Object subEventLock = new Object(); - /** Constructs a {@link MediaButton} with subtitles disabled. */ + /** Constructs a {@link MediaButton} with {@link FontFactory#getDefaultFont()} for subtitles. */ public MediaButton(final int renderModes, final float width, final float height, final GLMediaPlayer mPlayer) { this(renderModes, width, height, mPlayer, null); } /** - * Constructs a {@link MediaButton} prepared for using subtitles. + * Constructs a {@link MediaButton} prepared for using subtitles * @param renderModes * @param width * @param height * @param mPlayer - * @param subFont text/ASS subtitle font + * @param subFont text/ASS subtitle font, pass {@code null} for {@link FontFactory#getDefaultFont()}. + * {@link FontFactory#getFallbackFont()} is used {@link Font#getBestCoverage(Font, Font, CharSequence) if providing a better coverage} of a Text/ASS subtitle line. * @see #setSubtitleParams(Font, float, float, Alignment) * @see #setSubtitleColor(Vec4f, float) */ @@ -132,23 +135,13 @@ public class MediaButton extends TexSeqButton { mPlayer.setSubtitleEventListener(subEventListener); - final Font f; - if( null != subFont ) { - f = subFont; - subEnabled = true; - } else { - f = Scene.getDefaultFont(); - subEnabled = false; - } + setSubtitleParams(subFont, DEFAULT_ASS_SUB_HEIGHT, DEFAULT_ASS_SUB_POS, DEFAULT_ASS_SUB_ALIGNMENT); + this.subLabel = new Label(renderModes, this.subFont, ""); this.subZOffset = Button.DEFAULT_LABEL_ZOFFSET; - this.subLineHeightPct = DEFAULT_ASS_SUB_HEIGHT; - this.subLineDY = DEFAULT_ASS_SUB_POS; - this.subAlignment = DEFAULT_ASS_SUB_ALIGNMENT; - this.subLabel = new Label(renderModes, f, ""); - this.subLabel.setColor( DEFAULT_ASS_SUB_COLOR ); this.subLabel.moveTo(0, 0, subZOffset); this.subBlend = new Rectangle(renderModes, 1f, 1f, 0f); - this.subBlend.setColor( new Vec4f( 0, 0, 0, DEFAULT_ASS_SUB_BLEND ) ); + setSubtitleColor(DEFAULT_ASS_SUB_COLOR, DEFAULT_ASS_SUB_BLEND); + this.subTexImg = new ImageButton(renderModes, width, height, new ImageSequence(mPlayer.getTextureUnit(), true /* useBuildInTexLookup */)); this.subTexImg.setPerp().setToggleable(false).setDragAndResizeable(false).setInteractive(false); // this.subTexImg.setBorder(0.001f).setBorderColor(1, 1, 0, 1); @@ -157,15 +150,26 @@ public class MediaButton extends TexSeqButton { this.drawLastSub = null; } + /** Toggle enabling subtitle rendering */ + public void setSubtitlesEnabled(final boolean v) { + subEnabled = v; + } + /** - * Sets text/ASS subtitle parameter - * @param subFont text/ASS subtitle font + * Sets text/ASS subtitle parameter, enabling subtitle rendering + * @param subFont text/ASS subtitle font, pass {@code null} for {@link FontFactory#getDefaultFont()} + * {@link FontFactory#getFallbackFont()} is used {@link Font#getBestCoverage(Font, Font, CharSequence) if providing a better coverage} of a Text/ASS subtitle line. * @param subLineHeightPct text/ASS subtitle line height percentage, defaults to {@link #DEFAULT_ASS_SUB_HEIGHT} * @param subLineDY text/ASS y-axis offset to bottom in line-height, defaults to {@link #DEFAULT_ASS_SUB_POS} * @param subAlignment text/ASS subtitle alignment, defaults to {@link #DEFAULT_ASS_SUB_ALIGNMENT} */ public void setSubtitleParams(final Font subFont, final float subLineHeightPct, final float subLineDY, final Alignment subAlignment) { - this.subLabel.setFont(subFont); + if( null != subFont ) { + this.subFont = subFont; + } else { + this.subFont = FontFactory.getDefaultFont(); + } + this.subFallbackFont = FontFactory.getFallbackFont(); this.subLineHeightPct = subLineHeightPct; this.subLineDY = subLineDY; this.subAlignment = subAlignment; @@ -398,6 +402,7 @@ public class MediaButton extends TexSeqButton { } else if( SubtitleEvent.Type.Text == sub.type ) { final SubTextEvent assSub = (SubTextEvent)sub; if( newSub ) { + subLabel.setFont( Font.getBestCoverage(subFont, subFallbackFont, assSub.text) ); subLabel.setText(assSub.text); final AABBox subBox = subLabel.getBounds(gl.getGLProfile()); final float subLineHeight = subBox.getHeight() / assSub.lines; @@ -503,5 +508,4 @@ public class MediaButton extends TexSeqButton { pmv.popMv(); } } - } diff --git a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java index d93078288..f434bd0ad 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java +++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java @@ -38,6 +38,7 @@ import com.jogamp.common.util.InterruptSource; import com.jogamp.graph.curve.Region; import com.jogamp.graph.curve.opengl.GLRegion; import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Scene; import com.jogamp.graph.ui.Shape; @@ -106,7 +107,7 @@ public class MediaPlayer extends Widget { { super( new BoxLayout(aratio, 1, Alignment.None) ); - final Font fontInfo = Scene.getDefaultFont(), fontSymbols = Scene.getSymbolsFont(); + final Font fontInfo = FontFactory.getDefaultFont(), fontSymbols = FontFactory.getSymbolsFont(); if( null == fontInfo || null == fontSymbols ) { mButton = null; return; @@ -130,7 +131,7 @@ public class MediaPlayer extends Widget { this.setBorderColor(BorderColor).setBorder(BorderSz); this.setInteractive(true).setFixedARatioResize(true); - mButton = new MediaButton(renderModes, aratio, 1, mPlayer, fontInfo); + mButton = new MediaButton(renderModes, aratio, 1, mPlayer); mButton.setName("mp.mButton").setInteractive(false); mButton.setPerp().setPressedColorMod(1f, 1f, 1f, 0.85f); @@ -170,7 +171,7 @@ public class MediaPlayer extends Widget { audioLabel.setText("audio\n"+mp.getLang(mp.getAID())); subLabel.setText("sub\n"+mp.getLang(mp.getSID())); ctrlSlider.setMinMax(new Vec2f(0, mp.getDuration()), 0); - System.err.println("Init +"+mp.toString()); + System.err.println("Init "+mp.toString()); for(final GLMediaPlayer.Chapter c : mp.getChapters()) { if( DEBUG ) { @@ -623,9 +624,17 @@ public class MediaPlayer extends Widget { ctrlSlider.getKnob().setDraggable(true); } + /** Toggle enabling subtitle rendering */ + public void setSubtitlesEnabled(final boolean v) { + if( null != mButton ) { + mButton.setSubtitlesEnabled(v); + } + } + /** - * Sets text/ASS subtitle parameter - * @param subFont text/ASS subtitle font + * Sets text/ASS subtitle parameter, enabling subtitle rendering + * @param subFont text/ASS subtitle font, pass {@code null} for {@link FontFactory#getDefaultFont()} + * {@link FontFactory#getFallbackFont()} is used {@link Font#getBestCoverage(Font, Font, CharSequence) if providing a better coverage} of a Text/ASS subtitle line. * @param subLineHeightPct text/ASS subtitle line height percentage, defaults to {@link MediaButton#DEFAULT_ASS_SUB_HEIGHT} * @param subLineDY text/ASS y-axis offset to bottom in line-height, defaults to {@link MediaButton#DEFAULT_ASS_SUB_POS} * @param subAlignment text/ASS subtitle alignment, defaults to {@link #DEFAULT_ASS_SUB_ALIGNMENT} diff --git a/src/jogl/classes/com/jogamp/graph/font/Font.java b/src/jogl/classes/com/jogamp/graph/font/Font.java index 26557ec00..068363ce4 100644 --- a/src/jogl/classes/com/jogamp/graph/font/Font.java +++ b/src/jogl/classes/com/jogamp/graph/font/Font.java @@ -384,6 +384,25 @@ public interface Font { /** Returns number of {@link Glyph} IDs available, i.e. retrievable via {@link #getGlyph(int)} [0..count). */ int getGlyphCount(); + /** Returns the number of defined {@link Glyph}s (coverage), i.e. not {@link Glyph#isUndefined()}, of given text. */ + int getDefinedCount(final CharSequence text); + + /** + * Returns {@link Font} with best coverage for given text while favoring {@code a}. See {@link #getDefinedCount(CharSequence)}. + * <pre> + * return a.getDefinedCount(text) >= b.getDefinedCount(text) ? a : b; + * </pre> + */ + public static Font getBestCoverage(final Font a, final Font b, final CharSequence text) { + if( null != a && null != b ) { + return a.getDefinedCount(text) >= b.getDefinedCount(text) ? a : b; + } else if( null != a ) { + return a; + } else { + return b; + } + } + /** Returns the {@link Glyph} (unicode) `codepoint` symbol mapped to given {@link Glyph} `name`. */ char getGlyphCodepoint(final String name); diff --git a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java index cd39abdfe..eb74c5696 100644 --- a/src/jogl/classes/com/jogamp/graph/font/FontFactory.java +++ b/src/jogl/classes/com/jogamp/graph/font/FontFactory.java @@ -217,4 +217,32 @@ public class FontFactory { final Character.UnicodeBlock block = Character.UnicodeBlock.of( c ); return block != null && block != Character.UnicodeBlock.SPECIALS; } + + /** Returns {@link FontSet#getDefault() default} {@link Font} of {@link #getDefault() default} {@link FontSet} or {@code null} if n/a */ + public static Font getDefaultFont() { + try { + return getDefault().getDefault(); + } catch(final IOException ioe) { + ioe.printStackTrace(); + return null; + } + } + + /** Returns the default symbols {@link Font} or {@code null} if n/a */ + public static Font getSymbolsFont() { + try { + return get(SYMBOLS).getDefault(); + } catch(final IOException ioe) { + ioe.printStackTrace(); + return null; + } + } + + /** Returns registered fallback {@link Font}, maybe {@code null}. See {@link #setFallbackFont(Font)}. */ + public static synchronized Font getFallbackFont() { + return fallbackFont; + } + /** Registers given {@link Font} as the default fallback font. */ + public static synchronized void setFallbackFont(final Font f) { fallbackFont = f; } + private static Font fallbackFont = null; } diff --git a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java index c60629582..0a251a378 100644 --- a/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java +++ b/src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java @@ -224,6 +224,17 @@ class TypecastFont implements Font { public int getGlyphCount() { return font.getGlyphCount(); } @Override + public int getDefinedCount(final CharSequence text) { + int res = 0; + for(int i=text.length()-1; i>=0; --i) { + if( !getGlyph(text.charAt(i)).isUndefined() ) { + ++res; + } + } + return res; + } + + @Override public char getGlyphCodepoint(final String name) { final SymAndID value = nameToGlyph.get(name); if( null != value ) { |