Path: blob/master/src/java.desktop/share/classes/sun/font/FontStrikeDesc.java
41154 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) {112113if (FontUtilities.isMacOSX14 &&114(aa == VALUE_TEXT_ANTIALIAS_OFF ||115aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||116aa == VALUE_TEXT_ANTIALIAS_ON ||117aa == VALUE_TEXT_ANTIALIAS_GASP))118{119return INTVAL_TEXT_ANTIALIAS_ON;120}121122if (aa == VALUE_TEXT_ANTIALIAS_OFF ||123aa == VALUE_TEXT_ANTIALIAS_DEFAULT) {124return INTVAL_TEXT_ANTIALIAS_OFF;125} else if (aa == VALUE_TEXT_ANTIALIAS_ON) {126return INTVAL_TEXT_ANTIALIAS_ON;127} else if (aa == VALUE_TEXT_ANTIALIAS_GASP) {128if (font2D.useAAForPtSize(ptSize)) {129return INTVAL_TEXT_ANTIALIAS_ON;130} else {131return INTVAL_TEXT_ANTIALIAS_OFF;132}133} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||134aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR) {135return INTVAL_TEXT_ANTIALIAS_LCD_HRGB;136} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB ||137aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR) {138return INTVAL_TEXT_ANTIALIAS_LCD_VRGB;139} else {140return INTVAL_TEXT_ANTIALIAS_OFF;141}142}143144/* This maps a public text AA hint value into one of the subset of values145* used to index strikes. For the purpose of the strike cache there are146* only 4 values : OFF, ON, LCD_HRGB, LCD_VRGB.147* Font and FontRenderContext are needed to resolve the 'gasp' table.148* This is similar to the method above, but used by callers which have not149* already calculated the glyph device point size.150*/151public static int getAAHintIntVal(Font2D font2D, Font font,152FontRenderContext frc) {153Object aa = frc.getAntiAliasingHint();154155if (FontUtilities.isMacOSX14 &&156(aa == VALUE_TEXT_ANTIALIAS_OFF ||157aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||158aa == VALUE_TEXT_ANTIALIAS_ON ||159aa == VALUE_TEXT_ANTIALIAS_GASP))160{161return INTVAL_TEXT_ANTIALIAS_ON;162}163164if (aa == VALUE_TEXT_ANTIALIAS_OFF ||165aa == VALUE_TEXT_ANTIALIAS_DEFAULT) {166return INTVAL_TEXT_ANTIALIAS_OFF;167} else if (aa == VALUE_TEXT_ANTIALIAS_ON) {168return INTVAL_TEXT_ANTIALIAS_ON;169} else if (aa == VALUE_TEXT_ANTIALIAS_GASP) {170/* FRC.isIdentity() would have been useful */171int ptSize;172AffineTransform tx = frc.getTransform();173if (tx.isIdentity() && !font.isTransformed()) {174ptSize = font.getSize();175} else {176/* one or both transforms is not identity */177float size = font.getSize2D();178if (tx.isIdentity()) {179tx = font.getTransform();180tx.scale(size, size);181} else {182tx.scale(size, size);183if (font.isTransformed()) {184tx.concatenate(font.getTransform());185}186}187double shearx = tx.getShearX();188double scaley = tx.getScaleY();189if (shearx != 0) {190scaley = Math.sqrt(shearx * shearx + scaley * scaley);191}192ptSize = (int)(Math.abs(scaley)+0.5);193}194if (font2D.useAAForPtSize(ptSize)) {195return INTVAL_TEXT_ANTIALIAS_ON;196} else {197return INTVAL_TEXT_ANTIALIAS_OFF;198}199} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||200aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR) {201return INTVAL_TEXT_ANTIALIAS_LCD_HRGB;202} else if (aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB ||203aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR) {204return INTVAL_TEXT_ANTIALIAS_LCD_VRGB;205} else {206return INTVAL_TEXT_ANTIALIAS_OFF;207}208}209210public static int getFMHintIntVal(Object fm) {211if (fm == VALUE_FRACTIONALMETRICS_OFF ||212fm == VALUE_FRACTIONALMETRICS_DEFAULT) {213return INTVAL_FRACTIONALMETRICS_OFF;214} else {215return INTVAL_FRACTIONALMETRICS_ON;216}217}218219public FontStrikeDesc(AffineTransform devAt, AffineTransform at,220int fStyle, int aa, int fm) {221devTx = devAt;222glyphTx = at; // not cloning glyphTx. Callers trusted to not mutate it.223style = fStyle;224aaHint = aa;225fmHint = fm;226valuemask = fStyle;227switch (aa) {228case INTVAL_TEXT_ANTIALIAS_OFF :229break;230case INTVAL_TEXT_ANTIALIAS_ON :231valuemask |= AA_ON;232break;233case INTVAL_TEXT_ANTIALIAS_LCD_HRGB :234case INTVAL_TEXT_ANTIALIAS_LCD_HBGR :235valuemask |= AA_LCD_H;236break;237case INTVAL_TEXT_ANTIALIAS_LCD_VRGB :238case INTVAL_TEXT_ANTIALIAS_LCD_VBGR :239valuemask |= AA_LCD_V;240break;241default: break;242}243if (fm == INTVAL_FRACTIONALMETRICS_ON) {244valuemask |= FRAC_METRICS_ON;245}246}247248FontStrikeDesc(FontStrikeDesc desc) {249devTx = desc.devTx;250// Clone the TX in this case as this is called when its known251// that "desc" is being re-used by its creator.252glyphTx = (AffineTransform)desc.glyphTx.clone();253style = desc.style;254aaHint = desc.aaHint;255fmHint = desc.fmHint;256hashCode = desc.hashCode;257valuemask = desc.valuemask;258}259260261public String toString() {262return "FontStrikeDesc: Style="+style+ " AA="+aaHint+ " FM="+fmHint+263" devTx="+devTx+ " devTx.FontTx.ptSize="+glyphTx;264}265}266267268