提交 fe2fd819 编写于 作者: L lana

Merge

......@@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
......
......@@ -28,9 +28,8 @@
SUNWprivate_1.1 {
global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
......
......@@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector
BOOL saved = false;
/* Save and restore of graphics context is done before the iteration.
This seems to work using our test case (see bug ID 7158350) so we are restoring it at
the end of the for loop. If we find out that save/restore outside the loop
doesn't work on all cases then we will move the Save/Restore inside the loop.*/
CGContextSaveGState(cgRef);
CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSUInteger i;
......@@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector
}
// reset the font on the context after striking a unicode with CoreText
CGContextRestoreGState(cgRef);
if (saved) {
CGContextRestoreGState(cgRef);
}
}
// Using the Quartz Surface Data context, draw a hot-substituted character run
......
......@@ -37,6 +37,7 @@ package java.awt.color;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
......@@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable {
private static final long serialVersionUID = -3938515861990936766L;
transient long ID;
private transient Profile cmmProfile;
private transient ProfileDeferralInfo deferralInfo;
private transient ProfileActivator profileActivator;
......@@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable {
/**
* Constructs an ICC_Profile object with a given ID.
*/
ICC_Profile(long ID) {
this.ID = ID;
ICC_Profile(Profile p) {
this.cmmProfile = p;
}
......@@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable {
* Frees the resources associated with an ICC_Profile object.
*/
protected void finalize () {
if (ID != 0) {
CMSManager.getModule().freeProfile(ID);
if (cmmProfile != null) {
CMSManager.getModule().freeProfile(cmmProfile);
} else if (profileActivator != null) {
ProfileDeferralMgr.unregisterDeferral(profileActivator);
}
......@@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable {
public static ICC_Profile getInstance(byte[] data) {
ICC_Profile thisProfile;
long theID;
Profile p = null;
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
......@@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable {
ProfileDataVerifier.verify(data);
try {
theID = CMSManager.getModule().loadProfile(data);
p = CMSManager.getModule().loadProfile(data);
} catch (CMMException c) {
throw new IllegalArgumentException("Invalid ICC Profile Data");
}
try {
if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
(getData (theID, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigGrayTRCTag) != null)) {
thisProfile = new ICC_ProfileGray (theID);
if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) &&
(getData (p, icSigMediaWhitePointTag) != null) &&
(getData (p, icSigGrayTRCTag) != null)) {
thisProfile = new ICC_ProfileGray (p);
}
else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
(getData (theID, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigRedColorantTag) != null) &&
(getData (theID, icSigGreenColorantTag) != null) &&
(getData (theID, icSigBlueColorantTag) != null) &&
(getData (theID, icSigRedTRCTag) != null) &&
(getData (theID, icSigGreenTRCTag) != null) &&
(getData (theID, icSigBlueTRCTag) != null)) {
thisProfile = new ICC_ProfileRGB (theID);
else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
(getData (p, icSigMediaWhitePointTag) != null) &&
(getData (p, icSigRedColorantTag) != null) &&
(getData (p, icSigGreenColorantTag) != null) &&
(getData (p, icSigBlueColorantTag) != null) &&
(getData (p, icSigRedTRCTag) != null) &&
(getData (p, icSigGreenTRCTag) != null) &&
(getData (p, icSigBlueTRCTag) != null)) {
thisProfile = new ICC_ProfileRGB (p);
}
else {
thisProfile = new ICC_Profile (theID);
thisProfile = new ICC_Profile (p);
}
} catch (CMMException c) {
thisProfile = new ICC_Profile (theID);
thisProfile = new ICC_Profile (p);
}
return thisProfile;
}
......@@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable {
fileName);
}
try {
ID = CMSManager.getModule().loadProfile(profileData);
cmmProfile = CMSManager.getModule().loadProfile(profileData);
} catch (CMMException c) {
ProfileDataException pde = new
ProfileDataException("Invalid ICC Profile Data" + fileName);
......@@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable {
causing a deferred profile
to be loaded */
}
return getColorSpaceType(ID);
return getColorSpaceType(cmmProfile);
}
static int getColorSpaceType(long profileID) {
static int getColorSpaceType(Profile p) {
byte[] theHeader;
int theColorSpaceSig, theColorSpace;
theHeader = getData(profileID, icSigHead);
theHeader = getData(p, icSigHead);
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
theColorSpace = iccCStoJCS (theColorSpaceSig);
return theColorSpace;
......@@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable {
if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles();
}
return getPCSType(ID);
return getPCSType(cmmProfile);
}
static int getPCSType(long profileID) {
static int getPCSType(Profile p) {
byte[] theHeader;
int thePCSSig, thePCS;
theHeader = getData(profileID, icSigHead);
theHeader = getData(p, icSigHead);
thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
thePCS = iccCStoJCS(thePCSSig);
return thePCS;
......@@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this profile */
profileSize = mdl.getProfileSize(ID);
profileSize = mdl.getProfileSize(cmmProfile);
profileData = new byte [profileSize];
/* get the data for the profile */
mdl.getProfileData(ID, profileData);
mdl.getProfileData(cmmProfile, profileData);
return profileData;
}
......@@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
return getData(ID, tagSignature);
return getData(cmmProfile, tagSignature);
}
static byte[] getData(long profileID, int tagSignature) {
static byte[] getData(Profile p, int tagSignature) {
int tagSize;
byte[] tagData;
......@@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this tag */
tagSize = mdl.getTagSize(profileID, tagSignature);
tagSize = mdl.getTagSize(p, tagSignature);
tagData = new byte[tagSize]; /* get an array for the tag */
/* get the tag's data */
mdl.getTagData(profileID, tagSignature, tagData);
mdl.getTagData(p, tagSignature, tagData);
} catch(CMMException c) {
tagData = null;
}
......@@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
CMSManager.getModule().setTagData(ID, tagSignature, tagData);
CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
}
/**
......
......@@ -35,7 +35,7 @@
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
......@@ -76,8 +76,8 @@ extends ICC_Profile {
/**
* Constructs a new ICC_ProfileGray from a CMM ID.
*/
ICC_ProfileGray(long ID) {
super(ID);
ICC_ProfileGray(Profile p) {
super(p);
}
/**
......
......@@ -35,7 +35,7 @@
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
......@@ -114,8 +114,8 @@ extends ICC_Profile {
* @param ID The CMM ID for the profile.
*
*/
ICC_ProfileRGB(long ID) {
super(ID);
ICC_ProfileRGB(Profile p) {
super(p);
}
/**
......
......@@ -104,53 +104,53 @@ public class CMSManager {
cName = tcmm.getClass().getName();
}
public long loadProfile(byte[] data) {
public Profile loadProfile(byte[] data) {
System.err.print(cName + ".loadProfile");
long profileID = tcmm.loadProfile(data);
System.err.printf("(ID=%x)\n", profileID);
return profileID;
Profile p = tcmm.loadProfile(data);
System.err.printf("(ID=%s)\n", p.toString());
return p;
}
public void freeProfile(long profileID) {
System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
tcmm.freeProfile(profileID);
public void freeProfile(Profile p) {
System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
tcmm.freeProfile(p);
}
public int getProfileSize(long profileID) {
System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
int size = tcmm.getProfileSize(profileID);
public int getProfileSize(Profile p) {
System.err.print(cName + ".getProfileSize(ID=" + p + ")");
int size = tcmm.getProfileSize(p);
System.err.println("=" + size);
return size;
}
public void getProfileData(long profileID, byte[] data) {
System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
public void getProfileData(Profile p, byte[] data) {
System.err.print(cName + ".getProfileData(ID=" + p + ") ");
System.err.println("requested " + data.length + " byte(s)");
tcmm.getProfileData(profileID, data);
tcmm.getProfileData(p, data);
}
public int getTagSize(long profileID, int tagSignature) {
public int getTagSize(Profile p, int tagSignature) {
System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
profileID, signatureToString(tagSignature));
int size = tcmm.getTagSize(profileID, tagSignature);
p, signatureToString(tagSignature));
int size = tcmm.getTagSize(p, tagSignature);
System.err.println("=" + size);
return size;
}
public void getTagData(long profileID, int tagSignature,
public void getTagData(Profile p, int tagSignature,
byte[] data) {
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
profileID, signatureToString(tagSignature));
p, signatureToString(tagSignature));
System.err.println(" requested " + data.length + " byte(s)");
tcmm.getTagData(profileID, tagSignature, data);
tcmm.getTagData(p, tagSignature, data);
}
public void setTagData(long profileID, int tagSignature,
public void setTagData(Profile p, int tagSignature,
byte[] data) {
System.err.print(cName + ".setTagData(ID=" + profileID +
System.err.print(cName + ".setTagData(ID=" + p +
", TagSig=" + tagSignature + ")");
System.err.println(" sending " + data.length + " byte(s)");
tcmm.setTagData(profileID, tagSignature, data);
tcmm.setTagData(p, tagSignature, data);
}
/* methods for creating ColorTransforms */
......
......@@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile;
public interface PCMM {
/* methods invoked from ICC_Profile */
public long loadProfile(byte[] data);
public void freeProfile(long profileID);
public int getProfileSize(long profileID);
public void getProfileData(long profileID, byte[] data);
public void getTagData(long profileID, int tagSignature, byte[] data);
public int getTagSize(long profileID, int tagSignature);
public void setTagData(long profileID, int tagSignature, byte[] data);
public Profile loadProfile(byte[] data);
public void freeProfile(Profile p);
public int getProfileSize(Profile p);
public void getProfileData(Profile p, byte[] data);
public void getTagData(Profile p, int tagSignature, byte[] data);
public int getTagSize(Profile p, int tagSignature);
public void setTagData(Profile p, int tagSignature, byte[] data);
/* methods for creating ColorTransforms */
public ColorTransform createTransform(ICC_Profile profile, int renderType,
......
/*
* Copyright (c) 2013, 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.java2d.cmm;
import java.awt.color.CMMException;
public class Profile {
private final long nativePtr;
protected Profile(long ptr) {
nativePtr = ptr;
}
protected final long getNativePtr() {
if (nativePtr == 0L) {
throw new CMMException("Invalid profile: ptr is null");
}
return nativePtr;
}
}
......@@ -25,96 +25,139 @@
package sun.java2d.cmm.lcms;
import java.awt.color.CMMException;
import java.awt.color.ICC_Profile;
import java.util.Arrays;
import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
@Override
public long loadProfile(byte[] data) {
long id = loadProfileNative(data);
public Profile loadProfile(byte[] data) {
final Object disposerRef = new Object();
if (id != 0L) {
if (profiles == null) {
profiles = new HashMap<>();
}
profiles.put(id, new TagCache(id));
final long ptr = loadProfileNative(data, disposerRef);
if (ptr != 0L) {
return new LCMSProfile(ptr, disposerRef);
}
return id;
return null;
}
private native long loadProfileNative(byte[] data);
private native long loadProfileNative(byte[] data, Object ref);
@Override
public void freeProfile(long profileID) {
TagCache c = profiles.remove(profileID);
if (c != null) {
c.clear();
private LCMSProfile getLcmsProfile(Profile p) {
if (p instanceof LCMSProfile) {
return (LCMSProfile)p;
}
if (profiles.isEmpty()) {
profiles = null;
throw new CMMException("Invalid profile: " + p);
}
@Override
public void freeProfile(Profile p) {
// we use disposer, so this method does nothing
}
@Override
public int getProfileSize(final Profile p) {
synchronized (p) {
return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr());
}
freeProfileNative(profileID);
}
private native void freeProfileNative(long profileID);
private native int getProfileSizeNative(long ptr);
public native synchronized int getProfileSize(long profileID);
@Override
public void getProfileData(final Profile p, byte[] data) {
synchronized (p) {
getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data);
}
}
public native synchronized void getProfileData(long profileID, byte[] data);
private native void getProfileDataNative(long ptr, byte[] data);
@Override
public synchronized int getTagSize(long profileID, int tagSignature) {
TagCache cache = profiles.get(profileID);
public int getTagSize(Profile p, int tagSignature) {
final LCMSProfile profile = getLcmsProfile(p);
if (cache == null) {
cache = new TagCache(profileID);
profiles.put(profileID, cache);
synchronized (profile) {
TagData t = profile.getTag(tagSignature);
return t == null ? 0 : t.getSize();
}
TagData t = cache.getTag(tagSignature);
return t == null ? 0 : t.getSize();
}
private static native byte[] getTagNative(long profileID, int signature);
static native byte[] getTagNative(long profileID, int signature);
@Override
public synchronized void getTagData(long profileID, int tagSignature,
byte[] data)
public void getTagData(Profile p, int tagSignature, byte[] data)
{
TagCache cache = profiles.get(profileID);
if (cache == null) {
cache = new TagCache(profileID);
profiles.put(profileID, cache);
}
final LCMSProfile profile = getLcmsProfile(p);
TagData t = cache.getTag(tagSignature);
if (t != null) {
t.copyDataTo(data);
synchronized (profile) {
TagData t = profile.getTag(tagSignature);
if (t != null) {
t.copyDataTo(data);
}
}
}
@Override
public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
TagCache cache = profiles.get(profileID);
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
final LCMSProfile profile = getLcmsProfile(p);
if (cache != null) {
cache.clear();
synchronized (profile) {
profile.clearTagCache();
// Now we are going to update the profile with new tag data
// In some cases, we may change the pointer to the native
// profile.
//
// If we fail to write tag data for any reason, the old pointer
// should be used.
setTagDataNative(profile.getLcmsPtr(),
tagSignature, data);
}
setTagDataNative(profileID, tagSignature, data);
}
private native synchronized void setTagDataNative(long profileID, int tagSignature,
/**
* Writes supplied data as a tag into the profile.
* Destroys old profile, if new one was successfully
* created.
*
* Returns valid pointer to new profile.
*
* Throws CMMException if operation fails, preserve old profile from
* destruction.
*/
private native void setTagDataNative(long ptr, int tagSignature,
byte[] data);
public static native long getProfileID(ICC_Profile profile);
public synchronized static native LCMSProfile getProfileID(ICC_Profile profile);
/* Helper method used from LCMSColorTransfrom */
static long createTransform(
LCMSProfile[] profiles, int renderType,
int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked,
Object disposerRef)
{
long[] ptrs = new long[profiles.length];
for (int i = 0; i < profiles.length; i++) {
if (profiles[i] == null) throw new CMMException("Unknown profile ID");
ptrs[i] = profiles[i].getLcmsPtr();
}
return createNativeTransform(ptrs, renderType, inFormatter,
isInIntPacked, outFormatter, isOutIntPacked, disposerRef);
}
public static native long createNativeTransform(
private static native long createNativeTransform(
long[] profileIDs, int renderType,
int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked,
......@@ -175,59 +218,4 @@ public class LCMS implements PCMM {
return theLcms;
}
private static class TagData {
private int signature;
private byte[] data;
TagData(int sig, byte[] data) {
this.signature = sig;
this.data = data;
}
int getSize() {
return data.length;
}
byte[] getData() {
return Arrays.copyOf(data, data.length);
}
void copyDataTo(byte[] dst) {
System.arraycopy(data, 0, dst, 0, data.length);
}
int getSignature() {
return signature;
}
}
private static class TagCache {
private long profileID;
private HashMap<Integer, TagData> tags;
TagCache(long id) {
profileID = id;
tags = new HashMap<>();
}
TagData getTag(int sig) {
TagData t = tags.get(sig);
if (t == null) {
byte[] tagData = getTagNative(profileID, sig);
if (tagData != null) {
t = new TagData(sig, tagData);
tags.put(sig, t);
}
}
return t;
}
void clear() {
tags.clear();
}
}
private static HashMap<Long, TagCache> profiles;
}
/*
* Copyright (c) 2013, 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.java2d.cmm.lcms;
import java.awt.color.CMMException;
import java.util.Arrays;
import java.util.HashMap;
import sun.java2d.cmm.Profile;
final class LCMSProfile extends Profile {
private final TagCache tagCache;
private final Object disposerReferent;
LCMSProfile(long ptr, Object ref) {
super(ptr);
disposerReferent = ref;
tagCache = new TagCache(this);
}
final long getLcmsPtr() {
return this.getNativePtr();
}
TagData getTag(int sig) {
return tagCache.getTag(sig);
}
void clearTagCache() {
tagCache.clear();
}
static class TagCache {
final LCMSProfile profile;
private HashMap<Integer, TagData> tags;
TagCache(LCMSProfile p) {
profile = p;
tags = new HashMap<>();
}
TagData getTag(int sig) {
TagData t = tags.get(sig);
if (t == null) {
byte[] tagData = LCMS.getTagNative(profile.getNativePtr(), sig);
if (tagData != null) {
t = new TagData(sig, tagData);
tags.put(sig, t);
}
}
return t;
}
void clear() {
tags.clear();
}
}
static class TagData {
private int signature;
private byte[] data;
TagData(int sig, byte[] data) {
this.signature = sig;
this.data = data;
}
int getSize() {
return data.length;
}
byte[] getData() {
return Arrays.copyOf(data, data.length);
}
void copyDataTo(byte[] dst) {
System.arraycopy(data, 0, dst, 0, data.length);
}
int getSignature() {
return signature;
}
}
}
......@@ -62,7 +62,7 @@ public class LCMSTransform implements ColorTransform {
private boolean isOutIntPacked = false;
ICC_Profile[] profiles;
long [] profileIDs;
LCMSProfile[] lcmsProfiles;
int renderType;
int transformType;
......@@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform {
/* Actually, it is not a complete transform but just part of it */
profiles = new ICC_Profile[1];
profiles[0] = profile;
profileIDs = new long[1];
profileIDs[0] = LCMS.getProfileID(profile);
lcmsProfiles = new LCMSProfile[1];
lcmsProfiles[0] = LCMS.getProfileID(profile);
this.renderType = (renderType == ColorTransform.Any)?
ICC_Profile.icPerceptual : renderType;
this.transformType = transformType;
......@@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform {
size+=((LCMSTransform)transforms[i]).profiles.length;
}
profiles = new ICC_Profile[size];
profileIDs = new long[size];
lcmsProfiles = new LCMSProfile[size];
int j = 0;
for (int i=0; i < transforms.length; i++) {
LCMSTransform curTrans = (LCMSTransform)transforms[i];
System.arraycopy(curTrans.profiles, 0, profiles, j,
curTrans.profiles.length);
System.arraycopy(curTrans.profileIDs, 0, profileIDs, j,
curTrans.profileIDs.length);
System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
curTrans.lcmsProfiles.length);
j += curTrans.profiles.length;
}
renderType = ((LCMSTransform)transforms[0]).renderType;
......@@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform {
outFormatter = out.pixelType;
isOutIntPacked = out.isIntPacked;
ID = LCMS.createNativeTransform(profileIDs, renderType,
ID = LCMS.createTransform(lcmsProfiles, renderType,
inFormatter, isInIntPacked,
outFormatter, isOutIntPacked,
disposerReferent);
......
/*
* Copyright (c) 2013, 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.print;
import java.awt.Window;
import java.awt.print.PrinterJob;
import javax.print.PrintService;
import javax.print.ServiceUIFactory;
import javax.print.attribute.PrintRequestAttributeSet;
public abstract class DocumentPropertiesUI {
/**
* For Win32 doc properties sheet.
*/
public static final int
DOCUMENTPROPERTIES_ROLE = ServiceUIFactory.RESERVED_UIROLE +100;
/**
* Name of (this) abstract class for Document Properties.
*/
public static final String
DOCPROPERTIESCLASSNAME = DocumentPropertiesUI.class.getName();
/**
* Invokes whatever code is needed to display a native dialog
* with the specified owner. The owner should be the cross-platform
* dialog. If the user cancels the dialog the return value is null.
* A non-null return value is always a new attribute set (or is it?)
* The cross-platform dialog may need to be updated to reflect the
* updated properties.
*/
public abstract PrintRequestAttributeSet
showDocumentProperties(PrinterJob job,
Window owner,
PrintService service,
PrintRequestAttributeSet aset);
}
/*
* Copyright (c) 2013, 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.print;
import java.awt.print.PrinterJob;
import javax.print.attribute.PrintRequestAttribute;
public class PrinterJobWrapper implements PrintRequestAttribute {
private static final long serialVersionUID = -8792124426995707237L;
private PrinterJob job;
public PrinterJobWrapper(PrinterJob job) {
this.job = job;
}
public PrinterJob getPrinterJob() {
return job;
}
public final Class getCategory() {
return PrinterJobWrapper.class;
}
public final String getName() {
return "printerjob-wrapper";
}
public String toString() {
return "printerjob-wrapper: " + job.toString();
}
public int hashCode() {
return job.hashCode();
}
}
......@@ -903,6 +903,9 @@ public abstract class RasterPrinterJob extends PrinterJob {
int x = bounds.x+bounds.width/3;
int y = bounds.y+bounds.height/3;
PrintService newService;
// temporarily add an attribute pointing back to this job.
PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this);
attributes.add(jobWrapper);
try {
newService =
ServiceUI.printDialog(gc, x, y,
......@@ -915,6 +918,7 @@ public abstract class RasterPrinterJob extends PrinterJob {
DocFlavor.SERVICE_FORMATTED.PAGEABLE,
attributes);
}
attributes.remove(PrinterJobWrapper.class);
if (newService == null) {
return false;
......
......@@ -46,6 +46,7 @@ import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
......@@ -119,8 +120,6 @@ public class ServiceDialog extends JDialog implements ActionListener {
private AppearancePanel pnlAppearance;
private boolean isAWT = false;
static {
initResource();
}
......@@ -801,9 +800,32 @@ public class ServiceDialog extends JDialog implements ActionListener {
if (dialog != null) {
dialog.show();
} else {
// REMIND: may want to notify the user why we're
// disabling the button
btnProperties.setEnabled(false);
DocumentPropertiesUI docPropertiesUI = null;
try {
docPropertiesUI =
(DocumentPropertiesUI)uiFactory.getUI
(DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE,
DocumentPropertiesUI.DOCPROPERTIESCLASSNAME);
} catch (Exception ex) {
}
if (docPropertiesUI != null) {
PrinterJobWrapper wrapper = (PrinterJobWrapper)
asCurrent.get(PrinterJobWrapper.class);
if (wrapper == null) {
return; // should not happen, defensive only.
}
PrinterJob job = wrapper.getPrinterJob();
if (job == null) {
return; // should not happen, defensive only.
}
PrintRequestAttributeSet newAttrs =
docPropertiesUI.showDocumentProperties
(job, ServiceDialog.this, psCurrent, asCurrent);
if (newAttrs != null) {
asCurrent.addAll(newAttrs);
updatePanels();
}
}
}
}
}
......
......@@ -930,9 +930,10 @@ imageio_fill_input_buffer(j_decompress_ptr cinfo)
* Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end.
*/
RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
input,
JPEGImageReader_readInputDataID,
......@@ -1017,9 +1018,11 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo)
memcpy(sb->buf, src->next_input_byte, offset);
}
GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input);
buflen = sb->bufferLength - offset;
if (buflen <= 0) {
if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
......@@ -1121,9 +1124,10 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
return;
}
RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
input,
JPEGImageReader_skipInputBytesID,
......@@ -2306,10 +2310,10 @@ imageio_empty_output_buffer (j_compress_ptr cinfo)
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject output = NULL;
GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
GET_IO_REF(output);
(*env)->CallVoidMethod(env,
output,
JPEGImageWriter_writeOutputDataID,
......@@ -2348,10 +2352,10 @@ imageio_term_destination (j_compress_ptr cinfo)
if (datacount != 0) {
jobject output = NULL;
GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
GET_IO_REF(output);
(*env)->CallVoidMethod(env,
output,
JPEGImageWriter_writeOutputDataID,
......
......@@ -179,6 +179,10 @@ JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_nativeLayout
FontInstanceAdapter fia(env, font2d, strike, mat, 72, 72, (le_int32) upem, (TTLayoutTableCache *) layoutTables);
LEErrorCode success = LE_NO_ERROR;
LayoutEngine *engine = LayoutEngine::layoutEngineFactory(&fia, script, lang, typo_flags & TYPO_MASK, success);
if (engine == NULL) {
env->SetIntField(gvdata, gvdCountFID, -1); // flag failure
return;
}
if (min < 0) min = 0; if (max < min) max = min; /* defensive coding */
// have to copy, yuck, since code does upcalls now. this will be soooo slow
......
......@@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value)
# endif
#endif
typedef union storeID_s { /* store SProfile stuff in a Java Long */
typedef struct lcmsProfile_s {
cmsHPROFILE pf;
} lcmsProfile_t, *lcmsProfile_p;
typedef union storeID_s { /* store SProfile stuff in a Java Long */
lcmsProfile_p lcmsPf;
cmsHTRANSFORM xf;
jobject jobj;
jlong j;
......@@ -106,7 +110,6 @@ typedef union {
jint j;
} TagSignature_t, *TagSignature_p;
static jfieldID Trans_profileIDs_fID;
static jfieldID Trans_renderType_fID;
static jfieldID Trans_ID_fID;
static jfieldID IL_isIntPacked_fID;
......@@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
static jfieldID IL_imageAtOnce_fID;
static jfieldID PF_ID_fID;
JavaVM *javaVM;
......@@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
return JNI_VERSION_1_6;
}
void LCMS_freeProfile(JNIEnv *env, jlong ptr) {
storeID_t sProfile;
sProfile.j = ptr;
if (sProfile.lcmsPf != NULL) {
if (sProfile.lcmsPf->pf != NULL) {
cmsCloseProfile(sProfile.lcmsPf->pf);
}
free(sProfile.lcmsPf);
}
}
void LCMS_freeTransform(JNIEnv *env, jlong ID)
{
storeID_t sTrans;
......@@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
jlong* ids;
size = (*env)->GetArrayLength (env, profileIDs);
ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0);
ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
#ifdef _LITTLE_ENDIAN
/* Reversing data packed into int for LE archs */
......@@ -186,6 +200,8 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
iccArray = (cmsHPROFILE*) malloc(
size*2*sizeof(cmsHPROFILE));
if (iccArray == NULL) {
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
return 0L;
}
......@@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
cmsColorSpaceSignature cs;
sTrans.j = ids[i];
icc = sTrans.pf;
icc = sTrans.lcmsPf->pf;
iccArray[j++] = icc;
/* Middle non-abstract profiles should be doubled before passing to
......@@ -215,13 +231,15 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j,
inFormatter, outFormatter, renderType, 0);
(*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0);
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
if (sTrans.xf == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
"sTrans.xf == NULL");
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot get color transform");
if ((*env)->ExceptionOccurred(env) == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot get color transform");
}
} else {
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
}
......@@ -236,20 +254,23 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: loadProfile
* Signature: ([B)J
* Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
*/
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
(JNIEnv *env, jobject obj, jbyteArray data)
(JNIEnv *env, jobject obj, jbyteArray data, jobject disposerRef)
{
jbyte* dataArray;
jint dataSize;
storeID_t sProf;
cmsHPROFILE pf;
if (JNU_IsNull(env, data)) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
return 0L;
}
sProf.j = 0L;
dataArray = (*env)->GetByteArrayElements (env, data, 0);
dataSize = (*env)->GetArrayLength (env, data);
......@@ -258,61 +279,56 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
return 0L;
}
sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
pf = cmsOpenProfileFromMem((const void *)dataArray,
(cmsUInt32Number) dataSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
if (sProf.pf == NULL) {
if (pf == NULL) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
} else {
/* Sanity check: try to save the profile in order
* to force basic validation.
*/
cmsUInt32Number pfSize = 0;
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) ||
if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
pfSize < sizeof(cmsICCHeader))
{
JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
cmsCloseProfile(pf);
pf = NULL;
}
}
return sProf.j;
}
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: freeProfile
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
(JNIEnv *env, jobject obj, jlong id)
{
storeID_t sProf;
sProf.j = id;
if (cmsCloseProfile(sProf.pf) == 0) {
J2dRlsTraceLn1(J2D_TRACE_ERROR, "LCMS_freeProfile: cmsCloseProfile(%d)"
"== 0", id);
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot close profile");
if (pf != NULL) {
// create profile holder
sProf.lcmsPf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t));
if (sProf.lcmsPf != NULL) {
// register the disposer record
sProf.lcmsPf->pf = pf;
Disposer_AddRecord(env, disposerRef, LCMS_freeProfile, sProf.j);
} else {
cmsCloseProfile(pf);
}
}
return sProf.j;
}
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileSize
* Method: getProfileSizeNative
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative
(JNIEnv *env, jobject obj, jlong id)
{
storeID_t sProf;
cmsUInt32Number pfSize = 0;
sProf.j = id;
if (cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
if (cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize) && ((jint)pfSize > 0)) {
return (jint)pfSize;
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
......@@ -323,10 +339,10 @@ JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileData
* Method: getProfileDataNative
* Signature: (J[B)V
*/
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative
(JNIEnv *env, jobject obj, jlong id, jbyteArray data)
{
storeID_t sProf;
......@@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
sProf.j = id;
// determine actual profile size
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) {
if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not access specified profile.");
return;
......@@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
dataArray = (*env)->GetByteArrayElements (env, data, 0);
status = cmsSaveProfileToMem(sProf.pf, dataArray, &pfSize);
status = cmsSaveProfileToMem(sProf.lcmsPf->pf, dataArray, &pfSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
......@@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
/* Get profile header info */
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
static cmsHPROFILE _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
/*
......@@ -412,7 +428,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return NULL;
}
status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
......@@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return data;
}
if (cmsIsTag(sProf.pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0);
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found");
......@@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return NULL;
}
bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
bufSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
......@@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
storeID_t sProf;
cmsHPROFILE pfReplace = NULL;
TagSignature_t sig;
cmsBool status;
cmsBool status = FALSE;
jbyte* dataArray;
int tagSize;
......@@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
}
if (tagSig == SigHead) {
status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize);
} else {
status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize);
/*
* New strategy for generic tags: create a place holder,
* dump all existing tags there, dump externally supplied
* tag, and return the new profile to the java.
*/
pfReplace = _writeCookedTag(sProf.lcmsPf->pf, sig.cms, dataArray, tagSize);
status = (pfReplace != NULL);
}
(*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
if (!status) {
JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
} else if (pfReplace != NULL) {
cmsCloseProfile(sProf.lcmsPf->pf);
sProf.lcmsPf->pf = pfReplace;
}
}
......@@ -624,12 +651,27 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileID
* Signature: (Ljava/awt/color/ICC_Profile;)J
* Signature: (Ljava/awt/color/ICC_Profile;)Lsun/java2d/cmm/lcms/LCMSProfile
*/
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
JNIEXPORT jobject JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileID
(JNIEnv *env, jclass cls, jobject pf)
{
return (*env)->GetLongField (env, pf, PF_ID_fID);
jfieldID fid = (*env)->GetFieldID (env,
(*env)->GetObjectClass(env, pf),
"cmmProfile", "Lsun/java2d/cmm/Profile;");
jclass clsLcmsProfile = (*env)->FindClass(env,
"sun/java2d/cmm/lcms/LCMSProfile");
jobject cmmProfile = (*env)->GetObjectField (env, pf, fid);
if (JNU_IsNull(env, cmmProfile)) {
return NULL;
}
if ((*env)->IsInstanceOf(env, cmmProfile, clsLcmsProfile)) {
return cmmProfile;
}
return NULL;
}
/*
......@@ -644,7 +686,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
* corresponding classes to avoid problems with invalidating ids by class
* unloading
*/
Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
......@@ -658,8 +699,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
}
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
......@@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
return TRUE;
}
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
cmsTagSignature sig,
/* Returns new profile handler, if it was created successfully,
NULL otherwise.
*/
static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
const cmsTagSignature sig,
jbyte *pData, jint size)
{
cmsBool status;
cmsUInt32Number pfSize = 0;
cmsUInt8Number* pfBuffer = NULL;
const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
cmsInt32Number i;
cmsHPROFILE pfSanity = NULL;
cmsICCHeader hdr = { 0 };
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
if (NULL != p) {
cmsICCHeader hdr = { 0 };
/* Populate the placeholder's header according to target profile */
hdr.flags = cmsGetHeaderFlags(pfTarget);
hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
hdr.model = cmsGetHeaderModel(pfTarget);
hdr.pcs = cmsGetPCS(pfTarget);
hdr.colorSpace = cmsGetColorSpace(pfTarget);
hdr.deviceClass = cmsGetDeviceClass(pfTarget);
hdr.version = cmsGetEncodedICCversion(pfTarget);
cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
cmsSetHeaderFlags(p, hdr.flags);
cmsSetHeaderManufacturer(p, hdr.manufacturer);
cmsSetHeaderModel(p, hdr.model);
cmsSetHeaderAttributes(p, hdr.attributes);
cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
cmsSetPCS(p, hdr.pcs);
cmsSetColorSpace(p, hdr.colorSpace);
cmsSetDeviceClass(p, hdr.deviceClass);
cmsSetEncodedICCversion(p, hdr.version);
if (cmsWriteRawTag(p, sig, pData, size)) {
if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
pfBuffer = malloc(pfSize);
if (pfBuffer != NULL) {
/* load raw profile data into the buffer */
if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) {
free(pfBuffer);
pfBuffer = NULL;
}
if (NULL == p) {
return NULL;
}
// Populate the placeholder's header according to target profile
hdr.flags = cmsGetHeaderFlags(pfTarget);
hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
hdr.model = cmsGetHeaderModel(pfTarget);
hdr.pcs = cmsGetPCS(pfTarget);
hdr.colorSpace = cmsGetColorSpace(pfTarget);
hdr.deviceClass = cmsGetDeviceClass(pfTarget);
hdr.version = cmsGetEncodedICCversion(pfTarget);
cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
cmsSetHeaderFlags(p, hdr.flags);
cmsSetHeaderManufacturer(p, hdr.manufacturer);
cmsSetHeaderModel(p, hdr.model);
cmsSetHeaderAttributes(p, hdr.attributes);
cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
cmsSetPCS(p, hdr.pcs);
cmsSetColorSpace(p, hdr.colorSpace);
cmsSetDeviceClass(p, hdr.deviceClass);
cmsSetEncodedICCversion(p, hdr.version);
// now write the user supplied tag
if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
cmsCloseProfile(p);
return NULL;
}
// copy tags from the original profile
for (i = 0; i < tagCount; i++) {
cmsBool isTagReady = FALSE;
const cmsTagSignature s = cmsGetTagSignature(pfTarget, i);
const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);
if (s == sig) {
// skip the user supplied tag
continue;
}
// read raw tag from the original profile
if (tagSize > 0) {
cmsUInt8Number* buf = (cmsUInt8Number*)malloc(tagSize);
if (buf != NULL) {
if (tagSize == cmsReadRawTag(pfTarget, s, buf, tagSize)) {
// now we are ready to write the tag
isTagReady = cmsWriteRawTag(p, s, buf, tagSize);
}
free(buf);
}
}
cmsCloseProfile(p);
}
if (pfBuffer == NULL) {
return FALSE;
if (!isTagReady) {
cmsCloseProfile(p);
return NULL;
}
}
/* re-open the placeholder profile */
p = cmsOpenProfileFromMem(pfBuffer, pfSize);
free(pfBuffer);
status = FALSE;
if (p != NULL) {
/* Note that pCookedTag points to internal structures of the placeholder,
* so this data is valid only while the placeholder is open.
*/
void *pCookedTag = cmsReadTag(p, sig);
if (pCookedTag != NULL) {
status = cmsWriteTag(pfTarget, sig, pCookedTag);
// now we have all tags moved to the new profile.
// do some sanity checks: write it to a memory buffer and read again.
if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
void* buf = malloc(pfSize);
if (buf != NULL) {
// load raw profile data into the buffer
if (cmsSaveProfileToMem(p, buf, &pfSize)) {
pfSanity = cmsOpenProfileFromMem(buf, pfSize);
}
free(buf);
}
pCookedTag = NULL;
}
if (pfSanity == NULL) {
// for some reason, we failed to save and read the updated profile
// It likely indicates that the profile is not correct, so we report
// a failure here.
cmsCloseProfile(p);
p = NULL;
} else {
// do final check whether we can read and handle the the target tag.
const void* pTag = cmsReadTag(pfSanity, sig);
if (pTag == NULL) {
// the tag can not be cooked
cmsCloseProfile(p);
p = NULL;
}
cmsCloseProfile(pfSanity);
pfSanity = NULL;
}
return status;
return p;
}
......@@ -142,7 +142,7 @@ public class XRTextRenderer extends GlyphListPipe {
}
int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8;
maskBuffer.compositeText(x11sd.picture, 0, maskFormat, eltList);
maskBuffer.compositeText(x11sd, (int) gl.getX(), (int) gl.getY(), 0, maskFormat, eltList);
eltList.clear();
} finally {
......
......@@ -267,8 +267,9 @@ public class XRBackendNative implements XRBackend {
private static native void
XRenderCompositeTextNative(int op, int src, int dst,
long maskFormat, int[] eltArray,
int[] glyphIDs, int eltCnt, int glyphCnt);
int srcX, int srcY, long maskFormat,
int[] eltArray, int[] glyphIDs, int eltCnt,
int glyphCnt);
public int XRenderCreateGlyphSet(int formatID) {
return XRenderCreateGlyphSetNative(getFormatPtr(formatID));
......@@ -278,11 +279,11 @@ public class XRBackendNative implements XRBackend {
public void XRenderCompositeText(byte op, int src, int dst,
int maskFormatID,
int src2, int src3, int dst2, int dst3,
int sx, int sy, int dx, int dy,
int glyphset, GrowableEltArray elts) {
GrowableIntArray glyphs = elts.getGlyphs();
XRenderCompositeTextNative(op, src, dst, 0, elts.getArray(),
XRenderCompositeTextNative(op, src, dst, sx, sy, 0, elts.getArray(),
glyphs.getArray(), elts.getSize(),
glyphs.getSize());
}
......
......@@ -285,7 +285,12 @@ public class XRCompositeManager {
if (xorEnabled) {
con.GCRectangles(dst.getXid(), dst.getGC(), rects);
} else {
con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
if (rects.getSize() == 1) {
con.renderRectangle(dst.getPicture(), compRule, solidColor,
rects.getX(0), rects.getY(0), rects.getWidth(0), rects.getHeight(0));
} else {
con.renderRectangles(dst.getPicture(), compRule, solidColor, rects);
}
}
}
......@@ -295,10 +300,10 @@ public class XRCompositeManager {
sy, 0, 0, dx, dy, w, h);
}
public void compositeText(int dst, int glyphSet, int maskFormat,
GrowableEltArray elts) {
con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0,
0, 0, glyphSet, elts);
public void compositeText(XRSurfaceData dst, int sx, int sy,
int glyphSet, int maskFormat, GrowableEltArray elts) {
con.XRenderCompositeText(compRule, src.picture, dst.picture,
maskFormat, sx, sy, 0, 0, glyphSet, elts);
}
public XRColor getMaskColor() {
......
......@@ -225,6 +225,9 @@ class XRPMScaledBlit extends ScaledBlit {
* @author Clemens Eisserer
*/
class XRPMTransformedBlit extends TransformBlit {
final Rectangle compositeBounds = new Rectangle();
final double[] srcCoords = new double[8];
final double[] dstCoords = new double[8];
public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
super(srcType, CompositeType.AnyAlpha, dstType);
......@@ -235,61 +238,68 @@ class XRPMTransformedBlit extends TransformBlit {
* method is functionally equal to: Shape shp =
* xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
* but performs significantly better.
* Returns true if the destination shape is parallel to x/y axis
*/
public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
double[] compBounds = new double[8];
compBounds[0] = dstx;
compBounds[1] = dsty;
compBounds[2] = dstx + width;
compBounds[3] = dsty;
compBounds[4] = dstx + width;
compBounds[5] = dsty + height;
compBounds[6] = dstx;
compBounds[7] = dsty + height;
tr.transform(compBounds, 0, compBounds, 0, 4);
double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
minX = Math.floor(minX);
minY = Math.floor(minY);
maxX = Math.ceil(maxX);
maxY = Math.ceil(maxY);
return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));
protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
srcCoords[0] = dstx;
srcCoords[1] = dsty;
srcCoords[2] = dstx + width;
srcCoords[3] = dsty;
srcCoords[4] = dstx + width;
srcCoords[5] = dsty + height;
srcCoords[6] = dstx;
srcCoords[7] = dsty + height;
tr.transform(srcCoords, 0, dstCoords, 0, 4);
double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
minX = Math.round(minX);
minY = Math.round(minY);
maxX = Math.round(maxX);
maxY = Math.round(maxY);
compositeBounds.x = (int) minX;
compositeBounds.y = (int) minY;
compositeBounds.width = (int) (maxX - minX);
compositeBounds.height = (int) (maxY - minY);
boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]);
boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]);
return is0or180 || is90or270;
}
public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
int dstx, int dsty, int width, int height) {
public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
try {
SunToolkit.awtLock();
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
int filter = XRUtils.ATransOpToXRQuality(hint);
boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
x11sdDst.validateAsDestination(null, clip);
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
trx.concatenate(xform);
AffineTransform maskTX = (AffineTransform) trx.clone();
trx.translate(-srcx, -srcy);
try {
trx.invert();
} catch (NoninvertibleTransformException ex) {
trx.setToIdentity();
System.err.println("Reseted to identity!");
}
boolean omitMask = isMaskOmittable(trx, comp, filter);
boolean omitMask = (filter == XRUtils.FAST)
|| (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
if (!omitMask) {
XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
......@@ -297,33 +307,17 @@ class XRPMTransformedBlit extends TransformBlit {
x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
} else {
int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
x11sdSrc.validateAsSource(trx, repeat, filter);
x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
}
} finally {
SunToolkit.awtUnlock();
}
}
/* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
* If
* translate
* is
* integer
* only
*/
&& trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
// 90 degree
// rotation
|| trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
// ExtraAlpha!=1
}
}
class XrSwToPMBlit extends Blit {
......
......@@ -911,8 +911,9 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative
JNIEXPORT void JNICALL
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
(JNIEnv *env, jclass cls, jint op, jint src, jint dst, jlong maskFmt,
jintArray eltArray, jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
(JNIEnv *env, jclass cls, jint op, jint src, jint dst,
jint sx, jint sy, jlong maskFmt, jintArray eltArray,
jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
jint i;
jint *ids;
jint *elts;
......@@ -991,7 +992,7 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst,
(XRenderPictFormat *) jlong_to_ptr(maskFmt),
0, 0, 0, 0, xelts, eltCnt);
sx, sy, 0, 0, xelts, eltCnt);
(*env)->ReleasePrimitiveArrayCritical(env, glyphIDArray, ids, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT);
......
......@@ -179,6 +179,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
private static final int SET_RES_LOW = 0x00000080;
private static final int SET_COLOR = 0x00000200;
private static final int SET_ORIENTATION = 0x00004000;
private static final int SET_COLLATED = 0x00008000;
/**
* Values must match those defined in wingdi.h & commdlg.h
......@@ -189,10 +190,33 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
private static final int PD_NOSELECTION = 0x00000004;
private static final int PD_COLLATE = 0x00000010;
private static final int PD_PRINTTOFILE = 0x00000020;
private static final int DM_ORIENTATION = 0x00000001;
private static final int DM_PRINTQUALITY = 0x00000400;
private static final int DM_COLOR = 0x00000800;
private static final int DM_DUPLEX = 0x00001000;
private static final int DM_ORIENTATION = 0x00000001;
private static final int DM_PAPERSIZE = 0x00000002;
private static final int DM_COPIES = 0x00000100;
private static final int DM_DEFAULTSOURCE = 0x00000200;
private static final int DM_PRINTQUALITY = 0x00000400;
private static final int DM_COLOR = 0x00000800;
private static final int DM_DUPLEX = 0x00001000;
private static final int DM_YRESOLUTION = 0x00002000;
private static final int DM_COLLATE = 0x00008000;
private static final short DMCOLLATE_FALSE = 0;
private static final short DMCOLLATE_TRUE = 1;
private static final short DMORIENT_PORTRAIT = 1;
private static final short DMORIENT_LANDSCAPE = 2;
private static final short DMCOLOR_MONOCHROME = 1;
private static final short DMCOLOR_COLOR = 2;
private static final short DMRES_DRAFT = -1;
private static final short DMRES_LOW = -2;
private static final short DMRES_MEDIUM = -3;
private static final short DMRES_HIGH = -4;
private static final short DMDUP_SIMPLEX = 1;
private static final short DMDUP_VERTICAL = 2;
private static final short DMDUP_HORIZONTAL = 3;
/**
* Pageable MAX pages
......@@ -592,13 +616,23 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
}
driverDoesMultipleCopies = false;
driverDoesCollation = false;
setNativePrintService(service.getName());
setNativePrintServiceIfNeeded(service.getName());
}
/* associates this job with the specified native service */
private native void setNativePrintService(String name)
throws PrinterException;
private String lastNativeService = null;
private void setNativePrintServiceIfNeeded(String name)
throws PrinterException {
if (name != null && !(name.equals(lastNativeService))) {
setNativePrintService(name);
lastNativeService = name;
}
}
public PrintService getPrintService() {
if (myService == null) {
String printerName = getNativePrintService();
......@@ -616,7 +650,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
myService = PrintServiceLookup.lookupDefaultPrintService();
if (myService != null) {
try {
setNativePrintService(myService.getName());
setNativePrintServiceIfNeeded(myService.getName());
} catch (Exception e) {
myService = null;
}
......@@ -1754,8 +1788,13 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
mAttMediaSizeName = ((Win32PrintService)myService).findPaperID(msn);
}
private void setWin32MediaAttrib(int dmIndex, int width, int length) {
MediaSizeName msn =
private void addPaperSize(PrintRequestAttributeSet aset,
int dmIndex, int width, int length) {
if (aset == null) {
return;
}
MediaSizeName msn =
((Win32PrintService)myService).findWin32Media(dmIndex);
if (msn == null) {
msn = ((Win32PrintService)myService).
......@@ -1763,10 +1802,12 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
}
if (msn != null) {
if (attributes != null) {
attributes.add(msn);
}
aset.add(msn);
}
}
private void setWin32MediaAttrib(int dmIndex, int width, int length) {
addPaperSize(attributes, dmIndex, width, length);
mAttMediaSizeName = dmIndex;
}
......@@ -1788,7 +1829,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
// no equivalent predefined value
mAttMediaTray = 7; // DMBIN_AUTO
} else if (attr == MediaTray.TOP) {
mAttMediaTray =1; // DMBIN_UPPER
mAttMediaTray = 1; // DMBIN_UPPER
} else {
if (attr instanceof Win32MediaTray) {
mAttMediaTray = ((Win32MediaTray)attr).winID;
......@@ -1914,6 +1955,254 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
}
}
private static final class DevModeValues {
int dmFields;
short copies;
short collate;
short color;
short duplex;
short orient;
short paper;
short bin;
short xres_quality;
short yres;
}
private void getDevModeValues(PrintRequestAttributeSet aset,
DevModeValues info) {
Copies c = (Copies)aset.get(Copies.class);
if (c != null) {
info.dmFields |= DM_COPIES;
info.copies = (short)c.getValue();
}
SheetCollate sc = (SheetCollate)aset.get(SheetCollate.class);
if (sc != null) {
info.dmFields |= DM_COLLATE;
info.collate = (sc == SheetCollate.COLLATED) ?
DMCOLLATE_TRUE : DMCOLLATE_FALSE;
}
Chromaticity ch = (Chromaticity)aset.get(Chromaticity.class);
if (ch != null) {
info.dmFields |= DM_COLOR;
if (ch == Chromaticity.COLOR) {
info.color = DMCOLOR_COLOR;
} else {
info.color = DMCOLOR_MONOCHROME;
}
}
Sides s = (Sides)aset.get(Sides.class);
if (s != null) {
info.dmFields |= DM_DUPLEX;
if (s == Sides.TWO_SIDED_LONG_EDGE) {
info.duplex = DMDUP_VERTICAL;
} else if (s == Sides.TWO_SIDED_SHORT_EDGE) {
info.duplex = DMDUP_HORIZONTAL;
} else { // Sides.ONE_SIDED
info.duplex = DMDUP_SIMPLEX;
}
}
OrientationRequested or =
(OrientationRequested)aset.get(OrientationRequested.class);
if (or != null) {
info.dmFields |= DM_ORIENTATION;
info.orient = (or == OrientationRequested.LANDSCAPE)
? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
}
Media m = (Media)aset.get(Media.class);
if (m instanceof MediaSizeName) {
info.dmFields |= DM_PAPERSIZE;
MediaSizeName msn = (MediaSizeName)m;
info.paper =
(short)((Win32PrintService)myService).findPaperID(msn);
}
MediaTray mt = null;
if (m instanceof MediaTray) {
mt = (MediaTray)m;
}
if (mt == null) {
SunAlternateMedia sam =
(SunAlternateMedia)aset.get(SunAlternateMedia.class);
if (sam != null && (sam.getMedia() instanceof MediaTray)) {
mt = (MediaTray)sam.getMedia();
}
}
if (mt != null) {
info.dmFields |= DM_DEFAULTSOURCE;
info.bin = (short)(((Win32PrintService)myService).findTrayID(mt));
}
PrintQuality q = (PrintQuality)aset.get(PrintQuality.class);
if (q != null) {
info.dmFields |= DM_PRINTQUALITY;
if (q == PrintQuality.DRAFT) {
info.xres_quality = DMRES_DRAFT;
} else if (q == PrintQuality.HIGH) {
info.xres_quality = DMRES_HIGH;
} else {
info.xres_quality = DMRES_MEDIUM;
}
}
PrinterResolution r =
(PrinterResolution)aset.get(PrinterResolution.class);
if (r != null) {
info.dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION;
info.xres_quality =
(short)r.getCrossFeedResolution(PrinterResolution.DPI);
info.yres = (short)r.getFeedResolution(PrinterResolution.DPI);
}
}
/* This method is called from native to update the values in the
* attribute set which originates from the cross-platform dialog,
* but updated by the native DocumentPropertiesUI which updates the
* devmode. This syncs the devmode back in to the attributes so that
* we can update the cross-platform dialog.
* The attribute set here is a temporary one installed whilst this
* happens,
*/
private final void setJobAttributes(PrintRequestAttributeSet attributes,
int fields, int values,
short copies,
short dmPaperSize,
short dmPaperWidth,
short dmPaperLength,
short dmDefaultSource,
short xRes,
short yRes) {
if (attributes == null) {
return;
}
if ((fields & DM_COPIES) != 0) {
attributes.add(new Copies(copies));
}
if ((fields & DM_COLLATE) != 0) {
if ((values & SET_COLLATED) != 0) {
attributes.add(SheetCollate.COLLATED);
} else {
attributes.add(SheetCollate.UNCOLLATED);
}
}
if ((fields & DM_ORIENTATION) != 0) {
if ((values & SET_ORIENTATION) != 0) {
attributes.add(OrientationRequested.LANDSCAPE);
} else {
attributes.add(OrientationRequested.PORTRAIT);
}
}
if ((fields & DM_COLOR) != 0) {
if ((values & SET_COLOR) != 0) {
attributes.add(Chromaticity.COLOR);
} else {
attributes.add(Chromaticity.MONOCHROME);
}
}
if ((fields & DM_PRINTQUALITY) != 0) {
/* value < 0 indicates quality setting.
* value > 0 indicates X resolution. In that case
* hopefully we will also find y-resolution specified.
* If its not, assume its the same as x-res.
* Maybe Java code should try to reconcile this against
* the printers claimed set of supported resolutions.
*/
if (xRes < 0) {
PrintQuality quality;
if ((values & SET_RES_LOW) != 0) {
quality = PrintQuality.DRAFT;
} else if ((fields & SET_RES_HIGH) != 0) {
quality = PrintQuality.HIGH;
} else {
quality = PrintQuality.NORMAL;
}
attributes.add(quality);
} else if (xRes > 0 && yRes > 0) {
attributes.add(
new PrinterResolution(xRes, yRes, PrinterResolution.DPI));
}
}
if ((fields & DM_DUPLEX) != 0) {
Sides sides;
if ((values & SET_DUP_VERTICAL) != 0) {
sides = Sides.TWO_SIDED_LONG_EDGE;
} else if ((values & SET_DUP_HORIZONTAL) != 0) {
sides = Sides.TWO_SIDED_SHORT_EDGE;
} else {
sides = Sides.ONE_SIDED;
}
attributes.add(sides);
}
if ((fields & DM_PAPERSIZE) != 0) {
addPaperSize(attributes, dmPaperSize, dmPaperWidth, dmPaperLength);
}
if ((fields & DM_DEFAULTSOURCE) != 0) {
MediaTray tray =
((Win32PrintService)myService).findMediaTray(dmDefaultSource);
attributes.add(new SunAlternateMedia(tray));
}
}
private native boolean showDocProperties(long hWnd,
PrintRequestAttributeSet aset,
int dmFields,
short copies,
short collate,
short color,
short duplex,
short orient,
short paper,
short bin,
short xres_quality,
short yres);
@SuppressWarnings("deprecation")
public PrintRequestAttributeSet
showDocumentProperties(Window owner,
PrintService service,
PrintRequestAttributeSet aset)
{
try {
setNativePrintServiceIfNeeded(service.getName());
} catch (PrinterException e) {
}
long hWnd = ((WWindowPeer)(owner.getPeer())).getHWnd();
DevModeValues info = new DevModeValues();
getDevModeValues(aset, info);
boolean ok =
showDocProperties(hWnd, aset,
info.dmFields,
info.copies,
info.collate,
info.color,
info.duplex,
info.orient,
info.paper,
info.bin,
info.xres_quality,
info.yres);
if (ok) {
return aset;
} else {
return null;
}
}
/* Printer Resolution. See also getXRes() and getYRes() */
private final void setResolutionDPI(int xres, int yres) {
......@@ -1956,7 +2245,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
}
//** END Functions called by native code for querying/updating attributes
}
}
class PrintToFileErrorDialog extends Dialog implements ActionListener{
public PrintToFileErrorDialog(Frame parent, String title, String message,
......
......@@ -70,6 +70,10 @@ public class Win32MediaTray extends MediaTray {
winEnumTable.add(this);
}
public int getDMBinID() {
return winID;
}
private static final String[] myStringTable ={
"Manual-Envelope",
"Automatic-Feeder",
......
......@@ -25,6 +25,8 @@
package sun.print;
import java.awt.Window;
import java.awt.print.PrinterJob;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
......@@ -39,6 +41,7 @@ import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
......@@ -69,6 +72,7 @@ import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener;
import sun.awt.windows.WPrinterJob;
public class Win32PrintService implements PrintService, AttributeUpdater,
SunPrinterJobService {
......@@ -282,6 +286,22 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
return 0;
}
public int findTrayID(MediaTray tray) {
getMediaTrays(); // make sure they are initialised.
if (tray instanceof Win32MediaTray) {
Win32MediaTray winTray = (Win32MediaTray)tray;
return winTray.getDMBinID();
}
for (int id=0; id<dmPaperBinToPrintService.length; id++) {
if (tray.equals(dmPaperBinToPrintService[id])) {
return id+1; // DMBIN_FIRST = 1;
}
}
return 0; // didn't find the tray
}
public MediaTray findMediaTray(int dmBin) {
if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
return dmPaperBinToPrintService[dmBin-1];
......@@ -673,7 +693,6 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
return arr2;
}
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
if (getJobStatus(printer, 2) != 1) {
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
......@@ -1596,8 +1615,76 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
}
}
public ServiceUIFactory getServiceUIFactory() {
return null;
private Win32DocumentPropertiesUI docPropertiesUI = null;
private static class Win32DocumentPropertiesUI
extends DocumentPropertiesUI {
Win32PrintService service;
private Win32DocumentPropertiesUI(Win32PrintService s) {
service = s;
}
public PrintRequestAttributeSet
showDocumentProperties(PrinterJob job,
Window owner,
PrintService service,
PrintRequestAttributeSet aset) {
if (!(job instanceof WPrinterJob)) {
return null;
}
WPrinterJob wJob = (WPrinterJob)job;
return wJob.showDocumentProperties(owner, service, aset);
}
}
private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {
return new Win32DocumentPropertiesUI(this);
}
private static class Win32ServiceUIFactory extends ServiceUIFactory {
Win32PrintService service;
Win32ServiceUIFactory(Win32PrintService s) {
service = s;
}
public Object getUI(int role, String ui) {
if (role <= ServiceUIFactory.MAIN_UIROLE) {
return null;
}
if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&
DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))
{
return service.getDocumentPropertiesUI();
}
throw new IllegalArgumentException("Unsupported role");
}
public String[] getUIClassNamesForRole(int role) {
if (role <= ServiceUIFactory.MAIN_UIROLE) {
return null;
}
if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {
String[] names = new String[0];
names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;
return names;
}
throw new IllegalArgumentException("Unsupported role");
}
}
private Win32ServiceUIFactory uiFactory = null;
public synchronized ServiceUIFactory getServiceUIFactory() {
if (uiFactory == null) {
uiFactory = new Win32ServiceUIFactory(this);
}
return uiFactory;
}
public String toString() {
......
......@@ -81,6 +81,7 @@ jmethodID AwtPrintControl::setToPageID;
jmethodID AwtPrintControl::setNativeAttID;
jmethodID AwtPrintControl::setRangeCopiesID;
jmethodID AwtPrintControl::setResID;
jmethodID AwtPrintControl::setJobAttributesID;
BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
......@@ -297,6 +298,10 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls)
AwtPrintControl::setPrinterID =
env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V");
AwtPrintControl::setJobAttributesID =
env->GetMethodID(cls, "setJobAttributes",
"(Ljavax/print/attribute/PrintRequestAttributeSet;IISSSSSSS)V");
DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL);
DASSERT(AwtPrintControl::getPrintDCID != NULL);
DASSERT(AwtPrintControl::setPrintDCID != NULL);
......@@ -327,6 +332,7 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtPrintControl::getSidesID != NULL);
DASSERT(AwtPrintControl::getSelectID != NULL);
DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL);
DASSERT(AwtPrintControl::setJobAttributesID != NULL);
CATCH_BAD_ALLOC;
......
......@@ -47,7 +47,6 @@ public:
static jmethodID setDevmodeID;
static jmethodID getDevnamesID;
static jmethodID setDevnamesID;
static jmethodID getWin32MediaID;
static jmethodID setWin32MediaID;
static jmethodID getWin32MediaTrayID;
......@@ -73,6 +72,7 @@ public:
static jmethodID setNativeAttID;
static jmethodID setRangeCopiesID;
static jmethodID setResID;
static jmethodID setJobAttributesID;
static void initIDs(JNIEnv *env, jclass cls);
static BOOL FindPrinter(jstring printerName, LPBYTE pPrinterEnum,
......
......@@ -329,6 +329,156 @@ static int CALLBACK fontEnumProcA(ENUMLOGFONTEXA *logfont,
static int embolden(int currentWeight);
static BOOL getPrintableArea(HDC pdc, HANDLE hDevMode, RectDouble *margin);
/************************************************************************
* DocumentProperties native support
*/
/* Values must match those defined in WPrinterJob.java */
static const DWORD SET_COLOR = 0x00000200;
static const DWORD SET_ORIENTATION = 0x00004000;
static const DWORD SET_COLLATED = 0x00008000;
static const DWORD SET_DUP_VERTICAL = 0x00000010;
static const DWORD SET_DUP_HORIZONTAL = 0x00000020;
static const DWORD SET_RES_HIGH = 0x00000040;
static const DWORD SET_RES_LOW = 0x00000080;
/*
* Copy DEVMODE state back into JobAttributes.
*/
static void UpdateJobAttributes(JNIEnv *env,
jobject wJob,
jobject attrSet,
DEVMODE *devmode) {
DWORD dmValues = 0;
int xRes = 0, yRes = 0;
if (devmode->dmFields & DM_COLOR) {
if (devmode->dmColor == DMCOLOR_COLOR) {
dmValues |= SET_COLOR;
}
}
if (devmode->dmFields & DM_ORIENTATION) {
if (devmode->dmOrientation == DMORIENT_LANDSCAPE) {
dmValues |= SET_ORIENTATION;
}
}
if (devmode->dmFields & DM_COLLATE &&
devmode->dmCollate == DMCOLLATE_TRUE) {
dmValues |= SET_COLLATED;
}
if (devmode->dmFields & DM_PRINTQUALITY) {
/* value < 0 indicates quality setting.
* value > 0 indicates X resolution. In that case
* hopefully we will also find y-resolution specified.
* If its not, assume its the same as x-res.
* Maybe Java code should try to reconcile this against
* the printers claimed set of supported resolutions.
*/
if (devmode->dmPrintQuality < 0) {
if (devmode->dmPrintQuality == DMRES_HIGH) {
dmValues |= SET_RES_HIGH;
} else if ((devmode->dmPrintQuality == DMRES_LOW) ||
(devmode->dmPrintQuality == DMRES_DRAFT)) {
dmValues |= SET_RES_LOW;
}
/* else if (devmode->dmPrintQuality == DMRES_MEDIUM)
* will set to NORMAL.
*/
} else {
xRes = devmode->dmPrintQuality;
yRes = (devmode->dmFields & DM_YRESOLUTION) ?
devmode->dmYResolution : devmode->dmPrintQuality;
}
}
if (devmode->dmFields & DM_DUPLEX) {
if (devmode->dmDuplex == DMDUP_HORIZONTAL) {
dmValues |= SET_DUP_HORIZONTAL;
} else if (devmode->dmDuplex == DMDUP_VERTICAL) {
dmValues |= SET_DUP_VERTICAL;
}
}
env->CallVoidMethod(wJob, AwtPrintControl::setJobAttributesID, attrSet,
devmode->dmFields, dmValues, devmode->dmCopies,
devmode->dmPaperSize, devmode->dmPaperWidth,
devmode->dmPaperLength, devmode->dmDefaultSource,
xRes, yRes);
}
JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_WPrinterJob_showDocProperties(JNIEnv *env,
jobject wJob,
jlong hWndParent,
jobject attrSet,
jint dmFields,
jshort copies,
jshort collate,
jshort color,
jshort duplex,
jshort orient,
jshort paper,
jshort bin,
jshort xres_quality,
jshort yres)
{
TRY;
HGLOBAL hDevMode = AwtPrintControl::getPrintHDMode(env, wJob);
HGLOBAL hDevNames = AwtPrintControl::getPrintHDName(env, wJob);
DEVMODE *devmode = NULL;
DEVNAMES *devnames = NULL;
LONG rval = IDCANCEL;
jboolean ret = JNI_FALSE;
if (hDevMode != NULL && hDevNames != NULL) {
devmode = (DEVMODE *)::GlobalLock(hDevMode);
devnames = (DEVNAMES *)::GlobalLock(hDevNames);
LPTSTR lpdevnames = (LPTSTR)devnames;
// No need to call _tcsdup as we won't unlock until we are done.
LPTSTR printerName = lpdevnames+devnames->wDeviceOffset;
LPTSTR portName = lpdevnames+devnames->wOutputOffset;
HANDLE hPrinter;
if (::OpenPrinter(printerName, &hPrinter, NULL) == TRUE) {
devmode->dmFields |= dmFields;
devmode->dmCopies = copies;
devmode->dmCollate = collate;
devmode->dmColor = color;
devmode->dmDuplex = duplex;
devmode->dmOrientation = orient;
devmode->dmPrintQuality = xres_quality;
devmode->dmYResolution = yres;
devmode->dmPaperSize = paper;
devmode->dmDefaultSource = bin;
rval = ::DocumentProperties((HWND)hWndParent,
hPrinter, printerName, devmode, devmode,
DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
if (rval == IDOK) {
UpdateJobAttributes(env, wJob, attrSet, devmode);
ret = JNI_TRUE;
}
VERIFY(::ClosePrinter(hPrinter));
}
::GlobalUnlock(hDevNames);
::GlobalUnlock(hDevMode);
}
return ret;
CATCH_BAD_ALLOC_RET(0);
}
/************************************************************************
* WPageDialog native methods
*/
......@@ -732,7 +882,6 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self,
memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG);
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
if (::PrintDlg(&pd)) {
printDC = pd.hDC;
hDevMode = pd.hDevMode;
......@@ -792,8 +941,19 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self,
jint imgPixelWid = GetDeviceCaps(printDC, HORZRES);
jint imgPixelHgt = GetDeviceCaps(printDC, VERTRES);
// The DC may be obtained when we first selected the printer as a
// result of a call to setNativePrintService.
// If the Devmode was obtained later on from the DocumentProperties dialog
// the DC won't have been updated and its settings may be for PORTRAIT.
// This may happen in other cases too, but was observed for the above.
// To get a DC compatible with this devmode we should really call
// CreateDC() again to get a DC for the devmode we are using.
// The changes for that are a lot more risk, so to minimise that
// risk, assume its not LANDSCAPE unless width > height, even if the
// devmode says its LANDSCAPE.
// if the values were obtained from a rotated device, swap.
if (getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) {
if ((getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) &&
(imgPixelWid > imgPixelHgt)) {
jint tmp;
tmp = xPixelRes;
xPixelRes = yPixelRes;
......@@ -941,6 +1101,9 @@ Java_sun_awt_windows_WPrinterJob_initPrinter(JNIEnv *env, jobject self) {
setBooleanField(env, self, DRIVER_COLLATE_STR, JNI_FALSE);
}
if (dmFields & DM_COPIES) {
setBooleanField(env, self, DRIVER_COPIES_STR, JNI_TRUE);
}
}
CATCH_BAD_ALLOC;
......
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 8020983
* @bug 8020983 8024697
* @summary Test verifies that jpeg writer instances are collected
* even if destroy() or reset() methods is not invoked.
*
......
/*
* Copyright (c) 2013, 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.
*
* 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.
*/
/**
* @test
* @bug 8024511
* @summary Verifies that instances of color profiles are destroyed correctly.
* A crash during profile destruction indicates failure.
*
* @run main DisposalCrashTest
*/
import static java.awt.color.ColorSpace.*;
import java.awt.color.ICC_Profile;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Vector;
public class DisposalCrashTest {
static final ReferenceQueue<ICC_Profile> queue = new ReferenceQueue<>();
static final Vector<Reference<? extends ICC_Profile>> v = new Vector<>();
public static void main(String[] args) {
int[] ids = new int[]{
CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC
};
for (int id : ids) {
ICC_Profile p = getCopyOf(id);
}
while (!v.isEmpty()) {
System.gc();
System.out.println(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {};
final Reference<? extends ICC_Profile> ref = queue.poll();
System.out.println("Got reference: " + ref);
v.remove(ref);
}
System.out.println("Test PASSED.");
}
private static ICC_Profile getCopyOf(int id) {
ICC_Profile std = ICC_Profile.getInstance(id);
byte[] data = std.getData();
ICC_Profile p = ICC_Profile.getInstance(data);
WeakReference<ICC_Profile> ref = new WeakReference<>(p, queue);
v.add(ref);
return p;
}
}
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 6476665 6523403 6733501 7042594
* @bug 6476665 6523403 6733501 7042594 7043064
* @summary Verifies reading and writing profiles and tags of the standard color
* spaces
* @run main ReadWriteProfileTest
......@@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable {
public void run() {
for (int i = 0; i < cspaces.length; i++) {
System.out.println("Profile: " + csNames[i]);
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData();
pf = ICC_Profile.getInstance(data);
......@@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable {
}
for (int tagSig : tags[i].keySet()) {
String signature = SigToString(tagSig);
System.out.printf("Tag: %s\n", signature);
System.out.flush();
byte [] tagData = pf.getData(tagSig);
byte [] empty = new byte[tagData.length];
boolean emptyDataRejected = false;
......@@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable {
throw new
RuntimeException("Test failed: empty tag data was not rejected.");
}
pf.setData(tagSig, tagData);
try {
pf.setData(tagSig, tagData);
} catch (IllegalArgumentException e) {
// let's ignore this exception for Kodak proprietary tags
if (isKodakExtention(signature)) {
System.out.println("Ignore Kodak tag: " + signature);
} else {
throw new RuntimeException("Test failed!", e);
}
}
byte [] tagData1 = pf.getData(tagSig);
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
{
System.err.println("Incorrect result of getData(int) with" +
" tag " +
Integer.toHexString(tagSig) +
SigToString(tagSig) +
" of " + csNames[i] + " profile");
throw new RuntimeException("Incorrect result of " +
......@@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable {
}
}
private static boolean isKodakExtention(String signature) {
return signature.matches("K\\d\\d\\d");
}
private static String SigToString(int tagSig ) {
return String.format("%c%c%c%c",
(char)(0xff & (tagSig >> 24)),
(char)(0xff & (tagSig >> 16)),
(char)(0xff & (tagSig >> 8)),
(char)(0xff & (tagSig)));
}
public static void main(String [] args) {
ReadWriteProfileTest test = new ReadWriteProfileTest();
test.run();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册