mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-09 14:38:42 +00:00
221 lines
7.2 KiB
Java
221 lines
7.2 KiB
Java
/*
|
|
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
package sun.font;
|
|
|
|
import java.io.*;
|
|
|
|
/**
|
|
* Stores glyph-related data, used in the pure-java glyphcache.
|
|
*
|
|
* @author Clemens Eisserer
|
|
*/
|
|
|
|
public class XRGlyphCacheEntry {
|
|
long glyphInfoPtr;
|
|
|
|
int lastUsed;
|
|
boolean pinned;
|
|
|
|
int xOff;
|
|
int yOff;
|
|
|
|
int glyphSet;
|
|
|
|
public XRGlyphCacheEntry(long glyphInfoPtr, GlyphList gl) {
|
|
this.glyphInfoPtr = glyphInfoPtr;
|
|
|
|
/* TODO: Does it make sence to cache results? */
|
|
xOff = Math.round(getXAdvance());
|
|
yOff = Math.round(getYAdvance());
|
|
}
|
|
|
|
public int getXOff() {
|
|
return xOff;
|
|
}
|
|
|
|
public int getYOff() {
|
|
return yOff;
|
|
}
|
|
|
|
public void setGlyphSet(int glyphSet) {
|
|
this.glyphSet = glyphSet;
|
|
}
|
|
|
|
public int getGlyphSet() {
|
|
return glyphSet;
|
|
}
|
|
|
|
public static int getGlyphID(long glyphInfoPtr) {
|
|
// We need to access the GlyphID with Unsafe.getAddress() because the
|
|
// corresponding field in the underlying C data-structure is of type
|
|
// 'void*' (see field 'cellInfo' of struct 'GlyphInfo'
|
|
// in src/share/native/sun/font/fontscalerdefs.h).
|
|
// On 64-bit Big-endian architectures it would be wrong to access this
|
|
// field with Unsafe.getInt().
|
|
return (int) StrikeCache.unsafe.getAddress(glyphInfoPtr +
|
|
StrikeCache.cacheCellOffset);
|
|
}
|
|
|
|
public static void setGlyphID(long glyphInfoPtr, int id) {
|
|
// We need to access the GlyphID with Unsafe.putAddress() because the
|
|
// corresponding field in the underlying C data-structure is of type
|
|
// 'void*' (see field 'cellInfo' of struct 'GlyphInfo' in
|
|
// src/share/native/sun/font/fontscalerdefs.h).
|
|
// On 64-bit Big-endian architectures it would be wrong to write this
|
|
// field with Unsafe.putInt() because it is also accessed from native
|
|
// code as a 'long'.
|
|
// See Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative()
|
|
// in src/solaris/native/sun/java2d/x11/XRBackendNative.c
|
|
StrikeCache.unsafe.putAddress(glyphInfoPtr +
|
|
StrikeCache.cacheCellOffset, (long)id);
|
|
}
|
|
|
|
public int getGlyphID() {
|
|
return getGlyphID(glyphInfoPtr);
|
|
}
|
|
|
|
public void setGlyphID(int id) {
|
|
setGlyphID(glyphInfoPtr, id);
|
|
}
|
|
|
|
public float getXAdvance() {
|
|
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.xAdvanceOffset);
|
|
}
|
|
|
|
public float getYAdvance() {
|
|
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.yAdvanceOffset);
|
|
}
|
|
|
|
public int getSourceRowBytes() {
|
|
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.rowBytesOffset);
|
|
}
|
|
|
|
public int getWidth() {
|
|
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.widthOffset);
|
|
}
|
|
|
|
public int getHeight() {
|
|
return StrikeCache.unsafe.getShort(glyphInfoPtr + StrikeCache.heightOffset);
|
|
}
|
|
|
|
public void writePixelData(ByteArrayOutputStream os, boolean uploadAsLCD) {
|
|
long pixelDataAddress =
|
|
StrikeCache.unsafe.getAddress(glyphInfoPtr +
|
|
StrikeCache.pixelDataOffset);
|
|
if (pixelDataAddress == 0L) {
|
|
return;
|
|
}
|
|
|
|
int width = getWidth();
|
|
int height = getHeight();
|
|
int rowBytes = getSourceRowBytes();
|
|
int paddedWidth = getPaddedWidth(uploadAsLCD);
|
|
|
|
if (!uploadAsLCD) {
|
|
for (int line = 0; line < height; line++) {
|
|
for(int x = 0; x < paddedWidth; x++) {
|
|
if(x < width) {
|
|
os.write(StrikeCache.unsafe.getByte(pixelDataAddress + (line * rowBytes + x)));
|
|
}else {
|
|
/*pad to multiple of 4 bytes per line*/
|
|
os.write(0);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (int line = 0; line < height; line++) {
|
|
int rowStart = line * rowBytes;
|
|
int rowBytesWidth = width * 3;
|
|
int srcpix = 0;
|
|
while (srcpix < rowBytesWidth) {
|
|
os.write(StrikeCache.unsafe.getByte
|
|
(pixelDataAddress + (rowStart + srcpix + 2)));
|
|
os.write(StrikeCache.unsafe.getByte
|
|
(pixelDataAddress + (rowStart + srcpix + 1)));
|
|
os.write(StrikeCache.unsafe.getByte
|
|
(pixelDataAddress + (rowStart + srcpix + 0)));
|
|
os.write(255);
|
|
srcpix += 3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public float getTopLeftXOffset() {
|
|
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftXOffset);
|
|
}
|
|
|
|
public float getTopLeftYOffset() {
|
|
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftYOffset);
|
|
}
|
|
|
|
public long getGlyphInfoPtr() {
|
|
return glyphInfoPtr;
|
|
}
|
|
|
|
public boolean isGrayscale(boolean listContainsLCDGlyphs) {
|
|
return getSourceRowBytes() == getWidth() && !(getWidth() == 0 && getHeight() == 0 && listContainsLCDGlyphs);
|
|
}
|
|
|
|
public int getPaddedWidth(boolean listContainsLCDGlyphs) {
|
|
int width = getWidth();
|
|
return isGrayscale(listContainsLCDGlyphs) ? (int) Math.ceil(width / 4.0) * 4 : width;
|
|
}
|
|
|
|
public int getDestinationRowBytes(boolean listContainsLCDGlyphs) {
|
|
boolean grayscale = isGrayscale(listContainsLCDGlyphs);
|
|
return grayscale ? getPaddedWidth(grayscale) : getWidth() * 4;
|
|
}
|
|
|
|
public int getGlyphDataLenth(boolean listContainsLCDGlyphs) {
|
|
return getDestinationRowBytes(listContainsLCDGlyphs) * getHeight();
|
|
}
|
|
|
|
public void setPinned() {
|
|
pinned = true;
|
|
}
|
|
|
|
public void setUnpinned() {
|
|
pinned = false;
|
|
}
|
|
|
|
public int getLastUsed() {
|
|
return lastUsed;
|
|
}
|
|
|
|
public void setLastUsed(int lastUsed) {
|
|
this.lastUsed = lastUsed;
|
|
}
|
|
|
|
public int getPixelCnt() {
|
|
return getWidth() * getHeight();
|
|
}
|
|
|
|
public boolean isPinned() {
|
|
return pinned;
|
|
}
|
|
}
|