Path: blob/master/src/java.desktop/macosx/classes/sun/font/CFont.java
41153 views
/*1* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.font;2627import java.awt.Font;28import java.awt.font.FontRenderContext;29import java.awt.geom.AffineTransform;30import java.awt.geom.GeneralPath;31import java.awt.geom.Point2D;32import java.awt.geom.Rectangle2D;33import java.util.ArrayList;3435// Right now this class is final to avoid a problem with native code.36// For some reason the JNI IsInstanceOf was not working correctly37// so we are checking the class specifically. If we subclass this38// we need to modify the native code in CFontWrapper.m39public final class CFont extends PhysicalFont implements FontSubstitution {4041/* CFontStrike doesn't call these methods so they are unimplemented.42* They are here to meet the requirements of PhysicalFont, needed43* because a CFont can sometimes be returned where a PhysicalFont44* is expected.45*/46StrikeMetrics getFontMetrics(long pScalerContext) {47throw new InternalError("Not implemented");48}4950float getGlyphAdvance(long pScalerContext, int glyphCode) {51throw new InternalError("Not implemented");52}5354void getGlyphMetrics(long pScalerContext, int glyphCode,55Point2D.Float metrics) {56throw new InternalError("Not implemented");57}5859long getGlyphImage(long pScalerContext, int glyphCode) {60throw new InternalError("Not implemented");61}6263Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext,64int glyphCode) {65throw new InternalError("Not implemented");66}6768GeneralPath getGlyphOutline(long pScalerContext, int glyphCode,69float x, float y) {70throw new InternalError("Not implemented");71}7273GeneralPath getGlyphVectorOutline(long pScalerContext,74int[] glyphs, int numGlyphs,75float x, float y) {76throw new InternalError("Not implemented");77}7879@Override80protected byte[] getTableBytes(int tag) {81return getTableBytesNative(getNativeFontPtr(), tag);82}8384private native byte[] getTableBytesNative(long nativeFontPtr, int tag);8586private static native long createNativeFont(final String nativeFontName,87final int style);88private static native void disposeNativeFont(final long nativeFontPtr);8990private boolean isFakeItalic;91private String nativeFontName;92private long nativeFontPtr;9394private native float getWidthNative(final long nativeFontPtr);95private native float getWeightNative(final long nativeFontPtr);9697private int fontWidth = -1;98private int fontWeight = -1;99100@Override101public int getWidth() {102if (fontWidth == -1) {103// Apple use a range of -1 -> +1, where 0.0 is normal104// OpenType uses a % range from 50% -> 200% where 100% is normal105// and maps these onto the integer values 1->9.106// Since that is what Font2D.getWidth() expects, remap to that.107float fw = getWidthNative(getNativeFontPtr());108if (fw == 0.0) { // short cut the common case109fontWidth = Font2D.FWIDTH_NORMAL;110return fontWidth;111}112fw += 1.0; fw *= 100.0;113if (fw <= 50.0) {114fontWidth = 1;115} else if (fw <= 62.5) {116fontWidth = 2;117} else if (fw <= 75.0) {118fontWidth = 3;119} else if (fw <= 87.5) {120fontWidth = 4;121} else if (fw <= 100.0) {122fontWidth = 5;123} else if (fw <= 112.5) {124fontWidth = 6;125} else if (fw <= 125.0) {126fontWidth = 7;127} else if (fw <= 150.0) {128fontWidth = 8;129} else {130fontWidth = 9;131}132}133return fontWidth;134}135136@Override137public int getWeight() {138if (fontWeight == -1) {139// Apple use a range of -1 -> +1, where 0 is medium/regular140// Map this on to the OpenType range of 100->900 where141// 500 is medium/regular.142// We'll actually map to 0->1000 but that's close enough.143float fw = getWeightNative(getNativeFontPtr());144if (fw == 0) {145return Font2D.FWEIGHT_NORMAL;146}147fw += 1.0; fw *= 500;148fontWeight = (int)fw;149}150return fontWeight;151}152153// this constructor is called from CFontWrapper.m154public CFont(String name) {155this(name, name);156}157158public CFont(String name, String inFamilyName) {159handle = new Font2DHandle(this);160fullName = name;161familyName = inFamilyName;162nativeFontName = fullName;163setStyle();164}165166/* Called from CFontManager too */167public CFont(CFont other, String logicalFamilyName) {168handle = new Font2DHandle(this);169fullName = logicalFamilyName;170familyName = logicalFamilyName;171nativeFontName = other.nativeFontName;172style = other.style;173isFakeItalic = other.isFakeItalic;174}175176public CFont createItalicVariant() {177CFont font = new CFont(this, familyName);178font.nativeFontName = fullName;179font.fullName =180fullName + (style == Font.BOLD ? "" : "-") + "Italic-Derived";181font.style |= Font.ITALIC;182font.isFakeItalic = true;183return font;184}185186protected synchronized long getNativeFontPtr() {187if (nativeFontPtr == 0L) {188nativeFontPtr = createNativeFont(nativeFontName, style);189}190return nativeFontPtr;191}192193private native long getCGFontPtrNative(long ptr);194195// This digs the CGFont out of the AWTFont.196protected synchronized long getPlatformNativeFontPtr() {197return getCGFontPtrNative(getNativeFontPtr());198}199200static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);201202private CompositeFont createCompositeFont() {203ArrayList<String> listOfString = new ArrayList<String>();204getCascadeList(nativeFontPtr, listOfString);205206// In some italic cases the standard Mac cascade list is missing Arabic.207listOfString.add("GeezaPro");208FontManager fm = FontManagerFactory.getInstance();209int numFonts = 1 + listOfString.size();210PhysicalFont[] fonts = new PhysicalFont[numFonts];211fonts[0] = this;212int idx = 1;213if (FontUtilities.isLogging()) {214FontUtilities.logInfo("Cascading list for " + this + " :");215}216for (String s : listOfString) {217if (FontUtilities.isLogging()) {218FontUtilities.logInfo("Fallback:" + s);219}220if (s.equals(".AppleSymbolsFB")) {221// Don't know why we get the weird name above .. replace.222s = "AppleSymbols";223}224Font2D f2d = fm.findFont2D(s, Font.PLAIN, FontManager.NO_FALLBACK);225if (f2d == null || f2d == this) {226continue;227}228fonts[idx++] = (PhysicalFont)f2d;229}230if (idx < fonts.length) {231PhysicalFont[] orig = fonts;232fonts = new PhysicalFont[idx];233System.arraycopy(orig, 0, fonts, 0, idx);234}235CompositeFont compFont = new CompositeFont(fonts);236compFont.mapper = new CCompositeGlyphMapper(compFont);237return compFont;238}239240private CompositeFont compFont;241242public CompositeFont getCompositeFont2D() {243if (compFont == null) {244compFont = createCompositeFont();245}246return compFont;247}248249@SuppressWarnings("deprecation")250protected synchronized void finalize() {251if (nativeFontPtr != 0) {252disposeNativeFont(nativeFontPtr);253}254nativeFontPtr = 0;255}256257protected CharToGlyphMapper getMapper() {258if (mapper == null) {259mapper = new CCharToGlyphMapper(this);260}261return mapper;262}263264protected FontStrike createStrike(FontStrikeDesc desc) {265if (isFakeItalic) {266desc = new FontStrikeDesc(desc);267desc.glyphTx.concatenate(AffineTransform.getShearInstance(-0.2, 0));268}269return new CStrike(this, desc);270}271272// <rdar://problem/5321707> sun.font.Font2D caches the last used strike,273// but does not check if the properties of the strike match the properties274// of the incoming java.awt.Font object (size, style, etc).275// Simple answer: don't cache.276private static FontRenderContext DEFAULT_FRC =277new FontRenderContext(null, false, false);278public FontStrike getStrike(final Font font) {279return getStrike(font, DEFAULT_FRC);280}281282public boolean equals(Object o) {283if (!super.equals(o)) {284return false;285}286287return ((Font2D)o).getStyle() == this.getStyle();288}289290public int hashCode() {291return super.hashCode() ^ this.getStyle();292}293294public String toString() {295return "CFont { fullName: " + fullName +296", familyName: " + familyName + ", style: " + style +297" } aka: " + super.toString();298}299}300301302