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