Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/font/FontStrikeDesc.java
38829 views
/*1* Copyright (c) 2003, 2005, 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 static sun.awt.SunHints.*;3132/*33* This class encapsulates every thing needed that distinguishes a strike.34* It can be used as a key to locate a FontStrike in a Hashmap/cache.35* It is not mutatable, but contains mutatable AffineTransform objects,36* which for performance reasons it does not keep private copies of.37* Therefore code constructing these must pass in transforms it guarantees38* not to mutate.39*/40public class FontStrikeDesc {4142/* Values to use as a mask that is used for faster comparison of43* two strikes using just an int equality test.44* The ones we don't use are listed here but commented out.45* ie style is already built and hint "OFF" values are zero.46* Note that this is used as a strike key and the same strike is used47* for HRGB and HBGR, so only the orientation needed (H or V) is needed48* to construct and distinguish a FontStrikeDesc. The rgb ordering49* needed for rendering is stored in the graphics state.50*/51// static final int STYLE_PLAIN = Font.PLAIN; // 0x000052// static final int STYLE_BOLD = Font.BOLD; // 0x000153// static final int STYLE_ITALIC = Font.ITALIC; // 0x000254// static final int STYLE_BOLDITALIC = Font.BOLD|Font.ITALIC; // 0x000355// static final int AA_OFF = 0x0000;56static final int AA_ON = 0x0010;57static final int AA_LCD_H = 0x0020;58static final int AA_LCD_V = 0x0040;59// static final int FRAC_METRICS_OFF = 0x0000;60static final int FRAC_METRICS_ON = 0x0100;61static final int FRAC_METRICS_SP = 0x0200;6263/* devTx is to get an inverse transform to get user space values64* for metrics. Its not used otherwise, as the glyphTx is the important65* one. But it does mean that a strike representing a 6pt font and identity66* graphics transform is not equal to one for a 12 pt font and 2x scaled67* graphics transform. Its likely to be very rare that this causes68* duplication.69*/70AffineTransform devTx;71AffineTransform glyphTx; // all of ptSize, Font tx and Graphics tx.72int style;73int aaHint;74int fmHint;75private int hashCode;76private int valuemask;7778public int hashCode() {79/* Can cache hashcode since a strike(desc) is immutable.*/80if (hashCode == 0) {81hashCode = glyphTx.hashCode() + devTx.hashCode() + valuemask;82}83return hashCode;84}8586public boolean equals(Object obj) {87try {88FontStrikeDesc desc = (FontStrikeDesc)obj;89return (desc.valuemask == this.valuemask &&90desc.glyphTx.equals(this.glyphTx) &&91desc.devTx.equals(this.devTx));92} catch (Exception e) {93/* class cast or NP exceptions should not happen often, if ever,94* and I am hoping that this is faster than an instanceof check.95*/96return false;97}98}99100FontStrikeDesc() {101// used with init102}103104105/* This maps a public text AA hint value into one of the subset of values106* used to index strikes. For the purpose of the strike cache there are107* only 4 values : OFF, ON, LCD_HRGB, LCD_VRGB.108* Font and ptSize are needed to resolve the 'gasp' table. The ptSize109* must therefore include device and font transforms.110*/111public static int getAAHintIntVal(Object aa, Font2D font2D, int ptSize) {112if (aa == VALUE_TEXT_ANTIALIAS_OFF ||113aa == VALUE_TEXT_ANTIALIAS_DEFAULT) {114return INTVAL_TEXT_ANTIALIAS_OFF;115} else if (aa == VALUE_TEXT_ANTIALIAS_ON) {116return INTVAL_TEXT_ANTIALIAS_ON;117} else if (aa == VALUE_TEXT_ANTIALIAS_GASP) {118if (font2D.useAAForPtSize(ptSize)) {119return INTVAL_TEXT_ANTIALIAS_ON;120} else {121return INTVAL_TEXT_ANTIALIAS_OFF;122}123} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||124aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR) {125return INTVAL_TEXT_ANTIALIAS_LCD_HRGB;126} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB ||127aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR) {128return INTVAL_TEXT_ANTIALIAS_LCD_VRGB;129} else {130return INTVAL_TEXT_ANTIALIAS_OFF;131}132}133134/* This maps a public text AA hint value into one of the subset of values135* used to index strikes. For the purpose of the strike cache there are136* only 4 values : OFF, ON, LCD_HRGB, LCD_VRGB.137* Font and FontRenderContext are needed to resolve the 'gasp' table.138* This is similar to the method above, but used by callers which have not139* already calculated the glyph device point size.140*/141public static int getAAHintIntVal(Font2D font2D, Font font,142FontRenderContext frc) {143Object aa = frc.getAntiAliasingHint();144if (aa == VALUE_TEXT_ANTIALIAS_OFF ||145aa == VALUE_TEXT_ANTIALIAS_DEFAULT) {146return INTVAL_TEXT_ANTIALIAS_OFF;147} else if (aa == VALUE_TEXT_ANTIALIAS_ON) {148return INTVAL_TEXT_ANTIALIAS_ON;149} else if (aa == VALUE_TEXT_ANTIALIAS_GASP) {150/* FRC.isIdentity() would have been useful */151int ptSize;152AffineTransform tx = frc.getTransform();153if (tx.isIdentity() && !font.isTransformed()) {154ptSize = font.getSize();155} else {156/* one or both transforms is not identity */157float size = font.getSize2D();158if (tx.isIdentity()) {159tx = font.getTransform();160tx.scale(size, size);161} else {162tx.scale(size, size);163if (font.isTransformed()) {164tx.concatenate(font.getTransform());165}166}167double shearx = tx.getShearX();168double scaley = tx.getScaleY();169if (shearx != 0) {170scaley = Math.sqrt(shearx * shearx + scaley * scaley);171}172ptSize = (int)(Math.abs(scaley)+0.5);173}174if (font2D.useAAForPtSize(ptSize)) {175return INTVAL_TEXT_ANTIALIAS_ON;176} else {177return INTVAL_TEXT_ANTIALIAS_OFF;178}179} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||180aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR) {181return INTVAL_TEXT_ANTIALIAS_LCD_HRGB;182} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB ||183aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR) {184return INTVAL_TEXT_ANTIALIAS_LCD_VRGB;185} else {186return INTVAL_TEXT_ANTIALIAS_OFF;187}188}189190public static int getFMHintIntVal(Object fm) {191if (fm == VALUE_FRACTIONALMETRICS_OFF ||192fm == VALUE_FRACTIONALMETRICS_DEFAULT) {193return INTVAL_FRACTIONALMETRICS_OFF;194} else {195return INTVAL_FRACTIONALMETRICS_ON;196}197}198199public FontStrikeDesc(AffineTransform devAt, AffineTransform at,200int fStyle, int aa, int fm) {201devTx = devAt;202glyphTx = at; // not cloning glyphTx. Callers trusted to not mutate it.203style = fStyle;204aaHint = aa;205fmHint = fm;206valuemask = fStyle;207switch (aa) {208case INTVAL_TEXT_ANTIALIAS_OFF :209break;210case INTVAL_TEXT_ANTIALIAS_ON :211valuemask |= AA_ON;212break;213case INTVAL_TEXT_ANTIALIAS_LCD_HRGB :214case INTVAL_TEXT_ANTIALIAS_LCD_HBGR :215valuemask |= AA_LCD_H;216break;217case INTVAL_TEXT_ANTIALIAS_LCD_VRGB :218case INTVAL_TEXT_ANTIALIAS_LCD_VBGR :219valuemask |= AA_LCD_V;220break;221default: break;222}223if (fm == INTVAL_FRACTIONALMETRICS_ON) {224valuemask |= FRAC_METRICS_ON;225}226}227228FontStrikeDesc(FontStrikeDesc desc) {229devTx = desc.devTx;230// Clone the TX in this case as this is called when its known231// that "desc" is being re-used by its creator.232glyphTx = (AffineTransform)desc.glyphTx.clone();233style = desc.style;234aaHint = desc.aaHint;235fmHint = desc.fmHint;236hashCode = desc.hashCode;237valuemask = desc.valuemask;238}239240241public String toString() {242return "FontStrikeDesc: Style="+style+ " AA="+aaHint+ " FM="+fmHint+243" devTx="+devTx+ " devTx.FontTx.ptSize="+glyphTx;244}245}246247248