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