/* * Copyright 2015 Brandon Borkholder * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jogamp.glg2d.impl; import static java.lang.Math.ceil; import java.awt.Font; import java.awt.FontMetrics; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.util.ArrayDeque; import java.util.Deque; import org.jogamp.glg2d.GLG2DTextHelper; import org.jogamp.glg2d.GLGraphics2D; public abstract class AbstractTextDrawer implements GLG2DTextHelper { protected GLGraphics2D g2d; protected Deque<FontState> stack = new ArrayDeque<FontState>(); @Override public void setG2D(GLGraphics2D g2d) { this.g2d = g2d; stack.clear(); stack.push(new FontState()); } @Override public void push(GLGraphics2D newG2d) { stack.push(stack.peek().clone()); } @Override public void pop(GLGraphics2D parentG2d) { stack.pop(); } @Override public void setHint(Key key, Object value) { if (key == RenderingHints.KEY_TEXT_ANTIALIASING) { stack.peek().antiAlias = value == RenderingHints.VALUE_TEXT_ANTIALIAS_ON; } } @Override public void resetHints() { setHint(RenderingHints.KEY_TEXT_ANTIALIASING, null); } @Override public void setFont(Font font) { stack.peek().font = font; } @Override public Font getFont() { return stack.peek().font; } @Override public FontMetrics getFontMetrics(Font font) { return new GLFontMetrics(font, getFontRenderContext()); } @Override public FontRenderContext getFontRenderContext() { return new FontRenderContext(g2d.getTransform(), stack.peek().antiAlias, false); } /** * The default implementation is good enough for now. */ public static class GLFontMetrics extends FontMetrics { private static final long serialVersionUID = 3676850359220061793L; protected FontRenderContext fontRenderContext; public GLFontMetrics(Font font, FontRenderContext frc) { super(font); fontRenderContext = frc; } @Override public FontRenderContext getFontRenderContext() { return fontRenderContext; } @Override public int charsWidth(char[] data, int off, int len) { if (len <= 0) { return 0; } Rectangle2D bounds = font.getStringBounds(data, off, len, getFontRenderContext()); return (int) ceil(bounds.getWidth()); } } protected static class FontState implements Cloneable { public Font font; public boolean antiAlias; @Override public FontState clone() { try { return (FontState) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } } } }