Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/font/XRGlyphCacheEntry.java
32287 views
/*1* Copyright (c) 2010, 2013, 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.io.*;2829/**30* Stores glyph-related data, used in the pure-java glyphcache.31*32* @author Clemens Eisserer33*/3435public class XRGlyphCacheEntry {36long glyphInfoPtr;3738int lastUsed;39boolean pinned;4041int xOff;42int yOff;4344int glyphSet;4546public XRGlyphCacheEntry(long glyphInfoPtr, GlyphList gl) {47this.glyphInfoPtr = glyphInfoPtr;4849/* TODO: Does it make sence to cache results? */50xOff = (int) Math.round(getXAdvance());51yOff = (int) Math.round(getYAdvance());52}5354public int getXOff() {55return xOff;56}5758public int getYOff() {59return yOff;60}6162public void setGlyphSet(int glyphSet) {63this.glyphSet = glyphSet;64}6566public int getGlyphSet() {67return glyphSet;68}6970public static int getGlyphID(long glyphInfoPtr) {71// We need to access the GlyphID with Unsafe.getAddress() because the72// corresponding field in the underlying C data-structure is of type73// 'void*' (see field 'cellInfo' of struct 'GlyphInfo'74// in src/share/native/sun/font/fontscalerdefs.h).75// On 64-bit Big-endian architectures it would be wrong to access this76// field with Unsafe.getInt().77return (int) StrikeCache.unsafe.getAddress(glyphInfoPtr +78StrikeCache.cacheCellOffset);79}8081public static void setGlyphID(long glyphInfoPtr, int id) {82// We need to access the GlyphID with Unsafe.putAddress() because the83// corresponding field in the underlying C data-structure is of type84// 'void*' (see field 'cellInfo' of struct 'GlyphInfo' in85// src/share/native/sun/font/fontscalerdefs.h).86// On 64-bit Big-endian architectures it would be wrong to write this87// field with Unsafe.putInt() because it is also accessed from native88// code as a 'long'.89// See Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative()90// in src/solaris/native/sun/java2d/x11/XRBackendNative.c91StrikeCache.unsafe.putAddress(glyphInfoPtr +92StrikeCache.cacheCellOffset, (long)id);93}9495public int getGlyphID() {96return getGlyphID(glyphInfoPtr);97}9899public void setGlyphID(int id) {100setGlyphID(glyphInfoPtr, id);101}102103public float getXAdvance() {104return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.xAdvanceOffset);105}106107public float getYAdvance() {108return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.yAdvanceOffset);109}110111public int getSourceRowBytes() {112return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.rowBytesOffset);113}114115public int getWidth() {116return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.widthOffset);117}118119public int getHeight() {120return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.heightOffset);121}122123public void writePixelData(ByteArrayOutputStream os, boolean uploadAsLCD) {124long pixelDataAddress =125StrikeCache.unsafe.getAddress(glyphInfoPtr +126StrikeCache.pixelDataOffset);127if (pixelDataAddress == 0L) {128return;129}130131int width = getWidth();132int height = getHeight();133int rowBytes = getSourceRowBytes();134int paddedWidth = getPaddedWidth(uploadAsLCD);135136if (!uploadAsLCD) {137for (int line = 0; line < height; line++) {138for(int x = 0; x < paddedWidth; x++) {139if(x < width) {140os.write(StrikeCache.unsafe.getByte(pixelDataAddress + (line * rowBytes + x)));141}else {142/*pad to multiple of 4 bytes per line*/143os.write(0);144}145}146}147} else {148for (int line = 0; line < height; line++) {149int rowStart = line * rowBytes;150int rowBytesWidth = width * 3;151int srcpix = 0;152while (srcpix < rowBytesWidth) {153os.write(StrikeCache.unsafe.getByte154(pixelDataAddress + (rowStart + srcpix + 2)));155os.write(StrikeCache.unsafe.getByte156(pixelDataAddress + (rowStart + srcpix + 1)));157os.write(StrikeCache.unsafe.getByte158(pixelDataAddress + (rowStart + srcpix + 0)));159os.write(255);160srcpix += 3;161}162}163}164}165166public float getTopLeftXOffset() {167return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftXOffset);168}169170public float getTopLeftYOffset() {171return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftYOffset);172}173174public long getGlyphInfoPtr() {175return glyphInfoPtr;176}177178public boolean isGrayscale(boolean listContainsLCDGlyphs) {179return getSourceRowBytes() == getWidth() && !(getWidth() == 0 && getHeight() == 0 && listContainsLCDGlyphs);180}181182public int getPaddedWidth(boolean listContainsLCDGlyphs) {183int width = getWidth();184return isGrayscale(listContainsLCDGlyphs) ? (int) Math.ceil(width / 4.0) * 4 : width;185}186187public int getDestinationRowBytes(boolean listContainsLCDGlyphs) {188boolean grayscale = isGrayscale(listContainsLCDGlyphs);189return grayscale ? getPaddedWidth(grayscale) : getWidth() * 4;190}191192public int getGlyphDataLenth(boolean listContainsLCDGlyphs) {193return getDestinationRowBytes(listContainsLCDGlyphs) * getHeight();194}195196public void setPinned() {197pinned = true;198}199200public void setUnpinned() {201pinned = false;202}203204public int getLastUsed() {205return lastUsed;206}207208public void setLastUsed(int lastUsed) {209this.lastUsed = lastUsed;210}211212public int getPixelCnt() {213return getWidth() * getHeight();214}215216public boolean isPinned() {217return pinned;218}219}220221222