提交 fe2fd819 编写于 作者: L lana

Merge

...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
SUNWprivate_1.1 { SUNWprivate_1.1 {
global: global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
......
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
SUNWprivate_1.1 { SUNWprivate_1.1 {
global: global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
......
...@@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector ...@@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector
BOOL saved = false; 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); CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSUInteger i; NSUInteger i;
...@@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector ...@@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector
} }
// reset the font on the context after striking a unicode with CoreText // 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 // Using the Quartz Surface Data context, draw a hot-substituted character run
......
...@@ -37,6 +37,7 @@ package java.awt.color; ...@@ -37,6 +37,7 @@ package java.awt.color;
import sun.java2d.cmm.PCMM; import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager; import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDataVerifier; import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr; import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo; import sun.java2d.cmm.ProfileDeferralInfo;
...@@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable { ...@@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable {
private static final long serialVersionUID = -3938515861990936766L; private static final long serialVersionUID = -3938515861990936766L;
transient long ID; private transient Profile cmmProfile;
private transient ProfileDeferralInfo deferralInfo; private transient ProfileDeferralInfo deferralInfo;
private transient ProfileActivator profileActivator; private transient ProfileActivator profileActivator;
...@@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable { ...@@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable {
/** /**
* Constructs an ICC_Profile object with a given ID. * Constructs an ICC_Profile object with a given ID.
*/ */
ICC_Profile(long ID) { ICC_Profile(Profile p) {
this.ID = ID; this.cmmProfile = p;
} }
...@@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable { ...@@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable {
* Frees the resources associated with an ICC_Profile object. * Frees the resources associated with an ICC_Profile object.
*/ */
protected void finalize () { protected void finalize () {
if (ID != 0) { if (cmmProfile != null) {
CMSManager.getModule().freeProfile(ID); CMSManager.getModule().freeProfile(cmmProfile);
} else if (profileActivator != null) { } else if (profileActivator != null) {
ProfileDeferralMgr.unregisterDeferral(profileActivator); ProfileDeferralMgr.unregisterDeferral(profileActivator);
} }
...@@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable { ...@@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable {
public static ICC_Profile getInstance(byte[] data) { public static ICC_Profile getInstance(byte[] data) {
ICC_Profile thisProfile; ICC_Profile thisProfile;
long theID; Profile p = null;
if (ProfileDeferralMgr.deferring) { if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles(); ProfileDeferralMgr.activateProfiles();
...@@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable { ...@@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable {
ProfileDataVerifier.verify(data); ProfileDataVerifier.verify(data);
try { try {
theID = CMSManager.getModule().loadProfile(data); p = CMSManager.getModule().loadProfile(data);
} catch (CMMException c) { } catch (CMMException c) {
throw new IllegalArgumentException("Invalid ICC Profile Data"); throw new IllegalArgumentException("Invalid ICC Profile Data");
} }
try { try {
if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) && if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) &&
(getData (theID, icSigMediaWhitePointTag) != null) && (getData (p, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigGrayTRCTag) != null)) { (getData (p, icSigGrayTRCTag) != null)) {
thisProfile = new ICC_ProfileGray (theID); thisProfile = new ICC_ProfileGray (p);
} }
else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) && else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) &&
(getData (theID, icSigMediaWhitePointTag) != null) && (getData (p, icSigMediaWhitePointTag) != null) &&
(getData (theID, icSigRedColorantTag) != null) && (getData (p, icSigRedColorantTag) != null) &&
(getData (theID, icSigGreenColorantTag) != null) && (getData (p, icSigGreenColorantTag) != null) &&
(getData (theID, icSigBlueColorantTag) != null) && (getData (p, icSigBlueColorantTag) != null) &&
(getData (theID, icSigRedTRCTag) != null) && (getData (p, icSigRedTRCTag) != null) &&
(getData (theID, icSigGreenTRCTag) != null) && (getData (p, icSigGreenTRCTag) != null) &&
(getData (theID, icSigBlueTRCTag) != null)) { (getData (p, icSigBlueTRCTag) != null)) {
thisProfile = new ICC_ProfileRGB (theID); thisProfile = new ICC_ProfileRGB (p);
} }
else { else {
thisProfile = new ICC_Profile (theID); thisProfile = new ICC_Profile (p);
} }
} catch (CMMException c) { } catch (CMMException c) {
thisProfile = new ICC_Profile (theID); thisProfile = new ICC_Profile (p);
} }
return thisProfile; return thisProfile;
} }
...@@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable { ...@@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable {
fileName); fileName);
} }
try { try {
ID = CMSManager.getModule().loadProfile(profileData); cmmProfile = CMSManager.getModule().loadProfile(profileData);
} catch (CMMException c) { } catch (CMMException c) {
ProfileDataException pde = new ProfileDataException pde = new
ProfileDataException("Invalid ICC Profile Data" + fileName); ProfileDataException("Invalid ICC Profile Data" + fileName);
...@@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable { ...@@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable {
causing a deferred profile causing a deferred profile
to be loaded */ to be loaded */
} }
return getColorSpaceType(ID); return getColorSpaceType(cmmProfile);
} }
static int getColorSpaceType(long profileID) { static int getColorSpaceType(Profile p) {
byte[] theHeader; byte[] theHeader;
int theColorSpaceSig, theColorSpace; int theColorSpaceSig, theColorSpace;
theHeader = getData(profileID, icSigHead); theHeader = getData(p, icSigHead);
theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace); theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
theColorSpace = iccCStoJCS (theColorSpaceSig); theColorSpace = iccCStoJCS (theColorSpaceSig);
return theColorSpace; return theColorSpace;
...@@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable { ...@@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable {
if (ProfileDeferralMgr.deferring) { if (ProfileDeferralMgr.deferring) {
ProfileDeferralMgr.activateProfiles(); ProfileDeferralMgr.activateProfiles();
} }
return getPCSType(ID); return getPCSType(cmmProfile);
} }
static int getPCSType(long profileID) { static int getPCSType(Profile p) {
byte[] theHeader; byte[] theHeader;
int thePCSSig, thePCS; int thePCSSig, thePCS;
theHeader = getData(profileID, icSigHead); theHeader = getData(p, icSigHead);
thePCSSig = intFromBigEndian(theHeader, icHdrPcs); thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
thePCS = iccCStoJCS(thePCSSig); thePCS = iccCStoJCS(thePCSSig);
return thePCS; return thePCS;
...@@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable { ...@@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule(); PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this profile */ /* get the number of bytes needed for this profile */
profileSize = mdl.getProfileSize(ID); profileSize = mdl.getProfileSize(cmmProfile);
profileData = new byte [profileSize]; profileData = new byte [profileSize];
/* get the data for the profile */ /* get the data for the profile */
mdl.getProfileData(ID, profileData); mdl.getProfileData(cmmProfile, profileData);
return profileData; return profileData;
} }
...@@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable { ...@@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles(); 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; int tagSize;
byte[] tagData; byte[] tagData;
...@@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable { ...@@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable {
PCMM mdl = CMSManager.getModule(); PCMM mdl = CMSManager.getModule();
/* get the number of bytes needed for this tag */ /* 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 */ tagData = new byte[tagSize]; /* get an array for the tag */
/* get the tag's data */ /* get the tag's data */
mdl.getTagData(profileID, tagSignature, tagData); mdl.getTagData(p, tagSignature, tagData);
} catch(CMMException c) { } catch(CMMException c) {
tagData = null; tagData = null;
} }
...@@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable { ...@@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles(); ProfileDeferralMgr.activateProfiles();
} }
CMSManager.getModule().setTagData(ID, tagSignature, tagData); CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData);
} }
/** /**
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
package java.awt.color; package java.awt.color;
import java.awt.image.LookupTable; import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo; import sun.java2d.cmm.ProfileDeferralInfo;
/** /**
...@@ -76,8 +76,8 @@ extends ICC_Profile { ...@@ -76,8 +76,8 @@ extends ICC_Profile {
/** /**
* Constructs a new ICC_ProfileGray from a CMM ID. * Constructs a new ICC_ProfileGray from a CMM ID.
*/ */
ICC_ProfileGray(long ID) { ICC_ProfileGray(Profile p) {
super(ID); super(p);
} }
/** /**
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
package java.awt.color; package java.awt.color;
import java.awt.image.LookupTable; import sun.java2d.cmm.Profile;
import sun.java2d.cmm.ProfileDeferralInfo; import sun.java2d.cmm.ProfileDeferralInfo;
/** /**
...@@ -114,8 +114,8 @@ extends ICC_Profile { ...@@ -114,8 +114,8 @@ extends ICC_Profile {
* @param ID The CMM ID for the profile. * @param ID The CMM ID for the profile.
* *
*/ */
ICC_ProfileRGB(long ID) { ICC_ProfileRGB(Profile p) {
super(ID); super(p);
} }
/** /**
......
...@@ -104,53 +104,53 @@ public class CMSManager { ...@@ -104,53 +104,53 @@ public class CMSManager {
cName = tcmm.getClass().getName(); cName = tcmm.getClass().getName();
} }
public long loadProfile(byte[] data) { public Profile loadProfile(byte[] data) {
System.err.print(cName + ".loadProfile"); System.err.print(cName + ".loadProfile");
long profileID = tcmm.loadProfile(data); Profile p = tcmm.loadProfile(data);
System.err.printf("(ID=%x)\n", profileID); System.err.printf("(ID=%s)\n", p.toString());
return profileID; return p;
} }
public void freeProfile(long profileID) { public void freeProfile(Profile p) {
System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID); System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
tcmm.freeProfile(profileID); tcmm.freeProfile(p);
} }
public int getProfileSize(long profileID) { public int getProfileSize(Profile p) {
System.err.print(cName + ".getProfileSize(ID=" + profileID + ")"); System.err.print(cName + ".getProfileSize(ID=" + p + ")");
int size = tcmm.getProfileSize(profileID); int size = tcmm.getProfileSize(p);
System.err.println("=" + size); System.err.println("=" + size);
return size; return size;
} }
public void getProfileData(long profileID, byte[] data) { public void getProfileData(Profile p, byte[] data) {
System.err.print(cName + ".getProfileData(ID=" + profileID + ") "); System.err.print(cName + ".getProfileData(ID=" + p + ") ");
System.err.println("requested " + data.length + " byte(s)"); 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)", System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
profileID, signatureToString(tagSignature)); p, signatureToString(tagSignature));
int size = tcmm.getTagSize(profileID, tagSignature); int size = tcmm.getTagSize(p, tagSignature);
System.err.println("=" + size); System.err.println("=" + size);
return size; return size;
} }
public void getTagData(long profileID, int tagSignature, public void getTagData(Profile p, int tagSignature,
byte[] data) { byte[] data) {
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)", System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
profileID, signatureToString(tagSignature)); p, signatureToString(tagSignature));
System.err.println(" requested " + data.length + " byte(s)"); 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) { byte[] data) {
System.err.print(cName + ".setTagData(ID=" + profileID + System.err.print(cName + ".setTagData(ID=" + p +
", TagSig=" + tagSignature + ")"); ", TagSig=" + tagSignature + ")");
System.err.println(" sending " + data.length + " byte(s)"); System.err.println(" sending " + data.length + " byte(s)");
tcmm.setTagData(profileID, tagSignature, data); tcmm.setTagData(p, tagSignature, data);
} }
/* methods for creating ColorTransforms */ /* methods for creating ColorTransforms */
......
...@@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile; ...@@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile;
public interface PCMM { public interface PCMM {
/* methods invoked from ICC_Profile */ /* methods invoked from ICC_Profile */
public long loadProfile(byte[] data); public Profile loadProfile(byte[] data);
public void freeProfile(long profileID); public void freeProfile(Profile p);
public int getProfileSize(long profileID); public int getProfileSize(Profile p);
public void getProfileData(long profileID, byte[] data); public void getProfileData(Profile p, byte[] data);
public void getTagData(long profileID, int tagSignature, byte[] data); public void getTagData(Profile p, int tagSignature, byte[] data);
public int getTagSize(long profileID, int tagSignature); public int getTagSize(Profile p, int tagSignature);
public void setTagData(long profileID, int tagSignature, byte[] data); public void setTagData(Profile p, int tagSignature, byte[] data);
/* methods for creating ColorTransforms */ /* methods for creating ColorTransforms */
public ColorTransform createTransform(ICC_Profile profile, int renderType, 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 @@ ...@@ -25,96 +25,139 @@
package sun.java2d.cmm.lcms; package sun.java2d.cmm.lcms;
import java.awt.color.CMMException;
import java.awt.color.ICC_Profile; import java.awt.color.ICC_Profile;
import java.util.Arrays;
import java.util.HashMap;
import sun.java2d.cmm.ColorTransform; import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM; import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.Profile;
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
public class LCMS implements PCMM { public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */ /* methods invoked from ICC_Profile */
@Override @Override
public long loadProfile(byte[] data) { public Profile loadProfile(byte[] data) {
long id = loadProfileNative(data); final Object disposerRef = new Object();
if (id != 0L) { final long ptr = loadProfileNative(data, disposerRef);
if (profiles == null) {
profiles = new HashMap<>(); if (ptr != 0L) {
} return new LCMSProfile(ptr, disposerRef);
profiles.put(id, new TagCache(id));
} }
return id; return null;
} }
private native long loadProfileNative(byte[] data); private native long loadProfileNative(byte[] data, Object ref);
@Override private LCMSProfile getLcmsProfile(Profile p) {
public void freeProfile(long profileID) { if (p instanceof LCMSProfile) {
TagCache c = profiles.remove(profileID); return (LCMSProfile)p;
if (c != null) {
c.clear();
} }
if (profiles.isEmpty()) { throw new CMMException("Invalid profile: " + p);
profiles = null; }
@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 @Override
public synchronized int getTagSize(long profileID, int tagSignature) { public int getTagSize(Profile p, int tagSignature) {
TagCache cache = profiles.get(profileID); final LCMSProfile profile = getLcmsProfile(p);
if (cache == null) { synchronized (profile) {
cache = new TagCache(profileID); TagData t = profile.getTag(tagSignature);
profiles.put(profileID, cache); 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 @Override
public synchronized void getTagData(long profileID, int tagSignature, public void getTagData(Profile p, int tagSignature, byte[] data)
byte[] data)
{ {
TagCache cache = profiles.get(profileID); final LCMSProfile profile = getLcmsProfile(p);
if (cache == null) {
cache = new TagCache(profileID);
profiles.put(profileID, cache);
}
TagData t = cache.getTag(tagSignature); synchronized (profile) {
if (t != null) { TagData t = profile.getTag(tagSignature);
t.copyDataTo(data); if (t != null) {
t.copyDataTo(data);
}
} }
} }
@Override @Override
public synchronized void setTagData(long profileID, int tagSignature, byte[] data) { public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
TagCache cache = profiles.get(profileID); final LCMSProfile profile = getLcmsProfile(p);
if (cache != null) { synchronized (profile) {
cache.clear(); 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); 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, long[] profileIDs, int renderType,
int inFormatter, boolean isInIntPacked, int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked, int outFormatter, boolean isOutIntPacked,
...@@ -175,59 +218,4 @@ public class LCMS implements PCMM { ...@@ -175,59 +218,4 @@ public class LCMS implements PCMM {
return theLcms; 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 { ...@@ -62,7 +62,7 @@ public class LCMSTransform implements ColorTransform {
private boolean isOutIntPacked = false; private boolean isOutIntPacked = false;
ICC_Profile[] profiles; ICC_Profile[] profiles;
long [] profileIDs; LCMSProfile[] lcmsProfiles;
int renderType; int renderType;
int transformType; int transformType;
...@@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform { ...@@ -84,8 +84,8 @@ public class LCMSTransform implements ColorTransform {
/* Actually, it is not a complete transform but just part of it */ /* Actually, it is not a complete transform but just part of it */
profiles = new ICC_Profile[1]; profiles = new ICC_Profile[1];
profiles[0] = profile; profiles[0] = profile;
profileIDs = new long[1]; lcmsProfiles = new LCMSProfile[1];
profileIDs[0] = LCMS.getProfileID(profile); lcmsProfiles[0] = LCMS.getProfileID(profile);
this.renderType = (renderType == ColorTransform.Any)? this.renderType = (renderType == ColorTransform.Any)?
ICC_Profile.icPerceptual : renderType; ICC_Profile.icPerceptual : renderType;
this.transformType = transformType; this.transformType = transformType;
...@@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform { ...@@ -105,14 +105,14 @@ public class LCMSTransform implements ColorTransform {
size+=((LCMSTransform)transforms[i]).profiles.length; size+=((LCMSTransform)transforms[i]).profiles.length;
} }
profiles = new ICC_Profile[size]; profiles = new ICC_Profile[size];
profileIDs = new long[size]; lcmsProfiles = new LCMSProfile[size];
int j = 0; int j = 0;
for (int i=0; i < transforms.length; i++) { for (int i=0; i < transforms.length; i++) {
LCMSTransform curTrans = (LCMSTransform)transforms[i]; LCMSTransform curTrans = (LCMSTransform)transforms[i];
System.arraycopy(curTrans.profiles, 0, profiles, j, System.arraycopy(curTrans.profiles, 0, profiles, j,
curTrans.profiles.length); curTrans.profiles.length);
System.arraycopy(curTrans.profileIDs, 0, profileIDs, j, System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
curTrans.profileIDs.length); curTrans.lcmsProfiles.length);
j += curTrans.profiles.length; j += curTrans.profiles.length;
} }
renderType = ((LCMSTransform)transforms[0]).renderType; renderType = ((LCMSTransform)transforms[0]).renderType;
...@@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform { ...@@ -152,7 +152,7 @@ public class LCMSTransform implements ColorTransform {
outFormatter = out.pixelType; outFormatter = out.pixelType;
isOutIntPacked = out.isIntPacked; isOutIntPacked = out.isIntPacked;
ID = LCMS.createNativeTransform(profileIDs, renderType, ID = LCMS.createTransform(lcmsProfiles, renderType,
inFormatter, isInIntPacked, inFormatter, isInIntPacked,
outFormatter, isOutIntPacked, outFormatter, isOutIntPacked,
disposerReferent); 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 { ...@@ -903,6 +903,9 @@ public abstract class RasterPrinterJob extends PrinterJob {
int x = bounds.x+bounds.width/3; int x = bounds.x+bounds.width/3;
int y = bounds.y+bounds.height/3; int y = bounds.y+bounds.height/3;
PrintService newService; PrintService newService;
// temporarily add an attribute pointing back to this job.
PrinterJobWrapper jobWrapper = new PrinterJobWrapper(this);
attributes.add(jobWrapper);
try { try {
newService = newService =
ServiceUI.printDialog(gc, x, y, ServiceUI.printDialog(gc, x, y,
...@@ -915,6 +918,7 @@ public abstract class RasterPrinterJob extends PrinterJob { ...@@ -915,6 +918,7 @@ public abstract class RasterPrinterJob extends PrinterJob {
DocFlavor.SERVICE_FORMATTED.PAGEABLE, DocFlavor.SERVICE_FORMATTED.PAGEABLE,
attributes); attributes);
} }
attributes.remove(PrinterJobWrapper.class);
if (newService == null) { if (newService == null) {
return false; return false;
......
...@@ -46,6 +46,7 @@ import java.awt.event.ItemEvent; ...@@ -46,6 +46,7 @@ import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.awt.event.ItemListener;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.print.PrinterJob;
import java.io.File; import java.io.File;
import java.io.FilePermission; import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
...@@ -119,8 +120,6 @@ public class ServiceDialog extends JDialog implements ActionListener { ...@@ -119,8 +120,6 @@ public class ServiceDialog extends JDialog implements ActionListener {
private AppearancePanel pnlAppearance; private AppearancePanel pnlAppearance;
private boolean isAWT = false; private boolean isAWT = false;
static { static {
initResource(); initResource();
} }
...@@ -801,9 +800,32 @@ public class ServiceDialog extends JDialog implements ActionListener { ...@@ -801,9 +800,32 @@ public class ServiceDialog extends JDialog implements ActionListener {
if (dialog != null) { if (dialog != null) {
dialog.show(); dialog.show();
} else { } else {
// REMIND: may want to notify the user why we're DocumentPropertiesUI docPropertiesUI = null;
// disabling the button try {
btnProperties.setEnabled(false); 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) ...@@ -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 * Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end. * will give us if we are near the end.
*/ */
RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input); GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env, ret = (*env)->CallIntMethod(env,
input, input,
JPEGImageReader_readInputDataID, JPEGImageReader_readInputDataID,
...@@ -1017,9 +1018,11 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo) ...@@ -1017,9 +1018,11 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo)
memcpy(sb->buf, src->next_input_byte, offset); memcpy(sb->buf, src->next_input_byte, offset);
} }
GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte); RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input);
buflen = sb->bufferLength - offset; buflen = sb->bufferLength - offset;
if (buflen <= 0) { if (buflen <= 0) {
if (!GET_ARRAYS(env, data, &(src->next_input_byte))) { if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
...@@ -1121,9 +1124,10 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes) ...@@ -1121,9 +1124,10 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
return; return;
} }
RELEASE_ARRAYS(env, data, src->next_input_byte);
GET_IO_REF(input); GET_IO_REF(input);
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env, ret = (*env)->CallLongMethod(env,
input, input,
JPEGImageReader_skipInputBytesID, JPEGImageReader_skipInputBytesID,
...@@ -2306,10 +2310,10 @@ imageio_empty_output_buffer (j_compress_ptr cinfo) ...@@ -2306,10 +2310,10 @@ imageio_empty_output_buffer (j_compress_ptr cinfo)
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject output = NULL; jobject output = NULL;
GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
GET_IO_REF(output);
(*env)->CallVoidMethod(env, (*env)->CallVoidMethod(env,
output, output,
JPEGImageWriter_writeOutputDataID, JPEGImageWriter_writeOutputDataID,
...@@ -2348,10 +2352,10 @@ imageio_term_destination (j_compress_ptr cinfo) ...@@ -2348,10 +2352,10 @@ imageio_term_destination (j_compress_ptr cinfo)
if (datacount != 0) { if (datacount != 0) {
jobject output = NULL; jobject output = NULL;
GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte)); RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
GET_IO_REF(output);
(*env)->CallVoidMethod(env, (*env)->CallVoidMethod(env,
output, output,
JPEGImageWriter_writeOutputDataID, JPEGImageWriter_writeOutputDataID,
......
...@@ -179,6 +179,10 @@ JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_nativeLayout ...@@ -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); FontInstanceAdapter fia(env, font2d, strike, mat, 72, 72, (le_int32) upem, (TTLayoutTableCache *) layoutTables);
LEErrorCode success = LE_NO_ERROR; LEErrorCode success = LE_NO_ERROR;
LayoutEngine *engine = LayoutEngine::layoutEngineFactory(&fia, script, lang, typo_flags & TYPO_MASK, success); 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 */ 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 // have to copy, yuck, since code does upcalls now. this will be soooo slow
......
...@@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value) ...@@ -94,8 +94,12 @@ cmsInt32Number TransportValue32(cmsInt32Number Value)
# endif # endif
#endif #endif
typedef union storeID_s { /* store SProfile stuff in a Java Long */ typedef struct lcmsProfile_s {
cmsHPROFILE pf; cmsHPROFILE pf;
} lcmsProfile_t, *lcmsProfile_p;
typedef union storeID_s { /* store SProfile stuff in a Java Long */
lcmsProfile_p lcmsPf;
cmsHTRANSFORM xf; cmsHTRANSFORM xf;
jobject jobj; jobject jobj;
jlong j; jlong j;
...@@ -106,7 +110,6 @@ typedef union { ...@@ -106,7 +110,6 @@ typedef union {
jint j; jint j;
} TagSignature_t, *TagSignature_p; } TagSignature_t, *TagSignature_p;
static jfieldID Trans_profileIDs_fID;
static jfieldID Trans_renderType_fID; static jfieldID Trans_renderType_fID;
static jfieldID Trans_ID_fID; static jfieldID Trans_ID_fID;
static jfieldID IL_isIntPacked_fID; static jfieldID IL_isIntPacked_fID;
...@@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID; ...@@ -118,7 +121,6 @@ static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID; static jfieldID IL_width_fID;
static jfieldID IL_height_fID; static jfieldID IL_height_fID;
static jfieldID IL_imageAtOnce_fID; static jfieldID IL_imageAtOnce_fID;
static jfieldID PF_ID_fID;
JavaVM *javaVM; JavaVM *javaVM;
...@@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { ...@@ -145,6 +147,18 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
return JNI_VERSION_1_6; 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) void LCMS_freeTransform(JNIEnv *env, jlong ID)
{ {
storeID_t sTrans; storeID_t sTrans;
...@@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform ...@@ -170,7 +184,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
jlong* ids; jlong* ids;
size = (*env)->GetArrayLength (env, profileIDs); size = (*env)->GetArrayLength (env, profileIDs);
ids = (*env)->GetPrimitiveArrayCritical(env, profileIDs, 0); ids = (*env)->GetLongArrayElements(env, profileIDs, 0);
#ifdef _LITTLE_ENDIAN #ifdef _LITTLE_ENDIAN
/* Reversing data packed into int for LE archs */ /* Reversing data packed into int for LE archs */
...@@ -186,6 +200,8 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform ...@@ -186,6 +200,8 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
iccArray = (cmsHPROFILE*) malloc( iccArray = (cmsHPROFILE*) malloc(
size*2*sizeof(cmsHPROFILE)); size*2*sizeof(cmsHPROFILE));
if (iccArray == NULL) { if (iccArray == NULL) {
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL"); J2dRlsTraceLn(J2D_TRACE_ERROR, "getXForm: iccArray == NULL");
return 0L; return 0L;
} }
...@@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform ...@@ -197,7 +213,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
cmsColorSpaceSignature cs; cmsColorSpaceSignature cs;
sTrans.j = ids[i]; sTrans.j = ids[i];
icc = sTrans.pf; icc = sTrans.lcmsPf->pf;
iccArray[j++] = icc; iccArray[j++] = icc;
/* Middle non-abstract profiles should be doubled before passing to /* Middle non-abstract profiles should be doubled before passing to
...@@ -215,13 +231,15 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform ...@@ -215,13 +231,15 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j, sTrans.xf = cmsCreateMultiprofileTransform(iccArray, j,
inFormatter, outFormatter, renderType, 0); inFormatter, outFormatter, renderType, 0);
(*env)->ReleasePrimitiveArrayCritical(env, profileIDs, ids, 0); (*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
if (sTrans.xf == NULL) { if (sTrans.xf == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: " J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_createNativeTransform: "
"sTrans.xf == NULL"); "sTrans.xf == NULL");
JNU_ThrowByName(env, "java/awt/color/CMMException", if ((*env)->ExceptionOccurred(env) == NULL) {
"Cannot get color transform"); JNU_ThrowByName(env, "java/awt/color/CMMException",
"Cannot get color transform");
}
} else { } else {
Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j); Disposer_AddRecord(env, disposerRef, LCMS_freeTransform, sTrans.j);
} }
...@@ -236,20 +254,23 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform ...@@ -236,20 +254,23 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform
/* /*
* Class: sun_java2d_cmm_lcms_LCMS * Class: sun_java2d_cmm_lcms_LCMS
* Method: loadProfile * Method: loadProfile
* Signature: ([B)J * Signature: ([B,Lsun/java2d/cmm/lcms/LCMSProfile;)V
*/ */
JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative 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; jbyte* dataArray;
jint dataSize; jint dataSize;
storeID_t sProf; storeID_t sProf;
cmsHPROFILE pf;
if (JNU_IsNull(env, data)) { if (JNU_IsNull(env, data)) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
return 0L; return 0L;
} }
sProf.j = 0L;
dataArray = (*env)->GetByteArrayElements (env, data, 0); dataArray = (*env)->GetByteArrayElements (env, data, 0);
dataSize = (*env)->GetArrayLength (env, data); dataSize = (*env)->GetArrayLength (env, data);
...@@ -258,61 +279,56 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative ...@@ -258,61 +279,56 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
return 0L; return 0L;
} }
sProf.pf = cmsOpenProfileFromMem((const void *)dataArray, pf = cmsOpenProfileFromMem((const void *)dataArray,
(cmsUInt32Number) dataSize); (cmsUInt32Number) dataSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
if (sProf.pf == NULL) { if (pf == NULL) {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
} else { } else {
/* Sanity check: try to save the profile in order /* Sanity check: try to save the profile in order
* to force basic validation. * to force basic validation.
*/ */
cmsUInt32Number pfSize = 0; cmsUInt32Number pfSize = 0;
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize) || if (!cmsSaveProfileToMem(pf, NULL, &pfSize) ||
pfSize < sizeof(cmsICCHeader)) pfSize < sizeof(cmsICCHeader))
{ {
JNU_ThrowIllegalArgumentException(env, "Invalid profile data"); JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
cmsCloseProfile(pf);
pf = NULL;
} }
} }
return sProf.j; if (pf != NULL) {
} // create profile holder
sProf.lcmsPf = (lcmsProfile_p)malloc(sizeof(lcmsProfile_t));
/* if (sProf.lcmsPf != NULL) {
* Class: sun_java2d_cmm_lcms_LCMS // register the disposer record
* Method: freeProfile sProf.lcmsPf->pf = pf;
* Signature: (J)V Disposer_AddRecord(env, disposerRef, LCMS_freeProfile, sProf.j);
*/ } else {
JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative cmsCloseProfile(pf);
(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");
} }
return sProf.j;
} }
/* /*
* Class: sun_java2d_cmm_lcms_LCMS * Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileSize * Method: getProfileSizeNative
* Signature: (J)I * 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) (JNIEnv *env, jobject obj, jlong id)
{ {
storeID_t sProf; storeID_t sProf;
cmsUInt32Number pfSize = 0; cmsUInt32Number pfSize = 0;
sProf.j = id; 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; return (jint)pfSize;
} else { } else {
JNU_ThrowByName(env, "java/awt/color/CMMException", JNU_ThrowByName(env, "java/awt/color/CMMException",
...@@ -323,10 +339,10 @@ JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize ...@@ -323,10 +339,10 @@ JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileSize
/* /*
* Class: sun_java2d_cmm_lcms_LCMS * Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileData * Method: getProfileDataNative
* Signature: (J[B)V * 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) (JNIEnv *env, jobject obj, jlong id, jbyteArray data)
{ {
storeID_t sProf; storeID_t sProf;
...@@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData ...@@ -338,7 +354,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
sProf.j = id; sProf.j = id;
// determine actual profile size // determine actual profile size
if (!cmsSaveProfileToMem(sProf.pf, NULL, &pfSize)) { if (!cmsSaveProfileToMem(sProf.lcmsPf->pf, NULL, &pfSize)) {
JNU_ThrowByName(env, "java/awt/color/CMMException", JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not access specified profile."); "Can not access specified profile.");
return; return;
...@@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData ...@@ -354,7 +370,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
dataArray = (*env)->GetByteArrayElements (env, data, 0); 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); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
...@@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData ...@@ -368,7 +384,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getProfileData
/* Get profile header info */ /* Get profile header info */
static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize); static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _setHeaderInfo(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 ...@@ -412,7 +428,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return NULL; return NULL;
} }
status = _getHeaderInfo(sProf.pf, dataArray, bufSize); status = _getHeaderInfo(sProf.lcmsPf->pf, dataArray, bufSize);
(*env)->ReleaseByteArrayElements (env, data, dataArray, 0); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
...@@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative ...@@ -425,8 +441,8 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return data; return data;
} }
if (cmsIsTag(sProf.pf, sig.cms)) { if (cmsIsTag(sProf.lcmsPf->pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0); tagSize = cmsReadRawTag(sProf.lcmsPf->pf, sig.cms, NULL, 0);
} else { } else {
JNU_ThrowByName(env, "java/awt/color/CMMException", JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found"); "ICC profile tag not found");
...@@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative ...@@ -449,7 +465,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
return NULL; 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); (*env)->ReleaseByteArrayElements (env, data, dataArray, 0);
...@@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative ...@@ -470,8 +486,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data) (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{ {
storeID_t sProf; storeID_t sProf;
cmsHPROFILE pfReplace = NULL;
TagSignature_t sig; TagSignature_t sig;
cmsBool status; cmsBool status = FALSE;
jbyte* dataArray; jbyte* dataArray;
int tagSize; int tagSize;
...@@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative ...@@ -493,15 +511,24 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
} }
if (tagSig == SigHead) { if (tagSig == SigHead) {
status = _setHeaderInfo(sProf.pf, dataArray, tagSize); status = _setHeaderInfo(sProf.lcmsPf->pf, dataArray, tagSize);
} else { } 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); (*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
if (!status) { if (!status) {
JNU_ThrowIllegalArgumentException(env, "Can not write tag data."); 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 ...@@ -624,12 +651,27 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert
/* /*
* Class: sun_java2d_cmm_lcms_LCMS * Class: sun_java2d_cmm_lcms_LCMS
* Method: getProfileID * 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) (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 ...@@ -644,7 +686,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
* corresponding classes to avoid problems with invalidating ids by class * corresponding classes to avoid problems with invalidating ids by class
* unloading * unloading
*/ */
Trans_profileIDs_fID = (*env)->GetFieldID (env, Trans, "profileIDs", "[J");
Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I"); Trans_renderType_fID = (*env)->GetFieldID (env, Trans, "renderType", "I");
Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J"); Trans_ID_fID = (*env)->GetFieldID (env, Trans, "ID", "J");
...@@ -658,8 +699,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS ...@@ -658,8 +699,6 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I"); IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z"); IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I"); 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) static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
...@@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize) ...@@ -714,76 +753,114 @@ static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
return TRUE; return TRUE;
} }
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, /* Returns new profile handler, if it was created successfully,
cmsTagSignature sig, NULL otherwise.
*/
static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget,
const cmsTagSignature sig,
jbyte *pData, jint size) jbyte *pData, jint size)
{ {
cmsBool status;
cmsUInt32Number pfSize = 0; cmsUInt32Number pfSize = 0;
cmsUInt8Number* pfBuffer = NULL; const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
cmsInt32Number i;
cmsHPROFILE pfSanity = NULL;
cmsICCHeader hdr = { 0 };
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL); cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
if (NULL != p) {
cmsICCHeader hdr = { 0 }; if (NULL == p) {
return NULL;
/* Populate the placeholder's header according to target profile */ }
hdr.flags = cmsGetHeaderFlags(pfTarget);
hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget); // Populate the placeholder's header according to target profile
hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget); hdr.flags = cmsGetHeaderFlags(pfTarget);
hdr.model = cmsGetHeaderModel(pfTarget); hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
hdr.pcs = cmsGetPCS(pfTarget); hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
hdr.colorSpace = cmsGetColorSpace(pfTarget); hdr.model = cmsGetHeaderModel(pfTarget);
hdr.deviceClass = cmsGetDeviceClass(pfTarget); hdr.pcs = cmsGetPCS(pfTarget);
hdr.version = cmsGetEncodedICCversion(pfTarget); hdr.colorSpace = cmsGetColorSpace(pfTarget);
cmsGetHeaderAttributes(pfTarget, &hdr.attributes); hdr.deviceClass = cmsGetDeviceClass(pfTarget);
cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID); hdr.version = cmsGetEncodedICCversion(pfTarget);
cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
cmsSetHeaderFlags(p, hdr.flags); cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
cmsSetHeaderManufacturer(p, hdr.manufacturer);
cmsSetHeaderModel(p, hdr.model); cmsSetHeaderFlags(p, hdr.flags);
cmsSetHeaderAttributes(p, hdr.attributes); cmsSetHeaderManufacturer(p, hdr.manufacturer);
cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID)); cmsSetHeaderModel(p, hdr.model);
cmsSetHeaderRenderingIntent(p, hdr.renderingIntent); cmsSetHeaderAttributes(p, hdr.attributes);
cmsSetPCS(p, hdr.pcs); cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
cmsSetColorSpace(p, hdr.colorSpace); cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
cmsSetDeviceClass(p, hdr.deviceClass); cmsSetPCS(p, hdr.pcs);
cmsSetEncodedICCversion(p, hdr.version); cmsSetColorSpace(p, hdr.colorSpace);
cmsSetDeviceClass(p, hdr.deviceClass);
cmsSetEncodedICCversion(p, hdr.version);
if (cmsWriteRawTag(p, sig, pData, size)) {
if (cmsSaveProfileToMem(p, NULL, &pfSize)) { // now write the user supplied tag
pfBuffer = malloc(pfSize); if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
if (pfBuffer != NULL) { cmsCloseProfile(p);
/* load raw profile data into the buffer */ return NULL;
if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) { }
free(pfBuffer);
pfBuffer = 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) { if (!isTagReady) {
return FALSE; cmsCloseProfile(p);
return NULL;
}
} }
/* re-open the placeholder profile */ // now we have all tags moved to the new profile.
p = cmsOpenProfileFromMem(pfBuffer, pfSize); // do some sanity checks: write it to a memory buffer and read again.
free(pfBuffer); if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
status = FALSE; void* buf = malloc(pfSize);
if (buf != NULL) {
if (p != NULL) { // load raw profile data into the buffer
/* Note that pCookedTag points to internal structures of the placeholder, if (cmsSaveProfileToMem(p, buf, &pfSize)) {
* so this data is valid only while the placeholder is open. pfSanity = cmsOpenProfileFromMem(buf, pfSize);
*/ }
void *pCookedTag = cmsReadTag(p, sig); free(buf);
if (pCookedTag != NULL) {
status = cmsWriteTag(pfTarget, sig, pCookedTag);
} }
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); 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 { ...@@ -142,7 +142,7 @@ public class XRTextRenderer extends GlyphListPipe {
} }
int maskFormat = containsLCDGlyphs ? XRUtils.PictStandardARGB32 : XRUtils.PictStandardA8; 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(); eltList.clear();
} finally { } finally {
......
...@@ -267,8 +267,9 @@ public class XRBackendNative implements XRBackend { ...@@ -267,8 +267,9 @@ public class XRBackendNative implements XRBackend {
private static native void private static native void
XRenderCompositeTextNative(int op, int src, int dst, XRenderCompositeTextNative(int op, int src, int dst,
long maskFormat, int[] eltArray, int srcX, int srcY, long maskFormat,
int[] glyphIDs, int eltCnt, int glyphCnt); int[] eltArray, int[] glyphIDs, int eltCnt,
int glyphCnt);
public int XRenderCreateGlyphSet(int formatID) { public int XRenderCreateGlyphSet(int formatID) {
return XRenderCreateGlyphSetNative(getFormatPtr(formatID)); return XRenderCreateGlyphSetNative(getFormatPtr(formatID));
...@@ -278,11 +279,11 @@ public class XRBackendNative implements XRBackend { ...@@ -278,11 +279,11 @@ public class XRBackendNative implements XRBackend {
public void XRenderCompositeText(byte op, int src, int dst, public void XRenderCompositeText(byte op, int src, int dst,
int maskFormatID, int maskFormatID,
int src2, int src3, int dst2, int dst3, int sx, int sy, int dx, int dy,
int glyphset, GrowableEltArray elts) { int glyphset, GrowableEltArray elts) {
GrowableIntArray glyphs = elts.getGlyphs(); 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.getArray(), elts.getSize(),
glyphs.getSize()); glyphs.getSize());
} }
......
...@@ -285,7 +285,12 @@ public class XRCompositeManager { ...@@ -285,7 +285,12 @@ public class XRCompositeManager {
if (xorEnabled) { if (xorEnabled) {
con.GCRectangles(dst.getXid(), dst.getGC(), rects); con.GCRectangles(dst.getXid(), dst.getGC(), rects);
} else { } 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 { ...@@ -295,10 +300,10 @@ public class XRCompositeManager {
sy, 0, 0, dx, dy, w, h); sy, 0, 0, dx, dy, w, h);
} }
public void compositeText(int dst, int glyphSet, int maskFormat, public void compositeText(XRSurfaceData dst, int sx, int sy,
GrowableEltArray elts) { int glyphSet, int maskFormat, GrowableEltArray elts) {
con.XRenderCompositeText(compRule, src.picture, dst, maskFormat, 0, 0, con.XRenderCompositeText(compRule, src.picture, dst.picture,
0, 0, glyphSet, elts); maskFormat, sx, sy, 0, 0, glyphSet, elts);
} }
public XRColor getMaskColor() { public XRColor getMaskColor() {
......
...@@ -225,6 +225,9 @@ class XRPMScaledBlit extends ScaledBlit { ...@@ -225,6 +225,9 @@ class XRPMScaledBlit extends ScaledBlit {
* @author Clemens Eisserer * @author Clemens Eisserer
*/ */
class XRPMTransformedBlit extends TransformBlit { 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) { public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
super(srcType, CompositeType.AnyAlpha, dstType); super(srcType, CompositeType.AnyAlpha, dstType);
...@@ -235,61 +238,68 @@ class XRPMTransformedBlit extends TransformBlit { ...@@ -235,61 +238,68 @@ class XRPMTransformedBlit extends TransformBlit {
* method is functionally equal to: Shape shp = * method is functionally equal to: Shape shp =
* xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds(); * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
* but performs significantly better. * 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) { protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
double[] compBounds = new double[8]; srcCoords[0] = dstx;
compBounds[0] = dstx; srcCoords[1] = dsty;
compBounds[1] = dsty; srcCoords[2] = dstx + width;
compBounds[2] = dstx + width; srcCoords[3] = dsty;
compBounds[3] = dsty; srcCoords[4] = dstx + width;
compBounds[4] = dstx + width; srcCoords[5] = dsty + height;
compBounds[5] = dsty + height; srcCoords[6] = dstx;
compBounds[6] = dstx; srcCoords[7] = dsty + height;
compBounds[7] = dsty + height;
tr.transform(srcCoords, 0, dstCoords, 0, 4);
tr.transform(compBounds, 0, compBounds, 0, 4);
double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6]))); double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7]))); double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6]))); double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
minX = Math.round(minX);
minX = Math.floor(minX); minY = Math.round(minY);
minY = Math.floor(minY); maxX = Math.round(maxX);
maxX = Math.ceil(maxX); maxY = Math.round(maxY);
maxY = Math.ceil(maxY);
compositeBounds.x = (int) minX;
return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY)); 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, public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform,
int dstx, int dsty, int width, int height) { int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
try { try {
SunToolkit.awtLock(); SunToolkit.awtLock();
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
int filter = XRUtils.ATransOpToXRQuality(hint); int filter = XRUtils.ATransOpToXRQuality(hint);
boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
XRSurfaceData x11sdDst = (XRSurfaceData) dst;
x11sdDst.validateAsDestination(null, clip); x11sdDst.validateAsDestination(null, clip);
XRSurfaceData x11sdSrc = (XRSurfaceData) src;
x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null); x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height); AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);
AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
trx.concatenate(xform); trx.concatenate(xform);
AffineTransform maskTX = (AffineTransform) trx.clone(); AffineTransform maskTX = (AffineTransform) trx.clone();
trx.translate(-srcx, -srcy); trx.translate(-srcx, -srcy);
try { try {
trx.invert(); trx.invert();
} catch (NoninvertibleTransformException ex) { } catch (NoninvertibleTransformException ex) {
trx.setToIdentity(); 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) { if (!omitMask) {
XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage(); XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
...@@ -297,33 +307,17 @@ class XRPMTransformedBlit extends TransformBlit { ...@@ -297,33 +307,17 @@ class XRPMTransformedBlit extends TransformBlit {
x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter); x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height); int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture, 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 { } else {
int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad; int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
x11sdSrc.validateAsSource(trx, repeat, filter); 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 { } finally {
SunToolkit.awtUnlock(); 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 { class XrSwToPMBlit extends Blit {
......
...@@ -911,8 +911,9 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative ...@@ -911,8 +911,9 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCreateGlyphSetNative
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
(JNIEnv *env, jclass cls, jint op, jint src, jint dst, jlong maskFmt, (JNIEnv *env, jclass cls, jint op, jint src, jint dst,
jintArray eltArray, jintArray glyphIDArray, jint eltCnt, jint glyphCnt) { jint sx, jint sy, jlong maskFmt, jintArray eltArray,
jintArray glyphIDArray, jint eltCnt, jint glyphCnt) {
jint i; jint i;
jint *ids; jint *ids;
jint *elts; jint *elts;
...@@ -991,7 +992,7 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative ...@@ -991,7 +992,7 @@ Java_sun_java2d_xr_XRBackendNative_XRenderCompositeTextNative
XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst, XRenderCompositeText32(awt_display, op, (Picture) src, (Picture) dst,
(XRenderPictFormat *) jlong_to_ptr(maskFmt), (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, glyphIDArray, ids, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, eltArray, elts, JNI_ABORT);
......
...@@ -179,6 +179,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -179,6 +179,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
private static final int SET_RES_LOW = 0x00000080; private static final int SET_RES_LOW = 0x00000080;
private static final int SET_COLOR = 0x00000200; private static final int SET_COLOR = 0x00000200;
private static final int SET_ORIENTATION = 0x00004000; private static final int SET_ORIENTATION = 0x00004000;
private static final int SET_COLLATED = 0x00008000;
/** /**
* Values must match those defined in wingdi.h & commdlg.h * Values must match those defined in wingdi.h & commdlg.h
...@@ -189,10 +190,33 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -189,10 +190,33 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
private static final int PD_NOSELECTION = 0x00000004; private static final int PD_NOSELECTION = 0x00000004;
private static final int PD_COLLATE = 0x00000010; private static final int PD_COLLATE = 0x00000010;
private static final int PD_PRINTTOFILE = 0x00000020; private static final int PD_PRINTTOFILE = 0x00000020;
private static final int DM_ORIENTATION = 0x00000001; private static final int DM_ORIENTATION = 0x00000001;
private static final int DM_PRINTQUALITY = 0x00000400; private static final int DM_PAPERSIZE = 0x00000002;
private static final int DM_COLOR = 0x00000800; private static final int DM_COPIES = 0x00000100;
private static final int DM_DUPLEX = 0x00001000; 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 * Pageable MAX pages
...@@ -592,13 +616,23 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -592,13 +616,23 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
} }
driverDoesMultipleCopies = false; driverDoesMultipleCopies = false;
driverDoesCollation = false; driverDoesCollation = false;
setNativePrintService(service.getName()); setNativePrintServiceIfNeeded(service.getName());
} }
/* associates this job with the specified native service */ /* associates this job with the specified native service */
private native void setNativePrintService(String name) private native void setNativePrintService(String name)
throws PrinterException; 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() { public PrintService getPrintService() {
if (myService == null) { if (myService == null) {
String printerName = getNativePrintService(); String printerName = getNativePrintService();
...@@ -616,7 +650,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -616,7 +650,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
myService = PrintServiceLookup.lookupDefaultPrintService(); myService = PrintServiceLookup.lookupDefaultPrintService();
if (myService != null) { if (myService != null) {
try { try {
setNativePrintService(myService.getName()); setNativePrintServiceIfNeeded(myService.getName());
} catch (Exception e) { } catch (Exception e) {
myService = null; myService = null;
} }
...@@ -1754,8 +1788,13 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -1754,8 +1788,13 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
mAttMediaSizeName = ((Win32PrintService)myService).findPaperID(msn); mAttMediaSizeName = ((Win32PrintService)myService).findPaperID(msn);
} }
private void setWin32MediaAttrib(int dmIndex, int width, int length) { private void addPaperSize(PrintRequestAttributeSet aset,
MediaSizeName msn = int dmIndex, int width, int length) {
if (aset == null) {
return;
}
MediaSizeName msn =
((Win32PrintService)myService).findWin32Media(dmIndex); ((Win32PrintService)myService).findWin32Media(dmIndex);
if (msn == null) { if (msn == null) {
msn = ((Win32PrintService)myService). msn = ((Win32PrintService)myService).
...@@ -1763,10 +1802,12 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -1763,10 +1802,12 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
} }
if (msn != null) { if (msn != null) {
if (attributes != null) { aset.add(msn);
attributes.add(msn);
}
} }
}
private void setWin32MediaAttrib(int dmIndex, int width, int length) {
addPaperSize(attributes, dmIndex, width, length);
mAttMediaSizeName = dmIndex; mAttMediaSizeName = dmIndex;
} }
...@@ -1788,7 +1829,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -1788,7 +1829,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
// no equivalent predefined value // no equivalent predefined value
mAttMediaTray = 7; // DMBIN_AUTO mAttMediaTray = 7; // DMBIN_AUTO
} else if (attr == MediaTray.TOP) { } else if (attr == MediaTray.TOP) {
mAttMediaTray =1; // DMBIN_UPPER mAttMediaTray = 1; // DMBIN_UPPER
} else { } else {
if (attr instanceof Win32MediaTray) { if (attr instanceof Win32MediaTray) {
mAttMediaTray = ((Win32MediaTray)attr).winID; mAttMediaTray = ((Win32MediaTray)attr).winID;
...@@ -1914,6 +1955,254 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -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() */ /* Printer Resolution. See also getXRes() and getYRes() */
private final void setResolutionDPI(int xres, int yres) { private final void setResolutionDPI(int xres, int yres) {
...@@ -1956,7 +2245,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget { ...@@ -1956,7 +2245,7 @@ public class WPrinterJob extends RasterPrinterJob implements DisposerTarget {
} }
//** END Functions called by native code for querying/updating attributes //** END Functions called by native code for querying/updating attributes
} }
class PrintToFileErrorDialog extends Dialog implements ActionListener{ class PrintToFileErrorDialog extends Dialog implements ActionListener{
public PrintToFileErrorDialog(Frame parent, String title, String message, public PrintToFileErrorDialog(Frame parent, String title, String message,
......
...@@ -70,6 +70,10 @@ public class Win32MediaTray extends MediaTray { ...@@ -70,6 +70,10 @@ public class Win32MediaTray extends MediaTray {
winEnumTable.add(this); winEnumTable.add(this);
} }
public int getDMBinID() {
return winID;
}
private static final String[] myStringTable ={ private static final String[] myStringTable ={
"Manual-Envelope", "Manual-Envelope",
"Automatic-Feeder", "Automatic-Feeder",
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.print; package sun.print;
import java.awt.Window;
import java.awt.print.PrinterJob;
import java.io.File; import java.io.File;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
...@@ -39,6 +41,7 @@ import javax.print.attribute.AttributeSet; ...@@ -39,6 +41,7 @@ import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities; import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax; import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet; import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute; import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet; import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet; import javax.print.attribute.HashPrintServiceAttributeSet;
...@@ -69,6 +72,7 @@ import javax.print.attribute.standard.PrintQuality; ...@@ -69,6 +72,7 @@ import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution; import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate; import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener; import javax.print.event.PrintServiceAttributeListener;
import sun.awt.windows.WPrinterJob;
public class Win32PrintService implements PrintService, AttributeUpdater, public class Win32PrintService implements PrintService, AttributeUpdater,
SunPrinterJobService { SunPrinterJobService {
...@@ -282,6 +286,22 @@ public class Win32PrintService implements PrintService, AttributeUpdater, ...@@ -282,6 +286,22 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
return 0; 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) { public MediaTray findMediaTray(int dmBin) {
if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) { if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
return dmPaperBinToPrintService[dmBin-1]; return dmPaperBinToPrintService[dmBin-1];
...@@ -673,7 +693,6 @@ public class Win32PrintService implements PrintService, AttributeUpdater, ...@@ -673,7 +693,6 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
return arr2; return arr2;
} }
private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() { private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
if (getJobStatus(printer, 2) != 1) { if (getJobStatus(printer, 2) != 1) {
return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS; return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
...@@ -1596,8 +1615,76 @@ public class Win32PrintService implements PrintService, AttributeUpdater, ...@@ -1596,8 +1615,76 @@ public class Win32PrintService implements PrintService, AttributeUpdater,
} }
} }
public ServiceUIFactory getServiceUIFactory() { private Win32DocumentPropertiesUI docPropertiesUI = null;
return 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() { public String toString() {
......
...@@ -81,6 +81,7 @@ jmethodID AwtPrintControl::setToPageID; ...@@ -81,6 +81,7 @@ jmethodID AwtPrintControl::setToPageID;
jmethodID AwtPrintControl::setNativeAttID; jmethodID AwtPrintControl::setNativeAttID;
jmethodID AwtPrintControl::setRangeCopiesID; jmethodID AwtPrintControl::setRangeCopiesID;
jmethodID AwtPrintControl::setResID; jmethodID AwtPrintControl::setResID;
jmethodID AwtPrintControl::setJobAttributesID;
BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) { BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
...@@ -297,6 +298,10 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) ...@@ -297,6 +298,10 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls)
AwtPrintControl::setPrinterID = AwtPrintControl::setPrinterID =
env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V"); 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::driverDoesMultipleCopiesID != NULL);
DASSERT(AwtPrintControl::getPrintDCID != NULL); DASSERT(AwtPrintControl::getPrintDCID != NULL);
DASSERT(AwtPrintControl::setPrintDCID != NULL); DASSERT(AwtPrintControl::setPrintDCID != NULL);
...@@ -327,6 +332,7 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) ...@@ -327,6 +332,7 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtPrintControl::getSidesID != NULL); DASSERT(AwtPrintControl::getSidesID != NULL);
DASSERT(AwtPrintControl::getSelectID != NULL); DASSERT(AwtPrintControl::getSelectID != NULL);
DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL); DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL);
DASSERT(AwtPrintControl::setJobAttributesID != NULL);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
......
...@@ -47,7 +47,6 @@ public: ...@@ -47,7 +47,6 @@ public:
static jmethodID setDevmodeID; static jmethodID setDevmodeID;
static jmethodID getDevnamesID; static jmethodID getDevnamesID;
static jmethodID setDevnamesID; static jmethodID setDevnamesID;
static jmethodID getWin32MediaID; static jmethodID getWin32MediaID;
static jmethodID setWin32MediaID; static jmethodID setWin32MediaID;
static jmethodID getWin32MediaTrayID; static jmethodID getWin32MediaTrayID;
...@@ -73,6 +72,7 @@ public: ...@@ -73,6 +72,7 @@ public:
static jmethodID setNativeAttID; static jmethodID setNativeAttID;
static jmethodID setRangeCopiesID; static jmethodID setRangeCopiesID;
static jmethodID setResID; static jmethodID setResID;
static jmethodID setJobAttributesID;
static void initIDs(JNIEnv *env, jclass cls); static void initIDs(JNIEnv *env, jclass cls);
static BOOL FindPrinter(jstring printerName, LPBYTE pPrinterEnum, static BOOL FindPrinter(jstring printerName, LPBYTE pPrinterEnum,
......
...@@ -329,6 +329,156 @@ static int CALLBACK fontEnumProcA(ENUMLOGFONTEXA *logfont, ...@@ -329,6 +329,156 @@ static int CALLBACK fontEnumProcA(ENUMLOGFONTEXA *logfont,
static int embolden(int currentWeight); static int embolden(int currentWeight);
static BOOL getPrintableArea(HDC pdc, HANDLE hDevMode, RectDouble *margin); 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 * WPageDialog native methods
*/ */
...@@ -732,7 +882,6 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self, ...@@ -732,7 +882,6 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self,
memset(&pd, 0, sizeof(PRINTDLG)); memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG); pd.lStructSize = sizeof(PRINTDLG);
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC; pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
if (::PrintDlg(&pd)) { if (::PrintDlg(&pd)) {
printDC = pd.hDC; printDC = pd.hDC;
hDevMode = pd.hDevMode; hDevMode = pd.hDevMode;
...@@ -792,8 +941,19 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self, ...@@ -792,8 +941,19 @@ Java_sun_awt_windows_WPrinterJob_validatePaper(JNIEnv *env, jobject self,
jint imgPixelWid = GetDeviceCaps(printDC, HORZRES); jint imgPixelWid = GetDeviceCaps(printDC, HORZRES);
jint imgPixelHgt = GetDeviceCaps(printDC, VERTRES); 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 the values were obtained from a rotated device, swap.
if (getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) { if ((getOrientationFromDevMode2(hDevMode) == DMORIENT_LANDSCAPE) &&
(imgPixelWid > imgPixelHgt)) {
jint tmp; jint tmp;
tmp = xPixelRes; tmp = xPixelRes;
xPixelRes = yPixelRes; xPixelRes = yPixelRes;
...@@ -941,6 +1101,9 @@ Java_sun_awt_windows_WPrinterJob_initPrinter(JNIEnv *env, jobject self) { ...@@ -941,6 +1101,9 @@ Java_sun_awt_windows_WPrinterJob_initPrinter(JNIEnv *env, jobject self) {
setBooleanField(env, self, DRIVER_COLLATE_STR, JNI_FALSE); setBooleanField(env, self, DRIVER_COLLATE_STR, JNI_FALSE);
} }
if (dmFields & DM_COPIES) {
setBooleanField(env, self, DRIVER_COPIES_STR, JNI_TRUE);
}
} }
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/** /**
* @test * @test
* @bug 8020983 * @bug 8020983 8024697
* @summary Test verifies that jpeg writer instances are collected * @summary Test verifies that jpeg writer instances are collected
* even if destroy() or reset() methods is not invoked. * 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 @@ ...@@ -23,7 +23,7 @@
/** /**
* @test * @test
* @bug 6476665 6523403 6733501 7042594 * @bug 6476665 6523403 6733501 7042594 7043064
* @summary Verifies reading and writing profiles and tags of the standard color * @summary Verifies reading and writing profiles and tags of the standard color
* spaces * spaces
* @run main ReadWriteProfileTest * @run main ReadWriteProfileTest
...@@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable { ...@@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable {
public void run() { public void run() {
for (int i = 0; i < cspaces.length; i++) { for (int i = 0; i < cspaces.length; i++) {
System.out.println("Profile: " + csNames[i]);
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData(); byte [] data = pf.getData();
pf = ICC_Profile.getInstance(data); pf = ICC_Profile.getInstance(data);
...@@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable { ...@@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable {
} }
for (int tagSig : tags[i].keySet()) { 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 [] tagData = pf.getData(tagSig);
byte [] empty = new byte[tagData.length]; byte [] empty = new byte[tagData.length];
boolean emptyDataRejected = false; boolean emptyDataRejected = false;
...@@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable { ...@@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable {
throw new throw new
RuntimeException("Test failed: empty tag data was not rejected."); 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); byte [] tagData1 = pf.getData(tagSig);
if (!Arrays.equals(tagData1, tags[i].get(tagSig))) if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
{ {
System.err.println("Incorrect result of getData(int) with" + System.err.println("Incorrect result of getData(int) with" +
" tag " + " tag " +
Integer.toHexString(tagSig) + SigToString(tagSig) +
" of " + csNames[i] + " profile"); " of " + csNames[i] + " profile");
throw new RuntimeException("Incorrect result of " + throw new RuntimeException("Incorrect result of " +
...@@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable { ...@@ -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) { public static void main(String [] args) {
ReadWriteProfileTest test = new ReadWriteProfileTest(); ReadWriteProfileTest test = new ReadWriteProfileTest();
test.run(); test.run();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册