Mercurial > hg > release > icedtea7-forest-2.6 > jdk
changeset 6363:d4bf5c15837c jdk7u14-b22
Merge
author | lana |
---|---|
date | Thu, 18 Apr 2013 14:38:37 -0700 |
parents | 87c6c2882d3f (current diff) 360347165596 (diff) |
children | d3fef82a86bb 39a85b6373fa |
files | .hgtags |
diffstat | 268 files changed, 8417 insertions(+), 1523 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Wed Apr 17 12:13:43 2013 -0700 +++ b/.hgtags Thu Apr 18 14:38:37 2013 -0700 @@ -213,6 +213,8 @@ 901c290c9c8b495a2696f10a87523363239d001b jdk7u9-b02 7302c386ca9c6cd20c27d0a2adb0b142f679d6b3 jdk7u9-b04 ffad06d7009576c3098705e05452ebc309a59e56 jdk7u9-b05 +3b1a395f1948c7063d342a0c3e26c8450c6e7acb jdk7u9-b31 +77f7e5f13763fed11afb6e12840d78bd55c2d979 jdk7u9-b32 c1efb11d7db509dafd7882811b2562ba593f6431 jdk7u10-b10 0243e41000c6f76654725cac31ffdc95633c63e7 jdk7u10-b11 c86a49dd4a0dca3a56f00429cfcffb2ad5f2a224 jdk7u10-b12 @@ -223,8 +225,11 @@ a1c5bac982a6d4aa58f551cb46cde53f526aca48 jdk7u10-b17 115d1e4365293846bbc911cf312886c471e37fbd jdk7u10-b18 84218dff5e4c7bc00fd9266769c0d12bdde866f5 jdk7u10-b30 +3515fd583ede49b125a0b5f72ac403b3984d199b jdk7u10-b31 ecc14534318c80dc7612c8b1d328a67849c5b07f jdk7u11-b20 d9969a953f693f5760b1d2759f11a2cb222e4f20 jdk7u11-b21 +c7282a85c6bcc717b7099a03db028ecb77b41098 jdk7u11-b32 +8fd5e105c6a288b01f8809a6c84a5a64a63f39be jdk7u11-b33 84da14fbd3ac12a3c6734fa4b6a366cfde1426af jdk7u11-b03 932ef74edbf984299a68c126c70bbe04ffbde9b5 jdk7u11-b04 fb35fb91f6478f8076993bcc4112746bcd9a2985 jdk7u11-b05 @@ -262,9 +267,23 @@ 835448d525a10bb826f4f7ebe272fc410bdb0f5d jdk7u15-b01 0443fe2d8023111b52f4c8db32e038f4a5a9f373 jdk7u15-b02 70b0f967c0649c501fb14a27bb06daeccbff823a jdk7u15-b30 +9f20468265071696b4d2ece286bc228a4d5a302a jdk7u15-b31 +3ef25219292f57ea56ac0ef338ceadf5fd098bdf jdk7u15-b33 87e45d30e24db726ea03b20d861f0a025e437641 jdk7u15-b03 b5ae6fb92e71df1833221026efe50863593bf682 jdk7u17-b01 b130c8cfecfc552614047b3244d5d94439827fcd jdk7u17-b02 +a474615061bf610105a426780a7ac4c95bd76456 jdk7u17-b30 +1ad6f413e250bd2671b4908e232bd0d244c917a7 jdk7u17-b31 +8261e56b7f91c7553e8485b206bdc9030a3546e4 jdk7u21-b01 +af6be9d7aed7c323858932c908b049f4bcdb6a3e jdk7u21-b05 +ffc1454e644a39265cd6d80ef4b4c12c5dbf35c9 jdk7u21-b06 +b453d9be6b3f5496aa217ade7478d3b7fa32b13b jdk7u21-b07 +de4e41c5c549136209a68154d847cf126e563b88 jdk7u21-b08 +622aedcdda610a148a082558a0c25d8b3b735d07 jdk7u21-b09 +f447c3bbf074439ece0ce9fea82c857f93817801 jdk7u21-b10 +f9323b9d020ce8d313af2d2e2682e2b6cabcc40d jdk7u21-b11 +08ed0bfc9668f04ce4e3803f16aad92f6e50f885 jdk7u21-b30 +f3cf02a53684b9fbefabb212c80dfbea0c27f113 jdk7u21-b12 555ea0c4e9567294d37793777d521902d43f1a39 jdk7u14-b16 950fa827c2ec8a3a1ceba755994ae59016daa621 jdk7u14-b17 e7ba683c15009b166127c3437fe9fbaf4eee6efe jdk7u14-b18
--- a/make/common/Release.gmk Wed Apr 17 12:13:43 2013 -0700 +++ b/make/common/Release.gmk Thu Apr 18 14:38:37 2013 -0700 @@ -244,7 +244,7 @@ trim-image-jre trim-image-jdk \ identify-image-jre identify-image-jdk \ process-image-jre process-image-jdk \ -compare-image \ +compare-image \ sec-files sec-files-win jgss-files server-jdk-image :: @$(ECHO) ">>>Making "$@" @ `$(DATE)` ..." @@ -254,9 +254,9 @@ images:: sanity-images post-sanity-images \ $(INITIAL_IMAGE_JRE) $(EXTRA_JRE_TARGETS) $(INITIAL_IMAGE_JDK) \ trim-image-jre trim-image-jdk \ - identify-image-jre identify-image-jdk \ + identify-image-jre identify-image-jdk \ process-image-jre process-image-jdk sec-files sec-files-win \ - jgss-files $(EXTRA_IMAGE_TARGETS) server-jdk-image + jgss-files $(EXTRA_IMAGE_TARGETS) server-jdk-image else images:: sanity-images post-sanity-images \ @@ -940,7 +940,7 @@ done $(RM) $(JRE_BIN_LIST) -# Duplicate current j2re-image contents to server-j2re-image +# Duplicate current j2re-image contents to server-j2re-image # for the server version of jre, before deploy build server-jdk-image:: ifeq ($(PLATFORM), macosx)
--- a/make/sun/font/FILES_c.gmk Wed Apr 17 12:13:43 2013 -0700 +++ b/make/sun/font/FILES_c.gmk Thu Apr 18 14:38:37 2013 -0700 @@ -106,7 +106,21 @@ OpenTypeLayoutEngine.cpp \ ThaiLayoutEngine.cpp \ ScriptAndLanguageTags.cpp \ - FontInstanceAdapter.cpp + FontInstanceAdapter.cpp \ + ContextualGlyphInsertionProc2.cpp \ + ContextualGlyphSubstProc2.cpp \ + GXLayoutEngine2.cpp \ + IndicRearrangementProcessor2.cpp \ + LigatureSubstProc2.cpp \ + MorphTables2.cpp \ + NonContextualGlyphSubstProc2.cpp \ + SegmentArrayProcessor2.cpp \ + SegmentSingleProcessor2.cpp \ + SimpleArrayProcessor2.cpp \ + SingleTableProcessor2.cpp \ + StateTableProcessor2.cpp \ + SubtableProcessor2.cpp \ + TrimmedArrayProcessor2.cpp ifeq ($(PLATFORM),windows)
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -175,7 +175,7 @@ setTitle(((Dialog) getTarget()).getTitle()); } - setAlwaysOnTop(getTarget().isAlwaysOnTop()); + updateAlwaysOnTopState(); updateMinimumSize(); final Shape shape = getTarget().getShape(); @@ -422,8 +422,8 @@ } @Override - public void setAlwaysOnTop(boolean value) { - platformWindow.setAlwaysOnTop(value); + public void updateAlwaysOnTopState() { + platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop()); } @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CClipboard.java Thu Apr 18 14:38:37 2013 -0700 @@ -110,4 +110,12 @@ public native void declareTypes(long[] formats, SunClipboard newOwner); public native void setData(byte[] data, long format); + + /** + * Invokes native check whether a change count on the general pasteboard is different + * than when we set it. The different count value means the current owner lost + * pasteboard ownership and someone else put data on the clipboard. + * @since 1.7 + */ + public native void checkPasteboard(); }
--- a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Thu Apr 18 14:38:37 2013 -0700 @@ -112,6 +112,14 @@ public void handleFocusEvent(boolean focused) { this.focused = focused; + if (focused) { + // see bug 8010925 + // we can't put this to handleWindowFocusEvent because + // it won't be invoced if focuse is moved to a html element + // on the same page. + CClipboard clipboard = (CClipboard) Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.checkPasteboard(); + } if (parentWindowActive) { responder.handleWindowFocusEvent(focused); }
--- a/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -180,7 +180,7 @@ } @Override - public void setAlwaysOnTop(boolean alwaysOnTop) { + public void updateAlwaysOnTopState() { } @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -87,7 +87,7 @@ } // 1.6 peer method - public void setAlwaysOnTop(boolean value) { + public void updateAlwaysOnTopState() { // no-op, since we just show the native print dialog }
--- a/src/macosx/native/sun/awt/CClipboard.m Wed Apr 17 12:13:43 2013 -0700 +++ b/src/macosx/native/sun/awt/CClipboard.m Thu Apr 18 14:38:37 2013 -0700 @@ -193,18 +193,18 @@ - (void) checkPasteboard:(id)application { AWT_ASSERT_APPKIT_THREAD; - + //NSLog(@"CClipboard checkPasteboard oldCount %d newCount %d newTypes %@", fChangeCount, [[NSPasteboard generalPasteboard] changeCount], [[NSPasteboard generalPasteboard] types]); - + // This is called via NSApplicationDidBecomeActiveNotification. - + // If the change count on the general pasteboard is different than when we set it // someone else put data on the clipboard. That means the current owner lost ownership. NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount]; - + if (fChangeCount != newChangeCount) { fChangeCount = newChangeCount; - + [self pasteboardChangedOwner:[NSPasteboard generalPasteboard]]; } } @@ -375,4 +375,21 @@ return returnValue; } +/* + * Class: sun_lwawt_macosx_CClipboard + * Method: checkPasteboard + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard +(JNIEnv *env, jobject inObject ) +{ + JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + [[CClipboard sharedClipboard] checkPasteboard:nil]; + }]; + + JNF_COCOA_EXIT(env); +} + +
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java Thu Apr 18 14:38:37 2013 -0700 @@ -238,12 +238,17 @@ * sending warnings to listeners. */ protected void warningOccurred(int code) { - if ((code < 0) || (code > MAX_WARNING)){ - throw new InternalError("Invalid warning index"); + cbLock.lock(); + try { + if ((code < 0) || (code > MAX_WARNING)){ + throw new InternalError("Invalid warning index"); + } + processWarningOccurred + ("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources", + Integer.toString(code)); + } finally { + cbLock.unlock(); } - processWarningOccurred - ("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources", - Integer.toString(code)); } /** @@ -260,7 +265,12 @@ * library warnings from being printed to stderr. */ protected void warningWithMessage(String msg) { - processWarningOccurred(msg); + cbLock.lock(); + try { + processWarningOccurred(msg); + } finally { + cbLock.unlock(); + } } public void setInput(Object input, @@ -269,18 +279,55 @@ { setThreadLock(); try { + cbLock.check(); + super.setInput(input, seekForwardOnly, ignoreMetadata); this.ignoreMetadata = ignoreMetadata; resetInternalState(); iis = (ImageInputStream) input; // Always works - setSource(structPointer, iis); + setSource(structPointer); } finally { clearThreadLock(); } } - private native void setSource(long structPointer, - ImageInputStream source); + /** + * This method is called from native code in order to fill + * native input buffer. + * + * We block any attempt to change the reading state during this + * method, in order to prevent a corruption of the native decoder + * state. + * + * @return number of bytes read from the stream. + */ + private int readInputData(byte[] buf, int off, int len) throws IOException { + cbLock.lock(); + try { + return iis.read(buf, off, len); + } finally { + cbLock.unlock(); + } + } + + /** + * This method is called from the native code in order to + * skip requested number of bytes in the input stream. + * + * @param n + * @return + * @throws IOException + */ + private long skipInputBytes(long n) throws IOException { + cbLock.lock(); + try { + return iis.skipBytes(n); + } finally { + cbLock.unlock(); + } + } + + private native void setSource(long structPointer); private void checkTablesOnly() throws IOException { if (debug) { @@ -332,6 +379,8 @@ public int getNumImages(boolean allowSearch) throws IOException { setThreadLock(); try { // locked thread + cbLock.check(); + return getNumImagesOnThread(allowSearch); } finally { clearThreadLock(); @@ -531,8 +580,13 @@ if (debug) { System.out.println("pushing back " + num + " bytes"); } - iis.seek(iis.getStreamPosition()-num); - // The buffer is clear after this, so no need to set haveSeeked. + cbLock.lock(); + try { + iis.seek(iis.getStreamPosition()-num); + // The buffer is clear after this, so no need to set haveSeeked. + } finally { + cbLock.unlock(); + } } /** @@ -639,7 +693,12 @@ * Ignore this profile. */ iccCS = null; - warningOccurred(WARNING_IGNORE_INVALID_ICC); + cbLock.lock(); + try { + warningOccurred(WARNING_IGNORE_INVALID_ICC); + } finally { + cbLock.unlock(); + } } } } @@ -648,6 +707,7 @@ setThreadLock(); try { if (currentImage != imageIndex) { + cbLock.check(); readHeader(imageIndex, true); } return width; @@ -660,6 +720,7 @@ setThreadLock(); try { if (currentImage != imageIndex) { + cbLock.check(); readHeader(imageIndex, true); } return height; @@ -688,6 +749,8 @@ setThreadLock(); try { if (currentImage != imageIndex) { + cbLock.check(); + readHeader(imageIndex, true); } @@ -711,6 +774,7 @@ private Iterator getImageTypesOnThread(int imageIndex) throws IOException { if (currentImage != imageIndex) { + cbLock.check(); readHeader(imageIndex, true); } @@ -926,6 +990,7 @@ setThreadLock(); try { if (!tablesOnlyChecked) { + cbLock.check(); checkTablesOnly(); } return streamMetadata; @@ -946,6 +1011,8 @@ return imageMetadata; } + cbLock.check(); + gotoImage(imageIndex); imageMetadata = new JPEGMetadata(false, false, iis, this); @@ -962,6 +1029,7 @@ throws IOException { setThreadLock(); try { + cbLock.check(); try { readInternal(imageIndex, param, false); } catch (RuntimeException e) { @@ -1191,58 +1259,63 @@ } target.setRect(destROI.x, destROI.y + y, raster); - processImageUpdate(image, - destROI.x, destROI.y+y, - raster.getWidth(), 1, - 1, 1, - destinationBands); - if ((y > 0) && (y%progInterval == 0)) { - int height = target.getHeight()-1; - float percentOfPass = ((float)y)/height; - if (progressive) { - if (knownPassCount != UNKNOWN) { - processImageProgress((pass + percentOfPass)*100.0F - / knownPassCount); - } else if (maxProgressivePass != Integer.MAX_VALUE) { - // Use the range of allowed progressive passes - processImageProgress((pass + percentOfPass)*100.0F - / (maxProgressivePass - minProgressivePass + 1)); + cbLock.lock(); + try { + processImageUpdate(image, + destROI.x, destROI.y+y, + raster.getWidth(), 1, + 1, 1, + destinationBands); + if ((y > 0) && (y%progInterval == 0)) { + int height = target.getHeight()-1; + float percentOfPass = ((float)y)/height; + if (progressive) { + if (knownPassCount != UNKNOWN) { + processImageProgress((pass + percentOfPass)*100.0F + / knownPassCount); + } else if (maxProgressivePass != Integer.MAX_VALUE) { + // Use the range of allowed progressive passes + processImageProgress((pass + percentOfPass)*100.0F + / (maxProgressivePass - minProgressivePass + 1)); + } else { + // Assume there are a minimum of MIN_ESTIMATED_PASSES + // and that there is always one more pass + // Compute the percentage as the percentage at the end + // of the previous pass, plus the percentage of this + // pass scaled to be the percentage of the total remaining, + // assuming a minimum of MIN_ESTIMATED_PASSES passes and + // that there is always one more pass. This is monotonic + // and asymptotic to 1.0, which is what we need. + int remainingPasses = // including this one + Math.max(2, MIN_ESTIMATED_PASSES-pass); + int totalPasses = pass + remainingPasses-1; + progInterval = Math.max(height/20*totalPasses, + totalPasses); + if (y%progInterval == 0) { + percentToDate = previousPassPercentage + + (1.0F - previousPassPercentage) + * (percentOfPass)/remainingPasses; + if (debug) { + System.out.print("pass= " + pass); + System.out.print(", y= " + y); + System.out.print(", progInt= " + progInterval); + System.out.print(", % of pass: " + percentOfPass); + System.out.print(", rem. passes: " + + remainingPasses); + System.out.print(", prev%: " + + previousPassPercentage); + System.out.print(", %ToDate: " + percentToDate); + System.out.print(" "); + } + processImageProgress(percentToDate*100.0F); + } + } } else { - // Assume there are a minimum of MIN_ESTIMATED_PASSES - // and that there is always one more pass - // Compute the percentage as the percentage at the end - // of the previous pass, plus the percentage of this - // pass scaled to be the percentage of the total remaining, - // assuming a minimum of MIN_ESTIMATED_PASSES passes and - // that there is always one more pass. This is monotonic - // and asymptotic to 1.0, which is what we need. - int remainingPasses = // including this one - Math.max(2, MIN_ESTIMATED_PASSES-pass); - int totalPasses = pass + remainingPasses-1; - progInterval = Math.max(height/20*totalPasses, - totalPasses); - if (y%progInterval == 0) { - percentToDate = previousPassPercentage + - (1.0F - previousPassPercentage) - * (percentOfPass)/remainingPasses; - if (debug) { - System.out.print("pass= " + pass); - System.out.print(", y= " + y); - System.out.print(", progInt= " + progInterval); - System.out.print(", % of pass: " + percentOfPass); - System.out.print(", rem. passes: " - + remainingPasses); - System.out.print(", prev%: " - + previousPassPercentage); - System.out.print(", %ToDate: " + percentToDate); - System.out.print(" "); - } - processImageProgress(percentToDate*100.0F); - } + processImageProgress(percentOfPass * 100.0F); } - } else { - processImageProgress(percentOfPass * 100.0F); } + } finally { + cbLock.unlock(); } } @@ -1255,33 +1328,58 @@ } private void passStarted (int pass) { - this.pass = pass; - previousPassPercentage = percentToDate; - processPassStarted(image, - pass, - minProgressivePass, - maxProgressivePass, - 0, 0, - 1,1, - destinationBands); + cbLock.lock(); + try { + this.pass = pass; + previousPassPercentage = percentToDate; + processPassStarted(image, + pass, + minProgressivePass, + maxProgressivePass, + 0, 0, + 1,1, + destinationBands); + } finally { + cbLock.unlock(); + } } private void passComplete () { - processPassComplete(image); + cbLock.lock(); + try { + processPassComplete(image); + } finally { + cbLock.unlock(); + } } void thumbnailStarted(int thumbnailIndex) { - processThumbnailStarted(currentImage, thumbnailIndex); + cbLock.lock(); + try { + processThumbnailStarted(currentImage, thumbnailIndex); + } finally { + cbLock.unlock(); + } } // Provide access to protected superclass method void thumbnailProgress(float percentageDone) { - processThumbnailProgress(percentageDone); + cbLock.lock(); + try { + processThumbnailProgress(percentageDone); + } finally { + cbLock.unlock(); + } } // Provide access to protected superclass method void thumbnailComplete() { - processThumbnailComplete(); + cbLock.lock(); + try { + processThumbnailComplete(); + } finally { + cbLock.unlock(); + } } /** @@ -1305,6 +1403,11 @@ public void abort() { setThreadLock(); try { + /** + * NB: we do not check the call back lock here, + * we allow to abort the reader any time. + */ + super.abort(); abortRead(structPointer); } finally { @@ -1327,6 +1430,7 @@ setThreadLock(); Raster retval = null; try { + cbLock.check(); /* * This could be further optimized by not resetting the dest. * offset and creating a translated raster in readInternal() @@ -1366,6 +1470,8 @@ public int getNumThumbnails(int imageIndex) throws IOException { setThreadLock(); try { + cbLock.check(); + getImageMetadata(imageIndex); // checks iis state for us // Now check the jfif segments JFIFMarkerSegment jfif = @@ -1386,6 +1492,8 @@ throws IOException { setThreadLock(); try { + cbLock.check(); + if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); @@ -1404,6 +1512,8 @@ throws IOException { setThreadLock(); try { + cbLock.check(); + if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); @@ -1423,6 +1533,8 @@ throws IOException { setThreadLock(); try { + cbLock.check(); + if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); @@ -1463,6 +1575,7 @@ public void reset() { setThreadLock(); try { + cbLock.check(); super.reset(); } finally { clearThreadLock(); @@ -1474,6 +1587,8 @@ public void dispose() { setThreadLock(); try { + cbLock.check(); + if (structPointer != 0) { disposerRecord.dispose(); structPointer = 0; @@ -1535,6 +1650,36 @@ theThread = null; } } + + private CallBackLock cbLock = new CallBackLock(); + + private static class CallBackLock { + + private State lockState; + + CallBackLock() { + lockState = State.Unlocked; + } + + void check() { + if (lockState != State.Unlocked) { + throw new IllegalStateException("Access to the reader is not allowed"); + } + } + + private void lock() { + lockState = State.Locked; + } + + private void unlock() { + lockState = State.Unlocked; + } + + private static enum State { + Unlocked, + Locked + } + } } /**
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java Thu Apr 18 14:38:37 2013 -0700 @@ -178,8 +178,7 @@ static { java.security.AccessController.doPrivileged( new sun.security.action.LoadLibraryAction("jpeg")); - initWriterIDs(ImageOutputStream.class, - JPEGQTable.class, + initWriterIDs(JPEGQTable.class, JPEGHuffmanTable.class); } @@ -195,11 +194,13 @@ public void setOutput(Object output) { setThreadLock(); try { + cbLock.check(); + super.setOutput(output); // validates output resetInternalState(); ios = (ImageOutputStream) output; // so this will always work // Set the native destination - setDest(structPointer, ios); + setDest(structPointer); } finally { clearThreadLock(); } @@ -354,6 +355,8 @@ ImageWriteParam param) throws IOException { setThreadLock(); try { + cbLock.check(); + writeOnThread(streamMetadata, image, param); } finally { clearThreadLock(); @@ -1077,13 +1080,18 @@ haveMetadata, restartInterval); - if (aborted) { - processWriteAborted(); - } else { - processImageComplete(); + cbLock.lock(); + try { + if (aborted) { + processWriteAborted(); + } else { + processImageComplete(); + } + + ios.flush(); + } finally { + cbLock.unlock(); } - - ios.flush(); currentImage++; // After a successful write } @@ -1091,6 +1099,8 @@ throws IOException { setThreadLock(); try { + cbLock.check(); + prepareWriteSequenceOnThread(streamMetadata); } finally { clearThreadLock(); @@ -1170,6 +1180,8 @@ throws IOException { setThreadLock(); try { + cbLock.check(); + if (sequencePrepared == false) { throw new IllegalStateException("sequencePrepared not called!"); } @@ -1183,6 +1195,8 @@ public void endWriteSequence() throws IOException { setThreadLock(); try { + cbLock.check(); + if (sequencePrepared == false) { throw new IllegalStateException("sequencePrepared not called!"); } @@ -1195,6 +1209,10 @@ public synchronized void abort() { setThreadLock(); try { + /** + * NB: we do not check the call back lock here, we allow to abort + * the reader any time. + */ super.abort(); abortWrite(structPointer); } finally { @@ -1218,6 +1236,8 @@ public void reset() { setThreadLock(); try { + cbLock.check(); + super.reset(); } finally { clearThreadLock(); @@ -1227,6 +1247,8 @@ public void dispose() { setThreadLock(); try { + cbLock.check(); + if (structPointer != 0) { disposerRecord.dispose(); structPointer = 0; @@ -1246,13 +1268,18 @@ * sending warnings to listeners. */ void warningOccurred(int code) { - if ((code < 0) || (code > MAX_WARNING)){ - throw new InternalError("Invalid warning index"); + cbLock.lock(); + try { + if ((code < 0) || (code > MAX_WARNING)){ + throw new InternalError("Invalid warning index"); + } + processWarningOccurred + (currentImage, + "com.sun.imageio.plugins.jpeg.JPEGImageWriterResources", + Integer.toString(code)); + } finally { + cbLock.unlock(); } - processWarningOccurred - (currentImage, - "com.sun.imageio.plugins.jpeg.JPEGImageWriterResources", - Integer.toString(code)); } /** @@ -1269,21 +1296,41 @@ * library warnings from being printed to stderr. */ void warningWithMessage(String msg) { - processWarningOccurred(currentImage, msg); + cbLock.lock(); + try { + processWarningOccurred(currentImage, msg); + } finally { + cbLock.unlock(); + } } void thumbnailStarted(int thumbnailIndex) { - processThumbnailStarted(currentImage, thumbnailIndex); + cbLock.lock(); + try { + processThumbnailStarted(currentImage, thumbnailIndex); + } finally { + cbLock.unlock(); + } } // Provide access to protected superclass method void thumbnailProgress(float percentageDone) { - processThumbnailProgress(percentageDone); + cbLock.lock(); + try { + processThumbnailProgress(percentageDone); + } finally { + cbLock.unlock(); + } } // Provide access to protected superclass method void thumbnailComplete() { - processThumbnailComplete(); + cbLock.lock(); + try { + processThumbnailComplete(); + } finally { + cbLock.unlock(); + } } ///////// End of Package-access API @@ -1610,16 +1657,14 @@ ////////////// Native methods and callbacks /** Sets up static native structures. */ - private static native void initWriterIDs(Class iosClass, - Class qTableClass, + private static native void initWriterIDs(Class qTableClass, Class huffClass); /** Sets up per-writer native structure and returns a pointer to it. */ private native long initJPEGImageWriter(); /** Sets up native structures for output stream */ - private native void setDest(long structPointer, - ImageOutputStream ios); + private native void setDest(long structPointer); /** * Returns <code>true</code> if the write was aborted. @@ -1744,7 +1789,12 @@ } raster.setRect(sourceLine); if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines - processImageProgress((float) y / (float) sourceHeight * 100.0F); + cbLock.lock(); + try { + processImageProgress((float) y / (float) sourceHeight * 100.0F); + } finally { + cbLock.unlock(); + } } } @@ -1772,6 +1822,25 @@ } } + /** + * This method is called from native code in order to write encoder + * output to the destination. + * + * We block any attempt to change the writer state during this + * method, in order to prevent a corruption of the native encoder + * state. + */ + private void writeOutputData(byte[] data, int offset, int len) + throws IOException + { + cbLock.lock(); + try { + ios.write(data, offset, len); + } finally { + cbLock.unlock(); + } + } + private Thread theThread = null; private int theLockCount = 0; @@ -1806,4 +1875,34 @@ theThread = null; } } + + private CallBackLock cbLock = new CallBackLock(); + + private static class CallBackLock { + + private State lockState; + + CallBackLock() { + lockState = State.Unlocked; + } + + void check() { + if (lockState != State.Unlocked) { + throw new IllegalStateException("Access to the writer is not allowed"); + } + } + + private void lock() { + lockState = State.Locked; + } + + private void unlock() { + lockState = State.Unlocked; + } + + private static enum State { + Unlocked, + Locked + } + } }
--- a/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -32,6 +32,7 @@ import java.io.ObjectInputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; import java.security.Permission; import java.util.Map; import java.util.logging.Level; @@ -213,7 +214,6 @@ Object moi; - // ------------------------------ // ------------------------------ Constructor<?> cons = findConstructor(theClass, null); @@ -224,6 +224,7 @@ // Instantiate the new object try { ReflectUtil.checkPackageAccess(theClass); + ensureClassAccess(theClass); moi= cons.newInstance(); } catch (InvocationTargetException e) { // Wrap the exception. @@ -270,7 +271,6 @@ checkMBeanPermission(theClass, null, null, "instantiate"); // Instantiate the new object - // ------------------------------ // ------------------------------ final Class<?>[] tab; @@ -300,6 +300,7 @@ } try { ReflectUtil.checkPackageAccess(theClass); + ensureClassAccess(theClass); moi = cons.newInstance(params); } catch (NoSuchMethodError error) { @@ -741,4 +742,13 @@ sm.checkPermission(perm); } } + + private static void ensureClassAccess(Class clazz) + throws IllegalAccessException + { + int mod = clazz.getModifiers(); + if (!Modifier.isPublic(mod)) { + throw new IllegalAccessException("Class is not public and can't be instantiated"); + } + } }
--- a/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java Thu Apr 18 14:38:37 2013 -0700 @@ -56,7 +56,7 @@ // from simultaneous creation and destruction // reduces possibility of deadlock, compared to // synchronizing to the class instance - private Object traRecLock = new Object(); + private final Object traRecLock = new Object(); // DEVICE ATTRIBUTES @@ -474,7 +474,7 @@ This is necessary for Receivers retrieved via MidiSystem.getReceiver() (which opens the device implicitely). */ - protected abstract class AbstractReceiver implements MidiDeviceReceiver { + abstract class AbstractReceiver implements MidiDeviceReceiver { private boolean open = true; @@ -483,24 +483,24 @@ Receiver. Therefore, subclasses should not override this method. Instead, they should implement implSend(). */ - public synchronized void send(MidiMessage message, long timeStamp) { - if (open) { - implSend(message, timeStamp); - } else { + @Override + public final synchronized void send(final MidiMessage message, + final long timeStamp) { + if (!open) { throw new IllegalStateException("Receiver is not open"); } + implSend(message, timeStamp); } - - protected abstract void implSend(MidiMessage message, long timeStamp); - + abstract void implSend(MidiMessage message, long timeStamp); /** Close the Receiver. * Here, the call to the magic method closeInternal() takes place. * Therefore, subclasses that override this method must call * 'super.close()'. */ - public void close() { + @Override + public final void close() { open = false; synchronized (AbstractMidiDevice.this.traRecLock) { AbstractMidiDevice.this.getReceiverList().remove(this); @@ -508,11 +508,12 @@ AbstractMidiDevice.this.closeInternal(this); } - public MidiDevice getMidiDevice() { + @Override + public final MidiDevice getMidiDevice() { return AbstractMidiDevice.this; } - protected boolean isOpen() { + final boolean isOpen() { return open; }
--- a/src/share/classes/com/sun/media/sound/FastShortMessage.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/media/sound/FastShortMessage.java Thu Apr 18 14:38:37 2013 -0700 @@ -32,7 +32,7 @@ * * @author Florian Bomers */ -class FastShortMessage extends ShortMessage { +final class FastShortMessage extends ShortMessage { private int packedMsg; public FastShortMessage(int packedMsg) throws InvalidMidiDataException {
--- a/src/share/classes/com/sun/media/sound/FastSysexMessage.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/media/sound/FastSysexMessage.java Thu Apr 18 14:38:37 2013 -0700 @@ -32,7 +32,7 @@ * * @author Florian Bomers */ -class FastSysexMessage extends SysexMessage { +final class FastSysexMessage extends SysexMessage { FastSysexMessage(byte[] data) throws InvalidMidiDataException { super(data);
--- a/src/share/classes/com/sun/media/sound/MidiOutDevice.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/media/sound/MidiOutDevice.java Thu Apr 18 14:38:37 2013 -0700 @@ -103,9 +103,9 @@ class MidiOutReceiver extends AbstractReceiver { - protected void implSend(MidiMessage message, long timeStamp) { - int length = message.getLength(); - int status = message.getStatus(); + void implSend(final MidiMessage message, final long timeStamp) { + final int length = message.getLength(); + final int status = message.getStatus(); if (length <= 3 && status != 0xF0 && status != 0xF7) { int packedMsg; if (message instanceof ShortMessage) { @@ -140,11 +140,15 @@ } nSendShortMessage(id, packedMsg, timeStamp); } else { + final byte[] data; if (message instanceof FastSysexMessage) { - nSendLongMessage(id, ((FastSysexMessage) message).getReadOnlyMessage(), - length, timeStamp); + data = ((FastSysexMessage) message).getReadOnlyMessage(); } else { - nSendLongMessage(id, message.getMessage(), length, timeStamp); + data = message.getMessage(); + } + final int dataLength = Math.min(length, data.length); + if (dataLength > 0) { + nSendLongMessage(id, data, dataLength, timeStamp); } } }
--- a/src/share/classes/com/sun/media/sound/RealTimeSequencer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/com/sun/media/sound/RealTimeSequencer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1026,7 +1026,7 @@ class SequencerReceiver extends AbstractReceiver { - protected void implSend(MidiMessage message, long timeStamp) { + void implSend(MidiMessage message, long timeStamp) { if (recording) { long tickPos = 0;
--- a/src/share/classes/java/awt/Window.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/awt/Window.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -2234,7 +2234,7 @@ WindowPeer peer = (WindowPeer)this.peer; synchronized(getTreeLock()) { if (peer != null) { - peer.setAlwaysOnTop(alwaysOnTop); + peer.updateAlwaysOnTopState(); } } }
--- a/src/share/classes/java/awt/peer/WindowPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/awt/peer/WindowPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -55,15 +55,14 @@ void toBack(); /** - * Sets if the window should always stay on top of all other windows or - * not. + * Updates the window's always-on-top state. + * Sets if the window should always stay + * on top of all other windows or not. * - * @param alwaysOnTop if the window should always stay on top of all other - * windows or not - * + * @see Window#getAlwaysOnTop() * @see Window#setAlwaysOnTop(boolean) */ - void setAlwaysOnTop(boolean alwaysOnTop); + void updateAlwaysOnTopState(); /** * Updates the window's focusable state.
--- a/src/share/classes/java/beans/ThreadGroupContext.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/beans/ThreadGroupContext.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -29,7 +29,6 @@ import com.sun.beans.finder.PropertyEditorFinder; import java.awt.GraphicsEnvironment; -import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; @@ -42,7 +41,7 @@ */ final class ThreadGroupContext { - private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>(); + private static final WeakIdentityMap<ThreadGroupContext> contexts = new WeakIdentityMap<>(); /** * Returns the appropriate {@code AppContext} for the caller, @@ -69,6 +68,8 @@ private BeanInfoFinder beanInfoFinder; private PropertyEditorFinder propertyEditorFinder; + private ThreadGroupContext() { + } boolean isDesignTime() { return this.isDesignTime;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/beans/WeakIdentityMap.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,181 @@ +/* + * 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 java.beans; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +/** + * Hash table based mapping, which uses weak references to store keys + * and reference-equality in place of object-equality to compare them. + * An entry will automatically be removed when its key is no longer + * in ordinary use. Both null values and the null key are supported. + * + * @see java.util.IdentityHashMap + * @see java.util.WeakHashMap + */ +final class WeakIdentityMap<T> { + + private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two + private static final Object NULL = new Object(); // special object for null key + + private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); + + private Entry<T>[] table = newTable(1<<3); // table's length MUST be a power of two + private int threshold = 6; // the next size value at which to resize + private int size = 0; // the number of key-value mappings + + public T get(Object key) { + removeStaleEntries(); + if (key == null) { + key = NULL; + } + int hash = key.hashCode(); + int index = getIndex(this.table, hash); + for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) { + if (entry.isMatched(key, hash)) { + return entry.value; + } + } + return null; + } + + public T put(Object key, T value) { + removeStaleEntries(); + if (key == null) { + key = NULL; + } + int hash = key.hashCode(); + int index = getIndex(this.table, hash); + for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) { + if (entry.isMatched(key, hash)) { + T oldValue = entry.value; + entry.value = value; + return oldValue; + } + } + this.table[index] = new Entry<T>(key, hash, value, this.queue, this.table[index]); + if (++this.size >= this.threshold) { + if (this.table.length == MAXIMUM_CAPACITY) { + this.threshold = Integer.MAX_VALUE; + } + else { + removeStaleEntries(); + Entry<T>[] table = newTable(this.table.length * 2); + transfer(this.table, table); + + // If ignoring null elements and processing ref queue caused massive + // shrinkage, then restore old table. This should be rare, but avoids + // unbounded expansion of garbage-filled tables. + if (this.size >= this.threshold / 2) { + this.table = table; + this.threshold *= 2; + } + else { + transfer(table, this.table); + } + } + } + return null; + } + + private void removeStaleEntries() { + for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) { + @SuppressWarnings("unchecked") + Entry<T> entry = (Entry<T>) ref; + int index = getIndex(this.table, entry.hash); + + Entry<T> prev = this.table[index]; + Entry<T> current = prev; + while (current != null) { + Entry<T> next = current.next; + if (current == entry) { + if (prev == entry) { + this.table[index] = next; + } + else { + prev.next = next; + } + entry.value = null; // Help GC + entry.next = null; // Help GC + this.size--; + break; + } + prev = current; + current = next; + } + } + } + + private void transfer(Entry<T>[] oldTable, Entry<T>[] newTable) { + for (int i = 0; i < oldTable.length; i++) { + Entry<T> entry = oldTable[i]; + oldTable[i] = null; + while (entry != null) { + Entry<T> next = entry.next; + Object key = entry.get(); + if (key == null) { + entry.value = null; // Help GC + entry.next = null; // Help GC + this.size--; + } + else { + int index = getIndex(newTable, entry.hash); + entry.next = newTable[index]; + newTable[index] = entry; + } + entry = next; + } + } + } + + + @SuppressWarnings("unchecked") + private Entry<T>[] newTable(int length) { + return (Entry<T>[]) new Entry<?>[length]; + } + + private static int getIndex(Entry<?>[] table, int hash) { + return hash & (table.length - 1); + } + + private static class Entry<T> extends WeakReference<Object> { + private final int hash; + private T value; + private Entry<T> next; + + Entry(Object key, int hash, T value, ReferenceQueue<Object> queue, Entry<T> next) { + super(key, queue); + this.hash = hash; + this.value = value; + this.next = next; + } + + boolean isMatched(Object key, int hash) { + return (this.hash == hash) && (key == get()); + } + } +}
--- a/src/share/classes/java/io/ObjectInputStream.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/io/ObjectInputStream.java Thu Apr 18 14:38:37 2013 -0700 @@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import static java.io.ObjectStreamClass.processQueue; +import sun.reflect.misc.ReflectUtil; /** * An ObjectInputStream deserializes primitive data and objects previously @@ -1519,6 +1520,12 @@ } } + private boolean isCustomSubclass() { + // Return true if this class is a custom subclass of ObjectInputStream + return getClass().getClassLoader() + != ObjectInputStream.class.getClassLoader(); + } + /** * Reads in and returns class descriptor for a dynamic proxy class. Sets * passHandle to proxy class descriptor's assigned handle. If proxy class @@ -1548,6 +1555,15 @@ try { if ((cl = resolveProxyClass(ifaces)) == null) { resolveEx = new ClassNotFoundException("null class"); + } else if (!Proxy.isProxyClass(cl)) { + throw new InvalidClassException("Not a proxy"); + } else { + // ReflectUtil.checkProxyPackageAccess makes a test + // equivalent to isCustomSubclass so there's no need + // to condition this call to isCustomSubclass == true here. + ReflectUtil.checkProxyPackageAccess( + getClass().getClassLoader(), + cl.getInterfaces()); } } catch (ClassNotFoundException ex) { resolveEx = ex; @@ -1589,9 +1605,12 @@ Class cl = null; ClassNotFoundException resolveEx = null; bin.setBlockDataMode(true); + final boolean checksRequired = isCustomSubclass(); try { if ((cl = resolveClass(readDesc)) == null) { resolveEx = new ClassNotFoundException("null class"); + } else if (checksRequired) { + ReflectUtil.checkPackageAccess(cl); } } catch (ClassNotFoundException ex) { resolveEx = ex;
--- a/src/share/classes/java/lang/Integer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/lang/Integer.java Thu Apr 18 14:38:37 2013 -0700 @@ -607,7 +607,7 @@ int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE - h = Math.min(i, Integer.MAX_VALUE - (-low)); + h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } high = h;
--- a/src/share/classes/java/lang/ProcessBuilder.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/lang/ProcessBuilder.java Thu Apr 18 14:38:37 2013 -0700 @@ -30,6 +30,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.FileOutputStream; +import java.security.AccessControlException; import java.util.Arrays; import java.util.ArrayList; import java.util.List; @@ -1012,8 +1013,9 @@ String prog = cmdarray[0]; SecurityManager security = System.getSecurityManager(); - if (security != null) + if (security != null) { security.checkExec(prog); + } String dir = directory == null ? null : directory.toString(); @@ -1024,13 +1026,24 @@ redirects, redirectErrorStream); } catch (IOException e) { + String exceptionInfo = ": " + e.getMessage(); + Throwable cause = e; + if (security != null) { + // Can not disclose the fail reason for read-protected files. + try { + security.checkRead(prog); + } catch (AccessControlException ace) { + exceptionInfo = ""; + cause = ace; + } + } // It's much easier for us to create a high-quality error // message than the low-level C code which found the problem. throw new IOException( "Cannot run program \"" + prog + "\"" + (dir == null ? "" : " (in directory \"" + dir + "\")") - + ": " + e.getMessage(), - e); + + exceptionInfo, + cause); } } }
--- a/src/share/classes/java/lang/invoke/MethodHandles.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Thu Apr 18 14:38:37 2013 -0700 @@ -1236,6 +1236,30 @@ checkMethod(refKind, refc, method); if (method.isMethodHandleInvoke()) return fakeMethodHandleInvoke(method); + + Class<?> refcAsSuper; + if (refKind == REF_invokeSpecial && + refc != lookupClass() && + refc != (refcAsSuper = lookupClass().getSuperclass()) && + refc.isAssignableFrom(lookupClass())) { + assert(!method.getName().equals("<init>")); // not this code path + // Per JVMS 6.5, desc. of invokespecial instruction: + // If the method is in a superclass of the LC, + // and if our original search was above LC.super, + // repeat the search (symbolic lookup) from LC.super. + // FIXME: MemberName.resolve should handle this instead. + MemberName m2 = new MemberName(refcAsSuper, + method.getName(), + method.getMethodType(), + REF_invokeSpecial); + m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull()); + if (m2 == null) throw new InternalError(method.toString()); + method = m2; + refc = refcAsSuper; + // redo basic checks + checkMethod(refKind, refc, method); + } + MethodHandle mh = DirectMethodHandle.make(refc, method); mh = maybeBindCaller(method, mh, callerClass); mh = mh.setVarargs(method);
--- a/src/share/classes/java/lang/ref/Finalizer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/lang/ref/Finalizer.java Thu Apr 18 14:38:37 2013 -0700 @@ -38,9 +38,9 @@ */ static native void invokeFinalizeMethod(Object o) throws Throwable; - static private ReferenceQueue queue = new ReferenceQueue(); - static private Finalizer unfinalized = null; - static private Object lock = new Object(); + private static ReferenceQueue queue = new ReferenceQueue(); + private static Finalizer unfinalized = null; + private static final Object lock = new Object(); private Finalizer next = null, @@ -142,7 +142,11 @@ /* Called by Runtime.runFinalization() */ static void runFinalization() { forkSecondaryFinalizer(new Runnable() { + private volatile boolean running; public void run() { + if (running) + return; + running = true; for (;;) { Finalizer f = (Finalizer)queue.poll(); if (f == null) break; @@ -155,7 +159,11 @@ /* Invoked by java.lang.Shutdown */ static void runAllFinalizers() { forkSecondaryFinalizer(new Runnable() { + private volatile boolean running; public void run() { + if (running) + return; + running = true; for (;;) { Finalizer f; synchronized (lock) { @@ -168,10 +176,14 @@ } private static class FinalizerThread extends Thread { + private volatile boolean running; FinalizerThread(ThreadGroup g) { super(g, "Finalizer"); } public void run() { + if (running) + return; + running = true; for (;;) { try { Finalizer f = (Finalizer)queue.remove();
--- a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java Thu Apr 18 14:38:37 2013 -0700 @@ -124,7 +124,7 @@ * not connected already. */ protected void disconnect() { - disconnect0(connectedAddress.family); + disconnect0(connectedAddress.holder().getFamily()); connected = false; connectedAddress = null; connectedPort = -1;
--- a/src/share/classes/java/net/Inet4Address.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/Inet4Address.java Thu Apr 18 14:38:37 2013 -0700 @@ -102,27 +102,28 @@ Inet4Address() { super(); - hostName = null; - address = 0; - family = IPv4; + holder().hostName = null; + holder().address = 0; + holder().family = IPv4; } Inet4Address(String hostName, byte addr[]) { - this.hostName = hostName; - this.family = IPv4; + holder().hostName = hostName; + holder().family = IPv4; if (addr != null) { if (addr.length == INADDRSZ) { - address = addr[3] & 0xFF; + int address = addr[3] & 0xFF; address |= ((addr[2] << 8) & 0xFF00); address |= ((addr[1] << 16) & 0xFF0000); address |= ((addr[0] << 24) & 0xFF000000); + holder().address = address; } } } Inet4Address(String hostName, int address) { - this.hostName = hostName; - this.family = IPv4; - this.address = address; + holder().hostName = hostName; + holder().family = IPv4; + holder().address = address; } /** @@ -136,8 +137,8 @@ private Object writeReplace() throws ObjectStreamException { // will replace the to be serialized 'this' object InetAddress inet = new InetAddress(); - inet.hostName = this.hostName; - inet.address = this.address; + inet.holder().hostName = holder().getHostName(); + inet.holder().address = holder().getAddress(); /** * Prior to 1.4 an InetAddress was created with a family @@ -145,7 +146,7 @@ * For compatibility reasons we must therefore write the * the InetAddress with this family. */ - inet.family = 2; + inet.holder().family = 2; return inet; } @@ -159,7 +160,7 @@ * @since JDK1.1 */ public boolean isMulticastAddress() { - return ((address & 0xf0000000) == 0xe0000000); + return ((holder().getAddress() & 0xf0000000) == 0xe0000000); } /** @@ -169,7 +170,7 @@ * @since 1.4 */ public boolean isAnyLocalAddress() { - return address == 0; + return holder().getAddress() == 0; } /** @@ -198,6 +199,7 @@ // defined in "Documenting Special Use IPv4 Address Blocks // that have been Registered with IANA" by Bill Manning // draft-manning-dsua-06.txt + int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 169) && (((address >>> 16) & 0xFF) == 254); } @@ -214,6 +216,7 @@ // 10/8 prefix // 172.16/12 prefix // 192.168/16 prefix + int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 10) || ((((address >>> 24) & 0xFF) == 172) && (((address >>> 16) & 0xF0) == 16)) @@ -260,6 +263,7 @@ */ public boolean isMCLinkLocal() { // 224.0.0/24 prefix and ttl == 1 + int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 224) && (((address >>> 16) & 0xFF) == 0) && (((address >>> 8) & 0xFF) == 0); @@ -275,6 +279,7 @@ */ public boolean isMCSiteLocal() { // 239.255/16 prefix or ttl < 32 + int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 239) && (((address >>> 16) & 0xFF) == 255); } @@ -290,6 +295,7 @@ */ public boolean isMCOrgLocal() { // 239.192 - 239.195 + int address = holder().getAddress(); return (((address >>> 24) & 0xFF) == 239) && (((address >>> 16) & 0xFF) >= 192) && (((address >>> 16) & 0xFF) <= 195); @@ -303,6 +309,7 @@ * @return the raw IP address of this object. */ public byte[] getAddress() { + int address = holder().getAddress(); byte[] addr = new byte[INADDRSZ]; addr[0] = (byte) ((address >>> 24) & 0xFF); @@ -328,7 +335,7 @@ * @return a hash code value for this IP address. */ public int hashCode() { - return address; + return holder().getAddress(); } /** @@ -349,7 +356,7 @@ */ public boolean equals(Object obj) { return (obj != null) && (obj instanceof Inet4Address) && - (((InetAddress)obj).address == address); + (((InetAddress)obj).holder().getAddress() == holder().getAddress()); } // Utilities
--- a/src/share/classes/java/net/Inet4AddressImpl.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/Inet4AddressImpl.java Thu Apr 18 14:38:37 2013 -0700 @@ -40,7 +40,7 @@ public synchronized InetAddress anyLocalAddress() { if (anyLocalAddress == null) { anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00} - anyLocalAddress.hostName = "0.0.0.0"; + anyLocalAddress.holder().hostName = "0.0.0.0"; } return anyLocalAddress; }
--- a/src/share/classes/java/net/Inet6Address.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/Inet6Address.java Thu Apr 18 14:38:37 2013 -0700 @@ -213,18 +213,18 @@ Inet6Address() { super(); - hostName = null; + holder().hostName = null; ipaddress = new byte[INADDRSZ]; - family = IPv6; + holder().family = IPv6; } /* checking of value for scope_id should be done by caller * scope_id must be >= 0, or -1 to indicate not being set */ Inet6Address(String hostName, byte addr[], int scope_id) { - this.hostName = hostName; + holder().hostName = hostName; if (addr.length == INADDRSZ) { // normal IPv6 address - family = IPv6; + holder().family = IPv6; ipaddress = addr.clone(); } if (scope_id >= 0) { @@ -325,9 +325,9 @@ } private void initif(String hostName, byte addr[],NetworkInterface nif) throws UnknownHostException { - this.hostName = hostName; + holder().hostName = hostName; if (addr.length == INADDRSZ) { // normal IPv6 address - family = IPv6; + holder().family = IPv6; ipaddress = addr.clone(); } if (nif != null) { @@ -412,6 +412,11 @@ throws IOException, ClassNotFoundException { scope_ifname = null; scope_ifname_set = false; + + if (getClass().getClassLoader() != null) { + throw new SecurityException ("invalid address type"); + } + s.defaultReadObject(); if (ifname != null && !"".equals (ifname)) { @@ -445,7 +450,7 @@ ipaddress.length); } - if (family != IPv6) { + if (holder().getFamily() != IPv6) { throw new InvalidObjectException("invalid address family type"); } }
--- a/src/share/classes/java/net/Inet6AddressImpl.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/Inet6AddressImpl.java Thu Apr 18 14:38:37 2013 -0700 @@ -81,7 +81,7 @@ if (anyLocalAddress == null) { if (InetAddress.preferIPv6Address) { anyLocalAddress = new Inet6Address(); - anyLocalAddress.hostName = "::"; + anyLocalAddress.holder().hostName = "::"; } else { anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress(); }
--- a/src/share/classes/java/net/InetAddress.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/InetAddress.java Thu Apr 18 14:38:37 2013 -0700 @@ -34,8 +34,12 @@ import java.util.ArrayList; import java.security.AccessController; import java.io.ObjectStreamException; +import java.io.ObjectStreamField; import java.io.IOException; import java.io.ObjectInputStream; +import java.io.ObjectInputStream.GetField; +import java.io.ObjectOutputStream; +import java.io.ObjectOutputStream.PutField; import sun.security.action.*; import sun.net.InetAddressCachePolicy; import sun.net.util.IPAddressUtil; @@ -199,25 +203,47 @@ /* Specify address family preference */ static transient boolean preferIPv6Address = false; - /** - * @serial - */ - String hostName; + static class InetAddressHolder { + + InetAddressHolder() {} + + InetAddressHolder(String hostName, int address, int family) { + this.hostName = hostName; + this.address = address; + this.family = family; + } + + String hostName; + + String getHostName() { + return hostName; + } + + /** + * Holds a 32-bit IPv4 address. + */ + int address; - /** - * Holds a 32-bit IPv4 address. - * - * @serial - */ - int address; + int getAddress() { + return address; + } + + /** + * Specifies the address family type, for instance, '1' for IPv4 + * addresses, and '2' for IPv6 addresses. + */ + int family; - /** - * Specifies the address family type, for instance, '1' for IPv4 - * addresses, and '2' for IPv6 addresses. - * - * @serial - */ - int family; + int getFamily() { + return family; + } + } + + final transient InetAddressHolder holder; + + InetAddressHolder holder() { + return holder; + } /* Used to store the name service provider */ private static List<NameService> nameServices = null; @@ -245,6 +271,7 @@ * put in the address cache, since it is not created by name. */ InetAddress() { + holder = new InetAddressHolder(); } /** @@ -257,7 +284,7 @@ */ private Object readResolve() throws ObjectStreamException { // will replace the deserialized 'this' object - return new Inet4Address(this.hostName, this.address); + return new Inet4Address(holder().getHostName(), holder().getAddress()); } /** @@ -494,10 +521,10 @@ * @see SecurityManager#checkConnect */ String getHostName(boolean check) { - if (hostName == null) { - hostName = InetAddress.getHostFromNameService(this, check); + if (holder().getHostName() == null) { + holder().hostName = InetAddress.getHostFromNameService(this, check); } - return hostName; + return holder().getHostName(); } /** @@ -660,6 +687,7 @@ * @return a string representation of this IP address. */ public String toString() { + String hostName = holder().getHostName(); return ((hostName != null) ? hostName : "") + "/" + getHostAddress(); } @@ -1515,14 +1543,58 @@ } } + private static final long FIELDS_OFFSET; + private static final sun.misc.Unsafe UNSAFE; + + static { + try { + sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); + FIELDS_OFFSET = unsafe.objectFieldOffset( + InetAddress.class.getDeclaredField("holder") + ); + UNSAFE = unsafe; + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + private void readObject (ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject (); if (getClass().getClassLoader() != null) { - hostName = null; - address = 0; throw new SecurityException ("invalid address type"); } + GetField gf = s.readFields(); + String host = (String)gf.get("hostName", null); + int address= gf.get("address", 0); + int family= gf.get("family", 0); + InetAddressHolder h = new InetAddressHolder(host, address, family); + UNSAFE.putObject(this, FIELDS_OFFSET, h); + } + + /* needed because the serializable fields no longer exist */ + + /** + * @serialField hostName String + * @serialField address int + * @serialField family int + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("hostName", String.class), + new ObjectStreamField("address", int.class), + new ObjectStreamField("family", int.class), + }; + + private void writeObject (ObjectOutputStream s) throws + IOException { + if (getClass().getClassLoader() != null) { + throw new SecurityException ("invalid address type"); + } + PutField pf = s.putFields(); + pf.put("hostName", holder().hostName); + pf.put("address", holder().address); + pf.put("family", holder().family); + s.writeFields(); + s.flush(); } }
--- a/src/share/classes/java/net/InetSocketAddress.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/net/InetSocketAddress.java Thu Apr 18 14:38:37 2013 -0700 @@ -87,8 +87,8 @@ if (hostname != null) return hostname; if (addr != null) { - if (addr.hostName != null) - return addr.hostName; + if (addr.holder().getHostName() != null) + return addr.holder().getHostName(); else return addr.getHostAddress(); }
--- a/src/share/classes/java/rmi/server/LogStream.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/rmi/server/LogStream.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -120,6 +120,13 @@ */ @Deprecated public static synchronized void setDefaultStream(PrintStream newDefault) { + SecurityManager sm = System.getSecurityManager(); + + if (sm != null) { + sm.checkPermission( + new java.util.logging.LoggingPermission("control", null)); + } + defaultStream = newDefault; }
--- a/src/share/classes/java/sql/DriverManager.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/sql/DriverManager.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -516,7 +516,7 @@ */ try{ while(driversIterator.hasNext()) { - println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next()); + driversIterator.next(); } } catch(Throwable t) { // Do nothing
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Thu Apr 18 14:38:37 2013 -0700 @@ -40,6 +40,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; /** * A hash table supporting full concurrency of retrievals and @@ -1535,7 +1536,23 @@ @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject(); + // Don't call defaultReadObject() + ObjectInputStream.GetField oisFields = s.readFields(); + final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null); + + final int ssize = oisSegments.length; + if (ssize < 1 || ssize > MAX_SEGMENTS + || (ssize & (ssize-1)) != 0 ) // ssize not power of two + throw new java.io.InvalidObjectException("Bad number of segments:" + + ssize); + int sshift = 0, ssizeTmp = ssize; + while (ssizeTmp > 1) { + ++sshift; + ssizeTmp >>>= 1; + } + UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift); + UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1); + UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments); // set hashMask UNSAFE.putIntVolatile(this, HASHSEED_OFFSET, randomHashSeed(this)); @@ -1568,6 +1585,9 @@ private static final long TBASE; private static final int TSHIFT; private static final long HASHSEED_OFFSET; + private static final long SEGSHIFT_OFFSET; + private static final long SEGMASK_OFFSET; + private static final long SEGMENTS_OFFSET; static { int ss, ts; @@ -1581,6 +1601,12 @@ ss = UNSAFE.arrayIndexScale(sc); HASHSEED_OFFSET = UNSAFE.objectFieldOffset( ConcurrentHashMap.class.getDeclaredField("hashSeed")); + SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset( + ConcurrentHashMap.class.getDeclaredField("segmentShift")); + SEGMASK_OFFSET = UNSAFE.objectFieldOffset( + ConcurrentHashMap.class.getDeclaredField("segmentMask")); + SEGMENTS_OFFSET = UNSAFE.objectFieldOffset( + ConcurrentHashMap.class.getDeclaredField("segments")); } catch (Exception e) { throw new Error(e); }
--- a/src/share/classes/sun/awt/EmbeddedFrame.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/awt/EmbeddedFrame.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -532,7 +532,7 @@ public void toBack() {} public void updateFocusableWindowState() {} public void updateAlwaysOnTop() {} - public void setAlwaysOnTop(boolean alwaysOnTop) {} + public void updateAlwaysOnTopState() {} public Component getGlobalHeavyweightFocusOwner() { return null; } public void setBoundsPrivate(int x, int y, int width, int height) { setBounds(x, y, width, height, SET_BOUNDS);
--- a/src/share/classes/sun/awt/datatransfer/TransferableProxy.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/awt/datatransfer/TransferableProxy.java Thu Apr 18 14:38:37 2013 -0700 @@ -102,11 +102,11 @@ protected final boolean isLocal; } -class ClassLoaderObjectOutputStream extends ObjectOutputStream { +final class ClassLoaderObjectOutputStream extends ObjectOutputStream { private final Map<Set<String>, ClassLoader> map = new HashMap<Set<String>, ClassLoader>(); - public ClassLoaderObjectOutputStream(OutputStream os) throws IOException { + ClassLoaderObjectOutputStream(OutputStream os) throws IOException { super(os); } @@ -140,15 +140,15 @@ map.put(s, classLoader); } - public Map<Set<String>, ClassLoader> getClassLoaderMap() { + Map<Set<String>, ClassLoader> getClassLoaderMap() { return new HashMap(map); } } -class ClassLoaderObjectInputStream extends ObjectInputStream { +final class ClassLoaderObjectInputStream extends ObjectInputStream { private final Map<Set<String>, ClassLoader> map; - public ClassLoaderObjectInputStream(InputStream is, + ClassLoaderObjectInputStream(InputStream is, Map<Set<String>, ClassLoader> map) throws IOException { super(is); @@ -166,8 +166,11 @@ s.add(className); ClassLoader classLoader = map.get(s); - - return Class.forName(className, false, classLoader); + if (classLoader != null) { + return Class.forName(className, false, classLoader); + } else { + return super.resolveClass(classDesc); + } } protected Class<?> resolveProxyClass(String[] interfaces) @@ -179,6 +182,9 @@ } ClassLoader classLoader = map.get(s); + if (classLoader == null) { + return super.resolveProxyClass(interfaces); + } // The code below is mostly copied from the superclass. ClassLoader nonPublicLoader = null;
--- a/src/share/classes/sun/awt/image/ImageRepresentation.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/awt/image/ImageRepresentation.java Thu Apr 18 14:38:37 2013 -0700 @@ -333,10 +333,10 @@ hints = h; } - private native void setICMpixels(int x, int y, int w, int h, int[] lut, + private native boolean setICMpixels(int x, int y, int w, int h, int[] lut, byte[] pix, int off, int scansize, IntegerComponentRaster ict); - private native int setDiffICM(int x, int y, int w, int h, int[] lut, + private native boolean setDiffICM(int x, int y, int w, int h, int[] lut, int transPix, int numLut, IndexColorModel icm, byte[] pix, int off, int scansize, ByteComponentRaster bct, int chanOff); @@ -426,10 +426,10 @@ IndexColorModel icm = (IndexColorModel) model; ByteComponentRaster bct = (ByteComponentRaster) biRaster; int numlut = numSrcLUT; - if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex, + if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex, numSrcLUT, icm, pix, off, scansize, bct, - bct.getDataOffset(0)) == 0) { + bct.getDataOffset(0))) { convertToRGB(); } else { @@ -470,9 +470,14 @@ if (s_useNative) { // Note that setICMpixels modifies the raster directly // so we must mark it as changed afterwards - setICMpixels(x, y, w, h, srcLUT, pix, off, scansize, - iraster); - iraster.markDirty(); + if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize, + iraster)) + { + iraster.markDirty(); + } else { + abort(); + return; + } } else { int[] storage = new int[w*h];
--- a/src/share/classes/sun/font/CMap.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/font/CMap.java Thu Apr 18 14:38:37 2013 -0700 @@ -841,7 +841,6 @@ CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) { - System.err.println("WARNING: CMapFormat8 is untested."); bbuffer.position(offset+6); CharBuffer buffer = bbuffer.asCharBuffer(); firstCode = buffer.get(); @@ -884,7 +883,6 @@ CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) { - System.err.println("WARNING: CMapFormat8 is untested."); bbuffer.position(12); bbuffer.get(is32); nGroups = bbuffer.getInt(); @@ -915,7 +913,6 @@ CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) { - System.err.println("WARNING: CMapFormat10 is untested."); firstCode = bbuffer.getInt() & INTMASK; entryCount = bbuffer.getInt() & INTMASK; bbuffer.position(offset+20);
--- a/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -791,10 +791,10 @@ // convert source to IntArgbPre SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, - cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); + cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); Blit performop = Blit.getFromCache(src.getSurfaceType(), - CompositeType.Any, dstBuffer.getSurfaceType()); + CompositeType.Any, dstBuffer.getSurfaceType()); performop.Blit(src, dstBuffer, comp, clip, sx, sy, 0, 0, w, h); @@ -806,9 +806,9 @@ // now blit the buffer back to the destination convertdst = Blit.getFromCache(dstBuffer.getSurfaceType(), - CompositeType.SrcNoEa, - dst.getSurfaceType()); + CompositeType.SrcNoEa, + dst.getSurfaceType()); convertdst.Blit(dstBuffer, dst, AlphaComposite.Src, - clip, 0, 0, dx, dy, w, h); + clip, 0, 0, dx, dy, w, h); } }
--- a/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * 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
--- a/src/share/classes/sun/net/ftp/impl/FtpClient.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/net/ftp/impl/FtpClient.java Thu Apr 18 14:38:37 2013 -0700 @@ -1299,16 +1299,16 @@ * <code>null</code> if the command was unsuccessful. * @throws IOException if an error occured during the transmission. */ - public OutputStream putFileStream(String name, boolean unique) throws sun.net.ftp.FtpProtocolException, IOException { + public OutputStream putFileStream(String name, boolean unique) + throws sun.net.ftp.FtpProtocolException, IOException + { String cmd = unique ? "STOU " : "STOR "; Socket s = openDataConnection(cmd + name); if (s == null) { return null; } - if (type == TransferType.BINARY) { - return s.getOutputStream(); - } - return new sun.net.TelnetOutputStream(s.getOutputStream(), false); + boolean bm = (type == TransferType.BINARY); + return new sun.net.TelnetOutputStream(s.getOutputStream(), bm); } /**
--- a/src/share/classes/sun/reflect/misc/MethodUtil.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/reflect/misc/MethodUtil.java Thu Apr 18 14:38:37 2013 -0700 @@ -50,8 +50,28 @@ class Trampoline { + static { + if (Trampoline.class.getClassLoader() == null) { + throw new Error( + "Trampoline must not be defined by the bootstrap classloader"); + } + } + + private static void ensureInvocableMethod(Method m) + throws InvocationTargetException + { + Class<?> clazz = m.getDeclaringClass(); + if (clazz.equals(AccessController.class) || + clazz.equals(Method.class) || + clazz.getName().startsWith("java.lang.invoke.")) + throw new InvocationTargetException( + new UnsupportedOperationException("invocation not supported")); + } + private static Object invoke(Method m, Object obj, Object[] params) - throws InvocationTargetException, IllegalAccessException { + throws InvocationTargetException, IllegalAccessException + { + ensureInvocableMethod(m); return m.invoke(obj, params); } } @@ -255,16 +275,6 @@ */ public static Object invoke(Method m, Object obj, Object[] params) throws InvocationTargetException, IllegalAccessException { - if (m.getDeclaringClass().equals(AccessController.class) || - (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class) - && m.getName().equals("lookup")) || - (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class) - && (m.getName().startsWith("find") || - m.getName().startsWith("bind") || - m.getName().startsWith("unreflect"))) || - m.getDeclaringClass().equals(Method.class)) - throw new InvocationTargetException( - new UnsupportedOperationException("invocation not supported")); try { return bounce.invoke(null, new Object[] {m, obj, params}); } catch (InvocationTargetException ie) { @@ -297,10 +307,10 @@ Method.class, Object.class, Object[].class }; Method b = t.getDeclaredMethod("invoke", types); - ((AccessibleObject)b).setAccessible(true); - return b; - } - }); + b.setAccessible(true); + return b; + } + }); } catch (Exception e) { throw new InternalError("bouncer cannot be found"); }
--- a/src/share/classes/sun/reflect/misc/ReflectUtil.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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
--- a/src/share/classes/sun/rmi/server/MarshalInputStream.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java Thu Apr 18 14:38:37 2013 -0700 @@ -55,13 +55,19 @@ public class MarshalInputStream extends ObjectInputStream { /** - * value of "java.rmi.server.useCodebaseOnly" property, + * Value of "java.rmi.server.useCodebaseOnly" property, * as cached at class initialization time. + * + * The default value is true. That is, the value is true + * if the property is absent or is not equal to "false". + * The value is only false when the property is present + * and is equal to "false". */ private static final boolean useCodebaseOnlyProperty = - java.security.AccessController.doPrivileged( - new sun.security.action.GetBooleanAction( - "java.rmi.server.useCodebaseOnly")).booleanValue(); + ! java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "java.rmi.server.useCodebaseOnly", "true")) + .equalsIgnoreCase("false"); /** table to hold sun classes to which access is explicitly permitted */ protected static Map<String, Class<?>> permittedSunClasses
--- a/src/share/classes/sun/security/krb5/PrincipalName.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/security/krb5/PrincipalName.java Thu Apr 18 14:38:37 2013 -0700 @@ -461,7 +461,7 @@ } public String[] getNameStrings() { - return nameStrings; + return nameStrings.clone(); } public byte[][] toByteArray() {
--- a/src/share/classes/sun/security/pkcs/PKCS7.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/security/pkcs/PKCS7.java Thu Apr 18 14:38:37 2013 -0700 @@ -133,7 +133,8 @@ } catch (IOException ioe1) { ParsingException pe = new ParsingException( ioe1.getMessage()); - pe.initCause(ioe1); + pe.initCause(ioe); + pe.addSuppressed(ioe1); throw pe; } } @@ -281,19 +282,26 @@ len = certVals.length; certificates = new X509Certificate[len]; + int count = 0; for (int i = 0; i < len; i++) { ByteArrayInputStream bais = null; try { - if (certfac == null) - certificates[i] = new X509CertImpl(certVals[i]); - else { - byte[] encoded = certVals[i].toByteArray(); - bais = new ByteArrayInputStream(encoded); - certificates[i] = - (X509Certificate)certfac.generateCertificate(bais); - bais.close(); - bais = null; + byte tag = certVals[i].getTag(); + // We only parse the normal certificate. Other types of + // CertificateChoices ignored. + if (tag == DerValue.tag_Sequence) { + if (certfac == null) { + certificates[count] = new X509CertImpl(certVals[i]); + } else { + byte[] encoded = certVals[i].toByteArray(); + bais = new ByteArrayInputStream(encoded); + certificates[count] = + (X509Certificate)certfac.generateCertificate(bais); + bais.close(); + bais = null; + } + count++; } } catch (CertificateException ce) { ParsingException pe = new ParsingException(ce.getMessage()); @@ -308,6 +316,9 @@ bais.close(); } } + if (count != len) { + certificates = Arrays.copyOf(certificates, count); + } } // check if crls (implicit tag) are provided (crls are OPTIONAL)
--- a/src/share/classes/sun/security/pkcs/PKCS9Attribute.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/security/pkcs/PKCS9Attribute.java Thu Apr 18 14:38:37 2013 -0700 @@ -42,12 +42,14 @@ /** * Class supporting any PKCS9 attributes. - * Supports DER decoding and access to attribute values, but not - * DER encoding or setting of values. + * Supports DER decoding/encoding and access to attribute values. * * <a name="classTable"><h3>Type/Class Table</h3></a> * The following table shows the correspondence between * PKCS9 attribute types and value component classes. + * For types not listed here, its name is the OID + * in string form, its value is a (single-valued) + * byte array that is the SET's encoding. * * <P> * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER> @@ -185,6 +187,8 @@ */ static final ObjectIdentifier[] PKCS9_OIDS = new ObjectIdentifier[18]; + private final static Class<?> BYTE_ARRAY_CLASS; + static { // static initializer for PKCS9_OIDS for (int i = 1; i < PKCS9_OIDS.length - 2; i++) { PKCS9_OIDS[i] = @@ -196,6 +200,12 @@ ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,12}); PKCS9_OIDS[PKCS9_OIDS.length - 1] = ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,14}); + + try { + BYTE_ARRAY_CLASS = Class.forName("[B"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e.toString()); + } } // first element [0] not used @@ -331,7 +341,7 @@ VALUE_CLASSES[2] = str; // UnstructuredName VALUE_CLASSES[3] = // ContentType Class.forName("sun.security.util.ObjectIdentifier"); - VALUE_CLASSES[4] = Class.forName("[B"); // MessageDigest (byte[]) + VALUE_CLASSES[4] = BYTE_ARRAY_CLASS; // MessageDigest (byte[]) VALUE_CLASSES[5] = Class.forName("java.util.Date"); // SigningTime VALUE_CLASSES[6] = // Countersignature Class.forName("[Lsun.security.pkcs.SignerInfo;"); @@ -347,7 +357,7 @@ Class.forName("sun.security.x509.CertificateExtensions"); VALUE_CLASSES[15] = null; // not supported yet VALUE_CLASSES[16] = null; // not supported yet - VALUE_CLASSES[17] = Class.forName("[B"); // SignatureTimestampToken + VALUE_CLASSES[17] = BYTE_ARRAY_CLASS; // SignatureTimestampToken } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e.toString()); } @@ -379,13 +389,20 @@ }; /** - * The OID of this attribute is <code>PKCS9_OIDS[index]</code>. + * The OID of this attribute. + */ + private ObjectIdentifier oid; + + /** + * The index of the OID of this attribute in <code>PKCS9_OIDS</code>, + * or -1 if it's unknown. */ private int index; /** * Value set of this attribute. Its class is given by - * <code>VALUE_CLASSES[index]</code>. + * <code>VALUE_CLASSES[index]</code>. The SET itself + * as byte[] if unknown. */ private Object value; @@ -400,6 +417,8 @@ * <a href=#classTable>table</a> gives the class that <code>value</code> * must have for a given attribute. * + * @exception IllegalArgumentException + * if the <code>value</code> has the wrong type. */ public PKCS9Attribute(ObjectIdentifier oid, Object value) throws IllegalArgumentException { @@ -419,7 +438,7 @@ * attributes are accepted; in particular, case does not matter. * * @exception IllegalArgumentException - * if the <code>name</code> is not recognized of the + * if the <code>name</code> is not recognized or the * <code>value</code> has the wrong type. */ public PKCS9Attribute(String name, Object value) @@ -437,21 +456,17 @@ private void init(ObjectIdentifier oid, Object value) throws IllegalArgumentException { + this.oid = oid; index = indexOf(oid, PKCS9_OIDS, 1); - - if (index == -1) - throw new IllegalArgumentException( - "Unsupported OID " + oid + - " constructing PKCS9Attribute."); - - if (!VALUE_CLASSES[index].isInstance(value)) + Class<?> clazz = index == -1 ? BYTE_ARRAY_CLASS: VALUE_CLASSES[index]; + if (!clazz.isInstance(value)) { throw new IllegalArgumentException( "Wrong value class " + " for attribute " + oid + " constructing PKCS9Attribute; was " + value.getClass().toString() + ", should be " + - VALUE_CLASSES[index].toString()); - + clazz.toString()); + } this.value = value; } @@ -475,16 +490,19 @@ throw new IOException("PKCS9Attribute doesn't have two components"); // get the oid - ObjectIdentifier oid = val[0].getOID(); + oid = val[0].getOID(); + byte[] content = val[1].toByteArray(); + DerValue[] elems = new DerInputStream(content).getSet(1); + index = indexOf(oid, PKCS9_OIDS, 1); if (index == -1) { if (debug != null) { - debug.println("ignoring unsupported signer attribute: " + oid); + debug.println("Unsupported signer attribute: " + oid); } - throw new ParsingException("Unsupported PKCS9 attribute: " + oid); + value = content; + return; } - DerValue[] elems = new DerInputStream(val[1].toByteArray()).getSet(1); // check single valued have only one value if (SINGLE_VALUED[index] && elems.length > 1) throwSingleValuedException(); @@ -584,8 +602,11 @@ */ public void derEncode(OutputStream out) throws IOException { DerOutputStream temp = new DerOutputStream(); - temp.putOID(getOID()); + temp.putOID(oid); switch (index) { + case -1: // Unknown + temp.write((byte[])value); + break; case 1: // email address case 2: // unstructured name { // open scope @@ -704,6 +725,14 @@ } /** + * Returns if the attribute is known. Unknown attributes can be created + * from DER encoding with unknown OIDs. + */ + public boolean isKnown() { + return index != -1; + } + + /** * Get the value of this attribute. If the attribute is * single-valued, return just the one value. If the attribute is * multi-valued, return an array containing all the values. @@ -721,21 +750,23 @@ * Show whether this attribute is single-valued. */ public boolean isSingleValued() { - return SINGLE_VALUED[index]; + return index == -1 || SINGLE_VALUED[index]; } /** * Return the OID of this attribute. */ public ObjectIdentifier getOID() { - return PKCS9_OIDS[index]; + return oid; } /** * Return the name of this attribute. */ public String getName() { - return OID_NAME_TABLE.get(PKCS9_OIDS[index]); + return index == -1 ? + oid.toString() : + OID_NAME_TABLE.get(PKCS9_OIDS[index]); } /** @@ -762,10 +793,14 @@ buf.append("["); - buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); + if (index == -1) { + buf.append(oid.toString()); + } else { + buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index])); + } buf.append(": "); - if (SINGLE_VALUED[index]) { + if (index == -1 || SINGLE_VALUED[index]) { if (value instanceof byte[]) { // special case for octet string HexDumpEncoder hexDump = new HexDumpEncoder(); buf.append(hexDump.encodeBuffer((byte[]) value)); @@ -809,20 +844,21 @@ */ private void throwSingleValuedException() throws IOException { throw new IOException("Single-value attribute " + - getOID() + " (" + getName() + ")" + + oid + " (" + getName() + ")" + " has multiple values."); } /** * Throw an exception when the tag on a value encoding is - * wrong for the attribute whose value it is. + * wrong for the attribute whose value it is. This method + * will only be called for known tags. */ private void throwTagException(Byte tag) throws IOException { Byte[] expectedTags = PKCS9_VALUE_TAGS[index]; StringBuffer msg = new StringBuffer(100); msg.append("Value of attribute "); - msg.append(getOID().toString()); + msg.append(oid.toString()); msg.append(" ("); msg.append(getName()); msg.append(") has wrong tag: ");
--- a/src/share/classes/sun/security/util/UntrustedCertificates.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/classes/sun/security/util/UntrustedCertificates.java Thu Apr 18 14:38:37 2013 -0700 @@ -843,5 +843,52 @@ "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" + "-----END CERTIFICATE-----"); + // + // Revoked code signing certificate w/ a stolen key issued by GoDaddy + // used to sign malware + // + + // Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT, + // O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US + // Issuer: SERIALNUMBER=07969287, + // CN=Go Daddy Secure Certification Authority, + // OU=http://certificates.godaddy.com/repository, + // O="GoDaddy.com, Inc.", + // L=Scottsdale, + // ST=Arizona, + // C=US + // Serial: 2b:73:43:2a:a8:4f:44 + add("clearesult-consulting-inc-2AA84F44", + "-----BEGIN CERTIFICATE-----\n" + + "MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" + + "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" + + "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" + + "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" + + "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" + + "ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" + + "VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" + + "RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" + + "BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" + + "AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" + + "IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" + + "p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" + + "jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" + + "9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" + + "U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" + + "DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" + + "BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" + + "ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" + + "AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" + + "gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" + + "eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" + + "Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" + + "rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" + + "XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" + + "v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" + + "2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" + + "4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" + + "DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" + + "LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" + + "-----END CERTIFICATE-----"); } }
--- a/src/share/lib/security/java.security-linux Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/lib/security/java.security-linux Thu Apr 18 14:38:37 2013 -0700 @@ -124,19 +124,30 @@ # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. package.access=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr. - # # List of comma-separated packages that start with or equal this string # will cause a security exception to be thrown when @@ -148,19 +159,30 @@ # checkPackageDefinition. # package.definition=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr. - # # Determines whether this properties file can be appended to # or overridden on the command line via -Djava.security.properties @@ -373,7 +395,7 @@ # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2 +jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-macosx Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/lib/security/java.security-macosx Thu Apr 18 14:38:37 2013 -0700 @@ -125,17 +125,29 @@ # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. package.access=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr.,\ apple. @@ -150,17 +162,29 @@ # checkPackageDefinition. # package.definition=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr.,\ apple. @@ -376,7 +400,7 @@ # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2 +jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-solaris Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/lib/security/java.security-solaris Thu Apr 18 14:38:37 2013 -0700 @@ -126,17 +126,29 @@ # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. package.access=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr. # @@ -150,17 +162,29 @@ # checkPackageDefinition. # package.definition=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ oracle.jrockit.jfr. # @@ -375,7 +399,7 @@ # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2 +jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-windows Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/lib/security/java.security-windows Thu Apr 18 14:38:37 2013 -0700 @@ -125,17 +125,30 @@ # corresponding RuntimePermission ("accessClassInPackage."+package) has # been granted. package.access=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ + com.sun.java.accessibility.,\ oracle.jrockit.jfr. # @@ -149,17 +162,30 @@ # checkPackageDefinition. # package.definition=sun.,\ - com.sun.xml.internal.bind.,\ - com.sun.xml.internal.org.jvnet.staxex.,\ - com.sun.xml.internal.ws.,\ + com.sun.xml.internal.,\ com.sun.imageio.,\ com.sun.istack.internal.,\ com.sun.jmx.,\ com.sun.proxy.,\ - com.sun.org.apache.xerces.internal.utils.,\ + com.sun.org.apache.bcel.internal.,\ + com.sun.org.apache.regexp.internal.,\ + com.sun.org.apache.xerces.internal.,\ + com.sun.org.apache.xpath.internal.,\ + com.sun.org.apache.xalan.internal.extensions.,\ + com.sun.org.apache.xalan.internal.lib.,\ + com.sun.org.apache.xalan.internal.res.,\ + com.sun.org.apache.xalan.internal.templates.,\ com.sun.org.apache.xalan.internal.utils.,\ - com.sun.org.glassfish.external.,\ - com.sun.org.glassfish.gmbal.,\ + com.sun.org.apache.xalan.internal.xslt.,\ + com.sun.org.apache.xalan.internal.xsltc.cmdline.,\ + com.sun.org.apache.xalan.internal.xsltc.compiler.,\ + com.sun.org.apache.xalan.internal.xsltc.trax.,\ + com.sun.org.apache.xalan.internal.xsltc.util.,\ + com.sun.org.apache.xml.internal.res.,\ + com.sun.org.apache.xml.internal.serializer.utils.,\ + com.sun.org.apache.xml.internal.utils.,\ + com.sun.org.glassfish.,\ + com.sun.java.accessibility.,\ oracle.jrockit.jfr. # @@ -374,7 +400,7 @@ # jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048 # # -jdk.certpath.disabledAlgorithms=MD2 +jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security # (SSL/TLS) processing
--- a/src/share/native/java/lang/System.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/java/lang/System.c Thu Apr 18 14:38:37 2013 -0700 @@ -382,11 +382,19 @@ sprops->display_variant, sprops->format_variant, putID, getPropID); GETPROP(props, "file.encoding", jVMVal); if (jVMVal == NULL) { +#ifdef MACOSX + /* + * Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't + * want to use it to overwrite file.encoding + */ + PUTPROP(props, "file.encoding", sprops->encoding); +#else if (fmtdefault) { PUTPROP(props, "file.encoding", sprops->encoding); } else { PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding); } +#endif } else { (*env)->DeleteLocalRef(env, jVMVal); }
--- a/src/share/native/java/net/InetAddress.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/java/net/InetAddress.c Thu Apr 18 14:38:37 2013 -0700 @@ -33,8 +33,11 @@ */ jclass ia_class; -jfieldID ia_addressID; -jfieldID ia_familyID; +jclass iac_class; +jfieldID ia_holderID; +jfieldID iac_addressID; +jfieldID iac_familyID; +jfieldID iac_hostNameID; jfieldID ia_preferIPv6AddressID; /* @@ -48,10 +51,18 @@ CHECK_NULL(c); ia_class = (*env)->NewGlobalRef(env, c); CHECK_NULL(ia_class); - ia_addressID = (*env)->GetFieldID(env, ia_class, "address", "I"); - CHECK_NULL(ia_addressID); - ia_familyID = (*env)->GetFieldID(env, ia_class, "family", "I"); - CHECK_NULL(ia_familyID); + c = (*env)->FindClass(env,"java/net/InetAddress$InetAddressHolder"); + CHECK_NULL(c); + iac_class = (*env)->NewGlobalRef(env, c); + ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;"); + CHECK_NULL(ia_holderID); ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z"); CHECK_NULL(ia_preferIPv6AddressID); + + iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I"); + CHECK_NULL(iac_addressID); + iac_familyID = (*env)->GetFieldID(env, iac_class, "family", "I"); + CHECK_NULL(iac_familyID); + iac_hostNameID = (*env)->GetFieldID(env, iac_class, "hostName", "Ljava/lang/String;"); + CHECK_NULL(iac_hostNameID); }
--- a/src/share/native/java/net/net_util.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/java/net/net_util.c Thu Apr 18 14:38:37 2013 -0700 @@ -84,6 +84,58 @@ } } +/* The address, and family fields used to be in InetAddress + * but are now in an implementation object. So, there is an extra + * level of indirection to access them now. + */ + +extern jclass iac_class; +extern jfieldID ia_holderID; +extern jfieldID iac_addressID; +extern jfieldID iac_familyID; + +void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + (*env)->SetIntField(env, holder, iac_addressID, address); +} + +void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + (*env)->SetIntField(env, holder, iac_familyID, family); +} + +void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + (*env)->SetObjectField(env, holder, iac_hostNameID, host); +} + +int getInetAddress_addr(JNIEnv *env, jobject iaObj) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + return (*env)->GetIntField(env, holder, iac_addressID); +} + +int getInetAddress_family(JNIEnv *env, jobject iaObj) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + return (*env)->GetIntField(env, holder, iac_familyID); +} + +jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) { + jobject holder; + init(env); + holder = (*env)->GetObjectField(env, iaObj, ia_holderID); + return (*env)->GetObjectField(env, holder, iac_hostNameID); +} + JNIEXPORT jobject JNICALL NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) { jobject iaObj; @@ -110,8 +162,8 @@ iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID); CHECK_NULL_RETURN(iaObj, NULL); address = NET_IPv4MappedToIPv4(caddr); - (*env)->SetIntField(env, iaObj, ia_addressID, address); - (*env)->SetIntField(env, iaObj, ia_familyID, IPv4); + setInetAddress_addr(env, iaObj, address); + setInetAddress_family(env, iaObj, IPv4); } else { static jclass inet6Cls = 0; jint scope; @@ -131,7 +183,7 @@ (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress); - (*env)->SetIntField(env, iaObj, ia_familyID, IPv6); + setInetAddress_family(env, iaObj, IPv6); scope = getScopeID(him); (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); if (scope > 0) @@ -153,9 +205,8 @@ } iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID); CHECK_NULL_RETURN(iaObj, NULL); - (*env)->SetIntField(env, iaObj, ia_familyID, IPv4); - (*env)->SetIntField(env, iaObj, ia_addressID, - ntohl(him4->sin_addr.s_addr)); + setInetAddress_family(env, iaObj, IPv4); + setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr)); *port = ntohs(him4->sin_port); } return iaObj; @@ -167,8 +218,7 @@ jint family = AF_INET; #ifdef AF_INET6 - family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? - AF_INET : AF_INET6; + family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6; if (him->sa_family == AF_INET6) { #ifdef WIN32 struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him; @@ -183,7 +233,7 @@ return JNI_FALSE; } addrNew = NET_IPv4MappedToIPv4(caddrNew); - addrCur = (*env)->GetIntField(env, iaObj, ia_addressID); + addrCur = getInetAddress_addr(env, iaObj); if (addrNew == addrCur) { return JNI_TRUE; } else { @@ -215,7 +265,7 @@ return JNI_FALSE; } addrNew = ntohl(him4->sin_addr.s_addr); - addrCur = (*env)->GetIntField(env, iaObj, ia_addressID); + addrCur = getInetAddress_addr(env, iaObj); if (addrNew == addrCur) { return JNI_TRUE; } else {
--- a/src/share/native/java/net/net_util.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/java/net/net_util.h Thu Apr 18 14:38:37 2013 -0700 @@ -53,10 +53,18 @@ * i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID. */ extern jclass ia_class; -extern jfieldID ia_addressID; -extern jfieldID ia_familyID; +extern jfieldID iac_addressID; +extern jfieldID iac_familyID; +extern jfieldID iac_hostNameID; extern jfieldID ia_preferIPv6AddressID; +extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address); +extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family); +extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h); +extern int getInetAddress_addr(JNIEnv *env, jobject iaObj); +extern int getInetAddress_family(JNIEnv *env, jobject iaObj); +extern jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj); + extern jclass ia4_class; extern jmethodID ia4_ctrID;
--- a/src/share/native/sun/awt/image/awt_ImageRep.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/awt/image/awt_ImageRep.c Thu Apr 18 14:38:37 2013 -0700 @@ -45,6 +45,53 @@ # define TRUE 1 #endif +#define CHECK_STRIDE(yy, hh, ss) \ + if ((ss) != 0) { \ + int limit = 0x7fffffff / ((ss) > 0 ? (ss) : -(ss)); \ + if (limit < (yy) || limit < ((yy) + (hh) - 1)) { \ + /* integer oveflow */ \ + return JNI_FALSE; \ + } \ + } \ + +#define CHECK_SRC() \ + do { \ + int pixeloffset; \ + if (off < 0 || off >= srcDataLength) { \ + return JNI_FALSE; \ + } \ + CHECK_STRIDE(0, h, scansize); \ + \ + /* check scansize */ \ + pixeloffset = scansize * (h - 1); \ + if ((w - 1) > (0x7fffffff - pixeloffset)) { \ + return JNI_FALSE; \ + } \ + pixeloffset += (w - 1); \ + \ + if (off > (0x7fffffff - pixeloffset)) { \ + return JNI_FALSE; \ + } \ + } while (0) \ + +#define CHECK_DST(xx, yy) \ + do { \ + int soffset = (yy) * sStride; \ + int poffset = (xx) * pixelStride; \ + if (poffset > (0x7fffffff - soffset)) { \ + return JNI_FALSE; \ + } \ + poffset += soffset; \ + if (dstDataOff > (0x7fffffff - poffset)) { \ + return JNI_FALSE; \ + } \ + poffset += dstDataOff; \ + \ + if (poffset < 0 || poffset >= dstDataLength) { \ + return JNI_FALSE; \ + } \ + } while (0) \ + static jfieldID s_JnumSrcLUTID; static jfieldID s_JsrcLUTtransIndexID; @@ -58,7 +105,7 @@ /* * This routine is used to draw ICM pixels into a default color model */ -JNIEXPORT void JNICALL +JNIEXPORT jboolean JNICALL Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls, jint x, jint y, jint w, jint h, jintArray jlut, @@ -67,7 +114,10 @@ jobject jict) { unsigned char *srcData = NULL; + jint srcDataLength; int *dstData; + jint dstDataLength; + jint dstDataOff; int *dstP, *dstyP; unsigned char *srcyP, *srcP; int *srcLUT = NULL; @@ -80,12 +130,20 @@ if (JNU_IsNull(env, jlut)) { JNU_ThrowNullPointerException(env, "NullPointerException"); - return; + return JNI_FALSE; } if (JNU_IsNull(env, jpix)) { JNU_ThrowNullPointerException(env, "NullPointerException"); - return; + return JNI_FALSE; + } + + if (x < 0 || w < 1 || (0x7fffffff - x) < w) { + return JNI_FALSE; + } + + if (y < 0 || h < 1 || (0x7fffffff - y) < h) { + return JNI_FALSE; } sStride = (*env)->GetIntField(env, jict, g_ICRscanstrID); @@ -93,10 +151,47 @@ joffs = (*env)->GetObjectField(env, jict, g_ICRdataOffsetsID); jdata = (*env)->GetObjectField(env, jict, g_ICRdataID); + if (JNU_IsNull(env, jdata)) { + /* no destination buffer */ + return JNI_FALSE; + } + + if (JNU_IsNull(env, joffs) || (*env)->GetArrayLength(env, joffs) < 1) { + /* invalid data offstes in raster */ + return JNI_FALSE; + } + + srcDataLength = (*env)->GetArrayLength(env, jpix); + dstDataLength = (*env)->GetArrayLength(env, jdata); + + cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL); + if (cOffs == NULL) { + JNU_ThrowNullPointerException(env, "Null channel offset array"); + return JNI_FALSE; + } + + dstDataOff = cOffs[0]; + + /* the offset array is not needed anymore and can be released */ + (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT); + joffs = NULL; + cOffs = NULL; + + /* do basic validation: make sure that offsets for + * first pixel and for last pixel are safe to calculate and use */ + CHECK_STRIDE(y, h, sStride); + CHECK_STRIDE(x, w, pixelStride); + + CHECK_DST(x, y); + CHECK_DST(x + w -1, y + h - 1); + + /* check source array */ + CHECK_SRC(); + srcLUT = (int *) (*env)->GetPrimitiveArrayCritical(env, jlut, NULL); if (srcLUT == NULL) { JNU_ThrowNullPointerException(env, "Null IndexColorModel LUT"); - return; + return JNI_FALSE; } srcData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jpix, @@ -104,27 +199,18 @@ if (srcData == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); JNU_ThrowNullPointerException(env, "Null data array"); - return; - } - - cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL); - if (cOffs == NULL) { - (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - JNU_ThrowNullPointerException(env, "Null channel offset array"); - return; + return JNI_FALSE; } dstData = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL); if (dstData == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT); JNU_ThrowNullPointerException(env, "Null tile data array"); - return; + return JNI_FALSE; } - dstyP = dstData + cOffs[0] + y*sStride + x*pixelStride; + dstyP = dstData + dstDataOff + y*sStride + x*pixelStride; srcyP = srcData + off; for (yIdx = 0; yIdx < h; yIdx++, srcyP += scansize, dstyP+=sStride) { srcP = srcyP; @@ -137,12 +223,12 @@ /* Release the locked arrays */ (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); - (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT); + return JNI_TRUE; } -JNIEXPORT jint JNICALL +JNIEXPORT jboolean JNICALL Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls, jint x, jint y, jint w, jint h, jintArray jlut, @@ -150,7 +236,7 @@ jobject jicm, jbyteArray jpix, jint off, jint scansize, - jobject jbct, jint chanOff) + jobject jbct, jint dstDataOff) { unsigned int *srcLUT = NULL; unsigned int *newLUT = NULL; @@ -159,6 +245,8 @@ int mapSize; jobject jdata = NULL; jobject jnewlut = NULL; + jint srcDataLength; + jint dstDataLength; unsigned char *srcData; unsigned char *dstData; unsigned char *dataP; @@ -174,14 +262,23 @@ if (JNU_IsNull(env, jlut)) { JNU_ThrowNullPointerException(env, "NullPointerException"); - return 0; + return JNI_FALSE; } if (JNU_IsNull(env, jpix)) { JNU_ThrowNullPointerException(env, "NullPointerException"); - return 0; + return JNI_FALSE; + } + + if (x < 0 || w < 1 || (0x7fffffff - x) < w) { + return JNI_FALSE; } + if (y < 0 || h < 1 || (0x7fffffff - y) < h) { + return JNI_FALSE; + } + + sStride = (*env)->GetIntField(env, jbct, g_BCRscanstrID); pixelStride =(*env)->GetIntField(env, jbct, g_BCRpixstrID); jdata = (*env)->GetObjectField(env, jbct, g_BCRdataID); @@ -193,13 +290,31 @@ of byte data type, so we have to convert the image data to default representation. */ - return 0; + return JNI_FALSE; + } + + if (JNU_IsNull(env, jdata)) { + /* no destination buffer */ + return JNI_FALSE; } + + srcDataLength = (*env)->GetArrayLength(env, jpix); + dstDataLength = (*env)->GetArrayLength(env, jdata); + + CHECK_STRIDE(y, h, sStride); + CHECK_STRIDE(x, w, pixelStride); + + CHECK_DST(x, y); + CHECK_DST(x + w -1, y + h - 1); + + /* check source array */ + CHECK_SRC(); + srcLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jlut, NULL); if (srcLUT == NULL) { /* out of memory error already thrown */ - return 0; + return JNI_FALSE; } newLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jnewlut, @@ -208,7 +323,7 @@ (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); /* out of memory error already thrown */ - return 0; + return JNI_FALSE; } newNumLut = numLut; @@ -219,7 +334,7 @@ (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jnewlut, newLUT, JNI_ABORT); - return 0; + return JNI_FALSE; } /* Don't need these any more */ @@ -239,7 +354,7 @@ NULL); if (srcData == NULL) { /* out of memory error already thrown */ - return 0; + return JNI_FALSE; } dstData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jdata, @@ -247,10 +362,10 @@ if (dstData == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); /* out of memory error already thrown */ - return 0; + return JNI_FALSE; } - ydataP = dstData + chanOff + y*sStride + x*pixelStride; + ydataP = dstData + dstDataOff + y*sStride + x*pixelStride; ypixP = srcData + off; for (i=0; i < h; i++) { @@ -268,7 +383,7 @@ (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT); (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT); - return 1; + return JNI_TRUE; } static int compareLUTs(unsigned int *lut1, int numLut1, int transIdx,
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu Apr 18 14:38:37 2013 -0700 @@ -57,8 +57,8 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) /* Cached Java method ids */ -static jmethodID ImageInputStream_readID; -static jmethodID ImageInputStream_skipBytesID; +static jmethodID JPEGImageReader_readInputDataID; +static jmethodID JPEGImageReader_skipInputBytesID; static jmethodID JPEGImageReader_warningOccurredID; static jmethodID JPEGImageReader_warningWithMessageID; static jmethodID JPEGImageReader_setImageDataID; @@ -66,7 +66,7 @@ static jmethodID JPEGImageReader_pushBackID; static jmethodID JPEGImageReader_passStartedID; static jmethodID JPEGImageReader_passCompleteID; -static jmethodID ImageOutputStream_writeID; +static jmethodID JPEGImageWriter_writeOutputDataID; static jmethodID JPEGImageWriter_warningOccurredID; static jmethodID JPEGImageWriter_warningWithMessageID; static jmethodID JPEGImageWriter_writeMetadataID; @@ -923,7 +923,7 @@ RELEASE_ARRAYS(env, data, src->next_input_byte); ret = (*env)->CallIntMethod(env, sb->stream, - ImageInputStream_readID, + JPEGImageReader_readInputDataID, sb->hstreamBuffer, 0, sb->bufferLength); if ((*env)->ExceptionOccurred(env) @@ -1013,7 +1013,7 @@ } ret = (*env)->CallIntMethod(env, sb->stream, - ImageInputStream_readID, + JPEGImageReader_readInputDataID, sb->hstreamBuffer, offset, buflen); if ((*env)->ExceptionOccurred(env) @@ -1107,7 +1107,7 @@ RELEASE_ARRAYS(env, data, src->next_input_byte); ret = (*env)->CallLongMethod(env, sb->stream, - ImageInputStream_skipBytesID, + JPEGImageReader_skipInputBytesID, (jlong) num_bytes); if ((*env)->ExceptionOccurred(env) || !GET_ARRAYS(env, data, &(src->next_input_byte))) { @@ -1382,13 +1382,13 @@ jclass qTableClass, jclass huffClass) { - ImageInputStream_readID = (*env)->GetMethodID(env, - ImageInputStreamClass, - "read", + JPEGImageReader_readInputDataID = (*env)->GetMethodID(env, + cls, + "readInputData", "([BII)I"); - ImageInputStream_skipBytesID = (*env)->GetMethodID(env, - ImageInputStreamClass, - "skipBytes", + JPEGImageReader_skipInputBytesID = (*env)->GetMethodID(env, + cls, + "skipInputBytes", "(J)J"); JPEGImageReader_warningOccurredID = (*env)->GetMethodID(env, cls, @@ -1531,8 +1531,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setSource (JNIEnv *env, jobject this, - jlong ptr, - jobject source) { + jlong ptr) { imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr); j_common_ptr cinfo; @@ -1546,7 +1545,7 @@ cinfo = data->jpegObj; - imageio_set_stream(env, cinfo, data, source); + imageio_set_stream(env, cinfo, data, this); imageio_init_source((j_decompress_ptr) cinfo); } @@ -2291,7 +2290,7 @@ (*env)->CallVoidMethod(env, sb->stream, - ImageOutputStream_writeID, + JPEGImageWriter_writeOutputDataID, sb->hstreamBuffer, 0, sb->bufferLength); @@ -2328,7 +2327,7 @@ (*env)->CallVoidMethod(env, sb->stream, - ImageOutputStream_writeID, + JPEGImageWriter_writeOutputDataID, sb->hstreamBuffer, 0, datacount); @@ -2366,13 +2365,12 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs (JNIEnv *env, jclass cls, - jclass IOSClass, jclass qTableClass, jclass huffClass) { - ImageOutputStream_writeID = (*env)->GetMethodID(env, - IOSClass, - "write", + JPEGImageWriter_writeOutputDataID = (*env)->GetMethodID(env, + cls, + "writeOutputData", "([BII)V"); JPEGImageWriter_warningOccurredID = (*env)->GetMethodID(env, @@ -2496,8 +2494,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest (JNIEnv *env, jobject this, - jlong ptr, - jobject destination) { + jlong ptr) { imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr); j_compress_ptr cinfo; @@ -2511,7 +2508,7 @@ cinfo = (j_compress_ptr) data->jpegObj; - imageio_set_stream(env, data->jpegObj, data, destination); + imageio_set_stream(env, data->jpegObj, data, this); // Don't call the init method, as that depends on pinned arrays
--- a/src/share/native/sun/font/FontInstanceAdapter.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/FontInstanceAdapter.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -66,8 +66,21 @@ yScalePixelsToUnits = upem / yppem; }; + const void *FontInstanceAdapter::getFontTable(LETag tableTag) const { + size_t ignored = 0; + return getFontTable(tableTag, ignored); +} + +static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = { + GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG +}; + +const void *FontInstanceAdapter::getFontTable(LETag tableTag, size_t &length) const +{ + length = 0; + if (!layoutTables) { // t1 font return 0; } @@ -75,14 +88,19 @@ // cache in font's pscaler object // font disposer will handle for us - switch(tableTag) { - case GSUB_TAG: if (layoutTables->gsub_len != -1) return (void*)layoutTables->gsub; break; - case GPOS_TAG: if (layoutTables->gpos_len != -1) return (void*)layoutTables->gpos; break; - case GDEF_TAG: if (layoutTables->gdef_len != -1) return (void*)layoutTables->gdef; break; - case MORT_TAG: if (layoutTables->mort_len != -1) return (void*)layoutTables->mort; break; - case KERN_TAG: if (layoutTables->kern_len != -1) return (void*)layoutTables->kern; break; - default: - //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag); + int cacheIdx; + for (cacheIdx=0;cacheIdx<LAYOUTCACHE_ENTRIES;cacheIdx++) { + if (tableTag==cacheMap[cacheIdx]) break; + } + + if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if found + if (layoutTables->entries[cacheIdx].len != -1) { + length = layoutTables->entries[cacheIdx].len; + return layoutTables->entries[cacheIdx].ptr; + } + } else { + //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag); + // (don't load any other tables) return 0; } @@ -96,16 +114,13 @@ env->GetByteArrayRegion(tableBytes, 0, len, result); } - switch(tableTag) { - case GSUB_TAG: layoutTables->gsub = (void*)result; layoutTables->gsub_len = len; break; - case GPOS_TAG: layoutTables->gpos = (void*)result; layoutTables->gpos_len = len; break; - case GDEF_TAG: layoutTables->gdef = (void*)result; layoutTables->gdef_len = len; break; - case MORT_TAG: layoutTables->mort = (void*)result; layoutTables->mort_len = len; break; - case KERN_TAG: layoutTables->kern = (void*)result; layoutTables->kern_len = len; break; - default: break; + if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if cacheable table + layoutTables->entries[cacheIdx].len = len; + layoutTables->entries[cacheIdx].ptr = (const void*)result; } - return (void*)result; + length = len; + return (const void*)result; }; LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
--- a/src/share/native/sun/font/FontInstanceAdapter.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/FontInstanceAdapter.h Thu Apr 18 14:38:37 2013 -0700 @@ -86,6 +86,7 @@ // tables are cached with the native font scaler data // only supports gsub, gpos, gdef, mort tables at present virtual const void *getFontTable(LETag tableTag) const; + virtual const void *getFontTable(LETag tableTag, size_t &len) const; virtual void *getKernPairs() const { return layoutTables->kernPairs;
--- a/src/share/native/sun/font/fontscalerdefs.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/fontscalerdefs.h Thu Apr 18 14:38:37 2013 -0700 @@ -120,20 +120,19 @@ #define GPOS_TAG 0x47504F53 /* 'GPOS' */ #define GDEF_TAG 0x47444546 /* 'GDEF' */ #define MORT_TAG 0x6D6F7274 /* 'mort' */ +#define MORX_TAG 0x6D6F7278 /* 'morx' */ #define KERN_TAG 0x6B65726E /* 'kern' */ +typedef struct TTLayoutTableCacheEntry { + const void* ptr; + int len; +} TTLayoutTableCacheEntry; + +#define LAYOUTCACHE_ENTRIES 6 + typedef struct TTLayoutTableCache { - void* gsub; - void* gpos; - void* gdef; - void* mort; - void* kern; - void* kernPairs; - int gsub_len; - int gpos_len; - int gdef_len; - int mort_len; - int kern_len; + TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES]; + void* kernPairs; } TTLayoutTableCache; #include "sunfontids.h"
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -39,19 +39,20 @@ U_NAMESPACE_BEGIN -le_uint32 AlternateSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, + GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const { // NOTE: For now, we'll just pick the first alternative... LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); - if (coverageIndex >= 0) { + if (coverageIndex >= 0 && LE_SUCCESS(success)) { le_uint16 altSetCount = SWAPW(alternateSetCount); if (coverageIndex < altSetCount) { Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]); - const AlternateSetTable *alternateSetTable = - (const AlternateSetTable *) ((char *) this + alternateSetTableOffset); + const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success, + (const AlternateSetTable *) ((char *) this + alternateSetTableOffset)); TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]); if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -51,13 +51,17 @@ TTGlyphID alternateArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(AlternateSetTable, alternateArray) + struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable { le_uint16 alternateSetCount; Offset alternateSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const; }; +LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray) + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -26,7 +26,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -58,15 +58,18 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine) -ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) +ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, + le_int32 languageCode, le_int32 typoFlags, + const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, + LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) { fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount); fFeatureOrder = TRUE; } -ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, +ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, + le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) { @@ -88,8 +91,9 @@ // Input: characters // Output: characters, char indices, tags // Returns: output character count -le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, - LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success) +le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, + le_int32 max, le_bool rightToLeft, LEUnicode *&outChars, + LEGlyphStorage &glyphStorage, LEErrorCode &success) { if (LE_FAILURE(success)) { return 0; @@ -137,32 +141,30 @@ return; } - if (fGPOSTable != NULL) { + if (!fGPOSTable.isEmpty()) { OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success); - } else if (fGDEFTable != NULL) { - GDEFMarkFilter filter(fGDEFTable); - + } else if (!fGDEFTable.isEmpty()) { + GDEFMarkFilter filter(fGDEFTable, success); adjustMarkGlyphs(glyphStorage, &filter, success); } else { - GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; - GDEFMarkFilter filter(gdefTable); + LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); + GDEFMarkFilter filter(gdefTable, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); } } UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) - : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success) + : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success) { fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; - - fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); + /* OpenTypeLayoutEngine will allocate a substitution filter */ } UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine() { - delete fSubstitutionFilter; + /* OpenTypeLayoutEngine will cleanup the substitution filter */ } // "glyphs", "indices" -> glyphs, indices @@ -233,7 +235,7 @@ return; } - GDEFMarkFilter filter(fGDEFTable); + GDEFMarkFilter filter(fGDEFTable, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); }
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -75,7 +75,7 @@ * @internal */ ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ArabicShaping.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ArabicShaping.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -58,14 +58,16 @@ */ ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c) { - const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable; - le_int32 joiningType = joiningTypes->getGlyphClass(c); + LEErrorCode success = LE_NO_ERROR; + const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable, + ArabicShaping::shapingTypeTableLen); + le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success); - if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) { - return ArabicShaping::shapeTypes[joiningType]; - } + if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) { + return ArabicShaping::shapeTypes[joiningType]; + } - return ArabicShaping::ST_NOSHAPE_NONE; + return ArabicShaping::ST_NOSHAPE_NONE; } #define isolFeatureTag LE_ISOL_FEATURE_TAG
--- a/src/share/native/sun/font/layout/ArabicShaping.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ArabicShaping.h Thu Apr 18 14:38:37 2013 -0700 @@ -93,6 +93,8 @@ static ShapeType getShapeType(LEUnicode c); static const le_uint8 shapingTypeTable[]; + static const size_t shapingTypeTableLen; + static const ShapeType shapeTypes[]; static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/AttachmentPosnSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/AttachmentPosnSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -52,14 +52,14 @@ Offset markArrayOffset; Offset baseArrayOffset; - inline le_int32 getBaseCoverage(LEGlyphID baseGlyphId) const; + inline le_int32 getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const; le_uint32 process(GlyphIterator *glyphIterator) const; }; -inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(LEGlyphID baseGlyphID) const +inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const { - return getGlyphCoverage(baseCoverageTableOffset, baseGlyphID); + return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success); } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonData.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CanonData.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -3641,4 +3641,9 @@ 0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6 }; + +const size_t CanonShaping::glyphSubstitutionTableLen = sizeof(glyphSubstitutionTable)/sizeof(glyphSubstitutionTable[0]); + +const size_t CanonShaping::glyphDefinitionTableLen = sizeof(glyphDefinitionTable)/sizeof(glyphDefinitionTable[0]); + U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonShaping.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CanonShaping.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -59,15 +59,15 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft, LEUnicode *outChars, LEGlyphStorage &glyphStorage) { - const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable; - const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable(); + LEErrorCode success = LE_NO_ERROR; + LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen); + LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success); le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount); le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount); - LEErrorCode status = LE_NO_ERROR; le_int32 i; for (i = 0; i < charCount; i += 1) { - combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]); + combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success); indices[i] = i; } @@ -96,7 +96,7 @@ le_int32 index = indices[i]; outChars[i] = inChars[index]; - glyphStorage.setCharIndex(out, index, status); + glyphStorage.setCharIndex(out, index, success); } LE_DELETE_ARRAY(indices);
--- a/src/share/native/sun/font/layout/CanonShaping.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CanonShaping.h Thu Apr 18 14:38:37 2013 -0700 @@ -42,7 +42,9 @@ { public: static const le_uint8 glyphSubstitutionTable[]; + static const size_t glyphSubstitutionTableLen; static const le_uint8 glyphDefinitionTable[]; + static const size_t glyphDefinitionTableLen; static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft, LEUnicode *outChars, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ClassDefinitionTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -37,24 +37,51 @@ U_NAMESPACE_BEGIN -le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const +le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const { + LEReferenceTo<ClassDefinitionTable> thisRef(base, success); + if (LE_FAILURE(success)) return 0; + + switch(SWAPW(classFormat)) { + case 0: + return 0; + + case 1: + { + const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success); + return f1Table->getGlyphClass(f1Table, glyphID, success); + } + + case 2: + { + const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success); + return f2Table->getGlyphClass(f2Table, glyphID, success); + } + + default: + return 0; + } +} + +le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const +{ + LEReferenceTo<ClassDefinitionTable> thisRef(base, success); + if (LE_FAILURE(success)) return 0; + switch(SWAPW(classFormat)) { case 0: return 0; case 1: { - const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this; - - return f1Table->getGlyphClass(glyphID); + const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success); + return f1Table->hasGlyphClass(f1Table, glyphClass, success); } case 2: { - const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this; - - return f2Table->getGlyphClass(glyphID); + const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success); + return f2Table->hasGlyphClass(f2Table, glyphClass, success); } default: @@ -62,51 +89,32 @@ } } -le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const +le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const { - switch(SWAPW(classFormat)) { - case 0: - return 0; - - case 1: - { - const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this; - - return f1Table->hasGlyphClass(glyphClass); - } + if(LE_FAILURE(success)) return 0; - case 2: - { - const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this; - - return f2Table->hasGlyphClass(glyphClass); - } - - default: - return 0; - } -} - -le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const -{ + le_uint16 count = SWAPW(glyphCount); + LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count); TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID); TTGlyphID firstGlyph = SWAPW(startGlyph); - TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount); + TTGlyphID lastGlyph = firstGlyph + count; - if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) { - return SWAPW(classValueArray[ttGlyphID - firstGlyph]); + if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) { + return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) ); } return 0; } -le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const +le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const { - le_uint16 count = SWAPW(glyphCount); + if(LE_FAILURE(success)) return 0; + le_uint16 count = SWAPW(glyphCount); + LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count); int i; - for (i = 0; i < count; i += 1) { - if (SWAPW(classValueArray[i]) == glyphClass) { + for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) { + if (SWAPW(classValueArrayRef(i,success)) == glyphClass) { return TRUE; } } @@ -114,27 +122,31 @@ return FALSE; } -le_int32 ClassDefFormat2Table::getGlyphClass(LEGlyphID glyphID) const +le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const { + if(LE_FAILURE(success)) return 0; TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphID); le_uint16 rangeCount = SWAPW(classRangeCount); + LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount); le_int32 rangeIndex = - OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArray, rangeCount); + OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success); - if (rangeIndex < 0) { + if (rangeIndex < 0 || LE_FAILURE(success)) { return 0; } - return SWAPW(classRangeRecordArray[rangeIndex].rangeValue); + return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue); } -le_bool ClassDefFormat2Table::hasGlyphClass(le_int32 glyphClass) const +le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const { + if(LE_FAILURE(success)) return 0; le_uint16 rangeCount = SWAPW(classRangeCount); + LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount); int i; - for (i = 0; i < rangeCount; i += 1) { - if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) { + for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) { + if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) { return TRUE; } }
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ClassDefinitionTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -46,8 +46,20 @@ { le_uint16 classFormat; - le_int32 getGlyphClass(LEGlyphID glyphID) const; - le_bool hasGlyphClass(le_int32 glyphClass) const; + le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; + le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const; + + le_int32 getGlyphClass(LEGlyphID glyphID) const { + LETableReference base((const le_uint8*)this); + LEErrorCode ignored = LE_NO_ERROR; + return getGlyphClass(base,glyphID,ignored); + } + + le_bool hasGlyphClass(le_int32 glyphClass) const { + LETableReference base((const le_uint8*)this); + LEErrorCode ignored = LE_NO_ERROR; + return hasGlyphClass(base,glyphClass,ignored); + } }; struct ClassDefFormat1Table : ClassDefinitionTable @@ -56,9 +68,11 @@ le_uint16 glyphCount; le_uint16 classValueArray[ANY_NUMBER]; - le_int32 getGlyphClass(LEGlyphID glyphID) const; - le_bool hasGlyphClass(le_int32 glyphClass) const; + le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; + le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const; }; +LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray) + struct ClassRangeRecord { @@ -72,9 +86,10 @@ le_uint16 classRangeCount; GlyphRangeRecord classRangeRecordArray[ANY_NUMBER]; - le_int32 getGlyphClass(LEGlyphID glyphID) const; - le_bool hasGlyphClass(le_int32 glyphClass) const; + le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; + le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const; }; +LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ContextualGlyphInsertion.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualGlyphInsertion.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -49,6 +49,11 @@ { }; +struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2 +{ + le_uint32 insertionTableOffset; +}; + enum ContextualGlyphInsertionFlags { cgiSetMark = 0x8000, @@ -61,11 +66,17 @@ cgiMarkedInsertCountMask = 0x001F }; -struct LigatureSubstitutionStateEntry : StateEntry +struct ContextualGlyphInsertionStateEntry : StateEntry { ByteOffset currentInsertionListOffset; ByteOffset markedInsertionListOffset; }; +struct ContextualGlyphInsertionStateEntry2 : StateEntry2 +{ + le_uint16 currentInsertionListIndex; + le_uint16 markedInsertionListIndex; +}; + U_NAMESPACE_END #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,139 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "StateTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "ContextualGlyphInsertionProc2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2) + +ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2( + const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor2(morphSubtableHeader, success) +{ + contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success); + if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return; + le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset); + insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY); + entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); +} + +ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2() +{ +} + +void ContextualGlyphInsertionProcessor2::beginStateTable() +{ + markGlyph = 0; +} + +void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage, + le_int16 atGlyph, + le_int16 &index, + le_int16 count, + le_bool /* isKashidaLike */, + le_bool isBefore, + LEErrorCode &success) { + LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success); + + if(LE_FAILURE(success) || insertGlyphs==NULL) { + return; + } + + // Note: Kashida vs Split Vowel seems to only affect selection and highlighting. + // We note the flag, but do not layout different. + // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html + + le_int16 targetIndex = 0; + if(isBefore) { + // insert at beginning + insertGlyphs[targetIndex++] = glyphStorage[atGlyph]; + } else { + // insert at end + insertGlyphs[count] = glyphStorage[atGlyph]; + } + + while(count--) { + insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success); + } + glyphStorage.applyInsertions(); +} + +le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, + EntryTableIndex2 index, LEErrorCode &success) +{ + const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success); + + if(LE_FAILURE(success)) return 0; // TODO- which state? + + le_uint16 newState = SWAPW(entry->newStateIndex); + le_uint16 flags = SWAPW(entry->flags); + + le_int16 markIndex = SWAPW(entry->markedInsertionListIndex); + if (markIndex > 0) { + le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5; + le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike); + le_bool isBefore = (flags & cgiMarkInsertBefore); + doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success); + } + + le_int16 currIndex = SWAPW(entry->currentInsertionListIndex); + if (currIndex > 0) { + le_int16 count = flags & cgiCurrentInsertCountMask; + le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike); + le_bool isBefore = (flags & cgiCurrentInsertBefore); + doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success); + } + + if (flags & cgiSetMark) { + markGlyph = currGlyph; + } + + if (!(flags & cgiDontAdvance)) { + currGlyph += dir; + } + + return newState; +} + +void ContextualGlyphInsertionProcessor2::endStateTable() +{ +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,106 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 2013 - All Rights Reserved + * + */ + +#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H +#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "ContextualGlyphInsertionProc2.h" +#include "ContextualGlyphInsertion.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2 +{ +public: + virtual void beginStateTable(); + + virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, + le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success); + + virtual void endStateTable(); + + ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + virtual ~ContextualGlyphInsertionProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + ContextualGlyphInsertionProcessor2(); + + /** + * Perform the actual insertion + * @param atGlyph index of glyph to insert at + * @param index index into the insertionTable (in/out) + * @param count number of insertions + * @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently. + * @param isBefore if true, insert extra glyphs before the marked glyph + */ + void doInsertion(LEGlyphStorage &glyphStorage, + le_int16 atGlyph, + le_int16 &index, + le_int16 count, + le_bool isKashidaLike, + le_bool isBefore, + LEErrorCode &success); + + +protected: + le_int32 markGlyph; + LEReferenceToArrayOf<le_uint16> insertionTable; + LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable; + LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader; +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -43,13 +43,18 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor) -ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) - : StateTableProcessor(morphSubtableHeader) +ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success) { - contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader; - substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset); + contextualGlyphSubstitutionHeader.orphan(); + substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset); + - entryTable = (const ContextualGlyphSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset); + entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success, + (const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader), + entryTableOffset, LE_UNBOUNDED_ARRAY); + int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader), + 0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s } ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor() @@ -63,27 +68,26 @@ ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) { - const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index]; - ByteOffset newState = SWAPW(entry->newStateOffset); - le_int16 flags = SWAPW(entry->flags); - WordOffset markOffset = SWAPW(entry->markOffset); - WordOffset currOffset = SWAPW(entry->currOffset); - - if (markOffset != 0) { - const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2); - LEGlyphID mGlyph = glyphStorage[markGlyph]; - TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]); + LEErrorCode success = LE_NO_ERROR; + const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success); + ByteOffset newState = SWAPW(entry->newStateOffset); + le_int16 flags = SWAPW(entry->flags); + WordOffset markOffset = SWAPW(entry->markOffset); + WordOffset currOffset = SWAPW(entry->currOffset); - glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); - } + if (markOffset != 0 && LE_SUCCESS(success)) { + LEGlyphID mGlyph = glyphStorage[markGlyph]; + TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew. + + glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); + } - if (currOffset != 0) { - const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2); - LEGlyphID thisGlyph = glyphStorage[currGlyph]; - TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]); + if (currOffset != 0) { + LEGlyphID thisGlyph = glyphStorage[currGlyph]; + TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew. - glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); - } + glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } if (flags & cgsSetMark) { markGlyph = currGlyph;
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h Thu Apr 18 14:38:37 2013 -0700 @@ -56,7 +56,7 @@ virtual void endStateTable(); - ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); + ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~ContextualGlyphSubstitutionProcessor(); /** @@ -78,11 +78,11 @@ protected: ByteOffset substitutionTableOffset; - const ContextualGlyphSubstitutionStateEntry *entryTable; - + LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable; + LEReferenceToArrayOf<le_int16> int16Table; le_int32 markGlyph; - const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader; + LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,170 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "StateTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "ContextualGlyphSubstProc2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2) + +ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2( + const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success) +{ + if(LE_FAILURE(success)) return; + le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset); + perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY); + entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); +} + +ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2() +{ +} + +void ContextualGlyphSubstitutionProcessor2::beginStateTable() +{ + markGlyph = 0; +} + +le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, + EntryTableIndex2 index, LEErrorCode &success) +{ + if(LE_FAILURE(success)) return 0; + const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success); + if(LE_FAILURE(success)) return 0; + le_uint16 newState = SWAPW(entry->newStateIndex); + le_uint16 flags = SWAPW(entry->flags); + le_int16 markIndex = SWAPW(entry->markIndex); + le_int16 currIndex = SWAPW(entry->currIndex); + + if (markIndex != -1) { + le_uint32 offset = SWAPL(perGlyphTable(markIndex, success)); + LEGlyphID mGlyph = glyphStorage[markGlyph]; + TTGlyphID newGlyph = lookup(offset, mGlyph, success); + glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph); + } + + if (currIndex != -1) { + le_uint32 offset = SWAPL(perGlyphTable(currIndex, success)); + LEGlyphID thisGlyph = glyphStorage[currGlyph]; + TTGlyphID newGlyph = lookup(offset, thisGlyph, success); + glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } + + if (flags & cgsSetMark) { + markGlyph = currGlyph; + } + + if (!(flags & cgsDontAdvance)) { + currGlyph += dir; + } + + return newState; +} + +TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success) +{ + TTGlyphID newGlyph = 0xFFFF; + if(LE_FAILURE(success)) return newGlyph; + LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset); + if(LE_FAILURE(success)) return newGlyph; + le_int16 format = SWAPW(lookupTable->format); + + switch (format) { + case ltfSimpleArray: { +#ifdef TEST_FORMAT + // Disabled pending for design review + LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success); + LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY); + if(LE_FAILURE(success)) return newGlyph; + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); + newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success)); +#endif + break; + } + case ltfSegmentSingle: { +#ifdef TEST_FORMAT + // Disabled pending for design review + LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable; + const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid); + if (segment != NULL) { + newGlyph = SWAPW(segment->value); + } +#endif + break; + } + case ltfSegmentArray: { + //printf("Context Lookup Table Format4: specific interpretation needed!\n"); + break; + } + case ltfSingleTable: + { +#ifdef TEST_FORMAT + // Disabled pending for design review + LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable; + const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid); + if (segment != NULL) { + newGlyph = SWAPW(segment->value); + } +#endif + break; + } + case ltfTrimmedArray: { + LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success); + if (LE_FAILURE(success)) return newGlyph; + TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); + TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount); + TTGlyphID lastGlyph = firstGlyph + glyphCount; + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); + if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { + LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount); + newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success)); + } + } + default: + break; + } + return newGlyph; +} + +void ContextualGlyphSubstitutionProcessor2::endStateTable() +{ +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,92 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H +#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "ContextualGlyphSubstitution.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2 +{ +public: + virtual void beginStateTable(); + + virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success); + + virtual void endStateTable(); + + ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + virtual ~ContextualGlyphSubstitutionProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + ContextualGlyphSubstitutionProcessor2(); + TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success); + +protected: + LEReferenceToArrayOf<le_uint32> perGlyphTable; + LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable; + + le_int16 perGlyphTableFormat; + le_int32 markGlyph; + + LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -49,6 +49,11 @@ ByteOffset substitutionTableOffset; }; +struct ContextualGlyphHeader2 : MorphStateTableHeader2 +{ + le_uint32 perGlyphTableOffset; // no more substitution tables +}; + enum ContextualGlyphSubstitutionFlags { cgsSetMark = 0x8000, @@ -62,5 +67,11 @@ WordOffset currOffset; }; +struct ContextualGlyphStateEntry2 : StateEntry2 +{ + le_uint16 markIndex; + le_uint16 currIndex; +}; + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -217,7 +217,7 @@ } LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(subRuleSetCount); @@ -266,7 +266,7 @@ } LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { const ClassDefinitionTable *classDefinitionTable = @@ -394,7 +394,7 @@ } LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { le_uint16 srSetCount = SWAPW(chainSubRuleSetCount); @@ -465,7 +465,7 @@ } LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success); if (coverageIndex >= 0) { const ClassDefinitionTable *backtrackClassDefinitionTable =
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -43,6 +43,7 @@ #include "GlyphSubstitutionTables.h" #include "GlyphIterator.h" #include "LookupProcessor.h" +#include "LETableReference.h" U_NAMESPACE_BEGIN @@ -88,6 +89,8 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray) + struct SubRuleSetTable { @@ -95,6 +98,7 @@ Offset subRuleTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray) // NOTE: Multiple variable size arrays!! struct SubRuleTable @@ -104,6 +108,7 @@ TTGlyphID inputGlyphArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SubRuleTable, inputGlyphArray) struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable { @@ -113,12 +118,16 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray) + struct SubClassSetTable { le_uint16 subClassRuleCount; Offset subClassRuleTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray) + // NOTE: Multiple variable size arrays!! struct SubClassRuleTable @@ -128,6 +137,8 @@ le_uint16 classArray[ANY_NUMBER]; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SubClassRuleTable, classArray) + // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause // it has an array of coverage tables instead of a single coverage table... @@ -143,6 +154,7 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray) struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase { @@ -156,6 +168,8 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray) + struct ChainSubRuleSetTable { @@ -163,6 +177,7 @@ Offset chainSubRuleTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray) // NOTE: Multiple variable size arrays!! struct ChainSubRuleTable @@ -176,6 +191,7 @@ //le_uint16 substCount; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray) struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable { @@ -187,12 +203,15 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray) struct ChainSubClassSetTable { le_uint16 chainSubClassRuleCount; Offset chainSubClassRuleTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray) + // NOTE: Multiple variable size arrays!! struct ChainSubClassRuleTable @@ -206,6 +225,7 @@ //le_uint16 substCount; //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray) // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause // it has arrays of coverage tables instead of a single coverage table... @@ -225,6 +245,8 @@ le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; }; +LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray) + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/CoverageTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CoverageTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -56,6 +56,8 @@ le_int32 getGlyphCoverage(LEGlyphID glyphID) const; }; +LE_VAR_ARRAY(CoverageFormat1Table, glyphArray) + struct CoverageFormat2Table : CoverageTable { @@ -64,6 +66,7 @@ le_int32 getGlyphCoverage(LEGlyphID glyphID) const; }; +LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -39,10 +39,10 @@ U_NAMESPACE_BEGIN -le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID glyphID = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyphID); + le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success); le_uint16 eeCount = SWAPW(entryExitCount); if (coverageIndex < 0 || coverageIndex >= eeCount) { @@ -51,7 +51,7 @@ } LEPoint entryAnchor, exitAnchor; - Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); + Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor); if (entryOffset != 0) {
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -57,8 +57,9 @@ le_uint16 entryExitCount; EntryExitRecord entryExitRecords[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; +LE_VAR_ARRAY(CursiveAttachmentSubtable, entryExitRecords) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/DeviceTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/DeviceTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -57,6 +57,7 @@ static const le_uint16 fieldSignBits[]; static const le_uint16 fieldBits[]; }; +LE_VAR_ARRAY(DeviceTable, deltaValues) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ExtensionSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ExtensionSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -47,6 +47,8 @@ le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { + const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this + if (LE_FAILURE(success)) { return 0; } @@ -55,9 +57,11 @@ if (elt != lookupType) { le_uint32 extOffset = READ_LONG(extensionOffset); - LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset); + LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset); - return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success); + if(LE_SUCCESS(success)) { + return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success); + } } return 0;
--- a/src/share/native/sun/font/layout/Features.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/Features.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -38,19 +38,20 @@ U_NAMESPACE_BEGIN -const FeatureTable *FeatureListTable::getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const +LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const { - if (featureIndex >= SWAPW(featureCount)) { - return 0; - } + if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) { + return LEReferenceTo<FeatureTable>(); + } Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset; *featureTag = SWAPT(featureRecordArray[featureIndex].featureTag); - return (const FeatureTable *) ((char *) this + SWAPW(featureTableOffset)); + return LEReferenceTo<FeatureTable>(base, success, SWAPW(featureTableOffset)); } +#if 0 /* * Note: according to the OpenType Spec. v 1.4, the entries in the Feature * List Table are sorted alphabetically by feature tag; however, there seem @@ -82,5 +83,6 @@ return 0; #endif } +#endif U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GDEFMarkFilter.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -36,9 +36,12 @@ U_NAMESPACE_BEGIN -GDEFMarkFilter::GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable) +GDEFMarkFilter::GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success) + : classDefTable(gdefTable->getGlyphClassDefinitionTable(gdefTable, success)) { - classDefTable = gdefTable->getGlyphClassDefinitionTable(); + if(!classDefTable.isValid()) { + success = LE_INTERNAL_ERROR; + } } GDEFMarkFilter::~GDEFMarkFilter()
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GDEFMarkFilter.h Thu Apr 18 14:38:37 2013 -0700 @@ -46,13 +46,13 @@ class GDEFMarkFilter : public UMemory, public LEGlyphFilter { private: - const GlyphClassDefinitionTable *classDefTable; + const LEReferenceTo<GlyphClassDefinitionTable> classDefTable; GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class public: - GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable); + GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); virtual ~GDEFMarkFilter(); virtual le_bool accept(LEGlyphID glyph) const;
--- a/src/share/native/sun/font/layout/GXLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GXLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -41,9 +41,10 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine) -GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success) + GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success) : LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable) { + fMorphTable.orphan(); // nothing else to do? } @@ -70,7 +71,7 @@ return 0; } - fMorphTable->process(glyphStorage); + fMorphTable->process(fMorphTable, glyphStorage, success); return count; }
--- a/src/share/native/sun/font/layout/GXLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GXLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -74,7 +74,7 @@ * * @internal */ - GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success); + GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success); /** * The destructor, virtual for correct polymorphic invocation. @@ -104,7 +104,7 @@ * * @internal */ - const MorphTableHeader *fMorphTable; + LEReferenceTo<MorphTableHeader> fMorphTable; /** * This method does GX layout using the font's 'mort' table. It converts the
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/GXLayoutEngine2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,91 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "LayoutEngine.h" +#include "GXLayoutEngine2.h" +#include "LEGlyphStorage.h" +#include "MorphTables.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2) + +GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success) + : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable) +{ + // nothing else to do? +} + +GXLayoutEngine2::~GXLayoutEngine2() +{ + reset(); +} + +// apply 'morx' table +le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if (LE_FAILURE(success)) { + return 0; + } + + if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) { + success = LE_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success); + + if (LE_FAILURE(success)) { + return 0; + } + + fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success); + return count; +} + +// apply positional tables +void GXLayoutEngine2::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/, + LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success) +{ + if (LE_FAILURE(success)) { + return; + } + + if (chars == NULL || offset < 0 || count < 0) { + success = LE_ILLEGAL_ARGUMENT_ERROR; + return; + } + + // FIXME: no positional processing yet... +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/GXLayoutEngine2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,149 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __GXLAYOUTENGINE2_H +#define __GXLAYOUTENGINE2_H + +#include "LETypes.h" +#include "LayoutEngine.h" + +#include "MorphTables.h" + +U_NAMESPACE_BEGIN + +class LEFontInstance; +class LEGlyphStorage; + +/** + * This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT) + * fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's + * TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details. + * Information about 'mort' tables is in the chapter titled "Font Files." + * + * @internal + */ +class GXLayoutEngine2 : public LayoutEngine +{ +public: + /** + * This is the main constructor. It constructs an instance of GXLayoutEngine for + * a particular font, script and language. It takes the 'mort' table as a parameter since + * LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a + * GX font. + * + * Note: GX and AAT fonts don't contain any script and language specific tables, so + * the script and language are ignored. + * + * @param fontInstance - the font + * @param scriptCode - the script + * @param langaugeCode - the language + * @param morphTable - the 'mort' table + * @param success - set to an error code if the operation fails + * + * @see LayoutEngine::layoutEngineFactory + * @see ScriptAndLangaugeTags.h for script and language codes + * + * @internal + */ + GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success); + + /** + * The destructor, virtual for correct polymorphic invocation. + * + * @internal + */ + virtual ~GXLayoutEngine2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +protected: + + /** + * The address of the 'mort' table + * + * @internal + */ + const LEReferenceTo<MorphTableHeader2> fMorphTable; + + /** + * This method does GX layout using the font's 'mort' table. It converts the + * input character codes to glyph indices using mapCharsToGlyphs, and then + * applies the 'mort' table. + * + * Input parameters: + * @param chars - the input character context + * @param offset - the index of the first character to process + * @param count - the number of characters to process + * @param max - the number of characters in the input context + * @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run + * @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set. + * + * Output parameters: + * @param success - set to an error code if the operation fails + * + * @return the number of glyphs in the glyph index array + * + * @internal + */ + virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, + LEGlyphStorage &glyphStorage, LEErrorCode &success); + + /** + * This method adjusts the glyph positions using the font's + * 'kern', 'trak', 'bsln', 'opbd' and 'just' tables. + * + * Input parameters: + * @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed. + * + * Output parameters: + * @param success - set to an error code if the operation fails + * + * @internal + */ + virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, + LEGlyphStorage &glyphStorage, LEErrorCode &success); + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -36,24 +36,36 @@ U_NAMESPACE_BEGIN -const GlyphClassDefinitionTable *GlyphDefinitionTableHeader::getGlyphClassDefinitionTable() const +const LEReferenceTo<GlyphClassDefinitionTable> +GlyphDefinitionTableHeader::getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const { - return (const GlyphClassDefinitionTable *) ((char *) this + SWAPW(glyphClassDefOffset)); + if(LE_FAILURE(success)) return LEReferenceTo<GlyphClassDefinitionTable>(); + return LEReferenceTo<GlyphClassDefinitionTable>(base, success, SWAPW(glyphClassDefOffset)); } -const AttachmentListTable *GlyphDefinitionTableHeader::getAttachmentListTable() const +const LEReferenceTo<AttachmentListTable> +GlyphDefinitionTableHeader::getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const { - return (const AttachmentListTable *) ((char *) this + SWAPW(attachListOffset)); + if(LE_FAILURE(success)) return LEReferenceTo<AttachmentListTable>(); + return LEReferenceTo<AttachmentListTable>(base, success, SWAPW(attachListOffset)); } -const LigatureCaretListTable *GlyphDefinitionTableHeader::getLigatureCaretListTable() const +const LEReferenceTo<LigatureCaretListTable> +GlyphDefinitionTableHeader::getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const { - return (const LigatureCaretListTable *) ((char *) this + SWAPW(ligCaretListOffset)); + if(LE_FAILURE(success)) return LEReferenceTo<LigatureCaretListTable>(); + return LEReferenceTo<LigatureCaretListTable>(base, success, SWAPW(ligCaretListOffset)); } -const MarkAttachClassDefinitionTable *GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable() const +const LEReferenceTo<MarkAttachClassDefinitionTable> +GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const { - return (const MarkAttachClassDefinitionTable *) ((char *) this + SWAPW(MarkAttachClassDefOffset)); + if(LE_FAILURE(success)) return LEReferenceTo<MarkAttachClassDefinitionTable>(); + return LEReferenceTo<MarkAttachClassDefinitionTable>(base, success, SWAPW(MarkAttachClassDefOffset)); } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -60,12 +60,14 @@ le_uint16 glyphCount; Offset attachPointTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray) struct AttachPointTable { le_uint16 pointCount; le_uint16 pointIndexArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(AttachPointTable, pointIndexArray) struct LigatureCaretListTable { @@ -73,12 +75,14 @@ le_uint16 ligGlyphCount; Offset ligGlyphTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray) struct LigatureGlyphTable { le_uint16 caretCount; Offset caretValueTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray) struct CaretValueTable { @@ -111,10 +115,18 @@ Offset ligCaretListOffset; Offset MarkAttachClassDefOffset; - const GlyphClassDefinitionTable *getGlyphClassDefinitionTable() const; - const AttachmentListTable *getAttachmentListTable()const ; - const LigatureCaretListTable *getLigatureCaretListTable() const; - const MarkAttachClassDefinitionTable *getMarkAttachClassDefinitionTable() const; + const LEReferenceTo<GlyphClassDefinitionTable> + getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const; + const LEReferenceTo<AttachmentListTable> + getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success)const ; + const LEReferenceTo<LigatureCaretListTable> + getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const; + const LEReferenceTo<MarkAttachClassDefinitionTable> + getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base, + LEErrorCode &success) const; }; U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphIterator.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphIterator.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -41,18 +41,21 @@ U_NAMESPACE_BEGIN GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, - FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader) + FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader) : direction(1), position(-1), nextLimit(-1), prevLimit(-1), glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments), srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0), - glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL) + glyphClassDefinitionTable(), markAttachClassDefinitionTable() { + LEErrorCode success = LE_NO_ERROR; // TODO le_int32 glyphCount = glyphStorage.getGlyphCount(); - if (theGlyphDefinitionTableHeader != NULL) { - glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable(); - markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable(); + if (theGlyphDefinitionTableHeader.isValid()) { + glyphClassDefinitionTable = theGlyphDefinitionTableHeader + -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success); + markAttachClassDefinitionTable = theGlyphDefinitionTableHeader + ->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success); } nextLimit = glyphCount; @@ -380,6 +383,7 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index) const { + LEErrorCode success = LE_NO_ERROR; LEGlyphID glyphID = glyphStorage[index]; le_int32 glyphClass = gcdNoGlyphClass; @@ -387,8 +391,8 @@ return TRUE; } - if (glyphClassDefinitionTable != NULL) { - glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID); + if (glyphClassDefinitionTable.isValid()) { + glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success); } switch (glyphClass) @@ -410,8 +414,9 @@ le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift; - if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) { - return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType; + if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) { + return markAttachClassDefinitionTable + -> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType; } return FALSE; @@ -461,6 +466,7 @@ while (newPosition != nextLimit && delta > 0) { do { newPosition += direction; + //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta); } while (newPosition != nextLimit && filterGlyph(newPosition)); delta -= 1; @@ -468,6 +474,7 @@ position = newPosition; + //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta); return position != nextLimit; } @@ -483,6 +490,7 @@ while (newPosition != prevLimit && delta > 0) { do { newPosition -= direction; + //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta); } while (newPosition != prevLimit && filterGlyph(newPosition)); delta -= 1; @@ -490,6 +498,7 @@ position = newPosition; + //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta); return position != prevLimit; }
--- a/src/share/native/sun/font/layout/GlyphIterator.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphIterator.h Thu Apr 18 14:38:37 2013 -0700 @@ -49,7 +49,7 @@ class GlyphIterator : public UMemory { public: GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, - FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader); + FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader); GlyphIterator(GlyphIterator &that); @@ -117,8 +117,8 @@ FeatureMask featureMask; le_int32 glyphGroup; - const GlyphClassDefinitionTable *glyphClassDefinitionTable; - const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable; + LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable; + LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable; GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class };
--- a/src/share/native/sun/font/layout/GlyphLookupTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphLookupTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -37,21 +37,22 @@ U_NAMESPACE_BEGIN -le_bool GlyphLookupTableHeader::coversScript(LETag scriptTag) const +le_bool GlyphLookupTableHeader::coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const { - const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset)); + LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset)); - return scriptListOffset != 0 && scriptListTable->findScript(scriptTag) != NULL; + return (scriptListOffset != 0) && scriptListTable->findScript(scriptListTable, scriptTag, success) .isValid(); } -le_bool GlyphLookupTableHeader::coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const +le_bool GlyphLookupTableHeader::coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const { - const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset)); - const LangSysTable *langSysTable = scriptListTable->findLanguage(scriptTag, languageTag, exactMatch); + LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset)); + LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable, + scriptTag, languageTag, success, exactMatch); // FIXME: could check featureListOffset, lookupListOffset, and lookup count... // Note: don't have to SWAPW langSysTable->featureCount to check for non-zero. - return langSysTable != NULL && langSysTable->featureCount != 0; + return LE_SUCCESS(success)&&langSysTable.isValid() && langSysTable->featureCount != 0; } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphLookupTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphLookupTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -49,8 +49,8 @@ Offset featureListOffset; Offset lookupListOffset; - le_bool coversScript(LETag scriptTag) const; - le_bool coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const; + le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const; + le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const; }; U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphPositioningTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -41,16 +41,16 @@ U_NAMESPACE_BEGIN -void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, +void GlyphPositioningTableHeader::process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success, + const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success, const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const { if (LE_FAILURE(success)) { return; } - GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success); + GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success); if (LE_FAILURE(success)) { return; }
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphPositioningTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -40,6 +40,7 @@ #include "OpenTypeTables.h" #include "Lookups.h" #include "GlyphLookupTables.h" +#include "LETableReference.h" U_NAMESPACE_BEGIN @@ -51,9 +52,9 @@ struct GlyphPositioningTableHeader : public GlyphLookupTableHeader { - void process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, + void process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success, + const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success, const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const; };
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -57,7 +57,7 @@ typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable; GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor( - const GlyphPositioningTableHeader *glyphPositioningTableHeader, + const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader, LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, @@ -65,7 +65,7 @@ le_bool featureOrder, LEErrorCode& success) : LookupProcessor( - (char *) glyphPositioningTableHeader, + glyphPositioningTableHeader, SWAPW(glyphPositioningTableHeader->scriptListOffset), SWAPW(glyphPositioningTableHeader->featureListOffset), SWAPW(glyphPositioningTableHeader->lookupListOffset), @@ -84,7 +84,7 @@ { } -le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, +le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const @@ -102,55 +102,55 @@ case gpstSingle: { - const SinglePositioningSubtable *subtable = (const SinglePositioningSubtable *) lookupSubtable; + LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstPair: { - const PairPositioningSubtable *subtable = (const PairPositioningSubtable *) lookupSubtable; + LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstCursive: { - const CursiveAttachmentSubtable *subtable = (const CursiveAttachmentSubtable *) lookupSubtable; + LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToBase: { - const MarkToBasePositioningSubtable *subtable = (const MarkToBasePositioningSubtable *) lookupSubtable; + LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToLigature: { - const MarkToLigaturePositioningSubtable *subtable = (const MarkToLigaturePositioningSubtable *) lookupSubtable; + LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstMarkToMark: { - const MarkToMarkPositioningSubtable *subtable = (const MarkToMarkPositioningSubtable *) lookupSubtable; + LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fontInstance); + delta = subtable->process(subtable, glyphIterator, fontInstance, success); break; } case gpstContext: { - const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable; + LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; @@ -158,7 +158,7 @@ case gpstChainedContext: { - const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable; + LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; @@ -166,7 +166,7 @@ case gpstExtension: { - const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; + LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); break;
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.h Thu Apr 18 14:38:37 2013 -0700 @@ -51,7 +51,7 @@ class GlyphPositioningLookupProcessor : public LookupProcessor { public: - GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader, + GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader, LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, @@ -61,7 +61,7 @@ virtual ~GlyphPositioningLookupProcessor(); - virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, + virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; protected:
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -51,7 +51,7 @@ U_NAMESPACE_BEGIN GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor( - const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, + const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader, LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, @@ -60,7 +60,7 @@ le_bool featureOrder, LEErrorCode& success) : LookupProcessor( - (char *) glyphSubstitutionTableHeader, + glyphSubstitutionTableHeader, SWAPW(glyphSubstitutionTableHeader->scriptListOffset), SWAPW(glyphSubstitutionTableHeader->featureListOffset), SWAPW(glyphSubstitutionTableHeader->lookupListOffset), @@ -73,7 +73,7 @@ { } -le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, +le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { @@ -89,39 +89,39 @@ case gsstSingle: { - const SingleSubstitutionSubtable *subtable = (const SingleSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<SingleSubstitutionSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fFilter); + delta = subtable->process(subtable, glyphIterator, success, fFilter); break; } case gsstMultiple: { - const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<MultipleSubstitutionSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, success, fFilter); + delta = subtable->process(subtable, glyphIterator, success, fFilter); break; } case gsstAlternate: { - const AlternateSubstitutionSubtable *subtable = (const AlternateSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<AlternateSubstitutionSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fFilter); + delta = subtable->process(subtable, glyphIterator, success, fFilter); break; } case gsstLigature: { - const LigatureSubstitutionSubtable *subtable = (const LigatureSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<LigatureSubstitutionSubtable> subtable(lookupSubtable, success); - delta = subtable->process(glyphIterator, fFilter); + delta = subtable->process(subtable, glyphIterator, success, fFilter); break; } case gsstContext: { - const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; @@ -129,7 +129,7 @@ case gsstChainingContext: { - const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable; + const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, glyphIterator, fontInstance, success); break; @@ -137,7 +137,7 @@ case gsstExtension: { - const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable; + const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success); delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success); break;
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.h Thu Apr 18 14:38:37 2013 -0700 @@ -52,7 +52,7 @@ class GlyphSubstitutionLookupProcessor : public LookupProcessor { public: - GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader, + GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader, LETag scriptTag, LETag languageTag, const LEGlyphFilter *filter, @@ -63,7 +63,7 @@ virtual ~GlyphSubstitutionLookupProcessor(); - virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, + virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; protected:
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -42,11 +42,12 @@ U_NAMESPACE_BEGIN -le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage, +le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base, + LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount, @@ -57,7 +58,7 @@ return 0; } - GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success); + GlyphSubstitutionLookupProcessor processor(base, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success); return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success); }
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,11 +50,12 @@ struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader { - le_int32 process(LEGlyphStorage &glyphStorage, + le_int32 process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base, + LEGlyphStorage &glyphStorage, le_bool rightToLeft, LETag scriptTag, LETag languageTag, - const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEGlyphFilter *filter, const FeatureMap *featureMap, le_int32 featureMapCount,
--- a/src/share/native/sun/font/layout/HanLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/HanLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -64,7 +64,7 @@ #define features (loclFeatureMask) HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) { fFeatureMap = featureMap;
--- a/src/share/native/sun/font/layout/HanLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/HanLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -73,7 +73,7 @@ * @internal */ HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTablem, LEErrorCode &success); /**
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/HangulLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -209,7 +209,7 @@ } HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success) { fFeatureMap = featureMap;
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/HangulLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -79,7 +79,7 @@ * @internal */ HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ICUFeatures.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ICUFeatures.h Thu Apr 18 14:38:37 2013 -0700 @@ -54,16 +54,21 @@ le_uint16 lookupCount; le_uint16 lookupListIndexArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(FeatureTable, lookupListIndexArray) struct FeatureListTable { le_uint16 featureCount; FeatureRecord featureRecordArray[ANY_NUMBER]; - const FeatureTable *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const; + LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const; - const FeatureTable *getFeatureTable(LETag featureTag) const; +#if 0 + const LEReferenceTo<FeatureTable> getFeatureTable(const LETableReference &base, LETag featureTag, LEErrorCode &success) const; +#endif }; +LE_VAR_ARRAY(FeatureListTable, featureRecordArray) + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/IndicClassTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicClassTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -186,13 +186,15 @@ }; // FIXME: Should some of the bb's be pb's? (KA, NA, MA, YA, VA, etc. (approx 13)) +// U+C43 and U+C44 are _lm here not _dr. Similar to the situation with U+CC3 and +// U+CC4 in Kannada below. static const IndicClassTable::CharClass teluCharClasses[] = { _xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F _iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F - _da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F + _da, _dr, _dr, _lm, _lm, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F _xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx // 0C60 - 0C6F };
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -50,7 +50,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine) IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL) { if ( version2 ) {
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -81,7 +81,7 @@ * @internal */ IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/IndicRearrangement.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicRearrangement.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -49,6 +49,10 @@ { }; +struct IndicRearrangementSubtableHeader2 : MorphStateTableHeader2 +{ +}; + enum IndicRearrangementFlags { irfMarkFirst = 0x8000, @@ -85,6 +89,10 @@ { }; +struct IndicRearrangementStateEntry2 : StateEntry2 +{ +}; + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -43,11 +43,14 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor) -IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader) - : StateTableProcessor(morphSubtableHeader) + IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor(morphSubtableHeader, success), + indicRearrangementSubtableHeader(morphSubtableHeader, success), + entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader), + entryTableOffset, LE_UNBOUNDED_ARRAY), + int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY) + { - indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader; - entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset); } IndicRearrangementProcessor::~IndicRearrangementProcessor() @@ -62,7 +65,8 @@ ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) { - const IndicRearrangementStateEntry *entry = &entryTable[index]; + LEErrorCode success = LE_NO_ERROR; // todo- make a param? + const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success); ByteOffset newState = SWAPW(entry->newStateOffset); IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -58,7 +58,7 @@ void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const; - IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader); + IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~IndicRearrangementProcessor(); /** @@ -79,8 +79,9 @@ le_int32 firstGlyph; le_int32 lastGlyph; - const IndicRearrangementStateEntry *entryTable; - const IndicRearrangementSubtableHeader *indicRearrangementSubtableHeader; + LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader; + LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable; + LEReferenceToArrayOf<le_int16> int16Table; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,425 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "StateTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "IndicRearrangementProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2) + +IndicRearrangementProcessor2::IndicRearrangementProcessor2( + const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor2(morphSubtableHeader, success), indicRearrangementSubtableHeader(morphSubtableHeader, success), + entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY) +{ +} + +IndicRearrangementProcessor2::~IndicRearrangementProcessor2() +{ +} + +void IndicRearrangementProcessor2::beginStateTable() +{ + firstGlyph = 0; + lastGlyph = 0; +} + +le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, + EntryTableIndex2 index, LEErrorCode &success) +{ + const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success); + if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state? + le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state + IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags); + + if (flags & irfMarkFirst) { + firstGlyph = currGlyph; + } + + if (flags & irfMarkLast) { + lastGlyph = currGlyph; + } + + doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask)); + + if (!(flags & irfDontAdvance)) { + currGlyph += dir; + } + + return newState; // index to new state +} + +void IndicRearrangementProcessor2::endStateTable() +{ +} + +void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const +{ + LEGlyphID a, b, c, d; + le_int32 ia, ib, ic, id, ix, x; + LEErrorCode success = LE_NO_ERROR; + + switch(verb) + { + case irvNoAction: + break; + + case irvxA: + a = glyphStorage[firstGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + x = firstGlyph + 1; + + while (x <= lastGlyph) { + glyphStorage[x - 1] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x - 1, ix, success); + x += 1; + } + + glyphStorage[lastGlyph] = a; + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvDx: + d = glyphStorage[lastGlyph]; + id = glyphStorage.getCharIndex(lastGlyph, success); + x = lastGlyph - 1; + + while (x >= firstGlyph) { + glyphStorage[x + 1] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x + 1, ix, success); + x -= 1; + } + + glyphStorage[firstGlyph] = d; + glyphStorage.setCharIndex(firstGlyph, id, success); + break; + + case irvDxA: + a = glyphStorage[firstGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + + glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; + glyphStorage[lastGlyph] = a; + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvxAB: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + x = firstGlyph + 2; + + while (x <= lastGlyph) { + glyphStorage[x - 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x - 2, ix, success); + x += 1; + } + + glyphStorage[lastGlyph - 1] = a; + glyphStorage[lastGlyph] = b; + + glyphStorage.setCharIndex(lastGlyph - 1, ia, success); + glyphStorage.setCharIndex(lastGlyph, ib, success); + break; + + case irvxBA: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + x = firstGlyph + 2; + + while (x <= lastGlyph) { + glyphStorage[x - 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x - 2, ix, success); + x += 1; + } + + glyphStorage[lastGlyph - 1] = b; + glyphStorage[lastGlyph] = a; + + glyphStorage.setCharIndex(lastGlyph - 1, ib, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvCDx: + c = glyphStorage[lastGlyph - 1]; + d = glyphStorage[lastGlyph]; + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = lastGlyph - 2; + + while (x >= firstGlyph) { + glyphStorage[x + 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x + 2, ix, success); + x -= 1; + } + + glyphStorage[firstGlyph] = c; + glyphStorage[firstGlyph + 1] = d; + + glyphStorage.setCharIndex(firstGlyph, ic, success); + glyphStorage.setCharIndex(firstGlyph + 1, id, success); + break; + + case irvDCx: + c = glyphStorage[lastGlyph - 1]; + d = glyphStorage[lastGlyph]; + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = lastGlyph - 2; + + while (x >= firstGlyph) { + glyphStorage[x + 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x + 2, ix, success); + x -= 1; + } + + glyphStorage[firstGlyph] = d; + glyphStorage[firstGlyph + 1] = c; + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(firstGlyph + 1, ic, success); + break; + + case irvCDxA: + a = glyphStorage[firstGlyph]; + c = glyphStorage[lastGlyph - 1]; + d = glyphStorage[lastGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = lastGlyph - 2; + + while (x > firstGlyph) { + glyphStorage[x + 1] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x + 1, ix, success); + x -= 1; + } + + glyphStorage[firstGlyph] = c; + glyphStorage[firstGlyph + 1] = d; + glyphStorage[lastGlyph] = a; + + glyphStorage.setCharIndex(firstGlyph, ic, success); + glyphStorage.setCharIndex(firstGlyph + 1, id, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvDCxA: + a = glyphStorage[firstGlyph]; + c = glyphStorage[lastGlyph - 1]; + d = glyphStorage[lastGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = lastGlyph - 2; + + while (x > firstGlyph) { + glyphStorage[x + 1] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x + 1, ix, success); + x -= 1; + } + + glyphStorage[firstGlyph] = d; + glyphStorage[firstGlyph + 1] = c; + glyphStorage[lastGlyph] = a; + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(firstGlyph + 1, ic, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvDxAB: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + d = glyphStorage[lastGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = firstGlyph + 2; + + while (x < lastGlyph) { + glyphStorage[x - 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x - 2, ix, success); + x += 1; + } + + glyphStorage[firstGlyph] = d; + glyphStorage[lastGlyph - 1] = a; + glyphStorage[lastGlyph] = b; + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(lastGlyph - 1, ia, success); + glyphStorage.setCharIndex(lastGlyph, ib, success); + break; + + case irvDxBA: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + d = glyphStorage[lastGlyph]; + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + x = firstGlyph + 2; + + while (x < lastGlyph) { + glyphStorage[x - 2] = glyphStorage[x]; + ix = glyphStorage.getCharIndex(x, success); + glyphStorage.setCharIndex(x - 2, ix, success); + x += 1; + } + + glyphStorage[firstGlyph] = d; + glyphStorage[lastGlyph - 1] = b; + glyphStorage[lastGlyph] = a; + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(lastGlyph - 1, ib, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvCDxAB: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + + glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1]; + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph]; + + glyphStorage[lastGlyph - 1] = a; + glyphStorage[lastGlyph] = b; + + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + + glyphStorage.setCharIndex(firstGlyph, ic, success); + glyphStorage.setCharIndex(firstGlyph + 1, id, success); + + glyphStorage.setCharIndex(lastGlyph - 1, ia, success); + glyphStorage.setCharIndex(lastGlyph, ib, success); + break; + + case irvCDxBA: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + + glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1]; + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph]; + + glyphStorage[lastGlyph - 1] = b; + glyphStorage[lastGlyph] = a; + + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + + glyphStorage.setCharIndex(firstGlyph, ic, success); + glyphStorage.setCharIndex(firstGlyph + 1, id, success); + + glyphStorage.setCharIndex(lastGlyph - 1, ib, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + case irvDCxAB: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + + glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1]; + + glyphStorage[lastGlyph - 1] = a; + glyphStorage[lastGlyph] = b; + + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(firstGlyph + 1, ic, success); + + glyphStorage.setCharIndex(lastGlyph - 1, ia, success); + glyphStorage.setCharIndex(lastGlyph, ib, success); + break; + + case irvDCxBA: + a = glyphStorage[firstGlyph]; + b = glyphStorage[firstGlyph + 1]; + + glyphStorage[firstGlyph] = glyphStorage[lastGlyph]; + glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1]; + + glyphStorage[lastGlyph - 1] = b; + glyphStorage[lastGlyph] = a; + + ia = glyphStorage.getCharIndex(firstGlyph, success); + ib = glyphStorage.getCharIndex(firstGlyph + 1, success); + ic = glyphStorage.getCharIndex(lastGlyph - 1, success); + id = glyphStorage.getCharIndex(lastGlyph, success); + + glyphStorage.setCharIndex(firstGlyph, id, success); + glyphStorage.setCharIndex(firstGlyph + 1, ic, success); + + glyphStorage.setCharIndex(lastGlyph - 1, ib, success); + glyphStorage.setCharIndex(lastGlyph, ia, success); + break; + + default: + break; + } + +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,88 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __INDICREARRANGEMENTPROCESSOR2_H +#define __INDICREARRANGEMENTPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor.h" +#include "StateTableProcessor2.h" +#include "IndicRearrangement.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class IndicRearrangementProcessor2 : public StateTableProcessor2 +{ +public: + virtual void beginStateTable(); + + virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success); + + virtual void endStateTable(); + + void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const; + + IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + virtual ~IndicRearrangementProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +protected: + le_int32 firstGlyph; + le_int32 lastGlyph; + + LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable; + LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/IndicReordering.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicReordering.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -266,7 +266,7 @@ le_uint32 saveAuxData = fGlyphStorage.getAuxData(i+inv_count,success); const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass); int j; - for (j = 0 ; *(splitMatra)[j] != 0 ; j++) { + for (j = 0 ; j < SM_MAX_PIECES && *(splitMatra)[j] != 0 ; j++) { LEUnicode piece = (*splitMatra)[j]; if ( j == 0 ) { fOutChars[i+inv_count] = piece; @@ -357,7 +357,7 @@ const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass); int i; - for (i = 0; i < 3 && (*splitMatra)[i] != 0; i += 1) { + for (i = 0; i < SM_MAX_PIECES && (*splitMatra)[i] != 0; i += 1) { LEUnicode piece = (*splitMatra)[i]; IndicClassTable::CharClass pieceClass = classTable->getCharClass(piece); @@ -658,6 +658,11 @@ MPreFixups *mpreFixups = NULL; const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode); + if(classTable==NULL) { + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } + if (classTable->scriptFlags & SF_MPRE_FIXUP) { mpreFixups = new MPreFixups(charCount); if (mpreFixups == NULL) { @@ -1224,7 +1229,6 @@ LEUnicode currentChar; - LEUnicode virama; LEUnicode workChars[2]; LEGlyphStorage workGlyphs; @@ -1232,14 +1236,17 @@ //le_int32 offset = 0; +#if 0 +// TODO: Should this section of code have actually been doing something? // First find the relevant virama for the script we are dealing with - + LEUnicode virama; for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) { if ( classTable->isVirama(currentChar)) { virama = currentChar; break; } } +#endif for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) { if ( classTable->isConsonant(currentChar)) {
--- a/src/share/native/sun/font/layout/IndicReordering.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/IndicReordering.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -96,7 +96,9 @@ #define SF_POST_BASE_LIMIT_MASK 0x0000FFFFU #define SF_NO_POST_BASE_LIMIT 0x00007FFFU -typedef LEUnicode SplitMatra[3]; +#define SM_MAX_PIECES 3 + +typedef LEUnicode SplitMatra[SM_MAX_PIECES]; class MPreFixups; class LEGlyphStorage;
--- a/src/share/native/sun/font/layout/KernTable.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/KernTable.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -48,7 +48,7 @@ le_int16 value; // fword, kern value in funits }; #define KERN_PAIRINFO_SIZE 6 - +LE_CORRECT_SIZE(PairInfo, KERN_PAIRINFO_SIZE) struct Subtable_0 { le_uint16 nPairs; le_uint16 searchRange; @@ -56,6 +56,7 @@ le_uint16 rangeShift; }; #define KERN_SUBTABLE_0_HEADER_SIZE 8 +LE_CORRECT_SIZE(Subtable_0, KERN_SUBTABLE_0_HEADER_SIZE) // Kern table version 0 only struct SubtableHeader { @@ -64,6 +65,7 @@ le_uint16 coverage; }; #define KERN_SUBTABLE_HEADER_SIZE 6 +LE_CORRECT_SIZE(SubtableHeader, KERN_SUBTABLE_HEADER_SIZE) // Version 0 only, version 1 has different layout struct KernTableHeader { @@ -71,6 +73,7 @@ le_uint16 nTables; }; #define KERN_TABLE_HEADER_SIZE 4 +LE_CORRECT_SIZE(KernTableHeader, KERN_TABLE_HEADER_SIZE) #define COVERAGE_HORIZONTAL 0x1 #define COVERAGE_MINIMUM 0x2 @@ -92,21 +95,21 @@ * TODO: support multiple subtables * TODO: respect header flags */ -KernTable::KernTable(const LEFontInstance* font_, const void* tableData) - : pairs(0), font(font_) +KernTable::KernTable(const LETableReference& base, LEErrorCode &success) + : pairs(), pairsSwapped(NULL), fTable(base) { - const KernTableHeader* header = (const KernTableHeader*)tableData; - if (header == 0) { + if(LE_FAILURE(success) || (fTable.isEmpty())) { #if DEBUG fprintf(stderr, "no kern data\n"); #endif return; } + LEReferenceTo<KernTableHeader> header(fTable, success); #if DEBUG // dump first 32 bytes of header for (int i = 0; i < 64; ++i) { - fprintf(stderr, "%0.2x ", ((const char*)tableData)[i]&0xff); + fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff); if (((i+1)&0xf) == 0) { fprintf(stderr, "\n"); } else if (((i+1)&0x7) == 0) { @@ -115,12 +118,17 @@ } #endif - if (header->version == 0 && SWAPW(header->nTables) > 0) { - const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE); - if (subhead->version == 0) { + if(LE_FAILURE(success)) return; + + if (!header.isEmpty() && header->version == 0 && SWAPW(header->nTables) > 0) { + LEReferenceTo<SubtableHeader> subhead(header, success, KERN_TABLE_HEADER_SIZE); + + if (LE_SUCCESS(success) && !subhead.isEmpty() && subhead->version == 0) { coverage = SWAPW(subhead->coverage); if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning - const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE); + LEReferenceTo<Subtable_0> table(subhead, success, KERN_SUBTABLE_HEADER_SIZE); + + if(table.isEmpty() || LE_FAILURE(success)) return; nPairs = SWAPW(table->nPairs); @@ -134,19 +142,31 @@ rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange; #endif - pairs = (PairInfo*)font->getKernPairs(); - if (pairs == NULL) { - char *pairData = (char*)table + KERN_SUBTABLE_0_HEADER_SIZE; - char *pptr = pairData; - pairs = (PairInfo*)(malloc(nPairs*sizeof(PairInfo))); - PairInfo *p = (PairInfo*)pairs; - for (int i = 0; i < nPairs; i++, pptr += KERN_PAIRINFO_SIZE, p++) { - memcpy(p, pptr, KERN_PAIRINFO_SIZE); + if(LE_SUCCESS(success) && nPairs>0) { + // pairs is an instance member, and table is on the stack. + // set 'pairs' based on table.getAlias(). This will range check it. + + pairs = LEReferenceToArrayOf<PairInfo>(fTable, // based on overall table + success, + (const PairInfo*)table.getAlias(), // subtable 0 + .. + KERN_SUBTABLE_0_HEADER_SIZE, // .. offset of header size + nPairs); // count + } + if (LE_SUCCESS(success) && pairs.isValid()) { + pairsSwapped = (PairInfo*)(malloc(nPairs*sizeof(PairInfo))); + PairInfo *p = (PairInfo*)pairsSwapped; + for (int i = 0; LE_SUCCESS(success) && i < nPairs; i++, p++) { + memcpy(p, pairs.getAlias(i,success), KERN_PAIRINFO_SIZE); p->key = SWAPL(p->key); } - font->setKernPairs((void*)pairs); + fTable.getFont()->setKernPairs((void*)pairsSwapped); // store it } +#if 0 + fprintf(stderr, "coverage: %0.4x nPairs: %d pairs %p\n", coverage, nPairs, pairs.getAlias()); + fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); + fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift)); +#endif #if DEBUG fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs); fprintf(stderr, @@ -194,14 +214,17 @@ * Process the glyph positions. The positions array has two floats for each * glyph, plus a trailing pair to mark the end of the last glyph. */ -void KernTable::process(LEGlyphStorage& storage) +void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success) { - if (pairs) { - LEErrorCode success = LE_NO_ERROR; + if(LE_FAILURE(success)) return; + + if (pairsSwapped) { + success = LE_NO_ERROR; le_uint32 key = storage[0]; // no need to mask off high bits float adjust = 0; - for (int i = 1, e = storage.getGlyphCount(); i < e; ++i) { + + for (int i = 1, e = storage.getGlyphCount(); LE_SUCCESS(success)&& i < e; ++i) { key = key << 16 | (storage[i] & 0xffff); // argh, to do a binary search, we need to have the pair list in sorted order @@ -209,7 +232,7 @@ // so either I have to swap the element each time I examine it, or I have to swap // all the elements ahead of time and store them in the font - const PairInfo* p = pairs; + const PairInfo* p = pairsSwapped; const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */ if (key > tp->key) { p = tp; @@ -225,7 +248,7 @@ tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE)); le_uint32 tkey = tp->key; #if DEBUG - fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairs), tkey); + fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey); #endif if (tkey <= key) { if (tkey == key) { @@ -240,10 +263,10 @@ // device transform, or a faster way, such as moving the // entire kern table up to Java. LEPoint pt; - pt.fX = font->xUnitsToPoints(value); + pt.fX = fTable.getFont()->xUnitsToPoints(value); pt.fY = 0; - font->getKerningAdjustment(pt); + fTable.getFont()->getKerningAdjustment(pt); adjust += pt.fX; break; }
--- a/src/share/native/sun/font/layout/KernTable.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/KernTable.h Thu Apr 18 14:38:37 2013 -0700 @@ -26,7 +26,7 @@ /* * * - * (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved * */ @@ -38,6 +38,7 @@ #endif #include "LETypes.h" +#include "LETableReference.h" //#include "LEFontInstance.h" //#include "LEGlyphStorage.h" @@ -56,19 +57,20 @@ private: le_uint16 coverage; le_uint16 nPairs; - const PairInfo* pairs; - const LEFontInstance* font; + LEReferenceToArrayOf<PairInfo> pairs; + PairInfo *pairsSwapped; + const LETableReference &fTable; le_uint16 searchRange; le_uint16 entrySelector; le_uint16 rangeShift; public: - KernTable(const LEFontInstance* font, const void* tableData); + KernTable(const LETableReference &table, LEErrorCode &success); /* * Process the glyph positions. */ - void process(LEGlyphStorage& storage); + void process(LEGlyphStorage& storage, LEErrorCode &success); }; U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -43,7 +43,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine) KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) { fFeatureMap = KhmerReordering::getFeatureMap(fFeatureMapCount);
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -83,7 +83,7 @@ * @internal */ KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/LEFontInstance.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LEFontInstance.h Thu Apr 18 14:38:37 2013 -0700 @@ -190,6 +190,25 @@ */ virtual const void *getFontTable(LETag tableTag) const = 0; + /** + * This method reads a table from the font. Note that in general, + * it only makes sense to call this method on an <code>LEFontInstance</code> + * which represents a physical font - i.e. one which has been returned by + * <code>getSubFont()</code>. This is because each subfont in a composite font + * will have different tables, and there's no way to know which subfont to access. + * + * Subclasses which represent composite fonts should always return <code>NULL</code>. + * + * This version sets a length, for range checking. + * + * @param tableTag - the four byte table tag. (e.g. 'cmap') + * @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown. + * @return the address of the table in memory, or <code>NULL</code> + * if the table doesn't exist. + * @internal + */ + virtual const void* getFontTable(LETag tableTag, size_t &length) const { length=-1; return getFontTable(tableTag); } /* -1 = unknown length */ + virtual void *getKernPairs() const = 0; virtual void setKernPairs(void *pairs) const = 0;
--- a/src/share/native/sun/font/layout/LEGlyphFilter.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LEGlyphFilter.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -36,6 +36,7 @@ U_NAMESPACE_BEGIN +#ifndef U_HIDE_INTERNAL_API /** * This is a helper class that is used to * recognize a set of glyph indices. @@ -63,6 +64,7 @@ */ virtual le_bool accept(LEGlyphID glyph) const = 0; }; +#endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/LEInsertionList.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LEInsertionList.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* ********************************************************************** - * Copyright (C) 1998-2008, International Business Machines + * Copyright (C) 1998-2013, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -39,6 +39,7 @@ struct InsertionRecord; +#ifndef U_HIDE_INTERNAL_API /** * This class encapsulates the callback used by <code>LEInsertionList</code> * to apply an insertion from the insertion list. @@ -194,6 +195,7 @@ */ le_bool append; }; +#endif /* U_HIDE_INTERNAL_API */ U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/LEScripts.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LEScripts.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. @@ -241,8 +241,28 @@ palmScriptCode = 144, sindScriptCode = 145, waraScriptCode = 146, +/** + * @stable ICU 4.8 + */ - scriptCodeCount = 147 + afakScriptCode = 147, + jurcScriptCode = 148, + mrooScriptCode = 149, + nshuScriptCode = 150, + shrdScriptCode = 151, + soraScriptCode = 152, + takrScriptCode = 153, + tangScriptCode = 154, + woleScriptCode = 155, +/** + * @stable ICU 49 + */ + + hluwScriptCode = 156, /* bump to match current ICU */ + khojScriptCode = 157, + tirhScriptCode = 158, + + scriptCodeCount = 159 }; U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/LETableReference.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,443 @@ +/* + * Copyright (c) 2007, 2010, 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. + */ + +/* + * -*- c++ -*- + * + * (C) Copyright IBM Corp. and others 2013 - All Rights Reserved + * + * Range checking + * + */ + +#ifndef __LETABLEREFERENCE_H +#define __LETABLEREFERENCE_H + +#include "LETypes.h" +#include "LEFontInstance.h" + + +#define kQuestionmarkTableTag 0x3F3F3F3FUL +#define kTildeTableTag 0x7e7e7e7eUL +#ifdef __cplusplus + +// internal - interface for range checking +U_NAMESPACE_BEGIN + +#if LE_ASSERT_BAD_FONT +class LETableReference; // fwd +/** + * defined in OpenTypeUtilities.cpp + * @internal + */ +extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len); + +#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0); +#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z); +#if 0 +#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0); +#else +#define LE_TRACE_TR(x) +#endif + +#else +#define LE_DEBUG_TR(x) +#define LE_DEBUG_TR3(x,y,z) +#define LE_TRACE_TR(x) +#endif + +/** + * @internal + */ +class LETableReference { +public: +/** + * @internal + * Construct from a specific tag + */ + LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) : + fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) { + loadTable(success); + LE_TRACE_TR("INFO: new table load") + } + + LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) { + if(LE_FAILURE(success)) { + clear(); + } + LE_TRACE_TR("INFO: new clone") + } + + LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) : + fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) { + LE_TRACE_TR("INFO: new raw") + } + LETableReference() : + fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) { + LE_TRACE_TR("INFO: new empty") + } + + ~LETableReference() { + fTag=kTildeTableTag; + LE_TRACE_TR("INFO: new dtor") + } + + /** + * @internal + * @param length if LE_UINTPTR_MAX means "whole table" + * subset + */ + LETableReference(const LETableReference &parent, size_t offset, size_t length, + LEErrorCode &err) : + fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), + fStart((parent.fStart)+offset), fLength(length) { + if(LE_SUCCESS(err)) { + if(isEmpty()) { + //err = LE_MISSING_FONT_TABLE_ERROR; + clear(); // it's just empty. Not an error. + } else if(offset >= fParent->fLength) { + LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset); + err = LE_INDEX_OUT_OF_BOUNDS_ERROR; + clear(); + } else { + if(fLength == LE_UINTPTR_MAX && + fParent->fLength != LE_UINTPTR_MAX) { + fLength = (fParent->fLength) - offset; // decrement length as base address is incremented + } + if(fLength != LE_UINTPTR_MAX) { // if we have bounds: + if(offset+fLength > fParent->fLength) { + LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength); + err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded + clear(); + } + } + } + } else { + clear(); + } + LE_TRACE_TR("INFO: new subset") + } + + const void* getAlias() const { return (const void*)fStart; } + const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; } + le_bool isEmpty() const { return fStart==NULL || fLength==0; } + le_bool isValid() const { return !isEmpty(); } + le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; } + void clear() { fLength=0; fStart=NULL; } + size_t getLength() const { return fLength; } + const LEFontInstance* getFont() const { return fFont; } + LETag getTag() const { return fTag; } + const LETableReference* getParent() const { return fParent; } + + void addOffset(size_t offset, LEErrorCode &success) { + if(hasBounds()) { + if(offset > fLength) { + LE_DEBUG_TR("addOffset off end"); + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + return; + } else { + fLength -= offset; + } + } + fStart += offset; + } + + size_t ptrToOffset(const void *atPtr, LEErrorCode &success) const { + if(atPtr==NULL) return 0; + if(LE_FAILURE(success)) return LE_UINTPTR_MAX; + if((atPtr < fStart) || + (hasBounds() && (atPtr > fStart+fLength))) { + LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0); + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + return LE_UINTPTR_MAX; + } + return ((const le_uint8*)atPtr)-fStart; + } + + /** + * Clamp down the length, for range checking. + */ + size_t contractLength(size_t newLength) { + if(fLength!=LE_UINTPTR_MAX&&newLength>0&&newLength<=fLength) { + fLength = newLength; + } + return fLength; + } + + /** + * Throw an error if offset+length off end + */ +public: + size_t verifyLength(size_t offset, size_t length, LEErrorCode &success) { + if(isValid()&& + LE_SUCCESS(success) && + fLength!=LE_UINTPTR_MAX && length!=LE_UINTPTR_MAX && offset!=LE_UINTPTR_MAX && + (offset+length)>fLength) { + LE_DEBUG_TR3("verifyLength failed (%p) %d",NULL, offset+length); + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; +#if LE_ASSERT_BAD_FONT + fprintf(stderr, "offset=%lu, len=%lu, would be at %p, (%lu) off end. End at %p\n", offset,length, fStart+offset+length, (offset+length-fLength), (offset+length-fLength)+fStart); +#endif + } + return fLength; + } + + /** + * Change parent link to another + */ + LETableReference &reparent(const LETableReference &base) { + fParent = &base; + return *this; + } + + /** + * remove parent link. Factory functions should do this. + */ + void orphan(void) { + fParent=NULL; + } + +protected: + const LEFontInstance* fFont; + LETag fTag; + const LETableReference *fParent; + const le_uint8 *fStart; // keep as 8 bit internally, for pointer math + size_t fLength; + + void loadTable(LEErrorCode &success) { + if(LE_SUCCESS(success)) { + fStart = (const le_uint8*)(fFont->getFontTable(fTag, fLength)); // note - a null table is not an error. + } + } + + void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) { + fFont = NULL; + fTag = kQuestionmarkTableTag; + fParent = NULL; + fStart = (const le_uint8*)data; + fLength = length; + } +}; + + +template<class T> +class LETableVarSizer { + public: + inline static size_t getSize(); +}; + +// base definition- could override for adjustments +template<class T> inline +size_t LETableVarSizer<T>::getSize() { + return sizeof(T); +} + +/** + * \def LE_VAR_ARRAY + * @param x Type (T) + * @param y some member that is of length ANY_NUMBER + * Call this after defining a class, for example: + * LE_VAR_ARRAY(FeatureListTable,featureRecordArray) + * this is roughly equivalent to: + * template<> inline size_t LETableVarSizer<FeatureListTable>::getSize() { return sizeof(FeatureListTable) - (sizeof(le_uint16)*ANY_NUMBER); } + * it's a specialization that informs the LETableReference subclasses to NOT include the variable array in the size. + * dereferencing NULL is valid here because we never actually dereference it, just inside sizeof. + */ +#define LE_VAR_ARRAY(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return sizeof(x) - (sizeof(((const x*)0)->y)); } +/** + * \def LE_CORRECT_SIZE + * @param x type (T) + * @param y fixed size for T + */ +#define LE_CORRECT_SIZE(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return y; } + +/** + * Open a new entry based on an existing table + */ + +/** + * \def LE_UNBOUNDED_ARRAY + * define an array with no *known* bound. Will trim to available size. + * @internal + */ +#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX + +template<class T> +class LEReferenceToArrayOf : public LETableReference { +public: + LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count) + : LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) { + LE_TRACE_TR("INFO: new RTAO by offset") + if(LE_SUCCESS(success)) { + if(count == LE_UNBOUNDED_ARRAY) { // not a known length + count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); + } + if(LE_FAILURE(success)) { + fCount=0; + clear(); + } + } + + LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count) + : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) { +LE_TRACE_TR("INFO: new RTAO") + if(LE_SUCCESS(success)) { + if(count == LE_UNBOUNDED_ARRAY) { // not a known length + count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); + } + if(LE_FAILURE(success)) clear(); + } + LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count) + : LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) { +LE_TRACE_TR("INFO: new RTAO") + if(LE_SUCCESS(success)) { + if(count == LE_UNBOUNDED_ARRAY) { // not a known length + count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size + } + LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success); + } + if(LE_FAILURE(success)) clear(); + } + + LEReferenceToArrayOf() :LETableReference(), fCount(0) {} + + le_uint32 getCount() const { return fCount; } + + using LETableReference::getAlias; + + const T *getAlias(le_uint32 i, LEErrorCode &success) const { + return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success))); + } + + const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; } + + const T& getObject(le_uint32 i, LEErrorCode &success) const { + return *getAlias(i,success); + } + + const T& operator()(le_uint32 i, LEErrorCode &success) const { + return *getAlias(i,success); + } + + size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const { + if(LE_SUCCESS(success)&&i<getCount()) { + return LETableVarSizer<T>::getSize()*i; + } else { + success = LE_INDEX_OUT_OF_BOUNDS_ERROR; + } + return 0; + } + + LEReferenceToArrayOf<T> &reparent(const LETableReference &base) { + fParent = &base; + return *this; + } + + LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) { + LE_TRACE_TR("INFO: null RTAO") + } + +private: + le_uint32 fCount; +}; + + +template<class T> +class LEReferenceTo : public LETableReference { +public: + /** + * open a sub reference. + * @param parent parent reference + * @param success error status + * @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds. + */ + LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr) + : LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) { + verifyLength(0, LETableVarSizer<T>::getSize(), success); + if(LE_FAILURE(success)) clear(); + } + /** + * ptr plus offset + */ + LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset) + : LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) { + verifyLength(0, LETableVarSizer<T>::getSize(), success); + if(LE_FAILURE(success)) clear(); + } + LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset) + : LETableReference(parent, offset, LE_UINTPTR_MAX, success) { + verifyLength(0, LETableVarSizer<T>::getSize(), success); + if(LE_FAILURE(success)) clear(); + } + LEReferenceTo(const LETableReference &parent, LEErrorCode &success) + : LETableReference(parent, 0, LE_UINTPTR_MAX, success) { + verifyLength(0, LETableVarSizer<T>::getSize(), success); + if(LE_FAILURE(success)) clear(); + } + LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success) + : LETableReference(font, tableTag, success) { + verifyLength(0, LETableVarSizer<T>::getSize(), success); + if(LE_FAILURE(success)) clear(); + } + LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {} + LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {} + LEReferenceTo() : LETableReference(NULL) {} + + LEReferenceTo<T>& operator=(const T* other) { + setRaw(other); + return *this; + } + + LEReferenceTo<T> &reparent(const LETableReference &base) { + fParent = &base; + return *this; + } + + /** + * roll forward by one <T> size. + * same as addOffset(LETableVarSizer<T>::getSize(),success) + */ + void addObject(LEErrorCode &success) { + addOffset(LETableVarSizer<T>::getSize(), success); + } + void addObject(size_t count, LEErrorCode &success) { + addOffset(LETableVarSizer<T>::getSize()*count, success); + } + + const T *operator->() const { return getAlias(); } + const T *getAlias() const { return (const T*)fStart; } + const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; } +}; + + +U_NAMESPACE_END + +#endif + +#endif
--- a/src/share/native/sun/font/layout/LETypes.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LETypes.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -50,14 +50,15 @@ #endif #include "unicode/utypes.h" + +#ifdef __cplusplus #include "unicode/uobject.h" +#endif + #ifdef LE_USE_CMEMORY #include "cmemory.h" #endif -#endif /* not standalone */ - - -U_NAMESPACE_BEGIN +#endif /*! * \file @@ -296,12 +297,14 @@ */ typedef UChar32 LEUnicode32; +#ifndef U_HIDE_DEPRECATED_API /** * Used to represent 16-bit Unicode code points. * * @deprecated since ICU 2.4. Use LEUnicode16 instead */ typedef UChar LEUnicode; +#endif /* U_HIDE_DEPRECATED_API */ /** * Used to hold a pair of (x, y) values which represent a point. @@ -325,7 +328,7 @@ float fY; }; -#ifndef XP_CPLUSPLUS +#ifndef __cplusplus /** * Used to hold a pair of (x, y) values which represent a point. * @@ -335,6 +338,39 @@ #endif +#ifndef U_HIDE_INTERNAL_API + +#ifndef LE_ASSERT_BAD_FONT +#define LE_ASSERT_BAD_FONT 0 +#endif + +#if LE_ASSERT_BAD_FONT +#include <stdio.h> +#define LE_DEBUG_BAD_FONT(x) fprintf(stderr,"%s:%d: BAD FONT: %s\n", __FILE__, __LINE__, (x)); +#else +#define LE_DEBUG_BAD_FONT(x) +#endif + +/** + * Max value representable by a uintptr + */ + +#ifndef UINT32_MAX +#define LE_UINT32_MAX 0xFFFFFFFFU +#else +#define LE_UINT32_MAX UINT32_MAX +#endif + +#ifndef UINTPTR_MAX +#define LE_UINTPTR_MAX LE_UINT32_MAX +#else +#define LE_UINTPTR_MAX UINTPTR_MAX +#endif + +/** + * Range check for overflow + */ +#define LE_RANGE_CHECK(type, count, ptrfn) (( (LE_UINTPTR_MAX / sizeof(type)) < count ) ? NULL : (ptrfn)) /** * A convenience macro to get the length of an array. * @@ -356,7 +392,7 @@ * * @internal */ -#define LE_NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type)) +#define LE_NEW_ARRAY(type, count) (type *) LE_RANGE_CHECK(type,count,uprv_malloc((count) * sizeof(type))) /** * Re-allocate an array of basic types. This is used to isolate the rest of @@ -373,7 +409,52 @@ * @internal */ #define LE_DELETE_ARRAY(array) uprv_free((void *) (array)) -#endif +#else +/* !LE_USE_CMEMORY - Not using ICU memory - use C std lib versions */ + +#include <stdlib.h> +#include <string.h> + +/** + * A convenience macro to get the length of an array. + * + * @internal + */ +#define LE_ARRAY_SIZE(array) (sizeof array / sizeof array[0]) + +/** + * A convenience macro for copying an array. + * + * @internal + */ +#define LE_ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0]) + +/** + * Allocate an array of basic types. This is used to isolate the rest of + * the LayoutEngine code from cmemory.h. + * + * @internal + */ +#define LE_NEW_ARRAY(type, count) LE_RANGE_CHECK(type,count,(type *) malloc((count) * sizeof(type))) + +/** + * Re-allocate an array of basic types. This is used to isolate the rest of + * the LayoutEngine code from cmemory.h. + * + * @internal + */ +#define LE_GROW_ARRAY(array, newSize) realloc((void *) (array), (newSize) * sizeof (array)[0]) + + /** + * Free an array of basic types. This is used to isolate the rest of + * the LayoutEngine code from cmemory.h. + * + * @internal + */ +#define LE_DELETE_ARRAY(array) free((void *) (array)) + +#endif /* LE_USE_CMEMORY */ +#endif /* U_HIDE_INTERNAL_API */ /** * A macro to construct the four-letter tags used to @@ -536,7 +617,7 @@ LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */ LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */ LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */ - LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */ + LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */ LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */ LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */ LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */ @@ -588,6 +669,68 @@ }; /** + * @internal + */ +enum LEFeatureENUMs { + LE_Kerning_FEATURE_ENUM = 0, /**< Requests Kerning. Formerly LayoutEngine::kTypoFlagKern */ + LE_Ligatures_FEATURE_ENUM = 1, /**< Requests Ligatures. Formerly LayoutEngine::kTypoFlagLiga */ + LE_NoCanon_FEATURE_ENUM = 2, /**< Requests No Canonical Processing */ + LE_CLIG_FEATURE_ENUM, /**< Feature specific enum */ + LE_DLIG_FEATURE_ENUM, /**< Feature specific enum */ + LE_HLIG_FEATURE_ENUM, /**< Feature specific enum */ + LE_LIGA_FEATURE_ENUM, /**< Feature specific enum */ + LE_RLIG_FEATURE_ENUM, /**< Feature specific enum */ + LE_SMCP_FEATURE_ENUM, /**< Feature specific enum */ + LE_FRAC_FEATURE_ENUM, /**< Feature specific enum */ + LE_AFRC_FEATURE_ENUM, /**< Feature specific enum */ + LE_ZERO_FEATURE_ENUM, /**< Feature specific enum */ + LE_SWSH_FEATURE_ENUM, /**< Feature specific enum */ + LE_CSWH_FEATURE_ENUM, /**< Feature specific enum */ + LE_SALT_FEATURE_ENUM, /**< Feature specific enum */ + LE_NALT_FEATURE_ENUM, /**< Feature specific enum */ + LE_RUBY_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS01_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS02_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS03_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS04_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS05_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS06_FEATURE_ENUM, /**< Feature specific enum */ + LE_SS07_FEATURE_ENUM, /**< Feature specific enum */ + + LE_CHAR_FILTER_FEATURE_ENUM = 31, /**< Apply CharSubstitutionFilter */ + LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM +}; + +#define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM) +#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM) +#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM) +#define LE_CLIG_FEATURE_FLAG (1 << LE_CLIG_FEATURE_ENUM) +#define LE_DLIG_FEATURE_FLAG (1 << LE_DLIG_FEATURE_ENUM) +#define LE_HLIG_FEATURE_FLAG (1 << LE_HLIG_FEATURE_ENUM) +#define LE_LIGA_FEATURE_FLAG (1 << LE_LIGA_FEATURE_ENUM) +#define LE_RLIG_FEATURE_FLAG (1 << LE_RLIG_FEATURE_ENUM) +#define LE_SMCP_FEATURE_FLAG (1 << LE_SMCP_FEATURE_ENUM) +#define LE_FRAC_FEATURE_FLAG (1 << LE_FRAC_FEATURE_ENUM) +#define LE_AFRC_FEATURE_FLAG (1 << LE_AFRC_FEATURE_ENUM) +#define LE_ZERO_FEATURE_FLAG (1 << LE_ZERO_FEATURE_ENUM) +#define LE_SWSH_FEATURE_FLAG (1 << LE_SWSH_FEATURE_ENUM) +#define LE_CSWH_FEATURE_FLAG (1 << LE_CSWH_FEATURE_ENUM) +#define LE_SALT_FEATURE_FLAG (1 << LE_SALT_FEATURE_ENUM) +#define LE_NALT_FEATURE_FLAG (1 << LE_NALT_FEATURE_ENUM) +#define LE_RUBY_FEATURE_FLAG (1 << LE_RUBY_FEATURE_ENUM) +#define LE_SS01_FEATURE_FLAG (1 << LE_SS01_FEATURE_ENUM) +#define LE_SS02_FEATURE_FLAG (1 << LE_SS02_FEATURE_ENUM) +#define LE_SS03_FEATURE_FLAG (1 << LE_SS03_FEATURE_ENUM) +#define LE_SS04_FEATURE_FLAG (1 << LE_SS04_FEATURE_ENUM) +#define LE_SS05_FEATURE_FLAG (1 << LE_SS05_FEATURE_ENUM) +#define LE_SS06_FEATURE_FLAG (1 << LE_SS06_FEATURE_ENUM) +#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM) + +#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM) + +#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */ + +/** * Error codes returned by the LayoutEngine. * * @stable ICU 2.4 @@ -611,7 +754,7 @@ }; #endif -#ifndef XP_CPLUSPLUS +#ifndef __cplusplus /** * Error codes returned by the LayoutEngine. * @@ -638,7 +781,4 @@ #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code)) #endif -U_NAMESPACE_END -#endif - - +#endif /* __LETYPES_H */
--- a/src/share/native/sun/font/layout/LayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -33,6 +33,7 @@ #include "LETypes.h" #include "LEScripts.h" #include "LELanguages.h" +#include "LESwaps.h" #include "LayoutEngine.h" #include "ArabicLayoutEngine.h" @@ -44,6 +45,8 @@ #include "ThaiLayoutEngine.h" #include "TibetanLayoutEngine.h" #include "GXLayoutEngine.h" +#include "GXLayoutEngine2.h" + #include "ScriptAndLanguageTags.h" #include "CharSubstitutionFilter.h" @@ -63,6 +66,10 @@ /* Leave this copyright notice here! It needs to go somewhere in this library. */ static const char copyright[] = U_COPYRIGHT_STRING; +/* TODO: remove these? */ +const le_int32 LayoutEngine::kTypoFlagKern = LE_Kerning_FEATURE_FLAG; +const le_int32 LayoutEngine::kTypoFlagLiga = LE_Ligatures_FEATURE_FLAG; + const LEUnicode32 DefaultCharMapper::controlChars[] = { 0x0009, 0x000A, 0x000D, /*0x200C, 0x200D,*/ 0x200E, 0x200F, @@ -140,21 +147,21 @@ class CanonMarkFilter : public UMemory, public LEGlyphFilter { private: - const GlyphClassDefinitionTable *classDefTable; + const LEReferenceTo<GlyphClassDefinitionTable> classDefTable; CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class public: - CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable); + CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success); virtual ~CanonMarkFilter(); virtual le_bool accept(LEGlyphID glyph) const; }; -CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable) +CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success) + : classDefTable(gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success)) { - classDefTable = gdefTable->getMarkAttachClassDefinitionTable(); } CanonMarkFilter::~CanonMarkFilter() @@ -164,9 +171,10 @@ le_bool CanonMarkFilter::accept(LEGlyphID glyph) const { - le_int32 glyphClass = classDefTable->getGlyphClass(glyph); - - return glyphClass != 0; + LEErrorCode success = LE_NO_ERROR; + le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success); + if(LE_FAILURE(success)) return false; + return glyphClass != 0; } UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine) @@ -251,24 +259,24 @@ return 0; } - if ((fTypoFlags & 0x4) == 0) { // no canonical processing + if ((fTypoFlags & LE_NoCanon_FEATURE_FLAG) == 0) { // no canonical processing return count; } - const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable; + LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable); LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode); LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode); le_int32 i, dir = 1, out = 0, outCharCount = count; - if (canonGSUBTable->coversScript(scriptTag)) { + if (canonGSUBTable->coversScript(canonGSUBTable,scriptTag, success) || LE_SUCCESS(success)) { CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance); if (substitutionFilter == NULL) { success = LE_MEMORY_ALLOCATION_ERROR; return 0; } - const LEUnicode *inChars = &chars[offset]; - LEUnicode *reordered = NULL; + const LEUnicode *inChars = &chars[offset]; + LEUnicode *reordered = NULL; LEGlyphStorage fakeGlyphStorage; fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success); @@ -278,20 +286,20 @@ return 0; } - // This is the cheapest way to get mark reordering only for Hebrew. - // We could just do the mark reordering for all scripts, but most - // of them probably don't need it... - if (fScriptCode == hebrScriptCode) { - reordered = LE_NEW_ARRAY(LEUnicode, count); + // This is the cheapest way to get mark reordering only for Hebrew. + // We could just do the mark reordering for all scripts, but most + // of them probably don't need it... + if (fScriptCode == hebrScriptCode) { + reordered = LE_NEW_ARRAY(LEUnicode, count); - if (reordered == NULL) { - delete substitutionFilter; - success = LE_MEMORY_ALLOCATION_ERROR; - return 0; - } + if (reordered == NULL) { + delete substitutionFilter; + success = LE_MEMORY_ALLOCATION_ERROR; + return 0; + } - CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); - inChars = reordered; + CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage); + inChars = reordered; } fakeGlyphStorage.allocateAuxData(success); @@ -311,11 +319,11 @@ fakeGlyphStorage.setAuxData(out, canonFeatures, success); } - if (reordered != NULL) { - LE_DELETE_ARRAY(reordered); - } + if (reordered != NULL) { + LE_DELETE_ARRAY(reordered); + } - outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); + outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success); if (LE_FAILURE(success)) { delete substitutionFilter; @@ -416,16 +424,16 @@ return; } - GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable; - CanonMarkFilter filter(gdefTable); + LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, + CanonShaping::glyphDefinitionTableLen); + CanonMarkFilter filter(gdefTable, success); adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success); - if (fTypoFlags & 0x1) { /* kerning enabled */ - static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; - - KernTable kt(fFontInstance, getFontTable(kernTableTag)); - kt.process(glyphStorage); + if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ + LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); + KernTable kt(kernTable, success); + kt.process(glyphStorage, success); } // default is no adjustments @@ -510,9 +518,9 @@ glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success); } -const void *LayoutEngine::getFontTable(LETag tableTag) const +const void *LayoutEngine::getFontTable(LETag tableTag, size_t &length) const { - return fFontInstance->getFontTable(tableTag); + return fFontInstance->getFontTable(tableTag, length); } void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, @@ -559,37 +567,41 @@ void LayoutEngine::reset() { + if(fGlyphStorage!=NULL) { fGlyphStorage->reset(); + fGlyphStorage = NULL; + } } LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success) { - // 3 -> kerning and ligatures - return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success); + //kerning and ligatures - by default + return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, LE_DEFAULT_FEATURE_FLAG, success); } LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) { static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG; static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG; + static const le_uint32 morxTableTag = LE_MORX_TABLE_TAG; if (LE_FAILURE(success)) { return NULL; } - const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag); + LEReferenceTo<GlyphSubstitutionTableHeader> gsubTable(fontInstance,gsubTableTag,success); LayoutEngine *result = NULL; LETag scriptTag = 0x00000000; LETag languageTag = 0x00000000; - LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode); + LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode); // Right now, only invoke V2 processing for Devanagari. TODO: Allow more V2 scripts as they are // properly tested. - if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) { - result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success); - } - else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) { + if ( v2ScriptTag == dev2ScriptTag && gsubTable.isValid() && gsubTable->coversScript(gsubTable, v2ScriptTag, success )) { + result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success); + } + else if (gsubTable.isValid() && gsubTable->coversScript(gsubTable, scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode), success)) { switch (scriptCode) { case bengScriptCode: case devaScriptCode: @@ -608,6 +620,11 @@ result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); break; + case hebrScriptCode: + // Disable hebrew ligatures since they have only archaic uses, see ticket #8318 + result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags & ~kTypoFlagLiga, gsubTable, success); + break; + case hangScriptCode: result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); break; @@ -620,10 +637,10 @@ case janLanguageCode: case zhtLanguageCode: case zhsLanguageCode: - if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) { + if (gsubTable->coversScriptAndLanguage(gsubTable, scriptTag, languageTag, success, TRUE)) { result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success); break; - } + } // note: falling through to default case. default: @@ -646,26 +663,29 @@ break; } } else { - const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag); - - if (morphTable != NULL) { - result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success); + MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag); + if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) { + result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success); } else { - switch (scriptCode) { - case bengScriptCode: - case devaScriptCode: - case gujrScriptCode: - case kndaScriptCode: - case mlymScriptCode: - case oryaScriptCode: - case guruScriptCode: - case tamlScriptCode: - case teluScriptCode: - case sinhScriptCode: - { - result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); - break; - } + LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success); + if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort + result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success); + } else { + switch (scriptCode) { + case bengScriptCode: + case devaScriptCode: + case gujrScriptCode: + case kndaScriptCode: + case mlymScriptCode: + case oryaScriptCode: + case guruScriptCode: + case tamlScriptCode: + case teluScriptCode: + case sinhScriptCode: + { + result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); + break; + } case arabScriptCode: //case hebrScriptCode: @@ -683,9 +703,10 @@ result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); break; - default: - result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); - break; + default: + result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success); + break; + } } } }
--- a/src/share/native/sun/font/layout/LayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -26,7 +26,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -90,6 +90,14 @@ * @stable ICU 2.8 */ class U_LAYOUT_API LayoutEngine : public UObject { +public: +#ifndef U_HIDE_INTERNAL_API + /** @internal Flag to request kerning. Use LE_Kerning_FEATURE_FLAG instead. */ + static const le_int32 kTypoFlagKern; + /** @internal Flag to request ligatures. Use LE_Ligatures_FEATURE_FLAG instead. */ + static const le_int32 kTypoFlagLiga; +#endif /* U_HIDE_INTERNAL_API */ + protected: /** * The object which holds the glyph storage @@ -140,6 +148,7 @@ */ le_bool fFilterZeroWidth; +#ifndef U_HIDE_INTERNAL_API /** * This constructs an instance for a given font, script and language. Subclass constructors * must call this constructor. @@ -161,7 +170,10 @@ le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success); +#endif /* U_HIDE_INTERNAL_API */ + // Do not enclose the protected default constructor with #ifndef U_HIDE_INTERNAL_API + // or else the compiler will create a public default constructor. /** * This overrides the default no argument constructor to make it * difficult for clients to call it. Clients are expected to call @@ -268,12 +280,18 @@ * some other way must override this method. * * @param tableTag - the four byte table tag. + * @param length - length to use * * @return the address of the table. * * @internal */ - virtual const void *getFontTable(LETag tableTag) const; + virtual const void *getFontTable(LETag tableTag, size_t &length) const; + + /** + * @deprecated + */ + virtual const void *getFontTable(LETag tableTag) const { size_t ignored; return getFontTable(tableTag, ignored); } /** * This method does character to glyph mapping. The default implementation @@ -302,6 +320,7 @@ */ virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphStorage &glyphStorage, LEErrorCode &success); +#ifndef U_HIDE_INTERNAL_API /** * This is a convenience method that forces the advance width of mark * glyphs to be zero, which is required for proper selection and highlighting. @@ -336,7 +355,7 @@ * @internal */ static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success); - +#endif /* U_HIDE_INTERNAL_API */ public: /**
--- a/src/share/native/sun/font/layout/LigatureSubstProc.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LigatureSubstProc.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -47,15 +47,15 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor) -LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) - : StateTableProcessor(morphSubtableHeader) + LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) +: StateTableProcessor(morphSubtableHeader, success), ligatureSubstitutionHeader(morphSubtableHeader, success) { - ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader; + if(LE_FAILURE(success)) return; ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset); componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset); ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset); - entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset); + entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); } LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor() @@ -69,7 +69,9 @@ ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) { - const LigatureSubstitutionStateEntry *entry = &entryTable[index]; + LEErrorCode success = LE_NO_ERROR; + const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success); + ByteOffset newState = SWAPW(entry->newStateOffset); le_int16 flags = SWAPW(entry->flags); @@ -79,12 +81,16 @@ } componentStack[m] = currGlyph; + } else if ( m == -1) { + // bad font- skip this glyph. + currGlyph++; + return newState; } ByteOffset actionOffset = flags & lsfActionOffsetMask; if (actionOffset != 0) { - const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset); + LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset); LigatureActionEntry action; le_int32 offset, i = 0; le_int32 stack[nComponents]; @@ -93,7 +99,8 @@ do { le_uint32 componentGlyph = componentStack[m--]; - action = SWAPL(*ap++); + action = SWAPL(*ap.getAlias()); + ap.addObject(success); // ap++ if (m < 0) { m = nComponents - 1; @@ -101,29 +108,48 @@ offset = action & lafComponentOffsetMask; if (offset != 0) { - const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask)); + LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY); - i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]); + if(LE_FAILURE(success)) { + currGlyph++; + LE_DEBUG_BAD_FONT("off end of ligature substitution header"); + return newState; // get out! bad font + } + if(componentGlyph > glyphStorage.getGlyphCount()) { + LE_DEBUG_BAD_FONT("preposterous componentGlyph"); + currGlyph++; + return newState; // get out! bad font + } + i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success)); if (action & (lafLast | lafStore)) { - const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i); - TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset); + LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i); + TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias()); - glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); - stack[++mm] = componentGlyph; - i = 0; + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); + if(mm==nComponents) { + LE_DEBUG_BAD_FONT("exceeded nComponents"); + mm--; // don't overrun the stack. + } + stack[++mm] = componentGlyph; + i = 0; } else { - glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); } } - } while (!(action & lafLast)); +#if LE_ASSERT_BAD_FONT + if(m<0) { + LE_DEBUG_BAD_FONT("m<0") + } +#endif + } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items while (mm >= 0) { - if (++m >= nComponents) { - m = 0; - } + if (++m >= nComponents) { + m = 0; + } - componentStack[m] = stack[mm--]; + componentStack[m] = stack[mm--]; } }
--- a/src/share/native/sun/font/layout/LigatureSubstProc.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LigatureSubstProc.h Thu Apr 18 14:38:37 2013 -0700 @@ -58,7 +58,7 @@ virtual void endStateTable(); - LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); + LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~LigatureSubstitutionProcessor(); /** @@ -83,12 +83,12 @@ ByteOffset componentTableOffset; ByteOffset ligatureTableOffset; - const LigatureSubstitutionStateEntry *entryTable; + LEReferenceToArrayOf<LigatureSubstitutionStateEntry> entryTable; le_int32 componentStack[nComponents]; le_int16 m; - const LigatureSubstitutionHeader *ligatureSubstitutionHeader; + LEReferenceTo<LigatureSubstitutionHeader> ligatureSubstitutionHeader; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/LigatureSubstProc2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,170 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp and Others. 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "StateTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "LigatureSubstProc2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m)))) +#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m)) +#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v)) + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2) + +LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : StateTableProcessor2(morphSubtableHeader, success), + ligActionOffset(0), + ligatureSubstitutionHeader(morphSubtableHeader, success), componentOffset(0), ligatureOffset(0), entryTable() +{ + if (LE_FAILURE(success)) return; + + ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset); + componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset); + ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset); + + entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY); +} + +LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2() +{ +} + +void LigatureSubstitutionProcessor2::beginStateTable() +{ + m = -1; +} + +le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success) +{ + const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success); + if(LE_FAILURE(success)) return 0; + + le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex); + le_uint16 flags = SWAPW(entry->entryFlags); + le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex); + + if (flags & lsfSetComponent) { + if (++m >= nComponents) { + m = 0; + } + componentStack[m] = currGlyph; + } else if ( m == -1) { + // bad font- skip this glyph. + //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)") + currGlyph+= dir; + return nextStateIndex; + } + + ByteOffset actionOffset = flags & lsfPerformAction; + + if (actionOffset != 0) { + LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset + ap.addObject(ligActionIndex - 1, success); // index offset ( one before the actual start, because we will pre-increment) + LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY); + LigatureActionEntry action; + le_int32 offset, i = 0; + le_int32 stack[nComponents]; + le_int16 mm = -1; + + LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY); + if(LE_FAILURE(success)) { + currGlyph+= dir; + return nextStateIndex; // get out! bad font + } + + do { + le_uint32 componentGlyph = componentStack[m--]; // pop off + + ap.addObject(success); + action = SWAPL(*ap.getAlias()); + + if (m < 0) { + m = nComponents - 1; + } + + offset = action & lafComponentOffsetMask; + if (offset != 0) { + if(componentGlyph > glyphStorage.getGlyphCount()) { + LE_DEBUG_BAD_FONT("preposterous componentGlyph"); + currGlyph+= dir; + return nextStateIndex; // get out! bad font + } + i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success)); + + if (action & (lafLast | lafStore)) { + TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success)); + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph); + if(mm==nComponents) { + LE_DEBUG_BAD_FONT("exceeded nComponents"); + mm--; // don't overrun the stack. + } + stack[++mm] = componentGlyph; + i = 0; + } else { + glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF); + } + } +#if LE_ASSERT_BAD_FONT + if(m<0) { + LE_DEBUG_BAD_FONT("m<0") + } +#endif + } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items + + while (mm >= 0) { + if (++m >= nComponents) { + m = 0; + } + + componentStack[m] = stack[mm--]; + } + } + + if (!(flags & lsfDontAdvance)) { + currGlyph += dir; + } + + return nextStateIndex; +} + +void LigatureSubstitutionProcessor2::endStateTable() +{ +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/LigatureSubstProc2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,97 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __LIGATURESUBSTITUTIONPROCESSOR2_H +#define __LIGATURESUBSTITUTIONPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "LigatureSubstitution.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +#define nComponents 16 + +class LigatureSubstitutionProcessor2 : public StateTableProcessor2 +{ +public: + virtual void beginStateTable(); + + virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, + EntryTableIndex2 index, LEErrorCode &success); + + virtual void endStateTable(); + + LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + virtual ~LigatureSubstitutionProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + LigatureSubstitutionProcessor2(); + +protected: + le_uint32 ligActionOffset; + le_uint32 componentOffset; + le_uint32 ligatureOffset; + + LEReferenceToArrayOf<LigatureSubstitutionStateEntry2> entryTable; + + le_int32 componentStack[nComponents]; + le_int16 m; + + const LEReferenceTo<LigatureSubstitutionHeader2> ligatureSubstitutionHeader; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -40,10 +40,10 @@ U_NAMESPACE_BEGIN -le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); if (coverageIndex >= 0) { Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,6 +50,7 @@ le_uint16 ligatureCount; Offset ligatureTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureSetTable, ligatureTableOffsetArray) struct LigatureTable { @@ -57,14 +58,16 @@ le_uint16 compCount; TTGlyphID componentArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureTable, componentArray) struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable { le_uint16 ligSetCount; Offset ligSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const; }; +LE_VAR_ARRAY(LigatureSubstitutionSubtable, ligSetTableOffsetArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/LigatureSubstitution.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LigatureSubstitution.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -52,17 +52,32 @@ ByteOffset ligatureTableOffset; }; +struct LigatureSubstitutionHeader2 : MorphStateTableHeader2 +{ + le_uint32 ligActionOffset; + le_uint32 componentOffset; + le_uint32 ligatureOffset; +}; + enum LigatureSubstitutionFlags { lsfSetComponent = 0x8000, lsfDontAdvance = 0x4000, - lsfActionOffsetMask = 0x3FFF + lsfActionOffsetMask = 0x3FFF, // N/A in morx + lsfPerformAction = 0x2000 }; struct LigatureSubstitutionStateEntry : StateEntry { }; +struct LigatureSubstitutionStateEntry2 +{ + le_uint16 nextStateIndex; + le_uint16 entryFlags; + le_uint16 ligActionIndex; +}; + typedef le_uint32 LigatureActionEntry; enum LigatureActionFlags
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LookupProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -44,7 +44,7 @@ U_NAMESPACE_BEGIN -le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, +le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { @@ -57,7 +57,7 @@ le_uint32 delta; for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) { - const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable); + LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success); delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success); @@ -72,7 +72,7 @@ } le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, - le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, + le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const { if (LE_FAILURE(success)) { @@ -89,22 +89,21 @@ rightToLeft, 0, 0, glyphDefinitionTableHeader); le_int32 newGlyphCount = glyphCount; - for (le_uint16 order = 0; order < lookupOrderCount; order += 1) { + for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) { le_uint16 lookup = lookupOrderArray[order]; FeatureMask selectMask = lookupSelectArray[lookup]; if (selectMask != 0) { - const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup); - - if (!lookupTable) + const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success); + if (!lookupTable.isValid() ||LE_FAILURE(success) ) { continue; - + } le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); glyphIterator.reset(lookupFlags, selectMask); while (glyphIterator.findFeatureTag()) { - applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); + applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO if (LE_FAILURE(success)) { return 0; } @@ -124,7 +123,11 @@ return 0; } - const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex); + const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success); + if (!lookupTable.isValid()) { + success = LE_INTERNAL_ERROR; + return 0; + } le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); GlyphIterator tempIterator(*glyphIterator, lookupFlags); le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success); @@ -132,33 +135,35 @@ return delta; } -le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order) +le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success) { - le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0; + le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0; le_int32 store = order; - for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) { - le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]); + LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount); - if (lookupListIndex >= lookupSelectCount) - continue; + for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) { + le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success)); + if (lookupListIndex >= lookupSelectCount) { + continue; + } - lookupSelectArray[lookupListIndex] |= featureMask; - lookupOrderArray[store++] = lookupListIndex; + lookupSelectArray[lookupListIndex] |= featureMask; + lookupOrderArray[store++] = lookupListIndex; } return store - order; } -LookupProcessor::LookupProcessor(const char *baseAddress, +LookupProcessor::LookupProcessor(const LETableReference &baseAddress, Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures, LEErrorCode& success) - : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0), - lookupOrderArray(NULL), lookupOrderCount(0) + : lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0), + lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress) { - const ScriptListTable *scriptListTable = NULL; - const LangSysTable *langSysTable = NULL; + LEReferenceTo<ScriptListTable> scriptListTable; + LEReferenceTo<LangSysTable> langSysTable; le_uint16 featureCount = 0; le_uint16 lookupListCount = 0; le_uint16 requiredFeatureIndex; @@ -168,29 +173,33 @@ } if (scriptListOffset != 0) { - scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset); - langSysTable = scriptListTable->findLanguage(scriptTag, languageTag); + scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset); + langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success); - if (langSysTable != 0) { - featureCount = SWAPW(langSysTable->featureCount); - } + if (langSysTable.isValid() && LE_SUCCESS(success)) { + featureCount = SWAPW(langSysTable->featureCount); + } } if (featureListOffset != 0) { - featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset); + featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset); } if (lookupListOffset != 0) { - lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset); + lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset); + if(LE_SUCCESS(success) && lookupListTable.isValid()) { lookupListCount = SWAPW(lookupListTable->lookupCount); + } } - if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL || + if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() || featureCount == 0 || lookupListCount == 0) { return; } - requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex); + if(langSysTable.isValid()) { + requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex); + } lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount); if (lookupSelectArray == NULL) { @@ -205,31 +214,39 @@ lookupSelectCount = lookupListCount; le_int32 count, order = 0; - le_int32 featureReferences = 0; - const FeatureTable *featureTable = NULL; + le_uint32 featureReferences = 0; + LEReferenceTo<FeatureTable> featureTable; LETag featureTag; - const FeatureTable *requiredFeatureTable = NULL; + LEReferenceTo<FeatureTable> requiredFeatureTable; LETag requiredFeatureTag = 0x00000000U; // Count the total number of lookups referenced by all features. This will // be the maximum number of entries in the lookupOrderArray. We can't use // lookupListCount because some lookups might be referenced by more than // one feature. - for (le_int32 feature = 0; feature < featureCount; feature += 1) { - le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + if(featureListTable.isValid() && LE_SUCCESS(success)) { + LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount); - featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) { + le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success)); - if (!featureTable) - continue; + featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); + if (!featureTable.isValid() || LE_FAILURE(success)) { + continue; + } + featureReferences += SWAPW(featureTable->lookupCount); + } + } - featureReferences += SWAPW(featureTable->lookupCount); + if (!featureTable.isValid() || LE_FAILURE(success)) { + success = LE_INTERNAL_ERROR; + return; } if (requiredFeatureIndex != 0xFFFF) { - requiredFeatureTable = featureListTable->getFeatureTable(requiredFeatureIndex, &requiredFeatureTag); - featureReferences += SWAPW(featureTable->lookupCount); + requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success); + featureReferences += SWAPW(featureTable->lookupCount); } lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences); @@ -244,7 +261,7 @@ // If this is the required feature, add its lookups if (requiredFeatureTag == fm.tag) { - count += selectLookups(requiredFeatureTable, fm.mask, order); + count += selectLookups(requiredFeatureTable, fm.mask, order, success); } if (orderFeatures) { @@ -254,7 +271,8 @@ } for (le_uint16 feature = 0; feature < featureCount; feature += 1) { - le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount); + le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success)); // don't add the required feature to the list more than once... // TODO: Do we need this check? (Spec. says required feature won't be in feature list...) @@ -262,10 +280,10 @@ continue; } - featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); if (featureTag == fm.tag) { - count += selectLookups(featureTable, fm.mask, order + count); + count += selectLookups(featureTable, fm.mask, order + count, success); } } @@ -274,9 +292,10 @@ } order += count; - } else { - for (le_uint16 feature = 0; feature < featureCount; feature += 1) { - le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); + } else if(langSysTable.isValid()) { + LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount); + for (le_uint16 feature = 0; LE_SUCCESS(success)&& (feature < featureCount); feature += 1) { + le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature,success)); // don't add the required feature to the list more than once... // NOTE: This check is commented out because the spec. says that @@ -288,10 +307,10 @@ } #endif - featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex, &featureTag, success); if (featureTag == fm.tag) { - order += selectLookups(featureTable, fm.mask, order); + order += selectLookups(featureTable, fm.mask, order, success); } } }
--- a/src/share/native/sun/font/layout/LookupProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LookupProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -41,6 +41,7 @@ #include "LETypes.h" #include "LEFontInstance.h" #include "OpenTypeTables.h" +#include "LETableReference.h" //#include "Lookups.h" //#include "Features.h" @@ -59,19 +60,21 @@ class LookupProcessor : public UMemory { public: le_int32 process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, - le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const; + le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, const LEFontInstance *fontInstance, LEErrorCode& success) const; - le_uint32 applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; + le_uint32 applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; le_uint32 applySingleLookup(le_uint16 lookupTableIndex, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const; - virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 subtableType, + virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 subtableType, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const = 0; virtual ~LookupProcessor(); + const LETableReference &getReference() const { return fReference; } + protected: - LookupProcessor(const char *baseAddress, + LookupProcessor(const LETableReference &baseAddress, Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, @@ -84,10 +87,10 @@ LookupProcessor(); - le_int32 selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order); + le_int32 selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success); - const LookupListTable *lookupListTable; - const FeatureListTable *featureListTable; + LEReferenceTo<LookupListTable> lookupListTable; + LEReferenceTo<FeatureListTable> featureListTable; FeatureMask *lookupSelectArray; le_uint32 lookupSelectCount; @@ -95,6 +98,8 @@ le_uint16 *lookupOrderArray; le_uint32 lookupOrderCount; + LETableReference fReference; + private: LookupProcessor(const LookupProcessor &other); // forbid copying of this class
--- a/src/share/native/sun/font/layout/LookupTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LookupTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -49,22 +49,26 @@ of the derived classes, and implement it in the others by casting the "this" pointer to the type that has the implementation. */ -const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const +const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const { + le_int16 unity = SWAPW(unitSize); le_int16 probe = SWAPW(searchRange); le_int16 extra = SWAPW(rangeShift); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); - const LookupSegment *entry = segments; - const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra); + LEReferenceTo<LookupSegment> entry(base, success, segments); + LEReferenceTo<LookupSegment> trial(entry, success, extra); + + if(LE_FAILURE(success)) return NULL; if (SWAPW(trial->lastGlyph) <= ttGlyph) { entry = trial; } - while (probe > unity) { + while (probe > unity && LE_SUCCESS(success)) { probe >>= 1; - trial = (const LookupSegment *) ((char *) entry + probe); + trial = entry; // copy + trial.addOffset(probe, success); if (SWAPW(trial->lastGlyph) <= ttGlyph) { entry = trial; @@ -72,28 +76,29 @@ } if (SWAPW(entry->firstGlyph) <= ttGlyph) { - return entry; + return entry.getAlias(); } return NULL; } -const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const +const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const { le_int16 unity = SWAPW(unitSize); le_int16 probe = SWAPW(searchRange); le_int16 extra = SWAPW(rangeShift); TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); - const LookupSingle *entry = entries; - const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra); + LEReferenceTo<LookupSingle> entry(base, success, entries); + LEReferenceTo<LookupSingle> trial(entry, success, extra); if (SWAPW(trial->glyph) <= ttGlyph) { entry = trial; } - while (probe > unity) { + while (probe > unity && LE_SUCCESS(success)) { probe >>= 1; - trial = (const LookupSingle *) ((char *) entry + probe); + trial = entry; + trial.addOffset(probe, success); if (SWAPW(trial->glyph) <= ttGlyph) { entry = trial; @@ -101,7 +106,7 @@ } if (SWAPW(entry->glyph) == ttGlyph) { - return entry; + return entry.getAlias(); } return NULL;
--- a/src/share/native/sun/font/layout/LookupTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/LookupTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -39,6 +39,7 @@ #include "LETypes.h" #include "LayoutTables.h" +#include "LETableReference.h" U_NAMESPACE_BEGIN @@ -79,30 +80,34 @@ le_int16 entrySelector; le_int16 rangeShift; - const LookupSegment *lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const; + const LookupSegment *lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const; - const LookupSingle *lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const; + const LookupSingle *lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const; }; struct SimpleArrayLookupTable : LookupTable { LookupValue valueArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SimpleArrayLookupTable, valueArray) struct SegmentSingleLookupTable : BinarySearchLookupTable { LookupSegment segments[ANY_NUMBER]; }; +LE_VAR_ARRAY(SegmentSingleLookupTable, segments) struct SegmentArrayLookupTable : BinarySearchLookupTable { LookupSegment segments[ANY_NUMBER]; }; +LE_VAR_ARRAY(SegmentArrayLookupTable, segments) struct SingleTableLookupTable : BinarySearchLookupTable { LookupSingle entries[ANY_NUMBER]; }; +LE_VAR_ARRAY(SingleTableLookupTable, entries) struct TrimmedArrayLookupTable : LookupTable { @@ -110,6 +115,7 @@ TTGlyphID glyphCount; LookupValue valueArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(TrimmedArrayLookupTable, valueArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/Lookups.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/Lookups.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -37,33 +37,35 @@ U_NAMESPACE_BEGIN -const LookupTable *LookupListTable::getLookupTable(le_uint16 lookupTableIndex) const +const LEReferenceTo<LookupTable> LookupListTable::getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const { - if (lookupTableIndex >= SWAPW(lookupCount)) { - return 0; - } + LEReferenceToArrayOf<Offset> lookupTableOffsetArrayRef(base, success, (const Offset*)&lookupTableOffsetArray, SWAPW(lookupCount)); - Offset lookupTableOffset = lookupTableOffsetArray[lookupTableIndex]; - - return (const LookupTable *) ((char *) this + SWAPW(lookupTableOffset)); + if(LE_FAILURE(success) || lookupTableIndex>lookupTableOffsetArrayRef.getCount()) { + return LEReferenceTo<LookupTable>(); + } else { + return LEReferenceTo<LookupTable>(base, success, SWAPW(lookupTableOffsetArrayRef.getObject(lookupTableIndex, success))); + } } -const LookupSubtable *LookupTable::getLookupSubtable(le_uint16 subtableIndex) const +const LEReferenceTo<LookupSubtable> LookupTable::getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const { - if (subtableIndex >= SWAPW(subTableCount)) { - return 0; - } + LEReferenceToArrayOf<Offset> subTableOffsetArrayRef(base, success, (const Offset*)&subTableOffsetArray, SWAPW(subTableCount)); - Offset subtableOffset = subTableOffsetArray[subtableIndex]; - - return (const LookupSubtable *) ((char *) this + SWAPW(subtableOffset)); + if(LE_FAILURE(success) || subtableIndex>subTableOffsetArrayRef.getCount()) { + return LEReferenceTo<LookupSubtable>(); + } else { + return LEReferenceTo<LookupSubtable>(base, success, SWAPW(subTableOffsetArrayRef.getObject(subtableIndex, success))); + } } -le_int32 LookupSubtable::getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const +le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const { - const CoverageTable *coverageTable = (const CoverageTable *) ((char *) this + SWAPW(tableOffset)); + const LEReferenceTo<CoverageTable> coverageTable(base, success, SWAPW(tableOffset)); - return coverageTable->getGlyphCoverage(glyphID); + if(LE_FAILURE(success)) return 0; + + return coverageTable->getGlyphCoverage(glyphID); } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/Lookups.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/Lookups.h Thu Apr 18 14:38:37 2013 -0700 @@ -58,9 +58,14 @@ le_uint16 subtableFormat; Offset coverageTableOffset; - inline le_int32 getGlyphCoverage(LEGlyphID glyphID) const; + inline le_int32 getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const; + + le_int32 getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const; - le_int32 getGlyphCoverage(Offset tableOffset, LEGlyphID glyphID) const; + // convenience + inline le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const; + + inline le_int32 getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const; }; struct LookupTable @@ -70,20 +75,32 @@ le_uint16 subTableCount; Offset subTableOffsetArray[ANY_NUMBER]; - const LookupSubtable *getLookupSubtable(le_uint16 subtableIndex) const; + const LEReferenceTo<LookupSubtable> getLookupSubtable(const LEReferenceTo<LookupTable> &base, le_uint16 subtableIndex, LEErrorCode &success) const; }; +LE_VAR_ARRAY(LookupTable, subTableOffsetArray) struct LookupListTable { le_uint16 lookupCount; Offset lookupTableOffsetArray[ANY_NUMBER]; - const LookupTable *getLookupTable(le_uint16 lookupTableIndex) const; + const LEReferenceTo<LookupTable> getLookupTable(const LEReferenceTo<LookupListTable> &base, le_uint16 lookupTableIndex, LEErrorCode &success) const; }; +LE_VAR_ARRAY(LookupListTable, lookupTableOffsetArray) + +inline le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &base, LEGlyphID glyphID, LEErrorCode &success) const +{ + return getGlyphCoverage(base, coverageTableOffset, glyphID, success); +} -inline le_int32 LookupSubtable::getGlyphCoverage(LEGlyphID glyphID) const -{ - return getGlyphCoverage(coverageTableOffset, glyphID); +inline le_int32 LookupSubtable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const { + LEReferenceTo<LookupSubtable> thisRef(base, success, this); + return getGlyphCoverage(thisRef, glyphID, success); +} + +inline le_int32 LookupSubtable::getGlyphCoverage(const LETableReference &base, Offset tableOffset, LEGlyphID glyphID, LEErrorCode &success) const { + LEReferenceTo<LookupSubtable> thisRef(base, success, this); + return getGlyphCoverage(thisRef, tableOffset, glyphID, success); } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/MPreFixups.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MPreFixups.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 2002-2008 - All Rights Reserved + * (C) Copyright IBM Corp. 2002-2013 - All Rights Reserved * */ @@ -65,9 +65,9 @@ } } -void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& leSuccess) +void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success) { - if (LE_FAILURE(leSuccess)) { + if (LE_FAILURE(success)) { return; }
--- a/src/share/native/sun/font/layout/MarkArrays.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkArrays.h Thu Apr 18 14:38:37 2013 -0700 @@ -57,6 +57,7 @@ le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance, LEPoint &anchor) const; }; +LE_VAR_ARRAY(MarkArray, markRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -51,10 +51,10 @@ return 0xFFFF; } -le_int32 MarkToBasePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID markGlyph = glyphIterator->getCurrGlyphID(); - le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); + le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success); if (markCoverage < 0) { // markGlyph isn't a covered mark glyph @@ -75,7 +75,7 @@ // FIXME: We probably don't want to find a base glyph before a previous ligature... GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/)); LEGlyphID baseGlyph = findBaseGlyph(&baseIterator); - le_int32 baseCoverage = getBaseCoverage((LEGlyphID) baseGlyph); + le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success); const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)); le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
--- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -48,7 +48,7 @@ struct MarkToBasePositioningSubtable : AttachmentPositioningSubtable { - le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; LEGlyphID findBaseGlyph(GlyphIterator *glyphIterator) const; }; @@ -56,12 +56,14 @@ { Offset baseAnchorTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(BaseRecord, baseAnchorTableOffsetArray) struct BaseArray { le_int16 baseRecordCount; BaseRecord baseRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(BaseArray, baseRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -50,10 +50,10 @@ return 0xFFFF; } -le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID markGlyph = glyphIterator->getCurrGlyphID(); - le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); + le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success); if (markCoverage < 0) { // markGlyph isn't a covered mark glyph @@ -74,7 +74,7 @@ // FIXME: we probably don't want to find a ligature before a previous base glyph... GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/)); LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator); - le_int32 ligatureCoverage = getBaseCoverage((LEGlyphID) ligatureGlyph); + le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success); const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset)); le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
--- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -48,7 +48,7 @@ struct MarkToLigaturePositioningSubtable : AttachmentPositioningSubtable { - le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; LEGlyphID findLigatureGlyph(GlyphIterator *glyphIterator) const; }; @@ -56,18 +56,21 @@ { Offset ligatureAnchorTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ComponentRecord, ligatureAnchorTableOffsetArray) struct LigatureAttachTable { le_uint16 componentCount; ComponentRecord componentRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureAttachTable, componentRecordArray) struct LigatureArray { le_uint16 ligatureCount; Offset ligatureAttachTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LigatureArray, ligatureAttachTableOffsetArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -51,10 +51,10 @@ return 0xFFFF; } -le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID markGlyph = glyphIterator->getCurrGlyphID(); - le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph); + le_int32 markCoverage = getGlyphCoverage(base, (LEGlyphID) markGlyph, success); if (markCoverage < 0) { // markGlyph isn't a covered mark glyph @@ -74,7 +74,7 @@ GlyphIterator mark2Iterator(*glyphIterator); LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator); - le_int32 mark2Coverage = getBaseCoverage((LEGlyphID) mark2Glyph); + le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success); const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)); le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
--- a/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MarkToMarkPosnSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -48,7 +48,7 @@ struct MarkToMarkPositioningSubtable : AttachmentPositioningSubtable { - le_int32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_int32 process(const LETableReference &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; LEGlyphID findMark2Glyph(GlyphIterator *glyphIterator) const; }; @@ -56,12 +56,14 @@ { Offset mark2AnchorTableOffsetArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(Mark2Record, mark2AnchorTableOffsetArray) struct Mark2Array { le_uint16 mark2RecordCount; Mark2Record mark2RecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(Mark2Array, mark2RecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/MorphStateTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MorphStateTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -49,5 +49,10 @@ StateTableHeader stHeader; }; +struct MorphStateTableHeader2 : MorphSubtableHeader2 +{ + StateTableHeader2 stHeader; +}; + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/MorphTables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MorphTables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -44,61 +44,61 @@ U_NAMESPACE_BEGIN -void MorphTableHeader::process(LEGlyphStorage &glyphStorage) const +void MorphTableHeader::process(const LETableReference &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const { - const ChainHeader *chainHeader = chains; - le_uint32 chainCount = SWAPL(this->nChains); + le_uint32 chainCount = SWAPL(this->nChains); + LEReferenceTo<ChainHeader> chainHeader(base, success, chains); // moving header + LEReferenceToArrayOf<ChainHeader> chainHeaderArray(base, success, chains, chainCount); le_uint32 chain; - for (chain = 0; chain < chainCount; chain += 1) { + for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain += 1) { FeatureFlags defaultFlags = SWAPL(chainHeader->defaultFlags); le_uint32 chainLength = SWAPL(chainHeader->chainLength); le_int16 nFeatureEntries = SWAPW(chainHeader->nFeatureEntries); le_int16 nSubtables = SWAPW(chainHeader->nSubtables); - const MorphSubtableHeader *subtableHeader = - (const MorphSubtableHeader *)&chainHeader->featureTable[nFeatureEntries]; + LEReferenceTo<MorphSubtableHeader> subtableHeader = + LEReferenceTo<MorphSubtableHeader>(chainHeader,success, &(chainHeader->featureTable[nFeatureEntries])); le_int16 subtable; - for (subtable = 0; subtable < nSubtables; subtable += 1) { + for (subtable = 0; LE_SUCCESS(success) && (subtable < nSubtables); subtable += 1) { le_int16 length = SWAPW(subtableHeader->length); SubtableCoverage coverage = SWAPW(subtableHeader->coverage); FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures); // should check coverage more carefully... - if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0) { - subtableHeader->process(glyphStorage); + if ((coverage & scfVertical) == 0 && (subtableFeatures & defaultFlags) != 0 && LE_SUCCESS(success)) { + subtableHeader->process(subtableHeader, glyphStorage, success); } - subtableHeader = (const MorphSubtableHeader *) ((char *)subtableHeader + length); + subtableHeader.addOffset(length, success); } - - chainHeader = (const ChainHeader *)((char *)chainHeader + chainLength); + chainHeader.addOffset(chainLength, success); } } -void MorphSubtableHeader::process(LEGlyphStorage &glyphStorage) const +void MorphSubtableHeader::process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const { SubtableProcessor *processor = NULL; switch (SWAPW(coverage) & scfTypeMask) { case mstIndicRearrangement: - processor = new IndicRearrangementProcessor(this); + processor = new IndicRearrangementProcessor(base, success); break; case mstContextualGlyphSubstitution: - processor = new ContextualGlyphSubstitutionProcessor(this); + processor = new ContextualGlyphSubstitutionProcessor(base, success); break; case mstLigatureSubstitution: - processor = new LigatureSubstitutionProcessor(this); + processor = new LigatureSubstitutionProcessor(base, success); break; case mstReservedUnused: break; case mstNonContextualGlyphSubstitution: - processor = NonContextualGlyphSubstitutionProcessor::createInstance(this); + processor = NonContextualGlyphSubstitutionProcessor::createInstance(base, success); break; /* @@ -112,8 +112,10 @@ } if (processor != NULL) { - processor->process(glyphStorage); - delete processor; + if(LE_SUCCESS(success)) { + processor->process(glyphStorage, success); + } + delete processor; } }
--- a/src/share/native/sun/font/layout/MorphTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MorphTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -39,6 +39,7 @@ #include "LETypes.h" #include "LayoutTables.h" +#include "LETableReference.h" U_NAMESPACE_BEGIN @@ -65,6 +66,7 @@ le_int16 nSubtables; FeatureTableEntry featureTable[ANY_NUMBER]; }; +LE_VAR_ARRAY(ChainHeader, featureTable) struct MorphTableHeader { @@ -72,10 +74,12 @@ le_uint32 nChains; ChainHeader chains[ANY_NUMBER]; - void process(LEGlyphStorage &glyphStorage) const; + void process(const LETableReference& base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const; }; +LE_VAR_ARRAY(MorphTableHeader, chains) typedef le_int16 SubtableCoverage; +typedef le_uint32 SubtableCoverage2; enum SubtableCoverageFlags { @@ -102,7 +106,305 @@ SubtableCoverage coverage; FeatureFlags subtableFeatures; - void process(LEGlyphStorage &glyphStorage) const; + void process(const LEReferenceTo<MorphSubtableHeader> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const; +}; + +enum SubtableCoverageFlags2 +{ + scfVertical2 = 0x80000000, + scfReverse2 = 0x40000000, + scfIgnoreVt2 = 0x20000000, + scfReserved2 = 0x1FFFFF00, + scfTypeMask2 = 0x000000FF +}; + +struct MorphSubtableHeader2 +{ + le_uint32 length; + SubtableCoverage2 coverage; + FeatureFlags subtableFeatures; + + void process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const; +}; + +struct ChainHeader2 +{ + FeatureFlags defaultFlags; + le_uint32 chainLength; + le_uint32 nFeatureEntries; + le_uint32 nSubtables; + FeatureTableEntry featureTable[ANY_NUMBER]; +}; +LE_VAR_ARRAY(ChainHeader2, featureTable) + +struct MorphTableHeader2 +{ + le_int32 version; + le_uint32 nChains; + ChainHeader2 chains[ANY_NUMBER]; + + void process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage, le_int32 typoFlags, LEErrorCode &success) const; +}; +LE_VAR_ARRAY(MorphTableHeader2, chains) + +/* + * AAT Font Features + * source: https://developer.apple.com/fonts/registry/ + * (plus addition from ATS/SFNTLayoutTypes.h) + */ + +enum { + + allTypographicFeaturesType = 0, + + allTypeFeaturesOnSelector = 0, + allTypeFeaturesOffSelector = 1, + + ligaturesType = 1, + + requiredLigaturesOnSelector = 0, + requiredLigaturesOffSelector = 1, + commonLigaturesOnSelector = 2, + commonLigaturesOffSelector = 3, + rareLigaturesOnSelector = 4, + rareLigaturesOffSelector = 5, + logosOnSelector = 6, + logosOffSelector = 7, + rebusPicturesOnSelector = 8, + rebusPicturesOffSelector = 9, + diphthongLigaturesOnSelector = 10, + diphthongLigaturesOffSelector = 11, + squaredLigaturesOnSelector = 12, + squaredLigaturesOffSelector = 13, + abbrevSquaredLigaturesOnSelector = 14, + abbrevSquaredLigaturesOffSelector = 15, + symbolLigaturesOnSelector = 16, + symbolLigaturesOffSelector = 17, + contextualLigaturesOnSelector = 18, + contextualLigaturesOffSelector = 19, + historicalLigaturesOnSelector = 20, + historicalLigaturesOffSelector = 21, + + cursiveConnectionType = 2, + + unconnectedSelector = 0, + partiallyConnectedSelector = 1, + cursiveSelector = 2, + + letterCaseType = 3, + + upperAndLowerCaseSelector = 0, + allCapsSelector = 1, + allLowerCaseSelector = 2, + smallCapsSelector = 3, + initialCapsSelector = 4, + initialCapsAndSmallCapsSelector = 5, + + verticalSubstitutionType = 4, + + substituteVerticalFormsOnSelector = 0, + substituteVerticalFormsOffSelector = 1, + + linguisticRearrangementType = 5, + + linguisticRearrangementOnSelector = 0, + linguisticRearrangementOffSelector = 1, + + numberSpacingType = 6, + + monospacedNumbersSelector = 0, + proportionalNumbersSelector = 1, + + /* + appleReserved1Type = 7, + */ + + smartSwashType = 8, + + wordInitialSwashesOnSelector = 0, + wordInitialSwashesOffSelector = 1, + wordFinalSwashesOnSelector = 2, + wordFinalSwashesOffSelector = 3, + lineInitialSwashesOnSelector = 4, + lineInitialSwashesOffSelector = 5, + lineFinalSwashesOnSelector = 6, + lineFinalSwashesOffSelector = 7, + nonFinalSwashesOnSelector = 8, + nonFinalSwashesOffSelector = 9, + + diacriticsType = 9, + + showDiacriticsSelector = 0, + hideDiacriticsSelector = 1, + decomposeDiacriticsSelector = 2, + + verticalPositionType = 10, + + normalPositionSelector = 0, + superiorsSelector = 1, + inferiorsSelector = 2, + ordinalsSelector = 3, + + fractionsType = 11, + + noFractionsSelector = 0, + verticalFractionsSelector = 1, + diagonalFractionsSelector = 2, + + /* + appleReserved2Type = 12, + */ + + overlappingCharactersType = 13, + + preventOverlapOnSelector = 0, + preventOverlapOffSelector = 1, + + typographicExtrasType = 14, + + hyphensToEmDashOnSelector = 0, + hyphensToEmDashOffSelector = 1, + hyphenToEnDashOnSelector = 2, + hyphenToEnDashOffSelector = 3, + unslashedZeroOnSelector = 4, + slashedZeroOffSelector = 4, + unslashedZeroOffSelector = 5, + slashedZeroOnSelector = 5, + formInterrobangOnSelector = 6, + formInterrobangOffSelector = 7, + smartQuotesOnSelector = 8, + smartQuotesOffSelector = 9, + periodsToEllipsisOnSelector = 10, + periodsToEllipsisOffSelector = 11, + + mathematicalExtrasType = 15, + + hyphenToMinusOnSelector = 0, + hyphenToMinusOffSelector = 1, + asteriskToMultiplyOnSelector = 2, + asteriskToMultiplyOffSelector = 3, + slashToDivideOnSelector = 4, + slashToDivideOffSelector = 5, + inequalityLigaturesOnSelector = 6, + inequalityLigaturesOffSelector = 7, + exponentsOnSelector = 8, + exponentsOffSelector = 9, + + ornamentSetsType = 16, + + noOrnamentsSelector = 0, + dingbatsSelector = 1, + piCharactersSelector = 2, + fleuronsSelector = 3, + decorativeBordersSelector = 4, + internationalSymbolsSelector = 5, + mathSymbolsSelector = 6, + + characterAlternativesType = 17, + + noAlternatesSelector = 0, + + designComplexityType = 18, + + designLevel1Selector = 0, + designLevel2Selector = 1, + designLevel3Selector = 2, + designLevel4Selector = 3, + designLevel5Selector = 4, + designLevel6Selector = 5, + designLevel7Selector = 6, + + styleOptionsType = 19, + + noStyleOptionsSelector = 0, + displayTextSelector = 1, + engravedTextSelector = 2, + illuminatedCapsSelector = 3, + titlingCapsSelector = 4, + tallCapsSelector = 5, + + characterShapeType = 20, + + traditionalCharactersSelector = 0, + simplifiedCharactersSelector = 1, + jis1978CharactersSelector = 2, + jis1983CharactersSelector = 3, + jis1990CharactersSelector = 4, + traditionalAltOneSelector = 5, + traditionalAltTwoSelector = 6, + traditionalAltThreeSelector = 7, + traditionalAltFourSelector = 8, + traditionalAltFiveSelector = 9, + expertCharactersSelector = 10, + + numberCaseType = 21, + + lowerCaseNumbersSelector = 0, + upperCaseNumbersSelector = 1, + + textSpacingType = 22, + + proportionalTextSelector = 0, + monospacedTextSelector = 1, + halfWidthTextSelector = 2, + normallySpacedTextSelector = 3, + + transliterationType = 23, + + noTransliterationSelector = 0, + hanjaToHangulSelector = 1, + hiraganaToKatakanaSelector = 2, + katakanaToHiraganaSelector = 3, + kanaToRomanizationSelector = 4, + romanizationToHiraganaSelector = 5, + romanizationToKatakanaSelector = 6, + hanjaToHangulAltOneSelector = 7, + hanjaToHangulAltTwoSelector = 8, + hanjaToHangulAltThreeSelector = 9, + + annotationType = 24, + + noAnnotationSelector = 0, + boxAnnotationSelector = 1, + roundedBoxAnnotationSelector = 2, + circleAnnotationSelector = 3, + invertedCircleAnnotationSelector = 4, + parenthesisAnnotationSelector = 5, + periodAnnotationSelector = 6, + romanNumeralAnnotationSelector = 7, + diamondAnnotationSelector = 8, + + kanaSpacingType = 25, + + fullWidthKanaSelector = 0, + proportionalKanaSelector = 1, + + ideographicSpacingType = 26, + + fullWidthIdeographsSelector = 0, + proportionalIdeographsSelector = 1, + + cjkRomanSpacingType = 103, + + halfWidthCJKRomanSelector = 0, + proportionalCJKRomanSelector = 1, + defaultCJKRomanSelector = 2, + fullWidthCJKRomanSelector = 3, + + rubyKanaType = 28, + + rubyKanaOnSelector = 2, + rubyKanaOffSelector = 3, + +/* The following types are provided for compatibility; note that + their use is deprecated. */ + + adobeCharacterSpacingType = 100, /* prefer 22 */ + adobeKanaSpacingType = 101, /* prefer 25 */ + adobeKanjiSpacingType = 102, /* prefer 26 */ + adobeSquareLigatures = 104, /* prefer 1 */ + + lastFeatureType = -1 }; U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/MorphTables2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,248 @@ +/* + * 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. + * + */ + +/* + * (C) Copyright IBM Corp. and others 1998 - 2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "LayoutTables.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "IndicRearrangementProcessor2.h" +#include "ContextualGlyphSubstProc2.h" +#include "LigatureSubstProc2.h" +#include "NonContextualGlyphSubstProc2.h" +#include "ContextualGlyphInsertionProc2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +void MorphTableHeader2::process(const LEReferenceTo<MorphTableHeader2> &base, LEGlyphStorage &glyphStorage, + le_int32 typoFlags, LEErrorCode &success) const +{ + if(LE_FAILURE(success)) return; + + le_uint32 chainCount = SWAPL(this->nChains); + LEReferenceTo<ChainHeader2> chainHeader(base, success, &chains[0]); + /* chainHeader and subtableHeader are implemented as a moving pointer rather than an array dereference + * to (slightly) reduce code churn. However, must be careful to preincrement them the 2nd time through. + * We don't want to increment them at the end of the loop, as that would attempt to dereference + * out of range memory. + */ + le_uint32 chain; + + for (chain = 0; LE_SUCCESS(success) && (chain < chainCount); chain++) { + if (chain>0) { + le_uint32 chainLength = SWAPL(chainHeader->chainLength); + chainHeader.addOffset(chainLength, success); // Don't increment the first time + } + FeatureFlags flag = SWAPL(chainHeader->defaultFlags); + le_uint32 nFeatureEntries = SWAPL(chainHeader->nFeatureEntries); + le_uint32 nSubtables = SWAPL(chainHeader->nSubtables); + LEReferenceTo<MorphSubtableHeader2> subtableHeader(chainHeader, + success, (const MorphSubtableHeader2 *)&chainHeader->featureTable[nFeatureEntries]); + le_uint32 subtable; + if(LE_FAILURE(success)) break; // malformed table + + if (typoFlags != 0) { + le_uint32 featureEntry; + LEReferenceToArrayOf<FeatureTableEntry> featureTableRef(chainHeader, success, &chainHeader->featureTable[0], nFeatureEntries); + if(LE_FAILURE(success)) break; + // Feature subtables + for (featureEntry = 0; featureEntry < nFeatureEntries; featureEntry++) { + const FeatureTableEntry &featureTableEntry = featureTableRef(featureEntry, success); + le_int16 featureType = SWAPW(featureTableEntry.featureType); + le_int16 featureSetting = SWAPW(featureTableEntry.featureSetting); + le_uint32 enableFlags = SWAPL(featureTableEntry.enableFlags); + le_uint32 disableFlags = SWAPL(featureTableEntry.disableFlags); + switch (featureType) { + case ligaturesType: + if ((typoFlags & LE_Ligatures_FEATURE_ENUM ) && (featureSetting ^ 0x1)){ + flag &= disableFlags; + flag |= enableFlags; + } else { + if (((typoFlags & LE_RLIG_FEATURE_FLAG) && featureSetting == requiredLigaturesOnSelector) || + ((typoFlags & LE_CLIG_FEATURE_FLAG) && featureSetting == contextualLigaturesOnSelector) || + ((typoFlags & LE_HLIG_FEATURE_FLAG) && featureSetting == historicalLigaturesOnSelector) || + ((typoFlags & LE_LIGA_FEATURE_FLAG) && featureSetting == commonLigaturesOnSelector)) { + flag &= disableFlags; + flag |= enableFlags; + } + } + break; + case letterCaseType: + if ((typoFlags & LE_SMCP_FEATURE_FLAG) && featureSetting == smallCapsSelector) { + flag &= disableFlags; + flag |= enableFlags; + } + break; + case verticalSubstitutionType: + break; + case linguisticRearrangementType: + break; + case numberSpacingType: + break; + case smartSwashType: + if ((typoFlags & LE_SWSH_FEATURE_FLAG) && (featureSetting ^ 0x1)){ + flag &= disableFlags; + flag |= enableFlags; + } + break; + case diacriticsType: + break; + case verticalPositionType: + break; + case fractionsType: + if (((typoFlags & LE_FRAC_FEATURE_FLAG) && featureSetting == diagonalFractionsSelector) || + ((typoFlags & LE_AFRC_FEATURE_FLAG) && featureSetting == verticalFractionsSelector)) { + flag &= disableFlags; + flag |= enableFlags; + } else { + flag &= disableFlags; + } + break; + case typographicExtrasType: + if ((typoFlags & LE_ZERO_FEATURE_FLAG) && featureSetting == slashedZeroOnSelector) { + flag &= disableFlags; + flag |= enableFlags; + } + break; + case mathematicalExtrasType: + break; + case ornamentSetsType: + break; + case characterAlternativesType: + break; + case designComplexityType: + if (((typoFlags & LE_SS01_FEATURE_FLAG) && featureSetting == designLevel1Selector) || + ((typoFlags & LE_SS02_FEATURE_FLAG) && featureSetting == designLevel2Selector) || + ((typoFlags & LE_SS03_FEATURE_FLAG) && featureSetting == designLevel3Selector) || + ((typoFlags & LE_SS04_FEATURE_FLAG) && featureSetting == designLevel4Selector) || + ((typoFlags & LE_SS05_FEATURE_FLAG) && featureSetting == designLevel5Selector) || + ((typoFlags & LE_SS06_FEATURE_FLAG) && featureSetting == designLevel6Selector) || + ((typoFlags & LE_SS07_FEATURE_FLAG) && featureSetting == designLevel7Selector)) { + + flag &= disableFlags; + flag |= enableFlags; + } + break; + case styleOptionsType: + break; + case characterShapeType: + break; + case numberCaseType: + break; + case textSpacingType: + break; + case transliterationType: + break; + case annotationType: + if ((typoFlags & LE_NALT_FEATURE_FLAG) && featureSetting == circleAnnotationSelector) { + flag &= disableFlags; + flag |= enableFlags; + } + break; + case kanaSpacingType: + break; + case ideographicSpacingType: + break; + case rubyKanaType: + if ((typoFlags & LE_RUBY_FEATURE_FLAG) && featureSetting == rubyKanaOnSelector) { + flag &= disableFlags; + flag |= enableFlags; + } + break; + case cjkRomanSpacingType: + break; + default: + break; + } + } + } + + for (subtable = 0; LE_SUCCESS(success) && subtable < nSubtables; subtable++) { + if(subtable>0) { + le_uint32 length = SWAPL(subtableHeader->length); + subtableHeader.addOffset(length, success); // Don't addOffset for the last entry. + } + le_uint32 coverage = SWAPL(subtableHeader->coverage); + FeatureFlags subtableFeatures = SWAPL(subtableHeader->subtableFeatures); + // should check coverage more carefully... + if (((coverage & scfIgnoreVt2) || !(coverage & scfVertical2)) && (subtableFeatures & flag) != 0) { + subtableHeader->process(subtableHeader, glyphStorage, success); + } + } + } +} + +void MorphSubtableHeader2::process(const LEReferenceTo<MorphSubtableHeader2> &base, LEGlyphStorage &glyphStorage, LEErrorCode &success) const +{ + SubtableProcessor2 *processor = NULL; + + switch (SWAPL(coverage) & scfTypeMask2) + { + case mstIndicRearrangement: + processor = new IndicRearrangementProcessor2(base, success); + break; + + case mstContextualGlyphSubstitution: + processor = new ContextualGlyphSubstitutionProcessor2(base, success); + break; + + case mstLigatureSubstitution: + processor = new LigatureSubstitutionProcessor2(base, success); + break; + + case mstReservedUnused: + break; + + case mstNonContextualGlyphSubstitution: + processor = NonContextualGlyphSubstitutionProcessor2::createInstance(base, success); + break; + + + case mstContextualGlyphInsertion: + processor = new ContextualGlyphInsertionProcessor2(base, success); + break; + + default: + return; + break; /*NOTREACHED*/ + } + + if (processor != NULL) { + processor->process(glyphStorage, success); + delete processor; + } else { + if(LE_SUCCESS(success)) { + success = LE_MEMORY_ALLOCATION_ERROR; // because ptr is null and we didn't break out. + } + } +} + +U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MultipleSubstSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -39,7 +39,7 @@ U_NAMESPACE_BEGIN -le_uint32 MultipleSubstitutionSubtable::process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const +le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter) const { if (LE_FAILURE(success)) { return 0; @@ -58,7 +58,7 @@ return 0; } - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); le_uint16 seqCount = SWAPW(sequenceCount); if (coverageIndex >= 0 && coverageIndex < seqCount) {
--- a/src/share/native/sun/font/layout/MultipleSubstSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/MultipleSubstSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,14 +50,16 @@ le_uint16 glyphCount; TTGlyphID substituteArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(SequenceTable, substituteArray) struct MultipleSubstitutionSubtable : GlyphSubstitutionSubtable { le_uint16 sequenceCount; Offset sequenceTableOffsetArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode& success, const LEGlyphFilter *filter = NULL) const; }; +LE_VAR_ARRAY(MultipleSubstitutionSubtable, sequenceTableOffsetArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubst.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/NonContextualGlyphSubst.h Thu Apr 18 14:38:37 2013 -0700 @@ -26,7 +26,7 @@ /* * * - * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -50,6 +50,11 @@ LookupTable table; }; +struct NonContextualGlyphSubstitutionHeader2 : MorphSubtableHeader2 +{ + LookupTable table; +}; + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -47,8 +47,8 @@ { } -NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader) - : SubtableProcessor(morphSubtableHeader) +NonContextualGlyphSubstitutionProcessor::NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : SubtableProcessor(morphSubtableHeader, success) { } @@ -56,26 +56,27 @@ { } -SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const MorphSubtableHeader *morphSubtableHeader) +SubtableProcessor *NonContextualGlyphSubstitutionProcessor::createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); - switch (SWAPW(header->table.format)) - { + if(LE_FAILURE(success)) return NULL; + + switch (SWAPW(header->table.format)) { case ltfSimpleArray: - return new SimpleArrayProcessor(morphSubtableHeader); + return new SimpleArrayProcessor(morphSubtableHeader, success); case ltfSegmentSingle: - return new SegmentSingleProcessor(morphSubtableHeader); + return new SegmentSingleProcessor(morphSubtableHeader, success); case ltfSegmentArray: - return new SegmentArrayProcessor(morphSubtableHeader); + return new SegmentArrayProcessor(morphSubtableHeader, success); case ltfSingleTable: - return new SingleTableProcessor(morphSubtableHeader); + return new SingleTableProcessor(morphSubtableHeader, success); case ltfTrimmedArray: - return new TrimmedArrayProcessor(morphSubtableHeader); + return new TrimmedArrayProcessor(morphSubtableHeader, success); default: return NULL;
--- a/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc.h Thu Apr 18 14:38:37 2013 -0700 @@ -49,13 +49,13 @@ class NonContextualGlyphSubstitutionProcessor : public SubtableProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage) = 0; + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0; - static SubtableProcessor *createInstance(const MorphSubtableHeader *morphSubtableHeader); + static SubtableProcessor *createInstance(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); protected: NonContextualGlyphSubstitutionProcessor(); - NonContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader); + NonContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &status); virtual ~NonContextualGlyphSubstitutionProcessor();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,88 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "SimpleArrayProcessor2.h" +#include "SegmentSingleProcessor2.h" +#include "SegmentArrayProcessor2.h" +#include "SingleTableProcessor2.h" +#include "TrimmedArrayProcessor2.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2() +{ +} + +NonContextualGlyphSubstitutionProcessor2::NonContextualGlyphSubstitutionProcessor2( + const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : SubtableProcessor2(morphSubtableHeader, success) +{ +} + +NonContextualGlyphSubstitutionProcessor2::~NonContextualGlyphSubstitutionProcessor2() +{ +} + +SubtableProcessor2 *NonContextualGlyphSubstitutionProcessor2::createInstance( + const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + if(LE_FAILURE(success)) return NULL; + + switch (SWAPW(header->table.format)) + { + case ltfSimpleArray: + return new SimpleArrayProcessor2(morphSubtableHeader, success); + + case ltfSegmentSingle: + return new SegmentSingleProcessor2(morphSubtableHeader, success); + + case ltfSegmentArray: + return new SegmentArrayProcessor2(morphSubtableHeader, success); + + case ltfSingleTable: + return new SingleTableProcessor2(morphSubtableHeader, success); + + case ltfTrimmedArray: + return new TrimmedArrayProcessor2(morphSubtableHeader, success); + + default: + return NULL; + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/NonContextualGlyphSubstProc2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,68 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H +#define __NONCONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class NonContextualGlyphSubstitutionProcessor2 : public SubtableProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0; + + static SubtableProcessor2 *createInstance(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + +protected: + NonContextualGlyphSubstitutionProcessor2(); + NonContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~NonContextualGlyphSubstitutionProcessor2(); + +private: + NonContextualGlyphSubstitutionProcessor2(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class + NonContextualGlyphSubstitutionProcessor2 &operator=(const NonContextualGlyphSubstitutionProcessor2 &other); // forbid copying of this class +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -26,7 +26,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -64,11 +64,27 @@ #define loclFeatureTag LE_LOCL_FEATURE_TAG #define caltFeatureTag LE_CALT_FEATURE_TAG -// 'dlig' not used at the moment -#define dligFeatureTag 0x646C6967 +#define dligFeatureTag LE_DLIG_FEATURE_TAG +#define rligFeatureTag LE_RLIG_FEATURE_TAG +#define paltFeatureTag LE_PALT_FEATURE_TAG -// 'palt' -#define paltFeatureTag 0x70616C74 +#define hligFeatureTag LE_HLIG_FEATURE_TAG +#define smcpFeatureTag LE_SMCP_FEATURE_TAG +#define fracFeatureTag LE_FRAC_FEATURE_TAG +#define afrcFeatureTag LE_AFRC_FEATURE_TAG +#define zeroFeatureTag LE_ZERO_FEATURE_TAG +#define swshFeatureTag LE_SWSH_FEATURE_TAG +#define cswhFeatureTag LE_CSWH_FEATURE_TAG +#define saltFeatureTag LE_SALT_FEATURE_TAG +#define naltFeatureTag LE_NALT_FEATURE_TAG +#define rubyFeatureTag LE_RUBY_FEATURE_TAG +#define ss01FeatureTag LE_SS01_FEATURE_TAG +#define ss02FeatureTag LE_SS02_FEATURE_TAG +#define ss03FeatureTag LE_SS03_FEATURE_TAG +#define ss04FeatureTag LE_SS04_FEATURE_TAG +#define ss05FeatureTag LE_SS05_FEATURE_TAG +#define ss06FeatureTag LE_SS06_FEATURE_TAG +#define ss07FeatureTag LE_SS07_FEATURE_TAG #define ccmpFeatureMask 0x80000000UL #define ligaFeatureMask 0x40000000UL @@ -80,60 +96,146 @@ #define loclFeatureMask 0x01000000UL #define caltFeatureMask 0x00800000UL +#define dligFeatureMask 0x00400000UL +#define rligFeatureMask 0x00200000UL +#define hligFeatureMask 0x00100000UL +#define smcpFeatureMask 0x00080000UL +#define fracFeatureMask 0x00040000UL +#define afrcFeatureMask 0x00020000UL +#define zeroFeatureMask 0x00010000UL +#define swshFeatureMask 0x00008000UL +#define cswhFeatureMask 0x00004000UL +#define saltFeatureMask 0x00002000UL +#define naltFeatureMask 0x00001000UL +#define rubyFeatureMask 0x00000800UL +#define ss01FeatureMask 0x00000400UL +#define ss02FeatureMask 0x00000200UL +#define ss03FeatureMask 0x00000100UL +#define ss04FeatureMask 0x00000080UL +#define ss05FeatureMask 0x00000040UL +#define ss06FeatureMask 0x00000020UL +#define ss07FeatureMask 0x00000010UL + #define minimalFeatures (ccmpFeatureMask | markFeatureMask | mkmkFeatureMask | loclFeatureMask | caltFeatureMask) -#define ligaFeatures (ligaFeatureMask | cligFeatureMask | minimalFeatures) -#define kernFeatures (kernFeatureMask | paltFeatureMask | minimalFeatures) -#define kernAndLigaFeatures (ligaFeatures | kernFeatures) static const FeatureMap featureMap[] = { {ccmpFeatureTag, ccmpFeatureMask}, {ligaFeatureTag, ligaFeatureMask}, {cligFeatureTag, cligFeatureMask}, - {kernFeatureTag, kernFeatureMask}, + {kernFeatureTag, kernFeatureMask}, {paltFeatureTag, paltFeatureMask}, {markFeatureTag, markFeatureMask}, {mkmkFeatureTag, mkmkFeatureMask}, {loclFeatureTag, loclFeatureMask}, - {caltFeatureTag, caltFeatureMask} + {caltFeatureTag, caltFeatureMask}, + {hligFeatureTag, hligFeatureMask}, + {smcpFeatureTag, smcpFeatureMask}, + {fracFeatureTag, fracFeatureMask}, + {afrcFeatureTag, afrcFeatureMask}, + {zeroFeatureTag, zeroFeatureMask}, + {swshFeatureTag, swshFeatureMask}, + {cswhFeatureTag, cswhFeatureMask}, + {saltFeatureTag, saltFeatureMask}, + {naltFeatureTag, naltFeatureMask}, + {rubyFeatureTag, rubyFeatureMask}, + {ss01FeatureTag, ss01FeatureMask}, + {ss02FeatureTag, ss02FeatureMask}, + {ss03FeatureTag, ss03FeatureMask}, + {ss04FeatureTag, ss04FeatureMask}, + {ss05FeatureTag, ss05FeatureMask}, + {ss06FeatureTag, ss06FeatureMask}, + {ss07FeatureTag, ss07FeatureMask} }; static const le_int32 featureMapCount = LE_ARRAY_SIZE(featureMap); OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureMask(minimalFeatures), fFeatureMap(featureMap), fFeatureMapCount(featureMapCount), fFeatureOrder(FALSE), - fGSUBTable(gsubTable), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) + fGSUBTable(gsubTable), + fGDEFTable(fontInstance, LE_GDEF_TABLE_TAG, success), + fGPOSTable(fontInstance, LE_GPOS_TABLE_TAG, success), fSubstitutionFilter(NULL) { - static const le_uint32 gdefTableTag = LE_GDEF_TABLE_TAG; - static const le_uint32 gposTableTag = LE_GPOS_TABLE_TAG; - const GlyphPositioningTableHeader *gposTable = (const GlyphPositioningTableHeader *) getFontTable(gposTableTag); - - // todo: switch to more flags and bitfield rather than list of feature tags? - switch (typoFlags & ~0x80000000L) { - case 0: break; // default - case 1: fFeatureMask = kernFeatures; break; - case 2: fFeatureMask = ligaFeatures; break; - case 3: fFeatureMask = kernAndLigaFeatures; break; - default: break; - } - - if (typoFlags & 0x80000000L) { - fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); - } + applyTypoFlags(); setScriptAndLanguageTags(); - fGDEFTable = (const GlyphDefinitionTableHeader *) getFontTable(gdefTableTag); - // JK patch, 2008-05-30 - see Sinhala bug report and LKLUG font // if (gposTable != NULL && gposTable->coversScriptAndLanguage(fScriptTag, fLangSysTag)) { - if (gposTable != NULL && gposTable->coversScript(fScriptTag)) { - fGPOSTable = gposTable; + if (!fGPOSTable.isEmpty()&& !fGPOSTable->coversScript(fGPOSTable, fScriptTag, success)) { + fGPOSTable.clear(); // already loaded } } +void OpenTypeLayoutEngine::applyTypoFlags() { + const le_int32& typoFlags = fTypoFlags; + const LEFontInstance *fontInstance = fFontInstance; + + switch (typoFlags & (LE_SS01_FEATURE_FLAG + | LE_SS02_FEATURE_FLAG + | LE_SS03_FEATURE_FLAG + | LE_SS04_FEATURE_FLAG + | LE_SS05_FEATURE_FLAG + | LE_SS06_FEATURE_FLAG + | LE_SS07_FEATURE_FLAG)) { + case LE_SS01_FEATURE_FLAG: + fFeatureMask |= ss01FeatureMask; + break; + case LE_SS02_FEATURE_FLAG: + fFeatureMask |= ss02FeatureMask; + break; + case LE_SS03_FEATURE_FLAG: + fFeatureMask |= ss03FeatureMask; + break; + case LE_SS04_FEATURE_FLAG: + fFeatureMask |= ss04FeatureMask; + break; + case LE_SS05_FEATURE_FLAG: + fFeatureMask |= ss05FeatureMask; + break; + case LE_SS06_FEATURE_FLAG: + fFeatureMask |= ss06FeatureMask; + break; + case LE_SS07_FEATURE_FLAG: + fFeatureMask |= ss07FeatureMask; + break; + } + + if (typoFlags & LE_Kerning_FEATURE_FLAG) { + fFeatureMask |= (kernFeatureMask | paltFeatureMask); + // Convenience. + } + if (typoFlags & LE_Ligatures_FEATURE_FLAG) { + fFeatureMask |= (ligaFeatureMask | cligFeatureMask); + // Convenience TODO: should add: .. dligFeatureMask | rligFeatureMask ? + } + if (typoFlags & LE_CLIG_FEATURE_FLAG) fFeatureMask |= cligFeatureMask; + if (typoFlags & LE_DLIG_FEATURE_FLAG) fFeatureMask |= dligFeatureMask; + if (typoFlags & LE_HLIG_FEATURE_FLAG) fFeatureMask |= hligFeatureMask; + if (typoFlags & LE_LIGA_FEATURE_FLAG) fFeatureMask |= ligaFeatureMask; + if (typoFlags & LE_RLIG_FEATURE_FLAG) fFeatureMask |= rligFeatureMask; + if (typoFlags & LE_SMCP_FEATURE_FLAG) fFeatureMask |= smcpFeatureMask; + if (typoFlags & LE_FRAC_FEATURE_FLAG) fFeatureMask |= fracFeatureMask; + if (typoFlags & LE_AFRC_FEATURE_FLAG) fFeatureMask |= afrcFeatureMask; + if (typoFlags & LE_ZERO_FEATURE_FLAG) fFeatureMask |= zeroFeatureMask; + if (typoFlags & LE_SWSH_FEATURE_FLAG) fFeatureMask |= swshFeatureMask; + if (typoFlags & LE_CSWH_FEATURE_FLAG) fFeatureMask |= cswhFeatureMask; + if (typoFlags & LE_SALT_FEATURE_FLAG) fFeatureMask |= saltFeatureMask; + if (typoFlags & LE_RUBY_FEATURE_FLAG) fFeatureMask |= rubyFeatureMask; + if (typoFlags & LE_NALT_FEATURE_FLAG) { + // Mutually exclusive with ALL other features. http://www.microsoft.com/typography/otspec/features_ko.htm + fFeatureMask = naltFeatureMask; + } + + if (typoFlags & LE_CHAR_FILTER_FEATURE_FLAG) { + // This isn't a font feature, but requests a Char Substitution Filter + fSubstitutionFilter = new CharSubstitutionFilter(fontInstance); + } + +} + void OpenTypeLayoutEngine::reset() { // NOTE: if we're called from @@ -146,15 +248,17 @@ OpenTypeLayoutEngine::OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success) : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fFeatureOrder(FALSE), - fGSUBTable(NULL), fGDEFTable(NULL), fGPOSTable(NULL), fSubstitutionFilter(NULL) + fGSUBTable(), fGDEFTable(), fGPOSTable(), fSubstitutionFilter(NULL) { - setScriptAndLanguageTags(); + applyTypoFlags(); + setScriptAndLanguageTags(); } OpenTypeLayoutEngine::~OpenTypeLayoutEngine() { - if (fTypoFlags & 0x80000000L) { + if (fTypoFlags & LE_CHAR_FILTER_FEATURE_FLAG) { delete fSubstitutionFilter; + fSubstitutionFilter = NULL; } reset(); @@ -267,13 +371,13 @@ return 0; } - if (fGSUBTable != NULL) { - if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, + if (fGSUBTable.isValid()) { + if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable, fScriptTagV2, fLangSysTag, success)) { + count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureMap, fFeatureMapCount, fFeatureOrder, success); } else { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, + count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureMap, fFeatureMapCount, fFeatureOrder, success); } } @@ -294,13 +398,13 @@ return 0; } - if (fGSUBTable != NULL) { - if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, + if (fGSUBTable.isValid()) { + if (fScriptTagV2 != nullScriptTag && fGSUBTable->coversScriptAndLanguage(fGSUBTable,fScriptTagV2,fLangSysTag,success)) { + count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTagV2, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureMap, fFeatureMapCount, fFeatureOrder, success); } else { - count = fGSUBTable->process(glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, + count = fGSUBTable->process(fGSUBTable, glyphStorage, rightToLeft, fScriptTag, fLangSysTag, fGDEFTable, fSubstitutionFilter, fFeatureMap, fFeatureMapCount, fFeatureOrder, success); } } @@ -325,7 +429,7 @@ { LEUnicode *outChars = NULL; LEGlyphStorage fakeGlyphStorage; - le_int32 outCharCount, outGlyphCount, fakeGlyphCount; + le_int32 outCharCount, outGlyphCount; if (LE_FAILURE(success)) { return 0; @@ -343,11 +447,13 @@ } if (outChars != NULL) { - fakeGlyphCount = glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success); + // le_int32 fakeGlyphCount = + glyphProcessing(outChars, 0, outCharCount, outCharCount, rightToLeft, fakeGlyphStorage, success); LE_DELETE_ARRAY(outChars); // FIXME: a subclass may have allocated this, in which case this delete might not work... //adjustGlyphs(outChars, 0, outCharCount, rightToLeft, fakeGlyphs, fakeGlyphCount); } else { - fakeGlyphCount = glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success); + // le_int32 fakeGlyphCount = + glyphProcessing(chars, offset, count, max, rightToLeft, fakeGlyphStorage, success); //adjustGlyphs(chars, offset, count, rightToLeft, fakeGlyphs, fakeGlyphCount); } @@ -378,7 +484,7 @@ return; } - if (fGPOSTable != NULL) { + if (!fGPOSTable.isEmpty()) { GlyphPositionAdjustments *adjustments = new GlyphPositionAdjustments(glyphCount); le_int32 i; @@ -401,19 +507,20 @@ } #endif - if (fGPOSTable != NULL) { - if (fScriptTagV2 != nullScriptTag && fGPOSTable->coversScriptAndLanguage(fScriptTagV2,fLangSysTag)) { - fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, fGDEFTable, success, fFontInstance, - fFeatureMap, fFeatureMapCount, fFeatureOrder); + if (!fGPOSTable.isEmpty()) { + if (fScriptTagV2 != nullScriptTag && + fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) { + fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag, + fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); } else { - fGPOSTable->process(glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, fGDEFTable, success, fFontInstance, - fFeatureMap, fFeatureMapCount, fFeatureOrder); + fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag, + fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder); } - } else if ( fTypoFlags & 0x1 ) { - static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; - KernTable kt(fFontInstance, getFontTable(kernTableTag)); - kt.process(glyphStorage); + } else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ + LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); + KernTable kt(kernTable, success); + kt.process(glyphStorage, success); } float xAdjust = 0, yAdjust = 0;
--- a/src/share/native/sun/font/layout/OpenTypeLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/OpenTypeLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -24,7 +24,7 @@ */ /* - * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -35,6 +35,7 @@ #include "LEGlyphFilter.h" #include "LEFontInstance.h" #include "LayoutEngine.h" +#include "LETableReference.h" #include "GlyphSubstitutionTables.h" #include "GlyphDefinitionTables.h" @@ -88,7 +89,7 @@ * @internal */ OpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known @@ -184,6 +185,11 @@ */ static const LETag scriptTags[]; + /** + * apply the typoflags. Only called by the c'tors. + */ + void applyTypoFlags(); + protected: /** * A set of "default" features. The default characterProcessing method @@ -223,21 +229,21 @@ * * @internal */ - const GlyphSubstitutionTableHeader *fGSUBTable; + LEReferenceTo<GlyphSubstitutionTableHeader> fGSUBTable; /** * The address of the GDEF table. * * @internal */ - const GlyphDefinitionTableHeader *fGDEFTable; + LEReferenceTo<GlyphDefinitionTableHeader> fGDEFTable; /** * The address of the GPOS table. * * @internal */ - const GlyphPositioningTableHeader *fGPOSTable; + LEReferenceTo<GlyphPositioningTableHeader> fGPOSTable; /** * An optional filter used to inhibit substitutions
--- a/src/share/native/sun/font/layout/OpenTypeTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/OpenTypeTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -38,6 +38,7 @@ */ #include "LETypes.h" +#include "LETableReference.h" U_NAMESPACE_BEGIN @@ -50,7 +51,7 @@ #define LE_GLYPH_GROUP_MASK 0x00000001UL typedef le_uint32 FeatureMask; -#define SWAPT(atag) ((LETag) ((atag[0] << 24) + (atag[1] << 16) + (atag[2] << 8) + atag[3])) +#define SWAPT(atag) ((LETag) (((atag[0]) << 24) + ((atag[1]) << 16) + ((atag[2]) << 8) + (atag[3]))) struct TagAndOffsetRecord {
--- a/src/share/native/sun/font/layout/OpenTypeUtilities.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/OpenTypeUtilities.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -76,58 +76,74 @@ return bit; } -Offset OpenTypeUtilities::getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount) + +Offset OpenTypeUtilities::getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success) { - le_uint8 bit = highBit(recordCount); - le_int32 power = 1 << bit; - le_int32 extra = recordCount - power; - le_int32 probe = power; - le_int32 index = 0; + if(LE_FAILURE(success)) return 0; - if (SWAPT(records[extra].tag) <= tag) { - index = extra; + le_uint32 recordCount = records.getCount(); + le_uint8 bit = highBit(recordCount); + le_int32 power = 1 << bit; + le_int32 extra = recordCount - power; + le_int32 probe = power; + le_int32 index = 0; + + { + const ATag &aTag = records.getAlias(extra,success)->tag; + if (SWAPT(aTag) <= tag) { + index = extra; } + } - while (probe > (1 << 0)) { - probe >>= 1; + while (probe > (1 << 0) && LE_SUCCESS(success)) { + probe >>= 1; - if (SWAPT(records[index + probe].tag) <= tag) { - index += probe; - } + { + const ATag &aTag = records.getAlias(index+probe,success)->tag; + if (SWAPT(aTag) <= tag) { + index += probe; + } } + } - if (SWAPT(records[index].tag) == tag) { - return SWAPW(records[index].offset); + { + const ATag &aTag = records.getAlias(index,success)->tag; + if (SWAPT(aTag) == tag) { + return SWAPW(records.getAlias(index,success)->offset); } + } - return 0; + return 0; } -le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) +le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success) { + if(LE_FAILURE(success)) return -1; + + le_uint32 recordCount = records.getCount(); le_uint8 bit = highBit(recordCount); le_int32 power = 1 << bit; le_int32 extra = recordCount - power; le_int32 probe = power; le_int32 range = 0; - if (recordCount == 0) { - return -1; - } + if (recordCount == 0) { + return -1; + } - if (SWAPW(records[extra].firstGlyph) <= glyphID) { + if (SWAPW(records(extra,success).firstGlyph) <= glyphID) { range = extra; } - while (probe > (1 << 0)) { + while (probe > (1 << 0) && LE_SUCCESS(success)) { probe >>= 1; - if (SWAPW(records[range + probe].firstGlyph) <= glyphID) { + if (SWAPW(records(range + probe,success).firstGlyph) <= glyphID) { range += probe; } } - if (SWAPW(records[range].firstGlyph) <= glyphID && SWAPW(records[range].lastGlyph) >= glyphID) { + if (SWAPW(records(range,success).firstGlyph) <= glyphID && SWAPW(records(range,success).lastGlyph) >= glyphID) { return range; } @@ -199,6 +215,38 @@ } } +U_NAMESPACE_END +#if LE_ASSERT_BAD_FONT +#include <stdio.h> + +static const char *letagToStr(LETag tag, char *str) { + str[0]= 0xFF & (tag>>24); + str[1]= 0xFF & (tag>>16); + str[2]= 0xFF & (tag>>8); + str[3]= 0xFF & (tag>>0); + str[4]= 0; + return str; +} + +U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len) { + char tagbuf[5]; -U_NAMESPACE_END + fprintf(stderr, "%s:%d: LETableReference@0x%p: ", f, l, what); + fprintf(stderr, msg, ptr, len); + fprintf(stderr, "\n"); + + for(int depth=0;depth<10&&(what!=NULL);depth++) { + for(int i=0;i<depth;i++) { + fprintf(stderr, " "); // indent + } + if(!what->isValid()) { + fprintf(stderr, "(invalid)"); + } + fprintf(stderr, "@%p: tag (%s) font (0x%p), [0x%p+0x%lx]\n", what, letagToStr(what->getTag(), tagbuf), what->getFont(), + what->getAlias(), what->getLength()); + + what = what->getParent(); + } +} +#endif
--- a/src/share/native/sun/font/layout/OpenTypeUtilities.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/OpenTypeUtilities.h Thu Apr 18 14:38:37 2013 -0700 @@ -45,8 +45,17 @@ class OpenTypeUtilities /* not : public UObject because all methods are static */ { public: static le_int8 highBit(le_int32 value); - static Offset getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount); - static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount); + static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success); + /** + * @deprecated TODO remove + */ + static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) { + LEErrorCode success = LE_NO_ERROR; + LETableReference recordRef0((const le_uint8*)records); + LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount); + return getGlyphRangeIndex(glyphID, recordRef, success); + } + static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success); static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count); static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count); static void sort(le_uint16 *array, le_int32 count);
--- a/src/share/native/sun/font/layout/PairPositioningSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/PairPositioningSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -41,7 +41,7 @@ U_NAMESPACE_BEGIN -le_uint32 PairPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 PairPositioningSubtable::process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { switch(SWAPW(subtableFormat)) { @@ -50,27 +50,32 @@ case 1: { - const PairPositioningFormat1Subtable *subtable = (const PairPositioningFormat1Subtable *) this; + const LEReferenceTo<PairPositioningFormat1Subtable> subtable(base, success, (const PairPositioningFormat1Subtable *) this); - return subtable->process(glyphIterator, fontInstance); + if(LE_SUCCESS(success)) + return subtable->process(subtable, glyphIterator, fontInstance, success); + else + return 0; } case 2: { - const PairPositioningFormat2Subtable *subtable = (const PairPositioningFormat2Subtable *) this; + const LEReferenceTo<PairPositioningFormat2Subtable> subtable(base, success, (const PairPositioningFormat2Subtable *) this); - return subtable->process(glyphIterator, fontInstance); + if(LE_SUCCESS(success)) + return subtable->process(subtable, glyphIterator, fontInstance, success); + else + return 0; } - default: - return 0; + return 0; } } -le_uint32 PairPositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(firstGlyph); + le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success); GlyphIterator tempIterator(*glyphIterator); if (coverageIndex >= 0 && glyphIterator->next()) { @@ -110,10 +115,10 @@ return 0; } -le_uint32 PairPositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(firstGlyph); + le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success); GlyphIterator tempIterator(*glyphIterator); if (coverageIndex >= 0 && glyphIterator->next()) {
--- a/src/share/native/sun/font/layout/PairPositioningSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/PairPositioningSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -59,13 +59,14 @@ le_uint16 pairValueCount; PairValueRecord pairValueRecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(PairSetTable, pairValueRecordArray) struct PairPositioningSubtable : GlyphPositioningSubtable { ValueFormat valueFormat1; ValueFormat valueFormat2; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<PairPositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; struct PairPositioningFormat1Subtable : PairPositioningSubtable @@ -73,12 +74,13 @@ le_uint16 pairSetCount; Offset pairSetTableOffsetArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; private: const PairValueRecord *findPairValueRecord(TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize) const; }; +LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray) // NOTE: ValueRecord has a variable size struct Class2Record @@ -91,6 +93,7 @@ { Class2Record class2RecordArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(Class1Record, class2RecordArray) struct PairPositioningFormat2Subtable : PairPositioningSubtable { @@ -100,8 +103,9 @@ le_uint16 class2Count; Class1Record class1RecordArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<PairPositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; +LE_VAR_ARRAY(PairPositioningFormat2Subtable, class1RecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ScriptAndLanguage.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -38,29 +38,33 @@ U_NAMESPACE_BEGIN -const LangSysTable *ScriptTable::findLanguage(LETag languageTag, le_bool exactMatch) const +LEReferenceTo<LangSysTable> ScriptTable::findLanguage(const LETableReference& base, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const { le_uint16 count = SWAPW(langSysCount); Offset langSysTableOffset = exactMatch? 0 : SWAPW(defaultLangSysTableOffset); if (count > 0) { - Offset foundOffset = - OpenTypeUtilities::getTagOffset(languageTag, langSysRecordArray, count); + LEReferenceToArrayOf<TagAndOffsetRecord> langSysRecords(base, success, langSysRecordArray, count); + Offset foundOffset = + OpenTypeUtilities::getTagOffset(languageTag, langSysRecords, success); - if (foundOffset != 0) { - langSysTableOffset = foundOffset; - } + if (foundOffset != 0 && LE_SUCCESS(success)) { + langSysTableOffset = foundOffset; + } } if (langSysTableOffset != 0) { - return (const LangSysTable *) ((char *)this + langSysTableOffset); + return LEReferenceTo<LangSysTable>(base, success, langSysTableOffset); } - return NULL; + return LEReferenceTo<LangSysTable>(); } -const ScriptTable *ScriptListTable::findScript(LETag scriptTag) const +LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const { + if (LE_FAILURE(success) ) { + return LEReferenceTo<ScriptTable>(); // get out + } /* * There are some fonts that have a large, bogus value for scriptCount. To try * and protect against this, we use the offset in the first scriptRecord, @@ -74,38 +78,53 @@ * to be unsorted. */ le_uint16 count = SWAPW(scriptCount); + + if (count == 0) { + return LEReferenceTo<ScriptTable>(); // no items, no search + } + + // attempt to construct a ref with at least one element + LEReferenceToArrayOf<ScriptRecord> oneElementTable(base, success, &scriptRecordArray[0], 1); + + if( LE_FAILURE(success) ) { + return LEReferenceTo<ScriptTable>(); // couldn't even read the first record - bad font. + } + le_uint16 limit = ((SWAPW(scriptRecordArray[0].offset) - sizeof(ScriptListTable)) / sizeof(scriptRecordArray)) + ANY_NUMBER; Offset scriptTableOffset = 0; + if (count > limit) { // the scriptCount value is bogus; do a linear search // because limit may still be too large. - for(le_int32 s = 0; s < limit; s += 1) { - if (SWAPT(scriptRecordArray[s].tag) == scriptTag) { - scriptTableOffset = SWAPW(scriptRecordArray[s].offset); - break; - } + LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], limit); + for(le_int32 s = 0; (s < limit)&&LE_SUCCESS(success); s += 1) { + if (SWAPT(scriptRecordArrayRef(s,success).tag) == scriptTag) { + scriptTableOffset = SWAPW(scriptRecordArrayRef(s,success).offset); + break; + } } } else { - scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArray, count); + LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count); + scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO } if (scriptTableOffset != 0) { - return (const ScriptTable *) ((char *)this + scriptTableOffset); + return LEReferenceTo<ScriptTable>(base, success, scriptTableOffset); } - return NULL; + return LEReferenceTo<ScriptTable>(); } -const LangSysTable *ScriptListTable::findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const +LEReferenceTo<LangSysTable> ScriptListTable::findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const { - const ScriptTable *scriptTable = findScript(scriptTag); + const LEReferenceTo<ScriptTable> scriptTable = findScript(base, scriptTag, success); - if (scriptTable == 0) { - return NULL; - } + if (scriptTable.isEmpty()) { + return LEReferenceTo<LangSysTable>(); + } - return scriptTable->findLanguage(languageTag, exactMatch); + return scriptTable->findLanguage(scriptTable, languageTag, success, exactMatch).reparent(base); } U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/ScriptAndLanguage.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ScriptAndLanguage.h Thu Apr 18 14:38:37 2013 -0700 @@ -51,6 +51,7 @@ le_uint16 featureCount; le_uint16 featureIndexArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(LangSysTable, featureIndexArray) struct ScriptTable { @@ -58,8 +59,9 @@ le_uint16 langSysCount; LangSysRecord langSysRecordArray[ANY_NUMBER]; - const LangSysTable *findLanguage(LETag languageTag, le_bool exactMatch = FALSE) const; + LEReferenceTo<LangSysTable> findLanguage(const LETableReference &base, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const; }; +LE_VAR_ARRAY(ScriptTable, langSysRecordArray) typedef TagAndOffsetRecord ScriptRecord; @@ -68,9 +70,10 @@ le_uint16 scriptCount; ScriptRecord scriptRecordArray[ANY_NUMBER]; - const ScriptTable *findScript(LETag scriptTag) const; - const LangSysTable *findLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const; + LEReferenceTo<ScriptTable> findScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const; + LEReferenceTo<LangSysTable> findLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const; }; +LE_VAR_ARRAY(ScriptListTable, scriptRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. @@ -186,7 +186,18 @@ nbatScriptTag, /* 'nbat' (NBAT) */ palmScriptTag, /* 'palm' (PALM) */ sindScriptTag, /* 'sind' (SIND) */ - waraScriptTag /* 'wara' (WARA) */ + waraScriptTag, /* 'wara' (WARA) */ + afakScriptTag, /* 'afak' (AFAK) */ + jurcScriptTag, /* 'jurc' (JURC) */ + mrooScriptTag, /* 'mroo' (MROO) */ + nshuScriptTag, /* 'nshu' (NSHU) */ + shrdScriptTag, /* 'shrd' (SHARADA) */ + soraScriptTag, /* 'sora' (SORA_SOMPENG) */ + takrScriptTag, /* 'takr' (TAKRI) */ + tangScriptTag, /* 'tang' (TANG) */ + woleScriptTag, /* 'wole' (WOLE) */ + khojScriptTag, /* 'khoj' (KHOJ) */ + tirhScriptTag /* 'tirh' (TIRH) */ }; const LETag OpenTypeLayoutEngine::languageTags[] = {
--- a/src/share/native/sun/font/layout/ScriptAndLanguageTags.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ScriptAndLanguageTags.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved. + * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved. * * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS * YOU REALLY KNOW WHAT YOU'RE DOING. @@ -201,6 +201,17 @@ const LETag palmScriptTag = 0x70616C6D; /* 'palm' (PALM) */ const LETag sindScriptTag = 0x73696E64; /* 'sind' (SIND) */ const LETag waraScriptTag = 0x77617261; /* 'wara' (WARA) */ +const LETag afakScriptTag = 0x6166616B; /* 'afak' (AFAK) */ +const LETag jurcScriptTag = 0x6A757263; /* 'jurc' (JURC) */ +const LETag mrooScriptTag = 0x6D726F6F; /* 'mroo' (MROO) */ +const LETag nshuScriptTag = 0x6E736875; /* 'nshu' (NSHU) */ +const LETag shrdScriptTag = 0x73687264; /* 'shrd' (SHARADA) */ +const LETag soraScriptTag = 0x736F7261; /* 'sora' (SORA_SOMPENG) */ +const LETag takrScriptTag = 0x74616B72; /* 'takr' (TAKRI) */ +const LETag tangScriptTag = 0x74616E67; /* 'tang' (TANG) */ +const LETag woleScriptTag = 0x776F6C65; /* 'wole' (WOLE) */ +const LETag khojScriptTag = 0x6B686F6A; /* 'khoj' (KHOJ) */ +const LETag tirhScriptTag = 0x74697268; /* 'tirh' (TIRH) */ const LETag nullScriptTag = 0x00000000; /* '' (NULL) */
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SegmentArrayProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -46,19 +46,18 @@ { } -SegmentArrayProcessor::SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) - : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) +SegmentArrayProcessor::SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; - - segmentArrayLookupTable = (const SegmentArrayLookupTable *) &header->table; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); + segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader, success, (const SegmentArrayLookupTable*)&header->table); } SegmentArrayProcessor::~SegmentArrayProcessor() { } -void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage) +void SegmentArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { const LookupSegment *segments = segmentArrayLookupTable->segments; le_int32 glyphCount = glyphStorage.getGlyphCount(); @@ -66,17 +65,16 @@ for (glyph = 0; glyph < glyphCount; glyph += 1) { LEGlyphID thisGlyph = glyphStorage[glyph]; - const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segments, thisGlyph); + const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success); if (lookupSegment != NULL) { TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); le_int16 offset = SWAPW(lookupSegment->value); if (offset != 0) { - TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader + offset); - TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); - - glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + LEReferenceToArrayOf<TTGlyphID> glyphArray(subtableHeader, success, offset, LE_UNBOUNDED_ARRAY); + TTGlyphID newGlyph = SWAPW(glyphArray(LE_GET_GLYPH(thisGlyph) - firstGlyph, success)); + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); } } }
--- a/src/share/native/sun/font/layout/SegmentArrayProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SegmentArrayProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,9 +50,9 @@ class SegmentArrayProcessor : public NonContextualGlyphSubstitutionProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage); + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); - SegmentArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); + SegmentArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~SegmentArrayProcessor(); @@ -74,7 +74,7 @@ SegmentArrayProcessor(); protected: - const SegmentArrayLookupTable *segmentArrayLookupTable; + LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "SegmentArrayProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentArrayProcessor2) + +SegmentArrayProcessor2::SegmentArrayProcessor2() +{ +} + +SegmentArrayProcessor2::SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + segmentArrayLookupTable = LEReferenceTo<SegmentArrayLookupTable>(morphSubtableHeader, success, &header->table); // don't parent to 'header' as it is on the stack +} + +SegmentArrayProcessor2::~SegmentArrayProcessor2() +{ +} + +void SegmentArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + const LookupSegment *segments = segmentArrayLookupTable->segments; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + le_int32 glyph; + + for (glyph = 0; glyph < glyphCount; glyph += 1) { + LEGlyphID thisGlyph = glyphStorage[glyph]; + const LookupSegment *lookupSegment = segmentArrayLookupTable->lookupSegment(segmentArrayLookupTable, segments, thisGlyph, success); + + if (lookupSegment != NULL) { + TTGlyphID firstGlyph = SWAPW(lookupSegment->firstGlyph); + le_int16 offset = SWAPW(lookupSegment->value); + + if (offset != 0) { + TTGlyphID *glyphArray = (TTGlyphID *) ((char *) subtableHeader.getAliasTODO() + offset); + TTGlyphID newGlyph = SWAPW(glyphArray[LE_GET_GLYPH(thisGlyph) - firstGlyph]); + + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } + } + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SegmentArrayProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __SEGMENTARRAYPROCESSOR_H +#define __SEGMENTARRAYPROCESSOR_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class SegmentArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + SegmentArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~SegmentArrayProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + SegmentArrayProcessor2(); + +protected: + LEReferenceTo<SegmentArrayLookupTable> segmentArrayLookupTable; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SegmentSingleProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -46,29 +46,28 @@ { } -SegmentSingleProcessor::SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader) - : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) +SegmentSingleProcessor::SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; - - segmentSingleLookupTable = (const SegmentSingleLookupTable *) &header->table; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); + segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, (const SegmentSingleLookupTable*)&header->table); } SegmentSingleProcessor::~SegmentSingleProcessor() { } -void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage) +void SegmentSingleProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { const LookupSegment *segments = segmentSingleLookupTable->segments; le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyph; - for (glyph = 0; glyph < glyphCount; glyph += 1) { + for (glyph = 0; glyph < glyphCount && LE_SUCCESS(success); glyph += 1) { LEGlyphID thisGlyph = glyphStorage[glyph]; - const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segments, thisGlyph); + const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success); - if (lookupSegment != NULL) { + if (lookupSegment != NULL && LE_SUCCESS(success)) { TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value); glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
--- a/src/share/native/sun/font/layout/SegmentSingleProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SegmentSingleProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,9 +50,9 @@ class SegmentSingleProcessor : public NonContextualGlyphSubstitutionProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage); + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); - SegmentSingleProcessor(const MorphSubtableHeader *morphSubtableHeader); + SegmentSingleProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~SegmentSingleProcessor(); @@ -74,7 +74,7 @@ SegmentSingleProcessor(); protected: - const SegmentSingleLookupTable *segmentSingleLookupTable; + LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,79 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "SegmentSingleProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SegmentSingleProcessor2) + +SegmentSingleProcessor2::SegmentSingleProcessor2() +{ +} + +SegmentSingleProcessor2::SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + + segmentSingleLookupTable = LEReferenceTo<SegmentSingleLookupTable>(morphSubtableHeader, success, &header->table); +} + +SegmentSingleProcessor2::~SegmentSingleProcessor2() +{ +} + +void SegmentSingleProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + const LookupSegment *segments = segmentSingleLookupTable->segments; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + le_int32 glyph; + + for (glyph = 0; glyph < glyphCount; glyph += 1) { + LEGlyphID thisGlyph = glyphStorage[glyph]; + const LookupSegment *lookupSegment = segmentSingleLookupTable->lookupSegment(segmentSingleLookupTable, segments, thisGlyph, success); + + if (lookupSegment != NULL && LE_SUCCESS(success)) { + TTGlyphID newGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph) + SWAPW(lookupSegment->value); + + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SegmentSingleProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __SEGMENTSINGLEPROCESSOR_H +#define __SEGMENTSINGLEPROCESSOR_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class SegmentSingleProcessor2 : public NonContextualGlyphSubstitutionProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + SegmentSingleProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~SegmentSingleProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + SegmentSingleProcessor2(); + +protected: + LEReferenceTo<SegmentSingleLookupTable> segmentSingleLookupTable; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/ShapingTypeData.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ShapingTypeData.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -122,4 +122,6 @@ 0x00, 0x05, 0xFE, 0xFF, 0xFE, 0xFF, 0x00, 0x05, 0xFF, 0xF9, 0xFF, 0xFB, 0x00, 0x05 }; +const size_t ArabicShaping::shapingTypeTableLen = sizeof(shapingTypeTable)/sizeof(shapingTypeTable[0]); + U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SimpleArrayProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -46,29 +46,29 @@ { } -SimpleArrayProcessor::SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) - : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) +SimpleArrayProcessor::SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; - - simpleArrayLookupTable = (const SimpleArrayLookupTable *) &header->table; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); + simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, (const SimpleArrayLookupTable*)&header->table); } SimpleArrayProcessor::~SimpleArrayProcessor() { } -void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage) +void SimpleArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyph; - for (glyph = 0; glyph < glyphCount; glyph += 1) { + LEReferenceToArrayOf<LookupValue> valueArray(simpleArrayLookupTable, success, (const LookupValue*)&simpleArrayLookupTable->valueArray, LE_UNBOUNDED_ARRAY); + + for (glyph = 0; LE_SUCCESS(success) && (glyph < glyphCount); glyph += 1) { LEGlyphID thisGlyph = glyphStorage[glyph]; if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) { - TTGlyphID newGlyph = SWAPW(simpleArrayLookupTable->valueArray[LE_GET_GLYPH(thisGlyph)]); - - glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + TTGlyphID newGlyph = SWAPW(valueArray.getObject(LE_GET_GLYPH(thisGlyph),success)); + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); } } }
--- a/src/share/native/sun/font/layout/SimpleArrayProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SimpleArrayProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,9 +50,9 @@ class SimpleArrayProcessor : public NonContextualGlyphSubstitutionProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage); + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); - SimpleArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); + SimpleArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~SimpleArrayProcessor(); @@ -74,7 +74,7 @@ SimpleArrayProcessor(); protected: - const SimpleArrayLookupTable *simpleArrayLookupTable; + LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,78 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "SimpleArrayProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleArrayProcessor2) + +SimpleArrayProcessor2::SimpleArrayProcessor2() +{ +} + +SimpleArrayProcessor2::SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + + simpleArrayLookupTable = LEReferenceTo<SimpleArrayLookupTable>(morphSubtableHeader, success, &header->table); + valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &simpleArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY); +} + +SimpleArrayProcessor2::~SimpleArrayProcessor2() +{ +} + +void SimpleArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if (LE_FAILURE(success)) return; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + le_int32 glyph; + + for (glyph = 0; glyph < glyphCount; glyph += 1) { + LEGlyphID thisGlyph = glyphStorage[glyph]; + if (LE_GET_GLYPH(thisGlyph) < 0xFFFF) { + TTGlyphID newGlyph = SWAPW(valueArray(LE_GET_GLYPH(thisGlyph),success)); + + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SimpleArrayProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,83 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __SIMPLEARRAYPROCESSOR2_H +#define __SIMPLEARRAYPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class SimpleArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + SimpleArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~SimpleArrayProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + SimpleArrayProcessor2(); + +protected: + LEReferenceTo<SimpleArrayLookupTable> simpleArrayLookupTable; + LEReferenceToArrayOf<LookupValue> valueArray; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SinglePositioningSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -40,7 +40,7 @@ U_NAMESPACE_BEGIN -le_uint32 SinglePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 SinglePositioningSubtable::process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { switch(SWAPW(subtableFormat)) { @@ -49,16 +49,16 @@ case 1: { - const SinglePositioningFormat1Subtable *subtable = (const SinglePositioningFormat1Subtable *) this; + const LEReferenceTo<SinglePositioningFormat1Subtable> subtable(base, success, (const SinglePositioningFormat1Subtable *) this); - return subtable->process(glyphIterator, fontInstance); + return subtable->process(subtable, glyphIterator, fontInstance, success); } case 2: { - const SinglePositioningFormat2Subtable *subtable = (const SinglePositioningFormat2Subtable *) this; + const LEReferenceTo<SinglePositioningFormat2Subtable> subtable(base, success, (const SinglePositioningFormat2Subtable *) this); - return subtable->process(glyphIterator, fontInstance); + return subtable->process(subtable, glyphIterator, fontInstance, success); } default: @@ -66,10 +66,10 @@ } } -le_uint32 SinglePositioningFormat1Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 SinglePositioningFormat1Subtable::process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); if (coverageIndex >= 0) { valueRecord.adjustPosition(SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance); @@ -80,10 +80,10 @@ return 0; } -le_uint32 SinglePositioningFormat2Subtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const +le_uint32 SinglePositioningFormat2Subtable::process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int16 coverageIndex = (le_int16) getGlyphCoverage(glyph); + le_int16 coverageIndex = (le_int16) getGlyphCoverage(base, glyph, success); if (coverageIndex >= 0) { valueRecordArray[0].adjustPosition(coverageIndex, SWAPW(valueFormat), (const char *) this, *glyphIterator, fontInstance);
--- a/src/share/native/sun/font/layout/SinglePositioningSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SinglePositioningSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -48,7 +48,7 @@ struct SinglePositioningSubtable : GlyphPositioningSubtable { - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<SinglePositioningSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; struct SinglePositioningFormat1Subtable : SinglePositioningSubtable @@ -56,7 +56,7 @@ ValueFormat valueFormat; ValueRecord valueRecord; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<SinglePositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; struct SinglePositioningFormat2Subtable : SinglePositioningSubtable @@ -65,8 +65,9 @@ le_uint16 valueCount; ValueRecord valueRecordArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const; + le_uint32 process(const LEReferenceTo<SinglePositioningFormat2Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const; }; +LE_VAR_ARRAY(SinglePositioningFormat2Subtable, valueRecordArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SingleSubstitutionSubtables.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -39,7 +39,7 @@ U_NAMESPACE_BEGIN -le_uint32 SingleSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 SingleSubstitutionSubtable::process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const { switch(SWAPW(subtableFormat)) { @@ -48,16 +48,16 @@ case 1: { - const SingleSubstitutionFormat1Subtable *subtable = (const SingleSubstitutionFormat1Subtable *) this; + const LEReferenceTo<SingleSubstitutionFormat1Subtable> subtable(base, success, (const SingleSubstitutionFormat1Subtable *) this); - return subtable->process(glyphIterator, filter); + return subtable->process(subtable, glyphIterator, success, filter); } case 2: { - const SingleSubstitutionFormat2Subtable *subtable = (const SingleSubstitutionFormat2Subtable *) this; + const LEReferenceTo<SingleSubstitutionFormat2Subtable> subtable(base, success, (const SingleSubstitutionFormat2Subtable *) this); - return subtable->process(glyphIterator, filter); + return subtable->process(subtable, glyphIterator, success, filter); } default: @@ -65,10 +65,10 @@ } } -le_uint32 SingleSubstitutionFormat1Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 SingleSubstitutionFormat1Subtable::process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); if (coverageIndex >= 0) { TTGlyphID substitute = ((TTGlyphID) LE_GET_GLYPH(glyph)) + SWAPW(deltaGlyphID); @@ -83,10 +83,10 @@ return 0; } -le_uint32 SingleSubstitutionFormat2Subtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const +le_uint32 SingleSubstitutionFormat2Subtable::process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const { LEGlyphID glyph = glyphIterator->getCurrGlyphID(); - le_int32 coverageIndex = getGlyphCoverage(glyph); + le_int32 coverageIndex = getGlyphCoverage(base, glyph, success); if (coverageIndex >= 0) { TTGlyphID substitute = SWAPW(substituteArray[coverageIndex]);
--- a/src/share/native/sun/font/layout/SingleSubstitutionSubtables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SingleSubstitutionSubtables.h Thu Apr 18 14:38:37 2013 -0700 @@ -47,14 +47,14 @@ struct SingleSubstitutionSubtable : GlyphSubstitutionSubtable { - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LEReferenceTo<SingleSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const; }; struct SingleSubstitutionFormat1Subtable : SingleSubstitutionSubtable { le_int16 deltaGlyphID; - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LEReferenceTo<SingleSubstitutionFormat1Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const; }; struct SingleSubstitutionFormat2Subtable : SingleSubstitutionSubtable @@ -62,8 +62,9 @@ le_uint16 glyphCount; TTGlyphID substituteArray[ANY_NUMBER]; - le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const; + le_uint32 process(const LEReferenceTo<SingleSubstitutionFormat2Subtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const; }; +LE_VAR_ARRAY(SingleSubstitutionFormat2Subtable, substituteArray) U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/SingleTableProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SingleTableProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -46,26 +46,25 @@ { } -SingleTableProcessor::SingleTableProcessor(const MorphSubtableHeader *moprhSubtableHeader) - : NonContextualGlyphSubstitutionProcessor(moprhSubtableHeader) +SingleTableProcessor::SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) moprhSubtableHeader; - - singleTableLookupTable = (const SingleTableLookupTable *) &header->table; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); + singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, (const SingleTableLookupTable*)&header->table); } SingleTableProcessor::~SingleTableProcessor() { } -void SingleTableProcessor::process(LEGlyphStorage &glyphStorage) +void SingleTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { const LookupSingle *entries = singleTableLookupTable->entries; le_int32 glyph; le_int32 glyphCount = glyphStorage.getGlyphCount(); for (glyph = 0; glyph < glyphCount; glyph += 1) { - const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(entries, glyphStorage[glyph]); + const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success); if (lookupSingle != NULL) { glyphStorage[glyph] = SWAPW(lookupSingle->value);
--- a/src/share/native/sun/font/layout/SingleTableProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SingleTableProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,9 +50,9 @@ class SingleTableProcessor : public NonContextualGlyphSubstitutionProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage); + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); - SingleTableProcessor(const MorphSubtableHeader *morphSubtableHeader); + SingleTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~SingleTableProcessor(); @@ -74,7 +74,7 @@ SingleTableProcessor(); protected: - const SingleTableLookupTable *singleTableLookupTable; + LEReferenceTo<SingleTableLookupTable> singleTableLookupTable; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SingleTableProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,77 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "SingleTableProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SingleTableProcessor2) + +SingleTableProcessor2::SingleTableProcessor2() +{ +} + +SingleTableProcessor2::SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + + singleTableLookupTable = LEReferenceTo<SingleTableLookupTable>(morphSubtableHeader, success, &header->table); +} + +SingleTableProcessor2::~SingleTableProcessor2() +{ +} + +void SingleTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if(LE_FAILURE(success)) return; + const LookupSingle *entries = singleTableLookupTable->entries; + le_int32 glyph; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + + for (glyph = 0; glyph < glyphCount; glyph += 1) { + const LookupSingle *lookupSingle = singleTableLookupTable->lookupSingle(singleTableLookupTable, entries, glyphStorage[glyph], success); + + if (lookupSingle != NULL) { + glyphStorage[glyph] = SWAPW(lookupSingle->value); + } + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SingleTableProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __SINGLETABLEPROCESSOR2_H +#define __SINGLETABLEPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class SingleTableProcessor2 : public NonContextualGlyphSubstitutionProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + SingleTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~SingleTableProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + SingleTableProcessor2(); + +protected: + LEReferenceTo<SingleTableLookupTable> singleTableLookupTable; + +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/StateTableProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/StateTableProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -44,17 +44,18 @@ { } -StateTableProcessor::StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader) - : SubtableProcessor(morphSubtableHeader) +StateTableProcessor::StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : SubtableProcessor(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success), + stHeader(stateTableHeader, success, (const StateTableHeader*)&stateTableHeader->stHeader) { - stateTableHeader = (const MorphStateTableHeader *) morphSubtableHeader; - + if(LE_FAILURE(success)) return; stateSize = SWAPW(stateTableHeader->stHeader.stateSize); classTableOffset = SWAPW(stateTableHeader->stHeader.classTableOffset); stateArrayOffset = SWAPW(stateTableHeader->stHeader.stateArrayOffset); entryTableOffset = SWAPW(stateTableHeader->stHeader.entryTableOffset); - classTable = (const ClassTable *) ((char *) &stateTableHeader->stHeader + classTableOffset); + classTable = LEReferenceTo<ClassTable>(stateTableHeader, success, ((char *) &stateTableHeader->stHeader + classTableOffset)); + if(LE_FAILURE(success)) return; firstGlyph = SWAPW(classTable->firstGlyph); lastGlyph = firstGlyph + SWAPW(classTable->nGlyphs); } @@ -63,8 +64,11 @@ { } -void StateTableProcessor::process(LEGlyphStorage &glyphStorage) +void StateTableProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { + if (LE_FAILURE(success)) return; + LE_STATE_PATIENCE_INIT(); + // Start at state 0 // XXX: How do we know when to start at state 1? ByteOffset currentState = stateArrayOffset; @@ -76,6 +80,7 @@ beginStateTable(); while (currGlyph <= glyphCount) { + if(LE_STATE_PATIENCE_DECR()) break; // patience exceeded. ClassCode classCode = classCodeOOB; if (currGlyph == glyphCount) { // XXX: How do we handle EOT vs. EOL? @@ -90,10 +95,11 @@ } } - const EntryTableIndex *stateArray = (const EntryTableIndex *) ((char *) &stateTableHeader->stHeader + currentState); - EntryTableIndex entryTableIndex = stateArray[(le_uint8)classCode]; - + LEReferenceToArrayOf<EntryTableIndex> stateArray(stHeader, success, currentState, LE_UNBOUNDED_ARRAY); + EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success); + LE_STATE_PATIENCE_CURR(le_int32, currGlyph); currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); + LE_STATE_PATIENCE_INCR(currGlyph); } endStateTable();
--- a/src/share/native/sun/font/layout/StateTableProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/StateTableProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -49,7 +49,7 @@ class StateTableProcessor : public SubtableProcessor { public: - void process(LEGlyphStorage &glyphStorage); + void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); virtual void beginStateTable() = 0; @@ -58,7 +58,7 @@ virtual void endStateTable() = 0; protected: - StateTableProcessor(const MorphSubtableHeader *morphSubtableHeader); + StateTableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~StateTableProcessor(); StateTableProcessor(); @@ -68,11 +68,12 @@ ByteOffset stateArrayOffset; ByteOffset entryTableOffset; - const ClassTable *classTable; + LEReferenceTo<ClassTable> classTable; TTGlyphID firstGlyph; TTGlyphID lastGlyph; - const MorphStateTableHeader *stateTableHeader; + LEReferenceTo<MorphStateTableHeader> stateTableHeader; + LEReferenceTo<StateTableHeader> stHeader; // for convenience private: StateTableProcessor(const StateTableProcessor &other); // forbid copying of this class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/StateTableProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,236 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "StateTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "StateTableProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" +#include "LookupTables.h" + +U_NAMESPACE_BEGIN + +StateTableProcessor2::StateTableProcessor2() +{ +} + +StateTableProcessor2::StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : SubtableProcessor2(morphSubtableHeader, success), stateTableHeader(morphSubtableHeader, success), + stHeader(stateTableHeader, success, (const StateTableHeader2*)&stateTableHeader->stHeader), + nClasses(0), classTableOffset(0), stateArrayOffset(0), entryTableOffset(0), classTable(), format(0), + stateArray() +{ + if (LE_FAILURE(success)) { + return; + } + nClasses = SWAPL(stHeader->nClasses); + classTableOffset = SWAPL(stHeader->classTableOffset); + stateArrayOffset = SWAPL(stHeader->stateArrayOffset); + entryTableOffset = SWAPL(stHeader->entryTableOffset); + + classTable = LEReferenceTo<LookupTable>(stHeader, success, classTableOffset); + format = SWAPW(classTable->format); + + stateArray = LEReferenceToArrayOf<EntryTableIndex2>(stHeader, success, stateArrayOffset, LE_UNBOUNDED_ARRAY); +} + +StateTableProcessor2::~StateTableProcessor2() +{ +} + +void StateTableProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if (LE_FAILURE(success)) return; + // Start at state 0 + // XXX: How do we know when to start at state 1? + le_uint16 currentState = 0; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + + LE_STATE_PATIENCE_INIT(); + + le_int32 currGlyph = 0; + if ((coverage & scfReverse2) != 0) { // process glyphs in descending order + currGlyph = glyphCount - 1; + dir = -1; + } else { + dir = 1; + } + + beginStateTable(); + switch (format) { + case ltfSimpleArray: { +#ifdef TEST_FORMAT + LEReferenceTo<SimpleArrayLookupTable> lookupTable0(classTable, success); + if(LE_FAILURE(success)) break; + while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { + if (LE_FAILURE(success)) break; + if (LE_STATE_PATIENCE_DECR()) { + LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") + break; // patience exceeded. + } + LookupValue classCode = classCodeOOB; + if (currGlyph == glyphCount || currGlyph == -1) { + // XXX: How do we handle EOT vs. EOL? + classCode = classCodeEOT; + } else { + LEGlyphID gid = glyphStorage[currGlyph]; + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); + + if (glyphCode == 0xFFFF) { + classCode = classCodeDEL; + } else { + classCode = SWAPW(lookupTable0->valueArray[gid]); + } + } + EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success)); + LE_STATE_PATIENCE_CURR(le_int32, currGlyph); + currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex); // return a zero-based index instead of a byte offset + LE_STATE_PATIENCE_INCR(currGlyph); + } +#endif + break; + } + case ltfSegmentSingle: { + LEReferenceTo<SegmentSingleLookupTable> lookupTable2(classTable, success); + if(LE_FAILURE(success)) break; + while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { + if (LE_FAILURE(success)) break; + if (LE_STATE_PATIENCE_DECR()) { + LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") + break; // patience exceeded. + } + LookupValue classCode = classCodeOOB; + if (currGlyph == glyphCount || currGlyph == -1) { + // XXX: How do we handle EOT vs. EOL? + classCode = classCodeEOT; + } else { + LEGlyphID gid = glyphStorage[currGlyph]; + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); + + if (glyphCode == 0xFFFF) { + classCode = classCodeDEL; + } else { + const LookupSegment *segment = + lookupTable2->lookupSegment(lookupTable2, lookupTable2->segments, gid, success); + if (segment != NULL && LE_SUCCESS(success)) { + classCode = SWAPW(segment->value); + } + } + } + EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses,success)); + LE_STATE_PATIENCE_CURR(le_int32, currGlyph); + currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success); + LE_STATE_PATIENCE_INCR(currGlyph); + } + break; + } + case ltfSegmentArray: { + //printf("Lookup Table Format4: specific interpretation needed!\n"); + break; + } + case ltfSingleTable: { + LEReferenceTo<SingleTableLookupTable> lookupTable6(classTable, success); + while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { + if (LE_FAILURE(success)) break; + if (LE_STATE_PATIENCE_DECR()) { + LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") + break; // patience exceeded. + } + LookupValue classCode = classCodeOOB; + if (currGlyph == glyphCount || currGlyph == -1) { + // XXX: How do we handle EOT vs. EOL? + classCode = classCodeEOT; + } else if(currGlyph > glyphCount) { + // note if > glyphCount, we've run off the end (bad font) + currGlyph = glyphCount; + classCode = classCodeEOT; + } else { + LEGlyphID gid = glyphStorage[currGlyph]; + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid); + + if (glyphCode == 0xFFFF) { + classCode = classCodeDEL; + } else { + const LookupSingle *segment = lookupTable6->lookupSingle(lookupTable6, lookupTable6->entries, gid, success); + if (segment != NULL) { + classCode = SWAPW(segment->value); + } + } + } + EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success)); + LE_STATE_PATIENCE_CURR(le_int32, currGlyph); + currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success); + LE_STATE_PATIENCE_INCR(currGlyph); + } + break; + } + case ltfTrimmedArray: { + LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(classTable, success); + if (LE_FAILURE(success)) break; + TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph); + TTGlyphID lastGlyph = firstGlyph + SWAPW(lookupTable8->glyphCount); + + while ((dir == 1 && currGlyph <= glyphCount) || (dir == -1 && currGlyph >= -1)) { + if(LE_STATE_PATIENCE_DECR()) { + LE_DEBUG_BAD_FONT("patience exceeded - state table not moving") + break; // patience exceeded. + } + + LookupValue classCode = classCodeOOB; + if (currGlyph == glyphCount || currGlyph == -1) { + // XXX: How do we handle EOT vs. EOL? + classCode = classCodeEOT; + } else { + TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]); + if (glyphCode == 0xFFFF) { + classCode = classCodeDEL; + } else if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) { + classCode = SWAPW(lookupTable8->valueArray[glyphCode - firstGlyph]); + } + } + EntryTableIndex2 entryTableIndex = SWAPW(stateArray(classCode + currentState * nClasses, success)); + LE_STATE_PATIENCE_CURR(le_int32, currGlyph); + currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success); + LE_STATE_PATIENCE_INCR(currGlyph); + } + break; + } + default: + break; + } + + endStateTable(); +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/StateTableProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,85 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __STATETABLEPROCESSOR2_H +#define __STATETABLEPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "MorphStateTables.h" +#include "SubtableProcessor2.h" +#include "LookupTables.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class StateTableProcessor2 : public SubtableProcessor2 +{ +public: + void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + virtual void beginStateTable() = 0; + + virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success) = 0; + + virtual void endStateTable() = 0; + +protected: + StateTableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + virtual ~StateTableProcessor2(); + + StateTableProcessor2(); + + le_int32 dir; + le_uint16 format; + le_uint32 nClasses; + le_uint32 classTableOffset; + le_uint32 stateArrayOffset; + le_uint32 entryTableOffset; + + LEReferenceTo<LookupTable> classTable; + LEReferenceToArrayOf<EntryTableIndex2> stateArray; + LEReferenceTo<MorphStateTableHeader2> stateTableHeader; + LEReferenceTo<StateTableHeader2> stHeader; // for convenience + +private: + StateTableProcessor2(const StateTableProcessor2 &other); // forbid copying of this class + StateTableProcessor2 &operator=(const StateTableProcessor2 &other); // forbid copying of this class +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/StateTables.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/StateTables.h Thu Apr 18 14:38:37 2013 -0700 @@ -25,7 +25,7 @@ /* * - * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved + * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved * */ @@ -42,6 +42,41 @@ U_NAMESPACE_BEGIN + + + +/* + * State table loop detection. + * Detects if too many ( LE_STATE_PATIENCE_COUNT ) state changes occur without moving the glyph index 'g'. + * + * Usage (pseudocode): + * + * { + * LE_STATE_PATIENCE_INIT(); + * + * int g=0; // the glyph index - expect it to be moving + * + * for(;;) { + * if(LE_STATE_PATIENCE_DECR()) { // decrements the patience counter + * // ran out of patience, get out. + * break; + * } + * + * LE_STATE_PATIENCE_CURR(int, g); // store the 'current' + * state = newState(state,g); + * g+= <something, could be zero>; + * LE_STATE_PATIENCE_INCR(g); // if g has moved, increment the patience counter. Otherwise leave it. + * } + * + */ + +#define LE_STATE_PATIENCE_COUNT 4096 /**< give up if a state table doesn't move the glyph after this many iterations */ +#define LE_STATE_PATIENCE_INIT() le_uint32 le_patience_count = LE_STATE_PATIENCE_COUNT +#define LE_STATE_PATIENCE_DECR() --le_patience_count==0 +#define LE_STATE_PATIENCE_CURR(type,x) type le_patience_curr=(x) +#define LE_STATE_PATIENCE_INCR(x) if((x)!=le_patience_curr) ++le_patience_count; + + struct StateTableHeader { le_int16 stateSize; @@ -50,6 +85,14 @@ ByteOffset entryTableOffset; }; +struct StateTableHeader2 +{ + le_uint32 nClasses; + le_uint32 classTableOffset; + le_uint32 stateArrayOffset; + le_uint32 entryTableOffset; +}; + enum ClassCodes { classCodeEOT = 0, @@ -68,6 +111,7 @@ le_uint16 nGlyphs; ClassCode classArray[ANY_NUMBER]; }; +LE_VAR_ARRAY(ClassTable, classArray) enum StateNumber { @@ -85,6 +129,14 @@ le_int16 flags; }; +typedef le_uint16 EntryTableIndex2; + +struct StateEntry2 // same struct different interpretation +{ + le_uint16 newStateIndex; + le_uint16 flags; +}; + U_NAMESPACE_END #endif
--- a/src/share/native/sun/font/layout/SubtableProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SubtableProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -40,10 +40,10 @@ { } -SubtableProcessor::SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader) +SubtableProcessor::SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : length(0), coverage(0), subtableFeatures(0L), subtableHeader(morphSubtableHeader) { - subtableHeader = morphSubtableHeader; - + if(LE_FAILURE(success)) return; length = SWAPW(subtableHeader->length); coverage = SWAPW(subtableHeader->coverage); subtableFeatures = SWAPL(subtableHeader->subtableFeatures);
--- a/src/share/native/sun/font/layout/SubtableProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/SubtableProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -46,11 +46,11 @@ class SubtableProcessor : public UMemory { public: - virtual void process(LEGlyphStorage &glyphStorage) = 0; + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0; virtual ~SubtableProcessor(); protected: - SubtableProcessor(const MorphSubtableHeader *morphSubtableHeader); + SubtableProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); SubtableProcessor(); @@ -58,7 +58,7 @@ SubtableCoverage coverage; FeatureFlags subtableFeatures; - const MorphSubtableHeader *subtableHeader; + const LEReferenceTo<MorphSubtableHeader> subtableHeader; private:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SubtableProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,57 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +SubtableProcessor2::SubtableProcessor2() +{ +} + +SubtableProcessor2::SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : subtableHeader(morphSubtableHeader, success), length(0), coverage(0), subtableFeatures(0L) +{ + if(LE_FAILURE(success)) return; + + length = SWAPL(subtableHeader->length); + coverage = SWAPL(subtableHeader->coverage); + subtableFeatures = SWAPL(subtableHeader->subtableFeatures); +} + +SubtableProcessor2::~SubtableProcessor2() +{ +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/SubtableProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,70 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __SUBTABLEPROCESSOR2_H +#define __SUBTABLEPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class SubtableProcessor2 : public UMemory { +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success) = 0; + virtual ~SubtableProcessor2(); + +protected: + SubtableProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + SubtableProcessor2(); + + le_uint32 length; + SubtableCoverage2 coverage; + FeatureFlags subtableFeatures; + + const LEReferenceTo<MorphSubtableHeader2> subtableHeader; + +private: + + SubtableProcessor2(const SubtableProcessor2 &other); // forbid copying of this class + SubtableProcessor2 &operator=(const SubtableProcessor2 &other); // forbid copying of this class +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/ThaiLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ThaiLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -134,11 +134,10 @@ return; } - if (fTypoFlags & 0x1) { /* kerning enabled */ - static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG; - - KernTable kt(fFontInstance, getFontTable(kernTableTag)); - kt.process(glyphStorage); + if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */ + LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success); + KernTable kt(kernTable, success); + kt.process(glyphStorage, success); } // default is no adjustments
--- a/src/share/native/sun/font/layout/TibetanLayoutEngine.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/TibetanLayoutEngine.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -49,7 +49,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TibetanOpenTypeLayoutEngine) TibetanOpenTypeLayoutEngine::TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success) + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success) : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success) { fFeatureMap = TibetanReordering::getFeatureMap(fFeatureMapCount);
--- a/src/share/native/sun/font/layout/TibetanLayoutEngine.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/TibetanLayoutEngine.h Thu Apr 18 14:38:37 2013 -0700 @@ -83,7 +83,7 @@ * @internal */ TibetanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, - le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success); + le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success); /** * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor.cpp Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -46,22 +46,28 @@ { } -TrimmedArrayProcessor::TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader) - : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader) +TrimmedArrayProcessor::TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor(morphSubtableHeader, success), firstGlyph(0), lastGlyph(0) { - const NonContextualGlyphSubstitutionHeader *header = (const NonContextualGlyphSubstitutionHeader *) morphSubtableHeader; + LEReferenceTo<NonContextualGlyphSubstitutionHeader> header(morphSubtableHeader, success); + + if(LE_FAILURE(success)) return; - trimmedArrayLookupTable = (const TrimmedArrayLookupTable *) &header->table; - firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph); - lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount); + trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, (const TrimmedArrayLookupTable*)&header->table); + + if(LE_FAILURE(success)) return; + + firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph); + lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount); } TrimmedArrayProcessor::~TrimmedArrayProcessor() { } -void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage) +void TrimmedArrayProcessor::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) { + if(LE_FAILURE(success)) return; le_int32 glyphCount = glyphStorage.getGlyphCount(); le_int32 glyph;
--- a/src/share/native/sun/font/layout/TrimmedArrayProcessor.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor.h Thu Apr 18 14:38:37 2013 -0700 @@ -50,9 +50,9 @@ class TrimmedArrayProcessor : public NonContextualGlyphSubstitutionProcessor { public: - virtual void process(LEGlyphStorage &glyphStorage); + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); - TrimmedArrayProcessor(const MorphSubtableHeader *morphSubtableHeader); + TrimmedArrayProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success); virtual ~TrimmedArrayProcessor(); @@ -76,7 +76,7 @@ protected: TTGlyphID firstGlyph; TTGlyphID lastGlyph; - const TrimmedArrayLookupTable *trimmedArrayLookupTable; + LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.cpp Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" +#include "TrimmedArrayProcessor2.h" +#include "LEGlyphStorage.h" +#include "LESwaps.h" + +U_NAMESPACE_BEGIN + +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TrimmedArrayProcessor2) + +TrimmedArrayProcessor2::TrimmedArrayProcessor2() +{ +} + +TrimmedArrayProcessor2::TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success) + : NonContextualGlyphSubstitutionProcessor2(morphSubtableHeader, success) +{ + const LEReferenceTo<NonContextualGlyphSubstitutionHeader2> header(morphSubtableHeader, success); + + trimmedArrayLookupTable = LEReferenceTo<TrimmedArrayLookupTable>(morphSubtableHeader, success, &header->table); + firstGlyph = SWAPW(trimmedArrayLookupTable->firstGlyph); + lastGlyph = firstGlyph + SWAPW(trimmedArrayLookupTable->glyphCount); + valueArray = LEReferenceToArrayOf<LookupValue>(morphSubtableHeader, success, &trimmedArrayLookupTable->valueArray[0], LE_UNBOUNDED_ARRAY); +} + +TrimmedArrayProcessor2::~TrimmedArrayProcessor2() +{ +} + +void TrimmedArrayProcessor2::process(LEGlyphStorage &glyphStorage, LEErrorCode &success) +{ + if(LE_FAILURE(success)) return; + le_int32 glyphCount = glyphStorage.getGlyphCount(); + le_int32 glyph; + + for (glyph = 0; glyph < glyphCount; glyph += 1) { + LEGlyphID thisGlyph = glyphStorage[glyph]; + TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(thisGlyph); + + if ((ttGlyph > firstGlyph) && (ttGlyph < lastGlyph)) { + TTGlyphID newGlyph = SWAPW(valueArray(ttGlyph - firstGlyph, success)); + + glyphStorage[glyph] = LE_SET_GLYPH(thisGlyph, newGlyph); + } + } +} + +U_NAMESPACE_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/native/sun/font/layout/TrimmedArrayProcessor2.h Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +/* + * + * (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved + * + */ + +#ifndef __TRIMMEDARRAYPROCESSOR2_H +#define __TRIMMEDARRAYPROCESSOR2_H + +/** + * \file + * \internal + */ + +#include "LETypes.h" +#include "MorphTables.h" +#include "SubtableProcessor2.h" +#include "NonContextualGlyphSubst.h" +#include "NonContextualGlyphSubstProc2.h" + +U_NAMESPACE_BEGIN + +class LEGlyphStorage; + +class TrimmedArrayProcessor2 : public NonContextualGlyphSubstitutionProcessor2 +{ +public: + virtual void process(LEGlyphStorage &glyphStorage, LEErrorCode &success); + + TrimmedArrayProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success); + + virtual ~TrimmedArrayProcessor2(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.8 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.8 + */ + static UClassID getStaticClassID(); + +private: + TrimmedArrayProcessor2(); + +protected: + TTGlyphID firstGlyph; + TTGlyphID lastGlyph; + LEReferenceTo<TrimmedArrayLookupTable> trimmedArrayLookupTable; + LEReferenceToArrayOf<LookupValue> valueArray; +}; + +U_NAMESPACE_END +#endif
--- a/src/share/native/sun/font/layout/ValueRecords.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/layout/ValueRecords.h Thu Apr 18 14:38:37 2013 -0700 @@ -64,6 +64,7 @@ static le_int16 getFieldCount(ValueFormat valueFormat); static le_int16 getFieldIndex(ValueFormat valueFormat, ValueRecordField field); }; +LE_VAR_ARRAY(ValueRecord, values) enum ValueRecordFields {
--- a/src/share/native/sun/font/sunFont.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/share/native/sun/font/sunFont.c Thu Apr 18 14:38:37 2013 -0700 @@ -320,22 +320,20 @@ JNIEXPORT TTLayoutTableCache* newLayoutTableCache() { TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache)); if (ltc) { - ltc->gsub_len = -1; - ltc->gpos_len = -1; - ltc->gdef_len = -1; - ltc->mort_len = -1; - ltc->kern_len = -1; + int i; + for(i=0;i<LAYOUTCACHE_ENTRIES;i++) { + ltc->entries[i].len = -1; + } } return ltc; } JNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) { if (ltc) { - if (ltc->gsub) free(ltc->gsub); - if (ltc->gpos) free(ltc->gpos); - if (ltc->gdef) free(ltc->gdef); - if (ltc->mort) free(ltc->mort); - if (ltc->kern) free(ltc->kern); + int i; + for(i=0;i<LAYOUTCACHE_ENTRIES;i++) { + if(ltc->entries[i].ptr) free (ltc->entries[i].ptr); + } if (ltc->kernPairs) free(ltc->kernPairs); free(ltc); }
--- a/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1139,8 +1139,8 @@ focusLog.finest("Real native focused window: " + realNativeFocusedWindow + "\nKFM's focused window: " + focusedWindow); - // See 6522725, 6613426. - if (target == realNativeFocusedWindow) { + // A workaround for Metacity. See 6522725, 6613426, 7147075. + if (target == realNativeFocusedWindow && XWM.getWMID() == XWM.METACITY_WM) { focusLog.fine("The window is already natively focused."); return true; }
--- a/src/solaris/classes/sun/awt/X11/XWindowPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/classes/sun/awt/X11/XWindowPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -992,8 +992,8 @@ XLayerProtocol.LAYER_NORMAL); } - public void setAlwaysOnTop(boolean alwaysOnTop) { - this.alwaysOnTop = alwaysOnTop; + public void updateAlwaysOnTopState() { + this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop(); updateAlwaysOnTop(); }
--- a/src/solaris/native/java/lang/java_props_md.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/lang/java_props_md.c Thu Apr 18 14:38:37 2013 -0700 @@ -498,7 +498,12 @@ sprops.display_script = sprops.script; sprops.display_country = sprops.country; sprops.display_variant = sprops.variant; + +#ifdef MACOSX + sprops.sun_jnu_encoding = "UTF-8"; +#else sprops.sun_jnu_encoding = sprops.encoding; +#endif #ifdef _ALLBSD_SOURCE #if BYTE_ORDER == _LITTLE_ENDIAN
--- a/src/solaris/native/java/net/Inet4AddressImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/net/Inet4AddressImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -102,9 +102,6 @@ static jclass ni_iacls; static jclass ni_ia4cls; static jmethodID ni_ia4ctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iahostID; -static jfieldID ni_iafamilyID; static int initialized = 0; /* @@ -135,9 +132,6 @@ ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); initialized = 1; } @@ -238,9 +232,8 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr)); - (*env)->SetObjectField(env, iaObj, ni_iahostID, name); + setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr)); + setInetAddress_hostName(env, iaObj, name); (*env)->SetObjectArrayElement(env, ret, retLen - i -1, iaObj); i++; iterator = iterator->ai_next; @@ -395,9 +388,6 @@ static jclass ni_iacls; static jclass ni_ia4cls; static jmethodID ni_ia4ctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iahostID; -static jfieldID ni_iafamilyID; static int initialized = 0; /* @@ -431,9 +421,6 @@ ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); initialized = 1; } @@ -502,9 +489,8 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl((*addrp)->s_addr)); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr)); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, i, iaObj); addrp++; i++;
--- a/src/solaris/native/java/net/Inet6AddressImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -122,9 +122,6 @@ static jclass ni_ia6cls; static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iahostID; -static jfieldID ni_iafamilyID; static jfieldID ni_ia6ipaddressID; static int initialized = 0; @@ -161,9 +158,6 @@ ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); initialized = 1; } @@ -318,9 +312,8 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj); inetIndex++; } else if (iterator->ai_family == AF_INET6) { @@ -351,7 +344,7 @@ (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); } (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); inet6Index++; }
--- a/src/solaris/native/java/net/NetworkInterface.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/net/NetworkInterface.c Thu Apr 18 14:38:37 2013 -0700 @@ -118,8 +118,6 @@ static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; static jmethodID ni_ibctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iafamilyID; static jfieldID ni_ia6ipaddressID; static jfieldID ni_ibaddressID; static jfieldID ni_ib4broadcastID; @@ -195,8 +193,6 @@ ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V"); ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;"); ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;"); @@ -300,7 +296,7 @@ netif *ifs, *curr; #ifdef AF_INET6 - int family = ( (*env)->GetIntField(env, iaObj, ni_iafamilyID) == IPv4 ) ? AF_INET : AF_INET6; + int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6; #else int family = AF_INET; #endif @@ -325,7 +321,7 @@ if (family == addrP->family) { if (family == AF_INET) { int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr); - int address2 = (*env)->GetIntField(env, iaObj, ni_iaaddressID); + int address2 = getInetAddress_addr(env, iaObj); if (address1 == address2) { match = JNI_TRUE; @@ -651,7 +647,7 @@ if (addrP->family == AF_INET) { iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); if (iaObj) { - (*env)->SetIntField(env, iaObj, ni_iaaddressID, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); + setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr)); } ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj) { @@ -660,8 +656,7 @@ jobject ia2Obj = NULL; ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); if (ia2Obj) { - (*env)->SetIntField(env, ia2Obj, ni_iaaddressID, - htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); + setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr)); (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj); (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); }
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -616,14 +616,13 @@ iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port); #ifdef AF_INET6 - family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? - AF_INET : AF_INET6; + family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6; #else family = AF_INET; #endif if (family == AF_INET) { /* this api can't handle IPV6 addresses */ - int address = (*env)->GetIntField(env, iaObj, ia_addressID); - (*env)->SetIntField(env, addressObj, ia_addressID, address); + int address = getInetAddress_addr(env, iaObj); + setInetAddress_addr(env, addressObj, address); } return port; } @@ -1170,23 +1169,18 @@ */ static void mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jobject value) { static jfieldID ni_addrsID; - static jfieldID ia_addressID; struct in_addr in; jobjectArray addrArray; jsize len; jobject addr; int i; - if (ni_addrsID == NULL || ia_addressID == NULL) { + if (ni_addrsID == NULL ) { jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); CHECK_NULL(c); ni_addrsID = (*env)->GetFieldID(env, c, "addrs", "[Ljava/net/InetAddress;"); CHECK_NULL(ni_addrsID); - c = (*env)->FindClass(env,"java/net/InetAddress"); - CHECK_NULL(c); - ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL(ia_addressID); } addrArray = (*env)->GetObjectField(env, value, ni_addrsID); @@ -1207,8 +1201,8 @@ */ for (i = 0; i < len; i++) { addr = (*env)->GetObjectArrayElement(env, addrArray, i); - if ((*env)->GetIntField(env, addr, ia_familyID) == IPv4) { - in.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID)); + if (getInetAddress_family(env, addr) == IPv4) { + in.s_addr = htonl(getInetAddress_addr(env, addr)); break; } } @@ -1268,17 +1262,9 @@ * Throw exception if failed. */ static void mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) { - static jfieldID ia_addressID; struct in_addr in; - if (ia_addressID == NULL) { - jclass c = (*env)->FindClass(env,"java/net/InetAddress"); - CHECK_NULL(c); - ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL(ia_addressID); - } - - in.s_addr = htonl( (*env)->GetIntField(env, value, ia_addressID) ); + in.s_addr = htonl( getInetAddress_addr(env, value) ); if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&in, sizeof(in)) < 0) { @@ -1626,7 +1612,6 @@ if (isIPV4) { static jclass inet4_class; static jmethodID inet4_ctrID; - static jfieldID inet4_addrID; static jclass ni_class; static jmethodID ni_ctrID; @@ -1664,8 +1649,6 @@ CHECK_NULL_RETURN(c, NULL); inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V"); CHECK_NULL_RETURN(inet4_ctrID, NULL); - inet4_addrID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL_RETURN(inet4_addrID, NULL); inet4_class = (*env)->NewGlobalRef(env, c); CHECK_NULL_RETURN(inet4_class, NULL); } @@ -1673,10 +1656,10 @@ CHECK_NULL_RETURN(addr, NULL); #ifdef __linux__ - (*env)->SetIntField(env, addr, inet4_addrID, - (isOldKernel ? ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr)) ); + setInetAddress_addr(env, addr, (isOldKernel ? + ntohl(mreqn.imr_address.s_addr) : ntohl(in.s_addr))); #else - (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr)); + setInetAddress_addr(env, addr, ntohl(in.s_addr)); #endif /* @@ -2160,7 +2143,7 @@ ipv6_join_leave = ipv6_available(); #ifdef __linux__ - if ((*env)->GetIntField(env, iaObj, ia_familyID) == IPv4) { + if (getInetAddress_family(env, iaObj) == IPv4) { ipv6_join_leave = JNI_FALSE; } #endif @@ -2207,7 +2190,7 @@ CHECK_NULL(ni_indexID); } - mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID)); + mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname.imr_address.s_addr = 0; mname.imr_ifindex = (*env)->GetIntField(env, niObj, ni_indexID); mname_len = sizeof(struct ip_mreqn); @@ -2225,11 +2208,11 @@ } addr = (*env)->GetObjectArrayElement(env, addrArray, 0); - mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID)); + mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); #ifdef __linux__ - mname.imr_address.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID)); + mname.imr_address.s_addr = htonl(getInetAddress_addr(env, addr)); #else - mname.imr_interface.s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID)); + mname.imr_interface.s_addr = htonl(getInetAddress_addr(env, addr)); #endif mname_len = sizeof(struct ip_mreq); } @@ -2268,7 +2251,7 @@ } } - mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID)); + mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname.imr_address.s_addr = 0 ; mname.imr_ifindex = index; mname_len = sizeof(struct ip_mreqn); @@ -2298,7 +2281,7 @@ #else mname.imr_interface.s_addr = in.s_addr; #endif - mname.imr_multiaddr.s_addr = htonl((*env)->GetIntField(env, iaObj, ia_addressID)); + mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj)); mname_len = sizeof(struct ip_mreq); } } @@ -2363,10 +2346,10 @@ jbyte caddr[16]; jint family; jint address; - family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4? AF_INET : AF_INET6; + family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6; if (family == AF_INET) { /* will convert to IPv4-mapped address */ memset((char *) caddr, 0, 16); - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); caddr[10] = 0xff; caddr[11] = 0xff;
--- a/src/solaris/native/java/net/net_util_md.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/solaris/native/java/net/net_util_md.c Thu Apr 18 14:38:37 2013 -0700 @@ -818,7 +818,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean v4MappedAddress) { jint family; - family = (*env)->GetIntField(env, iaObj, ia_familyID); + family = getInetAddress_family(env, iaObj); #ifdef AF_INET6 /* needs work. 1. family 2. clean up him6 etc deallocate memory */ if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) { @@ -830,7 +830,7 @@ if (family == IPv4) { /* will convert to IPv4-mapped address */ memset((char *) caddr, 0, 16); - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); if (address == INADDR_ANY) { /* we would always prefer IPv6 wildcard address caddr[10] = 0xff; @@ -942,7 +942,7 @@ return -1; } memset((char *) him4, 0, sizeof(struct sockaddr_in)); - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (uint32_t) htonl(address); him4->sin_family = AF_INET;
--- a/src/windows/classes/java/lang/ProcessImpl.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/classes/java/lang/ProcessImpl.java Thu Apr 18 14:38:37 2013 -0700 @@ -144,6 +144,88 @@ } + // We guarantee the only command file execution for implicit [cmd.exe] run. + // http://technet.microsoft.com/en-us/library/bb490954.aspx + private static final char CMD_BAT_ESCAPE[] = {' ', '\t', '<', '>', '&', '|', '^'}; + private static final char WIN32_EXECUTABLE_ESCAPE[] = {' ', '\t', '<', '>'}; + + private static boolean isQuoted(boolean noQuotesInside, String arg, + String errorMessage) { + int lastPos = arg.length() - 1; + if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') { + // The argument has already been quoted. + if (noQuotesInside) { + if (arg.indexOf('"', 1) != lastPos) { + // There is ["] inside. + throw new IllegalArgumentException(errorMessage); + } + } + return true; + } + if (noQuotesInside) { + if (arg.indexOf('"') >= 0) { + // There is ["] inside. + throw new IllegalArgumentException(errorMessage); + } + } + return false; + } + + private static boolean needsEscaping(boolean isCmdFile, String arg) { + // Switch off MS heuristic for internal ["]. + // Please, use the explicit [cmd.exe] call + // if you need the internal ["]. + // Example: "cmd.exe", "/C", "Extended_MS_Syntax" + + // For [.exe] or [.com] file the unpaired/internal ["] + // in the argument is not a problem. + boolean argIsQuoted = isQuoted(isCmdFile, arg, + "Argument has embedded quote, use the explicit CMD.EXE call."); + + if (!argIsQuoted) { + char testEscape[] = isCmdFile + ? CMD_BAT_ESCAPE + : WIN32_EXECUTABLE_ESCAPE; + for (int i = 0; i < testEscape.length; ++i) { + if (arg.indexOf(testEscape[i]) >= 0) { + return true; + } + } + } + return false; + } + + private static String getExecutablePath(String path) + throws IOException + { + boolean pathIsQuoted = isQuoted(true, path, + "Executable name has embedded quote, split the arguments"); + + // Win32 CreateProcess requires path to be normalized + File fileToRun = new File(pathIsQuoted + ? path.substring(1, path.length() - 1) + : path); + + // From the [CreateProcess] function documentation: + // + // "If the file name does not contain an extension, .exe is appended. + // Therefore, if the file name extension is .com, this parameter + // must include the .com extension. If the file name ends in + // a period (.) with no extension, or if the file name contains a path, + // .exe is not appended." + // + // "If the file name !does not contain a directory path!, + // the system searches for the executable file in the following + // sequence:..." + // + // In practice ANY non-existent path is extended by [.exe] extension + // in the [CreateProcess] funcion with the only exception: + // the path ends by (.) + + return fileToRun.getPath(); + } + + private long handle = 0; private OutputStream stdin_stream; private InputStream stdout_stream; @@ -156,30 +238,47 @@ final boolean redirectErrorStream) throws IOException { - // Win32 CreateProcess requires cmd[0] to be normalized - cmd[0] = new File(cmd[0]).getPath(); + // The [executablePath] is not quoted for any case. + String executablePath = getExecutablePath(cmd[0]); + + // We need to extend the argument verification procedure + // to guarantee the only command file execution for implicit [cmd.exe] + // run. + String upPath = executablePath.toUpperCase(); + boolean isCmdFile = (upPath.endsWith(".CMD") || upPath.endsWith(".BAT")); StringBuilder cmdbuf = new StringBuilder(80); - for (int i = 0; i < cmd.length; i++) { - if (i > 0) { - cmdbuf.append(' '); - } + + // Quotation protects from interpretation of the [path] argument as + // start of longer path with spaces. Quotation has no influence to + // [.exe] extension heuristic. + cmdbuf.append('"'); + cmdbuf.append(executablePath); + cmdbuf.append('"'); + + for (int i = 1; i < cmd.length; i++) { + cmdbuf.append(' '); String s = cmd[i]; - if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) { - if (s.charAt(0) != '"') { - cmdbuf.append('"'); - cmdbuf.append(s); - if (s.endsWith("\\")) { - cmdbuf.append("\\"); - } - cmdbuf.append('"'); - } else if (s.endsWith("\"")) { - /* The argument has already been quoted. */ - cmdbuf.append(s); - } else { - /* Unmatched quote for the argument. */ - throw new IllegalArgumentException(); + if (needsEscaping(isCmdFile, s)) { + cmdbuf.append('"'); + cmdbuf.append(s); + + // The code protects the [java.exe] and console command line + // parser, that interprets the [\"] combination as an escape + // sequence for the ["] char. + // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + // + // If the argument is an FS path, doubling of the tail [\] + // char is not a problem for non-console applications. + // + // The [\"] sequence is not an escape sequence for the [cmd.exe] + // command line parser. The case of the [""] tail escape + // sequence could not be realized due to the argument validation + // procedure. + if (!isCmdFile && s.endsWith("\\")) { + cmdbuf.append('\\'); } + cmdbuf.append('"'); } else { cmdbuf.append(s); }
--- a/src/windows/classes/sun/awt/windows/WFileDialogPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/classes/sun/awt/windows/WFileDialogPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -237,7 +237,7 @@ // unused methods. Overridden to disable this functionality as // it requires HWND which is not available for FileDialog - public void setAlwaysOnTop(boolean value) {} + public void updateAlwaysOnTopState() {} public void setDirectory(String dir) {} public void setFile(String file) {} public void setTitle(String title) {}
--- a/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -117,7 +117,7 @@ // unused methods. Overridden to disable this functionality as // it requires HWND which is not available for FileDialog void initialize() {} - public void setAlwaysOnTop(boolean b) {} + public void updateAlwaysOnTopState() {} public void setResizable(boolean resizable) {} public void hide() {} public void enable() {}
--- a/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/classes/sun/awt/windows/WWindowPeer.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -132,6 +132,10 @@ } } + public void updateAlwaysOnTopState() { + setAlwaysOnTop(((Window)target).isAlwaysOnTop()); + } + public void updateFocusableWindowState() { setFocusableWindow(((Window)target).isFocusableWindow()); }
--- a/src/windows/native/java/io/WinNTFileSystem_md.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/io/WinNTFileSystem_md.c Thu Apr 18 14:38:37 2013 -0700 @@ -36,9 +36,7 @@ #include <windows.h> #include <io.h> -#include "jvm.h" #include "jni.h" -#include "jni_util.h" #include "io_util.h" #include "jlong.h" #include "io_util_md.h" @@ -115,13 +113,15 @@ DWORD len = (*GetFinalPathNameByHandle_func)(h, result, MAX_PATH, 0); if (len >= MAX_PATH) { /* retry with a buffer of the right size */ - result = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR)); - if (result != NULL) { + WCHAR* newResult = (WCHAR*)realloc(result, (len+1) * sizeof(WCHAR)); + if (newResult != NULL) { + result = newResult; len = (*GetFinalPathNameByHandle_func)(h, result, len, 0); } else { len = 0; } } + if (len > 0) { /** * Strip prefix (should be \\?\ or \\?\UNC)
--- a/src/windows/native/java/net/Inet4AddressImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/Inet4AddressImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -114,9 +114,6 @@ static jclass ni_iacls; static jclass ni_ia4cls; static jmethodID ni_ia4ctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iahostID; -static jfieldID ni_iafamilyID; static int initialized = 0; /* @@ -149,9 +146,6 @@ ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); initialized = 1; } @@ -208,8 +202,7 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl(address)); + setInetAddress_addr(env, iaObj, ntohl(address)); (*env)->SetObjectArrayElement(env, ret, 0, iaObj); JNU_ReleaseStringPlatformChars(env, host, hostname); return ret; @@ -242,9 +235,8 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl((*addrp)->s_addr)); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_addr(env, iaObj, ntohl((*addrp)->s_addr)); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, i, iaObj); addrp++; i++;
--- a/src/windows/native/java/net/Inet6AddressImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/Inet6AddressImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -77,9 +77,6 @@ static jclass ni_ia6cls; static jmethodID ni_ia4ctrID; static jmethodID ni_ia6ctrID; -static jfieldID ni_iaaddressID; -static jfieldID ni_iahostID; -static jfieldID ni_iafamilyID; static jfieldID ni_ia6ipaddressID; static int initialized = 0; @@ -104,9 +101,6 @@ ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V"); - ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); - ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); - ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); initialized = 1; } @@ -243,9 +237,8 @@ ret = NULL; goto cleanupAndReturn; } - (*env)->SetIntField(env, iaObj, ni_iaaddressID, - ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj); inetIndex ++; } else if (iterator->ai_family == AF_INET6) { @@ -269,7 +262,7 @@ (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); } (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); - (*env)->SetObjectField(env, iaObj, ni_iahostID, host); + setInetAddress_hostName(env, iaObj, host); (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); inet6Index ++; }
--- a/src/windows/native/java/net/NetworkInterface.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/NetworkInterface.c Thu Apr 18 14:38:37 2013 -0700 @@ -66,7 +66,6 @@ jfieldID ni_displayNameID; /* NetworkInterface.displayName */ jfieldID ni_childsID; /* NetworkInterface.childs */ jclass ni_iacls; /* InetAddress */ -jfieldID ni_iaAddr; /* InetAddress.address */ jclass ni_ia4cls; /* Inet4Address */ jmethodID ni_ia4Ctor; /* Inet4Address() */ @@ -475,7 +474,6 @@ ni_iacls = (*env)->FindClass(env, "java/net/InetAddress"); ni_iacls = (*env)->NewGlobalRef(env, ni_iacls); - ni_iaAddr = (*env)->GetFieldID(env, ni_iacls, "address", "I"); ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); @@ -563,7 +561,7 @@ } /* default ctor will set family to AF_INET */ - (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr)); + setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr)); if (addrs->mask != -1) { ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj == NULL) { @@ -576,8 +574,7 @@ free_netaddr(netaddrP); return NULL; } - (*env)->SetIntField(env, ia2Obj, ni_iaAddr, - ntohl(addrs->brdcast.him4.sin_addr.s_addr)); + setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr)); (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj); (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask); (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj); @@ -731,7 +728,7 @@ (JNIEnv *env, jclass cls, jobject iaObj) { netif *ifList, *curr; - jint addr = (*env)->GetIntField(env, iaObj, ni_iaAddr); + jint addr = getInetAddress_addr(env, iaObj); jobject netifObj = NULL; // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
--- a/src/windows/native/java/net/NetworkInterface.h Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/NetworkInterface.h Thu Apr 18 14:38:37 2013 -0700 @@ -71,7 +71,6 @@ extern jfieldID ni_childsID; /* NetworkInterface.childs */ extern jclass ni_iacls; /* InetAddress */ -extern jfieldID ni_iaAddr; /* InetAddress.address */ extern jclass ni_ia4cls; /* Inet4Address */ extern jmethodID ni_ia4Ctor; /* Inet4Address() */
--- a/src/windows/native/java/net/NetworkInterface_winXP.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/NetworkInterface_winXP.c Thu Apr 18 14:38:37 2013 -0700 @@ -33,6 +33,7 @@ #include "jni_util.h" #include "NetworkInterface.h" +#include "net_util.h" /* * Windows implementation of the java.net.NetworkInterface native methods. @@ -477,7 +478,7 @@ } /* default ctor will set family to AF_INET */ - (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr)); + setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr)); ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); if (ibObj == NULL) { @@ -490,8 +491,7 @@ free_netaddr(netaddrP); return NULL; } - (*env)->SetIntField(env, ia2Obj, ni_iaAddr, - ntohl(addrs->brdcast.him4.sin_addr.s_addr)); + setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr)); (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj); (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask); (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
--- a/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -432,7 +432,7 @@ int lcladdrlen; int address; - family = (*env)->GetIntField(env, addressObj, ia_familyID); + family = getInetAddress_family(env, addressObj); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family not supported"); @@ -452,7 +452,7 @@ JNU_ThrowNullPointerException(env, "argument address"); return; } else { - address = (*env)->GetIntField(env, addressObj, ia_addressID); + address = getInetAddress_addr(env, addressObj); } if (NET_InetAddressToSockaddr(env, addressObj, port, (struct sockaddr *)&lcladdr, &lcladdrlen, JNI_FALSE) != 0) { @@ -552,9 +552,9 @@ return; } - addr = (*env)->GetIntField(env, address, ia_addressID); + addr = getInetAddress_addr(env, address); - family = (*env)->GetIntField(env, address, ia_familyID); + family = getInetAddress_family(env, address); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family not supported"); @@ -670,7 +670,7 @@ return; } - family = (*env)->GetIntField(env, iaObj, ia_familyID); + family = getInetAddress_family(env, iaObj); if (family == IPv4) { fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); } else { @@ -714,7 +714,7 @@ if (!w2k_or_later) { /* avoid this check on Win 2K or better. Does not work with IPv6. * Check is not necessary on these OSes */ if (connected) { - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); } else { address = ntohl(rmtaddr.him4.sin_addr.s_addr); } @@ -823,7 +823,7 @@ if (IS_NULL(addressObj)) { JNU_ThrowNullPointerException(env, "Null address in peek()"); } else { - address = (*env)->GetIntField(env, addressObj, ia_addressID); + address = getInetAddress_addr(env, addressObj); /* We only handle IPv4 for now. Will support IPv6 once its in the os */ family = AF_INET; } @@ -905,9 +905,8 @@ JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", 0); return 0; } - (*env)->SetIntField(env, addressObj, ia_addressID, - ntohl(remote_addr.sin_addr.s_addr)); - (*env)->SetIntField(env, addressObj, ia_familyID, IPv4); + setInetAddress_addr(env, addressObj, ntohl(remote_addr.sin_addr.s_addr)); + setInetAddress_family(env, addressObj, IPv4); /* return port */ return ntohs(remote_addr.sin_port); @@ -1574,21 +1573,16 @@ { jobjectArray addrArray; static jfieldID ni_addrsID=0; - static jfieldID ia_familyID=0; jsize len; jobject addr; int i; - if (ni_addrsID == NULL || ia_familyID == NULL) { + if (ni_addrsID == NULL ) { jclass c = (*env)->FindClass(env, "java/net/NetworkInterface"); CHECK_NULL_RETURN (c, -1); ni_addrsID = (*env)->GetFieldID(env, c, "addrs", "[Ljava/net/InetAddress;"); CHECK_NULL_RETURN (ni_addrsID, -1); - c = (*env)->FindClass(env,"java/net/InetAddress"); - CHECK_NULL_RETURN (c, -1); - ia_familyID = (*env)->GetFieldID(env, c, "family", "I"); - CHECK_NULL_RETURN (ia_familyID, -1); } addrArray = (*env)->GetObjectField(env, nif, ni_addrsID); @@ -1606,7 +1600,7 @@ for (i=0; i<len; i++) { int fam; addr = (*env)->GetObjectArrayElement(env, addrArray, i); - fam = (*env)->GetIntField(env, addr, ia_familyID); + fam = getInetAddress_family(env, addr); if (fam == family) { *iaddr = addr; return 0; @@ -1618,20 +1612,13 @@ static int getInet4AddrFromIf (JNIEnv *env, jobject nif, struct in_addr *iaddr) { jobject addr; - static jfieldID ia_addressID; int ret = getInetAddrFromIf (env, IPv4, nif, &addr); if (ret == -1) { return -1; } - if (ia_addressID == 0) { - jclass c = (*env)->FindClass(env,"java/net/InetAddress"); - CHECK_NULL_RETURN (c, -1); - ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL_RETURN (ia_addressID, -1); - } - iaddr->s_addr = htonl((*env)->GetIntField(env, addr, ia_addressID)); + iaddr->s_addr = htonl(getInetAddress_addr(env, addr)); return 0; } @@ -1706,17 +1693,9 @@ } opt = java_net_SocketOptions_IP_MULTICAST_IF2; } else { - static jfieldID ia_addressID; struct in_addr in; - if (ia_addressID == NULL) { - jclass c = (*env)->FindClass(env,"java/net/InetAddress"); - CHECK_NULL(c); - ia_addressID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL(ia_addressID); - } - - in.s_addr = htonl((*env)->GetIntField(env, value, ia_addressID)); + in.s_addr = htonl(getInetAddress_addr(env, value)); if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&in, sizeof(in)) < 0) { @@ -1945,7 +1924,6 @@ if (isIPV4) { static jclass inet4_class; static jmethodID inet4_ctrID; - static jfieldID inet4_addrID; static jclass ni_class; static jmethodID ni_ctrID; @@ -1975,15 +1953,13 @@ CHECK_NULL_RETURN(c, NULL); inet4_ctrID = (*env)->GetMethodID(env, c, "<init>", "()V"); CHECK_NULL_RETURN(inet4_ctrID, NULL); - inet4_addrID = (*env)->GetFieldID(env, c, "address", "I"); - CHECK_NULL_RETURN(inet4_addrID, NULL); inet4_class = (*env)->NewGlobalRef(env, c); CHECK_NULL_RETURN(inet4_class, NULL); } addr = (*env)->NewObject(env, inet4_class, inet4_ctrID, 0); CHECK_NULL_RETURN(addr, NULL); - (*env)->SetIntField(env, addr, inet4_addrID, ntohl(in.s_addr)); + setInetAddress_addr(env, addr, ntohl(in.s_addr)); /* * For IP_MULTICAST_IF return InetAddress
--- a/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Thu Apr 18 14:38:37 2013 -0700 @@ -412,7 +412,7 @@ fdObj = (*env)->GetObjectField(env, this, psi_fdID); fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID); - family = (*env)->GetIntField(env, iaObj, ia_familyID); + family = getInetAddress_family(env, iaObj); if (family == IPv6 && !ipv6_supported) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", @@ -724,9 +724,8 @@ return; } - (*env)->SetIntField(env, socketAddressObj, ia_addressID, - ntohl(him.him4.sin_addr.s_addr)); - (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv4); + setInetAddress_addr(env, socketAddressObj, ntohl(him.him4.sin_addr.s_addr)); + setInetAddress_family(env, socketAddressObj, IPv4); (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj); } else { jbyteArray addr; @@ -754,7 +753,7 @@ } addr = (*env)->GetObjectField (env, socketAddressObj, ia6_ipaddressID); (*env)->SetByteArrayRegion (env, addr, 0, 16, (const char *)&him.him6.sin6_addr); - (*env)->SetIntField(env, socketAddressObj, ia_familyID, IPv6); + setInetAddress_family(env, socketAddressObj, IPv6); (*env)->SetIntField(env, socketAddressObj, ia6_scopeidID, him.him6.sin6_scope_id); } /* fields common to AF_INET and AF_INET6 */
--- a/src/windows/native/java/net/net_util_md.c Wed Apr 17 12:13:43 2013 -0700 +++ b/src/windows/native/java/net/net_util_md.c Thu Apr 18 14:38:37 2013 -0700 @@ -804,7 +804,7 @@ NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean v4MappedAddress) { jint family, iafam; - iafam = (*env)->GetIntField(env, iaObj, ia_familyID); + iafam = getInetAddress_family(env, iaObj); family = (iafam == IPv4)? AF_INET : AF_INET6; if (ipv6_available() && !(family == AF_INET && v4MappedAddress == JNI_FALSE)) { struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him; @@ -815,7 +815,7 @@ if (family == AF_INET) { /* will convert to IPv4-mapped address */ memset((char *) caddr, 0, 16); - address = (*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); if (address == INADDR_ANY) { /* we would always prefer IPv6 wildcard address caddr[10] = 0xff; @@ -854,7 +854,7 @@ return -1; } memset((char *) him4, 0, sizeof(struct sockaddr_in)); - address = (int)(*env)->GetIntField(env, iaObj, ia_addressID); + address = getInetAddress_addr(env, iaObj); him4->sin_port = htons((short) port); him4->sin_addr.s_addr = (u_long) htonl(address); him4->sin_family = AF_INET;
--- a/test/ProblemList.txt Wed Apr 17 12:13:43 2013 -0700 +++ b/test/ProblemList.txt Thu Apr 18 14:38:37 2013 -0700 @@ -1,4 +1,4 @@ -########################################################################### +########################################################################## # # Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -274,6 +274,11 @@ # 6962637 java/io/File/MaxPathLength.java windows-all +# 7162111 - these tests need to be updated to run headless +java/io/Serializable/resolveClass/deserializeButton/run.sh macosx-all +java/io/Serializable/serialver/classpath/run.sh macosx-all +java/io/Serializable/serialver/nested/run.sh macosx-all + ############################################################################ # jdk_nio @@ -388,6 +393,9 @@ # jdk_tools +# 8012474 +sun/tools/jmap/Basic.sh generic-all + # 6461635 com/sun/tools/attach/BasicTests.sh generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/font/TextLayout/TestKerning.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011, 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 + * @summary Test Kerning is working. + * @bug 8009530 + */ + +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.font.*; +import java.util.Map; +import java.util.HashMap; +import java.util.Locale; + +public class TestKerning extends Applet { + private Panel panel; + + static public void main(String[] args) { +System.out.println(System.getProperty("os.name")); + + Applet test = new TestKerning(); + test.init(); + test.start(); + + Frame f = new Frame("Test Kerning"); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + f.add("Center", test); + f.pack(); + f.setVisible(true); + } + + public Dimension getPreferredSize() { + return new Dimension(500, 200); + } + + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + private static final String testString = "To WAVA 1,45 office glyph."; + + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D)g; + Font f = new Font("Arial", Font.PLAIN, 36); + // testing Arial on Solaris. + if (!("SunOS".equals(System.getProperty("os.name")))) { + return; + } + if (!("Arial".equals(f.getFamily(Locale.ENGLISH)))) { + return; + } + Map m = new HashMap(); + m.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + Font kf = f.deriveFont(m); + g.setFont(f); + FontMetrics fm1 = g.getFontMetrics(); + int sw1 = fm1.stringWidth(testString); + g.drawString(testString, 10, 50); + g.setFont(kf); + FontMetrics fm2 = g.getFontMetrics(); + int sw2 = fm2.stringWidth(testString); + g.drawString(testString, 10, 90); + if (sw1 == sw2) { + System.out.println(sw1+" " + sw2); + throw new RuntimeException("No kerning"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012, 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. + */ + +/** + * Check that the value of file.encoding and sun.jnu.encoding match the expected + * values passed in on the command-line. + */ +public class ExpectedEncoding { + public static void main(String[] args) { + boolean failed = false; + if (args.length != 2) { + System.out.println("Usage:"); + System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>"); + System.exit(1); + } + String expectFileEnc = args[0]; + String expectSunJnuEnc = args[1]; + + String fileEnc = System.getProperty("file.encoding"); + String jnuEnc = System.getProperty("sun.jnu.encoding"); + + if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { + System.err.println("Expected file.encoding: " + expectFileEnc); + System.err.println("Actual file.encoding: " + fileEnc); + failed = true; + } + if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); + System.err.println("Actual sun.jnu.encoding: " + jnuEnc); + failed = true; + } + if (failed) { + throw new RuntimeException("Test Failed"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# Copyright (c) 2012 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 8003228 +# @summary Test the value of sun.jnu.encoding on Mac +# @author Brent Christian +# +# @run shell MacJNUEncoding.sh + +# Only run test on Mac +OS=`uname -s` +case "$OS" in + Darwin ) ;; + * ) + exit 0 + ;; +esac + +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTSRC}" = "" ] +then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi + +JAVAC="${TESTJAVA}"/bin/javac +JAVA="${TESTJAVA}"/bin/java + +echo "Building test classes..." +"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java + +echo "" +echo "Running test for C locale" +export LANG=C +export LC_ALL=C +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 +result1=$? + +echo "" +echo "Running test for en_US.UTF-8 locale" +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 +result2=$? + +echo "" +echo "Cleanup" +rm ${TESTCLASSES}/ExpectedEncoding.class + +if [ ${result1} -ne 0 ] ; then + echo "Test failed for C locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result1} +fi +if [ ${result2} -ne 0 ] ; then + echo "Test failed for en_US.UTF-8 locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result2} +fi +exit 0 +
--- a/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java Thu Apr 18 14:38:37 2013 -0700 @@ -31,7 +31,8 @@ * * @library ../../testlibrary * @build TestLibrary Dummy - * @run main/othervm/policy=security.policy ClassPathCodebase + * @run main/othervm/policy=security.policy + * -Djava.rmi.server.useCodebaseOnly=false ClassPathCodebase */ import java.io.*;
--- a/test/java/rmi/registry/readTest/readTest.sh Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/registry/readTest/readTest.sh Thu Apr 18 14:38:37 2013 -0700 @@ -61,7 +61,8 @@ #start rmiregistry without any local classes on classpath cd rmi_tmp # NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT -${TESTJAVA}${FS}bin${FS}rmiregistry 64005 > ..${FS}${RMIREG_OUT} 2>&1 & +${TESTJAVA}${FS}bin${FS}rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false \ + ${TESTTOOLVMOPTS} 64005 > ..${FS}${RMIREG_OUT} 2>&1 & RMIREG_PID=$! # allow some time to start sleep 3
--- a/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java Thu Apr 18 14:38:37 2013 -0700 @@ -64,6 +64,10 @@ TestLibrary.bomb(e); } + System.err.println("Setting codebase property to: " + remoteCodebase); + System.setProperty("java.rmi.server.codebase", + remoteCodebase.toString()); + /* * Load Foo from a non-RMI class loader so that it won't be already * loaded by an RMI class loader in this VM (for whatever that's
--- a/test/java/rmi/server/RMIClassLoader/downloadArrayClass/security.policy Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/server/RMIClassLoader/downloadArrayClass/security.policy Thu Apr 18 14:38:37 2013 -0700 @@ -7,6 +7,8 @@ }; grant { + permission java.util.PropertyPermission + "java.rmi.server.codebase", "read,write"; // permissions needed to move classes into separate codebase directories permission java.io.FilePermission
--- a/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java Thu Apr 18 14:38:37 2013 -0700 @@ -32,7 +32,8 @@ * @library ../../../testlibrary * @build TestLibrary FnnClass FnnUnmarshal NonpublicInterface * NonpublicInterface1 PublicInterface PublicInterface1 - * @run main/othervm/policy=security.policy LoadProxyClasses + * @run main/othervm/policy=security.policy + * -Djava.rmi.server.useCodebaseOnly=false LoadProxyClasses */ import java.rmi.server.RMIClassLoader;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/rmi/server/RMIClassLoader/useCodebaseOnlyDefault/UseCodebaseOnlyDefault.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,100 @@ +/* + * 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 8001040 + * @summary Tests proper parsing and defaulting of the + * "java.rmi.server.useCodebaseOnly" property. + * + * @run main/othervm UseCodebaseOnlyDefault true + * @run main/othervm -Djava.rmi.server.useCodebaseOnly=xyzzy UseCodebaseOnlyDefault true + * @run main/othervm -Djava.rmi.server.useCodebaseOnly UseCodebaseOnlyDefault true + * @run main/othervm -Djava.rmi.server.useCodebaseOnly=true UseCodebaseOnlyDefault true + * @run main/othervm -Djava.rmi.server.useCodebaseOnly=false UseCodebaseOnlyDefault false + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Field; +import sun.rmi.server.MarshalInputStream; + +/** + * usage: UseCodebaseOnlyDefault expected + * + * 'expected' is the expected value of useCodebaseOnly, which + * must be "true" or "false". + */ +public class UseCodebaseOnlyDefault { + static final String USAGE = "usage: UseCodebaseOnlyDefault boolean"; + static final String PROPNAME = "java.rmi.server.useCodebaseOnly"; + + /** + * Gets the actual useCodebaseOnly value by creating an instance + * of MarshalInputStream and reflecting on the useCodebaseOnly field. + */ + static boolean getActualValue() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject("foo"); + oos.close(); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + MarshalInputStream mis = new MarshalInputStream(bais); + + Field f = MarshalInputStream.class.getDeclaredField("useCodebaseOnly"); + f.setAccessible(true); + return f.getBoolean(mis); + } + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + throw new IllegalArgumentException(USAGE); + } + + boolean expected; + if (args[0].equals("true")) { + expected = true; + } else if (args[0].equals("false")) { + expected = false; + } else { + throw new IllegalArgumentException(USAGE); + } + System.out.println("expected = " + expected); + + String prop = System.getProperty(PROPNAME); + System.out.print("Property " + PROPNAME); + if (prop == null) { + System.out.println(" is not set"); + } else { + System.out.println(" = '" + prop + "'"); + } + + boolean actual = getActualValue(); + System.out.println("actual = " + actual); + + if (expected != actual) + throw new AssertionError("actual does not match expected value"); + } +}
--- a/test/java/rmi/testlibrary/RMID.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/rmi/testlibrary/RMID.java Thu Apr 18 14:38:37 2013 -0700 @@ -108,6 +108,9 @@ if (!TestParams.testClasses.equals("")) { args += " -C-Dtest.classes=" + TestParams.testClasses; } + + args += " -C-Djava.rmi.server.useCodebaseOnly=false "; + args += " " + getCodeCoverageArgs(); return args; }
--- a/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/security/cert/CertPathBuilder/targetConstraints/BuildEEBasicConstraints.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,18 +21,22 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @bug 6714842 * @library ../../../testlibrary * @build CertUtils - * @run main BuildEEBasicConstraints + * @run main/othervm BuildEEBasicConstraints * @summary make sure a PKIX CertPathBuilder builds a path to an * end entity certificate when the setBasicConstraints method of the * X509CertSelector of the targetConstraints PKIXBuilderParameters * parameter is set to -2. */ +import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertPath; import java.security.cert.CertStore; @@ -49,6 +53,9 @@ public final class BuildEEBasicConstraints { public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); X509Certificate rootCert = CertUtils.getCertFromFile("anchor.cer"); TrustAnchor anchor = new TrustAnchor
--- a/test/java/security/cert/pkix/policyChanges/TestPolicy.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/java/security/cert/pkix/policyChanges/TestPolicy.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,16 +21,22 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @bug 4684793 - * @summary verify that the RFC3280 policy processing changes are implemented correctly + * @summary verify that the RFC3280 policy processing changes are + * implemented correctly + * @run main/othervm TestPolicy * @author Andreas Sterbenz */ import java.io.*; import java.util.*; +import java.security.Security; import java.security.cert.*; public class TestPolicy { @@ -72,6 +78,10 @@ }; public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + factory = CertificateFactory.getInstance("X.509"); X509Certificate anchor = loadCertificate("anchor.cer");
--- a/test/javax/swing/JTree/8004298/bug8004298.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/javax/swing/JTree/8004298/bug8004298.java Thu Apr 18 14:38:37 2013 -0700 @@ -48,8 +48,13 @@ Robot robot = new Robot(); robot.setAutoDelay(50); SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); - UIManager.setLookAndFeel(new WindowsLookAndFeel()); - + try { + UIManager.setLookAndFeel(new WindowsLookAndFeel()); + } catch (javax.swing.UnsupportedLookAndFeelException ulafe) { + System.out.println(ulafe.getMessage()); + System.out.println("The test is considered PASSED"); + return; + } SwingUtilities.invokeAndWait(new Runnable() { @Override @@ -113,4 +118,4 @@ return super.getPathBounds(tree, path); } } -} \ No newline at end of file +}
--- a/test/javax/xml/crypto/dsig/SecurityManager/XMLDSigWithSecMgr.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/javax/xml/crypto/dsig/SecurityManager/XMLDSigWithSecMgr.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -26,6 +26,7 @@ * @bug 6436919 6460930 * @summary check that XML Signatures can be generated and validated with * SecurityManager enabled and default policy + * @run main/othervm XMLDSigWithSecMgr * @author Sean Mullan */ import java.io.*;
--- a/test/sun/java2d/OpenGL/CustomCompositeTest.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/java2d/OpenGL/CustomCompositeTest.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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
--- a/test/sun/misc/Version/Version.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/misc/Version/Version.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -29,11 +29,13 @@ * @run main Version */ +import java.util.regex.*; import static sun.misc.Version.*; + public class Version { public static void main(String[] args) throws Exception { - VersionInfo jdk = newVersionInfo(System.getProperty("java.runtime.version")); + VersionInfo jdk = jdkVersionInfo(System.getProperty("java.runtime.version")); VersionInfo v1 = new VersionInfo(jdkMajorVersion(), jdkMinorVersion(), jdkMicroVersion(), @@ -44,7 +46,7 @@ if (!jdk.equals(v1)) { throw new RuntimeException("Unmatched version: " + jdk + " vs " + v1); } - VersionInfo jvm = newVersionInfo(System.getProperty("java.vm.version")); + VersionInfo jvm = jvmVersionInfo(System.getProperty("java.vm.version")); VersionInfo v2 = new VersionInfo(jvmMajorVersion(), jvmMinorVersion(), jvmMicroVersion(), @@ -95,68 +97,68 @@ } } - private static VersionInfo newVersionInfo(String version) throws Exception { + private static VersionInfo jdkVersionInfo(String version) throws Exception { // valid format of the version string is: - // n.n.n[_uu[c]][-<identifer>]-bxx + // <major>.<minor>[.<micro>][_uu[c]][-<identifier>]-bxx int major = 0; int minor = 0; int micro = 0; int update = 0; String special = ""; int build = 0; - CharSequence cs = version; - if (cs.length() >= 5) { - if (Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && - Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && - Character.isDigit(cs.charAt(4))) { - major = Character.digit(cs.charAt(0), 10); - minor = Character.digit(cs.charAt(2), 10); - micro = Character.digit(cs.charAt(4), 10); - cs = cs.subSequence(5, cs.length()); - } else if (Character.isDigit(cs.charAt(0)) && - Character.isDigit(cs.charAt(1)) && cs.charAt(2) == '.' && - Character.isDigit(cs.charAt(3))) { - // HSX has nn.n (major.minor) version - major = Integer.valueOf(version.substring(0, 2)).intValue(); - minor = Character.digit(cs.charAt(3), 10); - cs = cs.subSequence(4, cs.length()); - } - if (cs.charAt(0) == '_' && cs.length() >= 3 && - Character.isDigit(cs.charAt(1)) && - Character.isDigit(cs.charAt(2))) { - int nextChar = 3; - String uu = cs.subSequence(1, 3).toString(); - update = Integer.valueOf(uu).intValue(); - if (cs.length() >= 4) { - char c = cs.charAt(3); - if (c >= 'a' && c <= 'z') { - special = Character.toString(c); - nextChar++; - } - } - cs = cs.subSequence(nextChar, cs.length()); - } - if (cs.charAt(0) == '-') { - // skip the first character - // valid format: <identifier>-bxx or bxx - // non-product VM will have -debug|-release appended - cs = cs.subSequence(1, cs.length()); - String[] res = cs.toString().split("-"); - for (int i = res.length - 1; i >= 0; i--) { - String s = res[i]; - if (s.charAt(0) == 'b') { - try { - build = Integer.parseInt(s.substring(1, s.length())); - break; - } catch (NumberFormatException nfe) { - // ignore - } - } - } - } - } + + String regex = "^([0-9]{1,2})"; // major + regex += "\\."; // separator + regex += "([0-9]{1,2})"; // minor + regex += "(\\."; // separator + regex += "([0-9]{1,2})"; // micro + regex += ")?"; // micro is optional + regex += "(_"; + regex += "([0-9]{2})"; // update + regex += "([a-z])?"; // special char (optional) + regex += ")?"; // _uu[c] is optional + regex += ".*"; // -<identifier> + regex += "(\\-b([0-9]{1,3}$))"; // JDK -bxx + + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(version); + m.matches(); + + major = Integer.parseInt(m.group(1)); + minor = Integer.parseInt(m.group(2)); + micro = (m.group(4) == null) ? 0 : Integer.parseInt(m.group(4)); + update = (m.group(6) == null) ? 0 : Integer.parseInt(m.group(6)); + special = (m.group(7) == null) ? "" : m.group(7); + build = Integer.parseInt(m.group(9)); + VersionInfo vi = new VersionInfo(major, minor, micro, update, special, build); System.out.printf("newVersionInfo: input=%s output=%s\n", version, vi); return vi; } + + private static VersionInfo jvmVersionInfo(String version) throws Exception { + // valid format of the version string is: + // <major>.<minor>-bxx[-<identifier>][-<debug_flavor>] + int major = 0; + int minor = 0; + int build = 0; + + String regex = "^([0-9]{1,2})"; // major + regex += "\\."; // separator + regex += "([0-9]{1,2})"; // minor + regex += "(\\-b([0-9]{1,3}))"; // JVM -bxx + regex += ".*"; + + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(version); + m.matches(); + + major = Integer.parseInt(m.group(1)); + minor = Integer.parseInt(m.group(2)); + build = Integer.parseInt(m.group(4)); + + VersionInfo vi = new VersionInfo(major, minor, 0, 0, "", build); + System.out.printf("newVersionInfo: input=%s output=%s\n", version, vi); + return vi; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/krb5/name/Immutable.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,41 @@ +/* + * 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 8005460 + * @summary [findbugs] Probably returned array should be cloned + */ + +import sun.security.krb5.PrincipalName; + +public class Immutable { + public static void main(String[] args) throws Exception { + PrincipalName pn1 = new PrincipalName("host/service@REALM"); + PrincipalName pn2 = (PrincipalName)pn1.clone(); + pn1.getNameStrings()[0] = "http"; + if (!pn1.equals(pn2)) { + throw new Exception(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/pkcs/pkcs9/UnknownAttribute.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,81 @@ +/* + * 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 8011867 + * @summary Accept unknown PKCS #9 attributes + */ + +import java.io.*; +import java.util.Arrays; + +import sun.misc.HexDumpEncoder; +import sun.security.pkcs.PKCS9Attribute; +import sun.security.util.DerValue; +import sun.security.util.ObjectIdentifier; + +public class UnknownAttribute { + + public static void main(String[] args) throws Exception { + // Unknown attr + PKCS9Attribute p1 = new PKCS9Attribute( + PKCS9Attribute.CHALLENGE_PASSWORD_STR, "t0p5ecr3t"); + if (!p1.isKnown()) { + throw new Exception(); + } + // Unknown attr from DER + byte[] data = { + 0x30, 0x08, // SEQUENCE OF + 0x06, 0x02, 0x2A, 0x03, // OID 1.2.3 and + 0x31, 0x02, 0x05, 0x00 // an empty SET + }; + PKCS9Attribute p2 = new PKCS9Attribute(new DerValue(data)); + if (p2.isKnown()) { + throw new Exception(); + } + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + p2.derEncode(bout); + new HexDumpEncoder().encodeBuffer(bout.toByteArray(), System.err); + if (!Arrays.equals(data, bout.toByteArray())) { + throw new Exception(); + } + // Unknown attr from value + try { + new PKCS9Attribute(new ObjectIdentifier("1.2.3"), "hello"); + throw new Exception(); + } catch (IllegalArgumentException iae) { + // Good. Unknown attr must have byte[] value type + } + PKCS9Attribute p3 = new PKCS9Attribute( + new ObjectIdentifier("1.2.3"), new byte[]{0x31,0x02,0x05,0x00}); + if (p3.isKnown()) { + throw new Exception(); + } + bout = new ByteArrayOutputStream(); + p3.derEncode(bout); + if (!Arrays.equals(data, bout.toByteArray())) { + throw new Exception(); + } + } +}
--- a/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/provider/certpath/DisabledAlgorithms/CPBuilder.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,6 +21,9 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @@ -392,6 +395,9 @@ } public static void main(String args[]) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
--- a/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorEndEntity.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,6 +21,9 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @@ -28,7 +31,7 @@ * @summary Disable MD2 support. * New CertPathValidatorException.BasicReason enum constant for * constrained algorithm. - * + * @run main/othervm CPValidatorEndEntity * @author Xuelei Fan */ @@ -313,6 +316,10 @@ } public static void main(String args[]) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + try { validate(endentiry_SHA1withRSA_1024_1024, intermediate_SHA1withRSA_1024_1024);
--- a/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorIntermediate.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,6 +21,9 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @@ -28,7 +31,7 @@ * @summary Disable MD2 support * new CertPathValidatorException.BasicReason enum constant for * constrained algorithm - * + * @run main/othervm CPValidatorIntermediate * @author Xuelei Fan */ @@ -212,6 +215,10 @@ } public static void main(String args[]) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + try { validate(intermediate_SHA1withRSA_1024_1024); validate(intermediate_SHA1withRSA_1024_512);
--- a/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/provider/certpath/DisabledAlgorithms/CPValidatorTrustAnchor.java Thu Apr 18 14:38:37 2013 -0700 @@ -21,6 +21,9 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /** * @test * @@ -28,7 +31,7 @@ * @summary Disable MD2 support * new CertPathValidatorException.BasicReason enum constant for * constrained algorithm - * + * @run main/othervm CPValidatorTrustAnchor * @author Xuelei Fan */ @@ -133,6 +136,10 @@ } public static void main(String args[]) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + try { validate(trustAnchor_SHA1withRSA_1024); validate(trustAnchor_SHA1withRSA_512);
--- a/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java Thu Apr 18 14:38:37 2013 -0700 @@ -201,6 +201,7 @@ import java.io.*; import java.net.*; +import java.security.Security; import java.security.KeyStore; import java.security.KeyFactory; import java.security.cert.Certificate; @@ -417,6 +418,10 @@ volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + if (debug) System.setProperty("javax.net.debug", "all");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/javax/net/ssl/TLSv12/DisabledShortRSAKeys.java Thu Apr 18 14:38:37 2013 -0700 @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2012, 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. + */ + +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + +/* + * @test + * @bug 7109274 + * @summary Consider disabling support for X.509 certificates with RSA keys + * less than 1024 bits + * + * @run main/othervm DisabledShortRSAKeys PKIX TLSv1.2 + * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1.2 + * @run main/othervm DisabledShortRSAKeys PKIX TLSv1.1 + * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1.1 + * @run main/othervm DisabledShortRSAKeys PKIX TLSv1 + * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1 + * @run main/othervm DisabledShortRSAKeys PKIX SSLv3 + * @run main/othervm DisabledShortRSAKeys SunX509 SSLv3 + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import javax.net.ssl.*; +import java.security.Security; +import java.security.KeyStore; +import java.security.KeyFactory; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.*; +import java.security.interfaces.*; +import sun.misc.BASE64Decoder; + + +public class DisabledShortRSAKeys { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = true; + + /* + * Where do we find the keystores? + */ + // Certificates and key used in the test. + static String trustedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + + "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + + "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + + "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + + "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + + "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + + "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + + "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + + "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + + "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + + "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + + "-----END CERTIFICATE-----"; + + static String targetCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + + "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" + + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" + + "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" + + "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" + + "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" + + "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" + + "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" + + "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" + + "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" + + "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" + + "-----END CERTIFICATE-----"; + + // Private key in the format of PKCS#8, key size is 512 bits. + static String targetPrivateKey = + "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" + + "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" + + "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" + + "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" + + "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" + + "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" + + "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" + + "3fnqsTgaUs4="; + + static char passphrase[] = "passphrase".toCharArray(); + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLContext context = generateSSLContext(null, targetCertStr, + targetPrivateKey); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) { + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write('A'); + sslOS.flush(); + + throw new Exception( + "RSA keys shorter than 1024 bits should be disabled"); + } catch (SSLHandshakeException sslhe) { + // the expected exception, ignore + } + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLContext context = generateSSLContext(trustedCertStr, null, null); + SSLSocketFactory sslsf = context.getSocketFactory(); + + try (SSLSocket sslSocket = + (SSLSocket)sslsf.createSocket("localhost", serverPort)) { + + // only enable the target protocol + sslSocket.setEnabledProtocols(new String[] {enabledProtocol}); + + // enable a block cipher + sslSocket.setEnabledCipherSuites( + new String[] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write('B'); + sslOS.flush(); + sslIS.read(); + + throw new Exception( + "RSA keys shorter than 1024 bits should be disabled"); + } catch (SSLHandshakeException sslhe) { + // the expected exception, ignore + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + private static String tmAlgorithm; // trust manager + private static String enabledProtocol; // the target protocol + + private static void parseArguments(String[] args) { + tmAlgorithm = args[0]; + enabledProtocol = args[1]; + } + + private static SSLContext generateSSLContext(String trustedCertStr, + String keyCertStr, String keySpecStr) throws Exception { + + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // create a key store + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + + // import the trused cert + Certificate trusedCert = null; + ByteArrayInputStream is = null; + if (trustedCertStr != null) { + is = new ByteArrayInputStream(trustedCertStr.getBytes()); + trusedCert = cf.generateCertificate(is); + is.close(); + + ks.setCertificateEntry("RSA Export Signer", trusedCert); + } + + if (keyCertStr != null) { + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + new BASE64Decoder().decodeBuffer(keySpecStr)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + RSAPrivateKey priKey = + (RSAPrivateKey)kf.generatePrivate(priKeySpec); + + // generate certificate chain + is = new ByteArrayInputStream(keyCertStr.getBytes()); + Certificate keyCert = cf.generateCertificate(is); + is.close(); + + Certificate[] chain = null; + if (trusedCert != null) { + chain = new Certificate[2]; + chain[0] = keyCert; + chain[1] = trusedCert; + } else { + chain = new Certificate[1]; + chain[0] = keyCert; + } + + // import the key entry. + ks.setKeyEntry("Whatever", priKey, passphrase, chain); + } + + // create SSL context + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + if (keyCertStr != null && !keyCertStr.isEmpty()) { + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ks = null; + } else { + ctx.init(null, tmf.getTrustManagers(), null); + } + + return ctx; + } + + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Get the customized arguments. + */ + parseArguments(args); + + /* + * Start the tests. + */ + new DisabledShortRSAKeys(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + DisabledShortRSAKeys() throws Exception { + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + // swallow for now. Show later + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + String whichRemote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + whichRemote = "server"; + } else { + remote = clientException; + local = serverException; + whichRemote = "client"; + } + + /* + * If both failed, return the curthread's exception, but also + * print the remote side Exception + */ + if ((local != null) && (remote != null)) { + System.out.println(whichRemote + " also threw:"); + remote.printStackTrace(); + System.out.println(); + throw local; + } + + if (remote != null) { + throw remote; + } + + if (local != null) { + throw local; + } + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +}
--- a/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Thu Apr 18 14:38:37 2013 -0700 @@ -23,6 +23,9 @@ * questions. */ +// This test case relies on updated static security property, no way to re-use +// security property in samevm/agentvm mode. + /* * @test * @bug 7106773 @@ -38,6 +41,7 @@ import java.util.*; import java.io.*; import javax.net.ssl.*; +import java.security.Security; import java.security.KeyStore; import java.security.KeyFactory; import java.security.cert.Certificate; @@ -275,6 +279,10 @@ volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // reset the security property to make sure that the algorithms + // and keys used in this test are not disabled. + Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); + if (debug) System.setProperty("javax.net.debug", "all");
--- a/test/tools/launcher/I18NJarTest.java Wed Apr 17 12:13:43 2013 -0700 +++ b/test/tools/launcher/I18NJarTest.java Thu Apr 18 14:38:37 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -52,6 +52,8 @@ private static final File cwd = new File("."); private static final File dir = new File("\uFF66\uFF67\uFF68\uFF69"); private static final String encoding = System.getProperty("sun.jnu.encoding", ""); + private static final String LANG = System.getenv("LANG"); + private static final String LC_ALL = System.getenv("LC_ALL"); public static void main(String... args) throws Exception { boolean localeAvailable = false; @@ -63,7 +65,16 @@ } if (!localeAvailable) { System.out.println("Warning: locale: " + Locale.JAPAN - + " not found, test passes vacuosly"); + + " not found, test passes vacuously"); + return; + } + if ("C".equals(LC_ALL) || "C".equals(LANG)) { + System.out.println("Warning: The LANG and/or LC_ALL env vars are " + + "set to \"C\":\n" + + " LANG=" + LANG + "\n" + + " LC_ALL=" + LC_ALL + "\n" + + "This test requires support for multi-byte filenames.\n" + + "Test passes vacuously."); return; } if (encoding.equals("MS932") || encoding.equals("UTF-8")) { @@ -73,7 +84,7 @@ } else { System.out.println("Warning: current encoding is " + encoding + "this test requires MS932 <Ja> or UTF-8," + - " test passes vacuosly"); + " test passes vacuously"); return; } dir.mkdir();