Compare commits

...

28 Commits
1825 ... 1865

Author SHA1 Message Date
Anton Tarasov
761239703b JBR-4107 A11y: macOS - wrong frame position if window is not on primary screen 2021-12-10 17:59:30 +03:00
Vitaly Provodin
c75d75b84d JBR-4081 enable java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java for regular runs 2021-12-10 07:07:07 +07:00
Anton Tarasov
59dde04f10 JBR-4081 VO: java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java crashes JBR at # V [libjvm.dylib+0x51d192] LinkResolver::resolve_invokeinterface 2021-12-09 18:43:49 +03:00
Vitaly Provodin
730e5d9e01 JBR-3756 remove JNF from mac-aarch64 binaries 2021-12-07 15:19:02 +07:00
Dmitry Batrak
4fde082d53 JBR-4084 Default font '. AppleSystemUIFont' does not have bold weight on Chinese characters 2021-12-06 19:06:29 +03:00
Vitaly.Provodin
a953db1c0e JBR-4081 excludes java/awt/dnd/RemoveDropTargetCrashTest/RemoveDropTargetCrashTest.java from VO regular runs on macOS 2021-12-05 05:40:36 +07:00
Dmitry Batrak
a155760e94 JBR-4072 Migrate font fallback implementation on macOS to cascade lists 2021-12-03 16:02:54 +03:00
Artem Semenov
51dc9aeb99 JBR-4012 On Idea Vo often speeks selected element of tables, lists, and trees 2021-12-01 20:37:28 +03:00
Martin Doerr
d69eac67d5 8270280: security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java OCSP response error
Backport-of: f4b3ee5dca

(cherry picked from commit 777ec9b757)
2021-11-29 15:22:29 +07:00
Dmitry Batrak
2a398ebb24 JBR-4021 Unexpected focus event order on window showing 2021-11-24 09:22:26 +03:00
Nikita Gubarkov
9e959b0043 JBR-4017 Open com.jetbrains.bootstrap package only for reflection 2021-11-23 11:24:21 +03:00
Vitaly Provodin
653123737c update the link to JBR for IDEA 2021.2.4 2021-11-23 10:03:30 +07:00
Ivan Lopatin
3c34696d27 IDEA-229577: Marked i3wm as GravityBuggy 2021-11-22 21:16:03 +07:00
Maxim Kartashev
aa0b61cb75 JBR-3923 Internal Error in c1_Instruction.cpp
Make C1 hotspot compiler bail out during CFG construction if there's a
cycle in the graph that isn't a natural loop and that has led to an
unexpected state of stack/locals like missing a phi function.

This is a temporary measure that lets hotspot continue working
even after encountering such bytecode patterns. The full solution
will probably involve more sophisticated CFG checks.
2021-11-19 09:27:49 +03:00
Dmitry Batrak
1002eff4f3 JBR-4007 [JCK] javax.swing.text.GlyphView.calcBreakSpots method breaks public API 2021-11-16 19:48:56 +03:00
Dmitry Batrak
f20a3d8679 JBR-4006 [JCK] javax.swing.text.html.CSS$Attribute.OVERFLOW_WRAP field breaks public API 2021-11-16 19:01:03 +03:00
Dmitry Batrak
961e036158 JBR-4005 [JCK] java.awt.Font.LAYOUT_NO_PAIRED_CHARS_AT_SCRIPT_SPLIT field breaks public API 2021-11-16 16:38:56 +03:00
Dmitry Batrak
cafb374afc JBR-3989 Broken focus state after a quick succession of activation/deactivation events on Windows 2021-11-15 15:47:11 +03:00
Vitaly Provodin
32def2fd42 JBR-3931 add the module jdk.unsupported.desktop into jbr 2021-11-12 05:37:10 +07:00
Alexey Ushakov
224f78ca62 JBR-3954 Transparent text color rendering (needed for experimental UI)
Performed conversion from ARGB_PRE to ARGB in the grayscale text shader
2021-11-11 19:40:35 +01:00
Nikita Gubarkov
b775b37bd3 JBR-3982 Fixed non-antialiased text rendering on macOS 2021-11-11 01:11:19 +03:00
Artem Semenov
bd366e24b1 JBR-3868 Combobox list is not voiced of VoiceOver 2021-11-10 22:15:09 +03:00
Dmitry Batrak
25e087d269 JBR-3979 Focus is not transferred to parent window 2021-11-10 19:52:00 +03:00
Mikhail Grishchenko
23bf121a1e update the link to JBR for IDEA 2021.3 EAP 2021-11-10 14:08:16 +07:00
Vitaly Provodin
b224bef5a3 JBR-3973 provide macos-x64 build with Shenandoah GC 2021-11-09 15:02:57 +07:00
Nikita Gubarkov
d0600837ed JBR-3951 JBR-2917 Generate native pixel format constants from StrikeCache.java 2021-11-09 02:07:43 +03:00
Nikita Gubarkov
77be5ba45f JBR-3951 JBR-2917 Add constants for glyph pixel formats 2021-11-08 15:00:22 +03:00
Ivan Lopatin
4af628cefe JBR-2687: Fixed problems with maximizing to a new screen 2021-11-08 17:15:50 +07:00
78 changed files with 1107 additions and 1080 deletions

View File

@@ -1,6 +1,7 @@
[![official JetBrains project](http://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
# Welcome to JetBrains Runtime!
# Welcome to JetBrains Runtime!
<a name="jetbrains-runtime"></a>
JetBrains Runtime is a fork of [OpenJDK](https://github.com/openjdk/jdk) available for Windows, Mac OS X, and Linux.
It includes a number enhancements in font rendering, HiDPI support, ligatures, performance improvements, and bugfixes.
@@ -11,8 +12,8 @@ can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntim
| IDE Version | Latest JBR | Date Released |
| --- | --- | --- |
| 2021.3 | [11_0_13-b1751.16](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr11_0_13b1751.16) | 2-Nov-2021 |
| 2021.2 | [11_0_12-b1504.40](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_12-b1504.40) | 28-Sep-2021 |
| 2021.3 | [11_0_13-b1751.19](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr11_0_13b1751.19) | 9-Nov-2021 |
| 2021.2 | [11_0_13-b1504.49](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jb11_0_13-b1504.49) | 15-Nov-2021 |
| 2021.1 | [11.0.11+9-b1341.60](https://confluence.jetbrains.com/pages/viewpage.action?pageId=218857477) | 15-Jun-2021 |
| 2020.3 | [11_0_11-b1145.115](https://confluence.jetbrains.com/pages/viewpage.action?pageId=219349001) | 21-Jun-2021 |

View File

@@ -47,12 +47,6 @@ architecture=${architecture:=x64}
source jb/project/tools/common.sh
function copyJNF {
__contents_dir=$1
mkdir -p ${__contents_dir}/Frameworks
cp -Rp Frameworks/JavaNativeFoundation.framework ${__contents_dir}/Frameworks
}
function do_configure {
if [[ "${architecture}" == *aarch64* ]]; then
# NOTE: aot, cds aren't supported yet
@@ -84,6 +78,7 @@ function do_configure {
$WITH_DEBUG_LEVEL \
--with-vendor-name="${VENDOR_NAME}" \
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
--with-jvm-features=shenandoahgc \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
@@ -134,11 +129,6 @@ function create_jbr {
cp ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Info.plist ${JRE_CONTENTS}
rm -rf ${JRE_CONTENTS}/Frameworks || do_exit $?
if [[ "${architecture}" == *aarch64* ]]; then
# we can't notarize this library as usual framework (with headers and tbd-file)
# but single library notarizes correctly
copyJNF ${JRE_CONTENTS}
fi
if [[ "${bundle_type}" == *jcef* ]] || [[ "${bundle_type}" == *dcevm* ]] || [[ "${bundle_type}" == fd ]]; then
cp -a ${JCEF_PATH}/Frameworks ${JRE_CONTENTS} || do_exit $?
fi
@@ -206,9 +196,6 @@ if [[ "${bundle_type}" == *jcef* ]] || [[ "${bundle_type}" == *dcevm* ]] || [[ "
fi
if [ "${bundle_type}" == "jcef" ] || [ "${bundle_type}" == "fd" ]; then
echo Creating $JBSDK.tar.gz ...
if [[ "${architecture}" == *aarch64* ]]; then
copyJNF $BASE_DIR/$JBRSDK_BUNDLE/Contents
fi
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release > release
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release
[ -f "${JBSDK}.tar.gz" ] && rm "${JBSDK}.tar.gz"

View File

@@ -52,6 +52,7 @@ jdk.sctp,
jdk.security.auth,
jdk.security.jgss,
jdk.unsupported,
jdk.unsupported.desktop,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent,

View File

@@ -840,6 +840,19 @@ bool BlockBegin::try_merge(ValueStack* new_state) {
}
}
for_each_stack_value(existing_state, index, existing_value) {
if ( !(existing_value->as_Phi() != NULL && existing_value->as_Phi()->block() == this)) {
TRACE_PHI(tty->print_cr("Re-entered loop head without existing phi for stack - bailout"));
return false;
}
}
for_each_local_value(existing_state, index, existing_value) {
if (!(existing_value == new_state->local_at(index) || (existing_value->as_Phi() != NULL && existing_value->as_Phi()->as_Phi()->block() == this))) {
TRACE_PHI(tty->print_cr("Re-entered loop head without existing phi for modified local - bailout"));
return false;
}
}
#ifdef ASSERT
// check that all necessary phi functions are present
for_each_stack_value(existing_state, index, existing_value) {

View File

@@ -127,12 +127,12 @@ module java.base {
exports javax.security.auth.spi;
exports javax.security.auth.x500;
exports javax.security.cert;
exports com.jetbrains.bootstrap;
// additional qualified exports may be inserted at build time
// see make/gensrc/GenModuleInfo.gmk
opens com.jetbrains.bootstrap;
exports com.jetbrains.internal to
java.desktop;
exports com.sun.crypto.provider to

View File

@@ -128,12 +128,8 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
};
}
// This mapper returns either the glyph code, or if the character can be
// replaced on-the-fly using CoreText substitution; the negative unicode
// value. If this "glyph code int" is treated as an opaque code, it will
// strike and measure exactly as a real glyph code - whether the character
// is present or not. Missing characters for any font on the system will
// be returned as 0, as the getMissingGlyphCode() function above indicates.
// Missing characters for any font on the system will be returned as 0,
// as the getMissingGlyphCode() function above indicates.
private static native void nativeCharsToGlyphs(final long nativeFontPtr,
int count, char[] unicodes,
int[] glyphs);

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2000-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sun.font;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
public final class CCompositeFont extends CompositeFont {
private final List<CFont> fallbackFonts = new ArrayList<>();
public CCompositeFont(CFont font) {
super(new PhysicalFont[]{font});
mapper = new CCompositeGlyphMapper(this);
}
@Override
public synchronized int getNumSlots() {
return super.getNumSlots();
}
@Override
public CFont getSlotFont(int slot) {
if (slot == 0) return (CFont) super.getSlotFont(0);
synchronized (this) {
return fallbackFonts.get(slot - 1);
}
}
@Override
synchronized FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
return super.getStrike(desc, copy);
}
@Override
protected synchronized int getValidatedGlyphCode(int glyphCode) {
return super.getValidatedGlyphCode(glyphCode);
}
@Override
public boolean hasSupplementaryChars() {
return false;
}
@Override
public boolean useAAForPtSize(int ptsize) {
return true;
}
public synchronized int findSlot(String fontName) {
for (int slot = 0; slot < numSlots; slot++) {
CFont slotFont = getSlotFont(slot);
if (fontName.equals(slotFont.getNativeFontName())) {
return slot;
}
}
return -1;
}
public synchronized int addSlot(CFont font) {
int slot = findSlot(font.getNativeFontName());
if (slot >= 0) return slot;
fallbackFonts.add(font);
lastFontStrike = new SoftReference<>(null);
strikeCache.clear();
return numSlots++;
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.font;
import java.awt.*;
public final class CCompositeGlyphMapper extends CompositeGlyphMapper {
public CCompositeGlyphMapper(CCompositeFont compFont) {
super(compFont);
}
@Override
protected int convertToGlyph(int unicode) {
CCompositeFont compositeFont = (CCompositeFont) font;
CFont mainFont = (CFont) font.getSlotFont(0);
String[] fallbackFontInfo = new String[2];
int glyphCode = nativeCodePointToGlyph(mainFont.getNativeFontPtr(), unicode, fallbackFontInfo);
if (glyphCode == missingGlyph) {
setCachedGlyphCode(unicode, missingGlyph);
return missingGlyph;
}
String fallbackFontName = fallbackFontInfo[0];
String fallbackFontFamilyName = fallbackFontInfo[1];
if (fallbackFontName == null || fallbackFontFamilyName == null) {
int result = compositeGlyphCode(0, glyphCode);
setCachedGlyphCode(unicode, result);
return result;
}
int slot = compositeFont.findSlot(fallbackFontName);
if (slot < 0) {
Font2D fallbackFont = FontManagerFactory.getInstance().findFont2D(fallbackFontName,
Font.PLAIN, FontManager.NO_FALLBACK);
if (!(fallbackFont instanceof CFont) ||
!fallbackFontName.equals(((CFont) fallbackFont).getNativeFontName())) {
// Native font fallback mechanism can return "hidden" fonts - their names start with dot,
// and they are not returned in a list of fonts available in system, but they can still be used
// if requested explicitly.
fallbackFont = new CFont(fallbackFontName, fallbackFontFamilyName, null);
}
if (mainFont.isFakeItalic()) fallbackFont = ((CFont)fallbackFont).createItalicVariant(false);
slot = compositeFont.addSlot((CFont) fallbackFont);
}
int result = compositeGlyphCode(slot, glyphCode);
setCachedGlyphCode(unicode, result);
return result;
}
// This invokes native font fallback mechanism, returning information about font (its Postscript and family names)
// able to display a given character, and corresponding glyph code
private static native int nativeCodePointToGlyph(long nativeFontPtr, int codePoint, String[] result);
}

View File

@@ -31,6 +31,9 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;
// Right now this class is final to avoid a problem with native code.
// For some reason the JNI IsInstanceOf was not working correctly
@@ -175,14 +178,12 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
isFakeItalic = other.isFakeItalic;
}
public CFont createItalicVariant(boolean updateStyle) {
public CFont createItalicVariant() {
CFont font = new CFont(this, familyName);
font.nativeFontName = fullName;
font.fullName =
fullName + (style == Font.BOLD ? "" : "-") + "Italic-Derived";
if (updateStyle) {
font.style |= Font.ITALIC;
}
font.style |= Font.ITALIC;
font.isFakeItalic = true;
return font;
}
@@ -204,11 +205,45 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return getCGFontPtrNative(getNativeFontPtr());
}
static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);
private CompositeFont createCompositeFont() {
ArrayList<String> listOfString = new ArrayList<String>();
getCascadeList(getNativeFontPtr(), listOfString);
Set<String> components = new LinkedHashSet<>(listOfString);
// In some italic cases the standard Mac cascade list is missing Arabic.
components.add("GeezaPro");
CFontManager fm = (CFontManager) FontManagerFactory.getInstance();
components.addAll(fm.getAdditionalFallbackVariants());
int numFonts = 1 + components.size();
PhysicalFont[] fonts = new PhysicalFont[numFonts];
fonts[0] = this;
int idx = 1;
for (String s : components) {
if (s.equals(".AppleSymbolsFB")) {
// Don't know why we get the weird name above .. replace.
s = "AppleSymbols";
}
Font2D f2d = fm.getOrCreateFallbackFont(s);
if (f2d == null || f2d == this) {
continue;
}
fonts[idx++] = (PhysicalFont)f2d;
}
if (idx < fonts.length) {
PhysicalFont[] orig = fonts;
fonts = new PhysicalFont[idx];
System.arraycopy(orig, 0, fonts, 0, idx);
}
return new CompositeFont(fonts);
}
private CompositeFont compFont;
public CompositeFont getCompositeFont2D() {
if (compFont == null) {
compFont = new CCompositeFont(this);
compFont = createCompositeFont();
}
return compFont;
}
@@ -236,14 +271,6 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return new CStrike(this, desc);
}
boolean isFakeItalic() {
return isFakeItalic;
}
String getNativeFontName() {
return nativeFontName;
}
@Override
public String getTypographicSubfamilyName() {
return faceName == null ? super.getTypographicSubfamilyName() : faceName;
@@ -276,8 +303,4 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
", familyName: " + familyName + ", style: " + style +
" } aka: " + super.toString();
}
public Font2D createItalic() {
return this.createItalicVariant(true);
}
}

View File

@@ -30,20 +30,27 @@ import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.plaf.FontUIResource;
import sun.awt.FontConfiguration;
import sun.awt.HeadlessToolkit;
import sun.lwawt.macosx.*;
import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
public final class CFontManager extends SunFontManager {
private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
private final Map<String, Font2D> fallbackFonts = new ConcurrentHashMap<>();
private final List<String> extFallbackVariants = new ArrayList<>();
@Override
protected FontConfiguration createFontConfiguration() {
@@ -226,6 +233,7 @@ public final class CFontManager extends SunFontManager {
public Object run() {
if (!loadedAllFonts) {
loadNativeFonts();
collectAdditionalFallbackVariants();
loadedAllFonts = true;
}
return null;
@@ -322,4 +330,39 @@ public final class CFontManager extends SunFontManager {
@Override
protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap,
HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {}
private void collectAdditionalFallbackVariants() {
if (AccessController.doPrivileged(new GetBooleanAction("mac.ext.font.fallback"))) {
for (String fontName : genericFonts.keySet()) {
boolean accept = false;
if (fontName.equals("ArialUnicodeMS")) {
accept = true;
} else if (fontName.startsWith("NotoSans")) {
int pos = fontName.indexOf('-');
accept = pos == -1 || fontName.substring(pos + 1).equals("Regular");
}
if (accept) {
extFallbackVariants.add(fontName);
}
}
Collections.sort(extFallbackVariants); // ensure predictable order
}
}
List<String> getAdditionalFallbackVariants() {
return extFallbackVariants;
}
Font2D getOrCreateFallbackFont(String fontName) {
Font2D font2D = findFont2D(fontName, Font.PLAIN, FontManager.NO_FALLBACK);
if (font2D != null || fontName.startsWith(".")) {
return font2D;
} else {
// macOS doesn't list some system fonts in [NSFontManager availableFontFamilies] output,
// so they are not registered in font manager as part of 'loadNativeFonts'.
// These fonts are present in [NSFontManager availableFonts] output though,
// and can be accessed in the same way as other system fonts.
return fallbackFonts.computeIfAbsent(fontName, name -> new CFont(name, null, null));
}
}
}

View File

@@ -360,18 +360,14 @@ public final class CStrike extends PhysicalStrike {
}
}
// This class stores glyph pointers, and is indexed based on glyph codes,
// and negative unicode values. See the comments in
// CCharToGlyphMapper for more details on our glyph code strategy.
// This class stores glyph pointers, and is indexed based on glyph codes.
private static class GlyphInfoCache extends CStrikeDisposer {
private static final int FIRST_LAYER_SIZE = 256;
private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
// rdar://problem/5204197
private final AtomicBoolean disposed = new AtomicBoolean(false);
private final long[] firstLayerCache;
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Long> generalCache;
GlyphInfoCache(final Font2D nativeFont, final FontStrikeDesc desc) {
@@ -380,19 +376,9 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized long get(final int index) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
return 0L;
}
return secondLayerCache.get(-index);
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (generalCache == null) {
@@ -406,21 +392,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final long value) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
}
secondLayerCache.put(-index, value);
return;
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (generalCache == null) {
@@ -443,14 +418,6 @@ public final class CStrike extends PhysicalStrike {
// clean out the first array
disposeLongArray(firstLayerCache);
// clean out the two layer arrays
if (secondLayerCache != null) {
final long[][] secondLayerLongArrayArray = secondLayerCache.cache;
for (final long[] longArray : secondLayerLongArrayArray) {
if (longArray != null) disposeLongArray(longArray);
}
}
// clean up everyone else
if (generalCache != null) {
for (Long aLong : generalCache.values()) {
@@ -492,42 +459,12 @@ public final class CStrike extends PhysicalStrike {
}
}
}
private static class SparseBitShiftingTwoLayerArray {
final long[][] cache;
final int shift;
final int secondLayerLength;
SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new long[1 << shift][];
this.secondLayerLength = size >> shift;
}
public long get(final int index) {
final int firstIndex = index >> shift;
final long[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) return 0L;
return firstLayerRow[index - (firstIndex * (1 << shift))];
}
public void put(final int index, final long value) {
final int firstIndex = index >> shift;
long[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) {
cache[firstIndex] = firstLayerRow = new long[secondLayerLength];
}
firstLayerRow[index - (firstIndex * (1 << shift))] = value;
}
}
}
private static class GlyphAdvanceCache {
private static final int FIRST_LAYER_SIZE = 256;
private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
private final float[] firstLayerCache = new float[FIRST_LAYER_SIZE];
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Float> generalCache;
// Empty non private constructor was added because access to this
@@ -537,17 +474,9 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized float get(final int index) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) return 0;
return secondLayerCache.get(-index);
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (generalCache == null) return 0;
@@ -557,21 +486,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final float value) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
}
secondLayerCache.put(-index, value);
return;
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (generalCache == null) {
@@ -580,34 +498,5 @@ public final class CStrike extends PhysicalStrike {
generalCache.put(Integer.valueOf(index), Float.valueOf(value));
}
private static class SparseBitShiftingTwoLayerArray {
final float[][] cache;
final int shift;
final int secondLayerLength;
SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new float[1 << shift][];
this.secondLayerLength = size >> shift;
}
public float get(final int index) {
final int firstIndex = index >> shift;
final float[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) return 0L;
return firstLayerRow[index - (firstIndex * (1 << shift))];
}
public void put(final int index, final float value) {
final int firstIndex = index >> shift;
float[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) {
cache[firstIndex] = firstLayerRow =
new float[secondLayerLength];
}
firstLayerRow[index - (firstIndex * (1 << shift))] = value;
}
}
}
}

View File

@@ -1245,23 +1245,6 @@ public class LWWindowPeer
return false;
}
AppContext targetAppContext = AWTAccessor.getComponentAccessor().getAppContext(getTarget());
KeyboardFocusManager kfm = AWTAccessor.getKeyboardFocusManagerAccessor()
.getCurrentKeyboardFocusManager(targetAppContext);
Window currentActive = kfm.getActiveWindow();
Window opposite = LWKeyboardFocusManagerPeer.getInstance().
getCurrentFocusedWindow();
// In case the toplevel is active but not focused, change focus directly,
// as requesting native focus on it will not have effect.
if (getTarget() == currentActive && !getTarget().hasFocus()) {
changeFocusedWindow(true, opposite);
return true;
}
return platformWindow.requestWindowFocus();
}

View File

@@ -25,14 +25,14 @@
package sun.lwawt.macosx;
import java.awt.Component;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.security.PrivilegedAction;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -48,6 +48,20 @@ import sun.awt.AWTAccessor;
class CAccessible extends CFRetainedResource implements Accessible {
private static Timer timer = null;
private final static int SELECTED_CHILDREN_MILLISECONDS_DEFAULT = 100;
private static int SELECTED_CHILDREN_MILLISECONDS;
static {
int scms = java.security.AccessController.doPrivileged(new PrivilegedAction<Integer>() {
@Override
public Integer run() {
return Integer.getInteger("sun.lwawt.macosx.CAccessible.selectedChildrenMilliSeconds",
SELECTED_CHILDREN_MILLISECONDS_DEFAULT);
}
});
SELECTED_CHILDREN_MILLISECONDS = scms >= 0 ? scms : SELECTED_CHILDREN_MILLISECONDS_DEFAULT;
}
public static CAccessible getCAccessible(final Accessible a) {
if (a == null) return null;
@@ -120,23 +134,29 @@ class CAccessible extends CFRetainedResource implements Accessible {
@Override
public void propertyChange(PropertyChangeEvent e) {
assert EventQueue.isDispatchThread();
String name = e.getPropertyName();
if ( ptr != 0 ) {
Object newValue = e.getNewValue();
Object oldValue = e.getOldValue();
if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) {
selectedTextChanged(ptr);
execute(ptr -> selectedTextChanged(ptr));
} else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
valueChanged(ptr);
execute(ptr -> valueChanged(ptr));
} else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) {
selectionChanged(ptr);
if (timer != null) {
timer.stop();
}
timer = new Timer(SELECTED_CHILDREN_MILLISECONDS, actionEvent -> execute(ptr -> selectionChanged(ptr)));
timer.setRepeats(false);
timer.start();
} else if (name.compareTo(ACCESSIBLE_TABLE_MODEL_CHANGED) == 0) {
valueChanged(ptr);
execute(ptr -> valueChanged(ptr));
if (CAccessible.getSwingAccessible(CAccessible.this) != null) {
Accessible a = CAccessible.getSwingAccessible(CAccessible.this);
AccessibleContext ac = a.getAccessibleContext();
if ((ac != null) && (ac.getAccessibleRole() == AccessibleRole.TABLE)) {
tableContentCacheClear(ptr);
execute(ptr -> tableContentCacheClear(ptr));
}
}
} else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
@@ -151,25 +171,33 @@ class CAccessible extends CFRetainedResource implements Accessible {
if (parentAccessible != null) {
parentRole = parentAccessible.getAccessibleContext().getAccessibleRole();
}
if (thisRole == AccessibleRole.COMBO_BOX) {
if (timer != null) {
timer.stop();
}
timer = new Timer(SELECTED_CHILDREN_MILLISECONDS, actionEvent -> execute(ptr -> selectionChanged(ptr)));
timer.setRepeats(false);
timer.start();
}
// At least for now don't handle combo box menu state changes.
// This may change when later fixing issues which currently
// exist for combo boxes, but for now the following is only
// for JPopupMenus, not for combobox menus.
if (parentRole != AccessibleRole.COMBO_BOX) {
//if (parentRole != AccessibleRole.COMBO_BOX) {
if (thisRole == AccessibleRole.POPUP_MENU) {
if ( newValue != null &&
((AccessibleState)newValue) == AccessibleState.VISIBLE ) {
menuOpened(ptr);
execute(ptr -> menuOpened(ptr));
} else if ( oldValue != null &&
((AccessibleState)oldValue) == AccessibleState.VISIBLE ) {
menuClosed(ptr);
execute(ptr -> menuClosed(ptr));
}
} else if (thisRole == AccessibleRole.MENU_ITEM) {
if ( newValue != null &&
((AccessibleState)newValue) == AccessibleState.FOCUSED ) {
menuItemSelected(ptr);
execute(ptr -> menuItemSelected(ptr));
}
}
//}
}
}
}

View File

@@ -109,6 +109,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native void nativeExitFullScreenMode(long nsWindowPtr);
static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native boolean nativeDelayShowing(long nsWindowPtr);
private static native void nativeRaiseLevel(long nsWindowPtr, boolean popup, boolean onlyIfParentIsActive);
// Loger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
@@ -1432,10 +1433,10 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
}
protected void applyWindowLevel(Window target) {
if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSFloatingWindowLevel));
} else if (target.getType() == Window.Type.POPUP) {
execute(ptr->CWrapper.NSWindow.setLevel(ptr, CWrapper.NSWindow.NSPopUpMenuWindowLevel));
boolean popup = target.getType() == Window.Type.POPUP;
boolean alwaysOnTop = target.isAlwaysOnTop();
if (popup || alwaysOnTop || owner != null) {
execute(ptr -> nativeRaiseLevel(ptr, popup, !popup && !alwaysOnTop));
}
}

View File

@@ -1961,6 +1961,29 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeRaiseLevel
(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean popup, jboolean onlyIfParentIsActive)
{
JNI_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
if (onlyIfParentIsActive) {
AWTWindow *parent = window;
do {
parent = parent.ownerWindow;
} while (parent != nil && !parent.nsWindow.isMainWindow);
if (parent == nil) {
return;
}
}
[nsWindow setLevel: popup ? NSPopUpMenuWindowLevel : NSFloatingWindowLevel];
}];
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeDelayShowing

View File

@@ -41,51 +41,6 @@ static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
#pragma mark --- CoreText Support ---
// Translates a Unicode into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyphRef"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, charRef, count);
if (fallback == NULL)
{
// use the original font if we somehow got duped into trying to fallback something we can't
fallback = (CTFontRef)font->fFont;
CFRetain(fallback);
}
CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
return fallback;
}
// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyph"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForJavaGlyphCode
(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
{
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
if (glyphCode >= 0)
{
*glyphRef = glyphCode;
CFRetain(font->fFont);
return (CTFontRef)font->fFont;
}
UTF16Char character = -glyphCode;
return JavaCT_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
}
// Breakup a 32 bit unicode value into the component surrogate pairs
void JavaCT_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
int value = uniChar - 0x10000;
UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
charRef[0] = high_surrogate;
charRef[1] = low_surrogate;
}
/*
* Callback for CoreText which uses the CoreTextProviderStruct to feed CT UniChars
* We only use it for one-off lines, and don't attempt to fragment our strings
@@ -129,7 +84,7 @@ static NSDictionary* ctsDictionaryFor(const NSFont *font, BOOL useFractionalMetr
// Itterates though each glyph, and if a transform is present for that glyph, apply it to the CGContext, and strike the glyph.
// If there is no per-glyph transform, just strike the glyph. Advances must also be transformed on-the-spot as well.
void JavaCT_DrawGlyphVector
(const QuartzSDOps *qsdo, const AWTStrike *strike, const BOOL useSubstituion, const int uniChars[], const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
(const QuartzSDOps *qsdo, const AWTStrike *strike, const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
{
CGPoint pt = { 0, 0 };
@@ -137,49 +92,12 @@ void JavaCT_DrawGlyphVector
CGContextRef cgRef = qsdo->cgRef;
CGAffineTransform ctmText = CGContextGetTextMatrix(cgRef);
BOOL saved = false;
CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSInteger i;
for (i = 0; i < length; i++)
{
CGGlyph glyph = glyphs[i];
int uniChar = uniChars[i];
// if we found a unichar instead of a glyph code, get the fallback font,
// find the glyph code for the fallback font, and set the font on the current context
if (uniChar != 0)
{
CTFontRef fallback;
if (uniChar > 0xFFFF) {
UTF16Char charRef[2];
JavaCT_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
CGGlyph glyphTmp[2];
fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
glyph = glyphTmp[0];
} else {
const UTF16Char u = uniChar;
fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, &u, (CGGlyph *)&glyph, 1);
}
if (fallback) {
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CFRelease(fallback);
if (cgFallback) {
if (!saved) {
CGContextSaveGState(cgRef);
saved = true;
}
CGContextSetFont(cgRef, cgFallback);
CFRelease(cgFallback);
}
}
} else {
if (saved) {
CGContextRestoreGState(cgRef);
saved = false;
}
}
// if we have per-glyph transformations
int tin = (g_gvTXIndicesAsInts == NULL) ? -1 : (g_gvTXIndicesAsInts[i] - 1) * 6;
@@ -214,10 +132,6 @@ void JavaCT_DrawGlyphVector
pt.y += advances[i].height;
}
// reset the font on the context after striking a unicode with CoreText
if (saved) {
CGContextRestoreGState(cgRef);
}
}
// Using the Quartz Surface Data context, draw a hot-substituted character run
@@ -327,24 +241,16 @@ static jclass jc_StandardGlyphVector = NULL;
// Checks the GlyphVector Java object for any transforms that were applied to individual characters. If none are present,
// strike the glyphs immediately in Core Graphics. Otherwise, obtain the arrays, and defer to above.
static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, BOOL useSubstituion, int *uniChars, CGGlyph *glyphs, CGSize *advances, size_t length)
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length)
{
// if we have no character substitution, and no per-glyph transformations - strike now!
// if we have no per-glyph transformations - strike now!
GET_SGV_CLASS();
DECLARE_FIELD(jm_StandardGlyphVector_gti, jc_StandardGlyphVector, "gti", "Lsun/font/StandardGlyphVector$GlyphTransformInfo;");
jobject gti = (*env)->GetObjectField(env, gVector, jm_StandardGlyphVector_gti);
if (gti == 0)
{
if (useSubstituion)
{
// quasi-simple case, substitution, but no per-glyph transforms
JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length);
}
else
{
// fast path, straight to CG without per-glyph transforms
CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
}
// fast path, straight to CG without per-glyph transforms
CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
return;
}
@@ -369,8 +275,8 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
return;
}
// slowest case, we have per-glyph transforms, and possibly glyph substitution as well
JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
// slowest case, we have per-glyph transforms
JavaCT_DrawGlyphVector(qsdo, strike, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT);
@@ -379,35 +285,11 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
}
// Retrieves advances for translated unicodes
// Uses "glyphs" as a temporary buffer for the glyph-to-unicode translation
void JavaCT_GetAdvancesForUnichars
(const NSFont *font, const int uniChars[], CGGlyph glyphs[], const size_t length, CGSize advances[])
{
// cycle over each spot, and if we discovered a unicode to substitute, we have to calculate the advance for it
size_t i;
for (i = 0; i < length; i++)
{
UniChar uniChar = uniChars[i];
if (uniChar == 0) continue;
CGGlyph glyph = 0;
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font, &uniChar, 1);
if (fallback) {
CTFontGetGlyphsForCharacters(fallback, &uniChar, &glyph, 1);
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &(advances[i]), 1);
CFRelease(fallback);
}
glyphs[i] = glyph;
}
}
// Fills the glyph buffer with glyphs from the GlyphVector object. Also checks to see if the glyph's positions have been
// already caculated from GlyphVector, or we simply ask Core Graphics to make some advances for us. Pre-calculated positions
// are translated into advances, since CG only understands advances.
static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, int *uniChars, CGSize *advances, size_t length, jintArray glyphsArray)
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length, jintArray glyphsArray)
{
// fill the glyph buffer
jint *glyphsAsInts = (*env)->GetPrimitiveArrayCritical(env, glyphsArray, NULL);
@@ -415,24 +297,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
return;
}
// if a glyph code from Java is negative, that means it is really a unicode value
// which we can use in CoreText to strike the character in another font
size_t i;
BOOL complex = NO;
for (i = 0; i < length; i++)
{
jint code = glyphsAsInts[i];
if (code < 0)
{
complex = YES;
uniChars[i] = -code;
glyphs[i] = 0;
}
else
{
uniChars[i] = 0;
glyphs[i] = code;
}
glyphs[i] = glyphsAsInts[i];
}
(*env)->ReleasePrimitiveArrayCritical(env, glyphsArray, glyphsAsInts, JNI_ABORT);
@@ -483,15 +351,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
// there were no pre-calculated positions from the glyph buffer on the Java side
AWTFont *awtFont = strike->fAWTFont;
CTFontGetAdvancesForGlyphs((CTFontRef)awtFont->fFont, kCTFontDefaultOrientation, glyphs, advances, length);
if (complex)
{
JavaCT_GetAdvancesForUnichars(awtFont->fFont, uniChars, glyphs, length, advances);
}
}
// continue on to the next stage of the pipe
doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, complex, uniChars, glyphs, advances, length);
doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, glyphs, advances, length);
}
// Obtains the glyph array to determine the number of glyphs we are dealing with. If we are dealing a large number of glyphs,
@@ -515,18 +378,16 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
// if we are small enough, fit everything onto the stack
CGGlyph glyphs[length];
int uniChars[length];
CGSize advances[length];
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
}
else
{
// otherwise, we should malloc and free buffers for this large run
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * length);
int *uniChars = (int *)malloc(sizeof(int) * length);
CGSize *advances = (CGSize *)malloc(sizeof(CGSize) * length);
if (glyphs == NULL || uniChars == NULL || advances == NULL)
if (glyphs == NULL || advances == NULL)
{
(*env)->DeleteLocalRef(env, glyphsArray);
[NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__];
@@ -534,10 +395,6 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
free(glyphs);
}
if (uniChars)
{
free(uniChars);
}
if (advances)
{
free(advances);
@@ -545,10 +402,9 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
return;
}
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
free(glyphs);
free(uniChars);
free(advances);
}

View File

@@ -21,9 +21,7 @@ static jmethodID sjm_getAccessibleSelection = NULL;
@implementation JavaComboBoxAccessibility
// NSAccessibilityElement protocol methods
- (id)accessibilityValue {
- (JavaComponentAccessibility *)accessibleSelection {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
if (axContext == NULL) return nil;
@@ -42,17 +40,17 @@ static jmethodID sjm_getAccessibleSelection = NULL;
if (axSelectedChild == NULL) {
return nil;
}
GET_ACCESSIBLENAME_METHOD_RETURN(nil);
jobject childName = (*env)->CallStaticObjectMethod(env, sjc_CAccessibility, sjm_getAccessibleName, axSelectedChild, fComponent);
CHECK_EXCEPTION();
if (childName == NULL) {
(*env)->DeleteLocalRef(env, axSelectedChild);
return nil;
}
NSString *selectedText = JavaStringToNSString(env, childName);
(*env)->DeleteLocalRef(env, axSelectedChild);
(*env)->DeleteLocalRef(env, childName);
return selectedText;
return [JavaComponentAccessibility createWithAccessible:axSelectedChild withEnv:env withView:fView];
}
// NSAccessibilityElement protocol methods
- (id)accessibilityValue {
return [[self accessibleSelection] accessibilityLabel];
}
- (NSArray *)accessibilitySelectedChildren {
return [NSArray arrayWithObject:[self accessibleSelection]];
}
@end

View File

@@ -528,7 +528,11 @@ static NSString* parentRole(NSAccessibilityRole nsRole)
return NO;
}
return isChildSelected(env, ((JavaComponentAccessibility *)[self parent])->fAccessible, fIndex, fComponent);
id parent = [self parent];
if ([parent isKindOfClass:[JavaComponentAccessibility class]]) {
return isChildSelected(env, ((JavaComponentAccessibility *)parent)->fAccessible, fIndex, fComponent);
}
return NO;
}
- (BOOL)isSelectable:(JNIEnv *)env
@@ -764,7 +768,7 @@ static NSString* parentRole(NSAccessibilityRole nsRole)
point.y += size.height;
// Now make it into Cocoa screen coords.
point.y = [[[[self view] window] screen] frame].size.height - point.y;
point.y = [[NSScreen screens][0] frame].size.height - point.y;
return NSMakeRect(point.x, point.y, size.width, size.height);
}
@@ -1081,7 +1085,7 @@ static NSNumber* JavaNumberToNSNumber(JNIEnv *env, jobject jnumber) {
"(Ljava/awt/Container;FF)Ljavax/accessibility/Accessible;", nil);
// Make it into java screen coords
point.y = [[[[self view] window] screen] frame].size.height - point.y;
point.y = [[NSScreen screens][0] frame].size.height - point.y;
jobject jparent = fComponent;

View File

@@ -26,10 +26,13 @@ static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject componen
- (jobject)tabGroup {
if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext);
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, tabGroupAxContext);
id parent = [self parent];
if ([parent isKindOfClass:[JavaComponentAccessibility class]]) {
jobject tabGroupAxContext = [(JavaComponentAccessibility *)parent axContextWithEnv:env];
fTabGroupAxContext = (*env)->NewWeakGlobalRef(env, tabGroupAxContext);
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, tabGroupAxContext);
}
}
return fTabGroupAxContext;
}

View File

@@ -83,10 +83,11 @@ static NSString* uiBoldName = nil;
(uiBoldName != nil && [name isEqualTo:uiBoldName])) {
if (style & java_awt_Font_BOLD) {
nsFont = [NSFont boldSystemFontOfSize:1.0];
nsFallbackBase = [NSFont fontWithName:@"LucidaGrande-Bold" size:1.0];
} else {
nsFont = [NSFont systemFontOfSize:1.0];
nsFallbackBase = [NSFont fontWithName:@"LucidaGrande" size:1.0];
}
nsFallbackBase = [NSFont fontWithName:@"Lucida Grande" size:1.0];
#ifdef DEBUG
NSLog(@"nsFont-name is : %@", nsFont.familyName);
NSLog(@"nsFont-family is : %@", nsFont.fontName);
@@ -3350,3 +3351,61 @@ Java_sun_awt_FontDescriptor_initIDs
{
}
#endif
/*
* Class: sun_font_CFont
* Method: getCascadeList
* Signature: (JLjava/util/ArrayList;)V
*/
JNIEXPORT void JNICALL
Java_sun_font_CFont_getCascadeList
(JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
{
JNI_COCOA_ENTER(env);
jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
if (alc == NULL) return;
jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
if (addMID == NULL) return;
CFIndex i;
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
NSFont* nsFont = awtFont->fFont;
#ifdef DEBUG
CFStringRef base = CTFontCopyFullName((CTFontRef)nsFont);
NSLog(@"BaseFont is : %@", (NSString*)base);
CFRelease(base);
#endif
bool anotherBaseFont = false;
if (awtFont->fFallbackBase != nil) {
nsFont = awtFont->fFallbackBase;
anotherBaseFont = true;
}
CTFontRef font = (CTFontRef)nsFont;
CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
CFRelease(codes);
CFIndex cnt = CFArrayGetCount(fds);
for (i= anotherBaseFont ? -1 : 0; i<cnt; i++) {
CFStringRef fontname;
if (i < 0) {
fontname = CTFontCopyPostScriptName(font);
} else {
CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
fontname = CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
}
#ifdef DEBUG
NSLog(@"Font is : %@", (NSString*)fontname);
#endif
jstring jFontName = (jstring)NSStringToJavaString(env, fontname);
CFRelease(fontname);
(*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);
if ((*env)->ExceptionOccurred(env)) {
CFRelease(fds);
return;
}
(*env)->DeleteLocalRef(env, jFontName);
}
CFRelease(fds);
JNI_COCOA_EXIT(env);
}

View File

@@ -28,7 +28,6 @@
#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h"
#import "CGGlyphOutlines.h"
#import "CoreTextSupport.h"
#import "JNIUtilities.h"
#include "fontscalerdefs.h"
#import "LWCToolkit.h"
@@ -160,24 +159,19 @@ JNI_COCOA_ENTER(env);
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
AWTFont *awtFont = awtStrike->fAWTFont;
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
CGGlyph glyph;
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
if (IS_OSX_GT10_13 || CGGI_IsColorFont(cgFallback)) {
CGGlyph glyph = glyphCode;
const CGFontRef cgFont = awtFont->fNativeCGFont;
if (IS_OSX_GT10_13 || CGGI_IsColorFont(cgFont)) {
CGAffineTransform matrix = awtStrike->fAltTx;
CGFloat fontSize = sqrt(fabs(matrix.a * matrix.d - matrix.b * matrix.c));
CTFontRef font = CTFontCreateWithGraphicsFont(cgFallback, fontSize, NULL, NULL);
CTFontRef font = CTFontCreateWithGraphicsFont(cgFont, fontSize, NULL, NULL);
CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
CFRelease(font);
advance.width /= fontSize;
advance.height /= fontSize;
} else {
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
CTFontGetAdvancesForGlyphs((CTFontRef)awtFont->fFont, kCTFontDefaultOrientation, &glyph, &advance, 1);
}
CFRelease(cgFallback);
CFRelease(fallback);
advance = CGSizeApplyAffineTransform(advance, awtStrike->fFontTx);
if (!JRSFontStyleUsesFractionalMetrics(awtStrike->fStyle)) {
advance.width = round(advance.width);
@@ -207,14 +201,9 @@ JNI_COCOA_ENTER(env);
tx.tx += x;
tx.ty += y;
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
CGGlyph glyph;
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
CGRect bbox;
JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, awtStrike->fStyle, &glyph, 1, &bbox);
CFRelease(fallback);
JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)awtFont->fFont, &tx, awtStrike->fStyle, &glyph, 1, &bbox);
// the origin of this bounding box is relative to the bottom-left corner baseline
CGFloat decender = -bbox.origin.y;
@@ -263,14 +252,12 @@ AWT_FONT_CLEANUP_CHECK(awtfont);
tx.tx += xPos;
tx.ty += yPos;
// get the right font and glyph for this "Java GlyphCode"
CGGlyph glyph;
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtfont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
NSFont *font = awtfont->fFont;
// get the advance of this glyph
CGSize advance;
CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
CTFontGetAdvancesForGlyphs((CTFontRef)font, kCTFontDefaultOrientation, &glyph, &advance, 1);
// Create AWTPath
path = AWTPathCreate(CGSizeMake(xPos, yPos));
@@ -279,8 +266,7 @@ AWT_FONT_CLEANUP_CHECK(path);
// Get the paths
tx = awtStrike->fTx;
tx = CGAffineTransformConcat(tx, sInverseTX);
AWTGetGlyphOutline(&glyph, (NSFont *)font, &advance, &tx, 0, 1, &path);
CFRelease(font);
AWTGetGlyphOutline(&glyph, font, &advance, &tx, 0, 1, &path);
pointCoords = (*env)->NewFloatArray(env, path->fNumberOfDataElements);
AWT_FONT_CLEANUP_CHECK(pointCoords);
@@ -334,19 +320,14 @@ JNIEXPORT void JNICALL Java_sun_font_CStrike_getNativeGlyphOutlineBounds
AWT_FONT_CLEANUP_SETUP;
AWT_FONT_CLEANUP_CHECK(awtfont);
// get the right font and glyph for this "Java GlyphCode"
CGGlyph glyph;
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(
awtfont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
CGRect bbox = CTFontGetBoundingRectsForGlyphs(
font, kCTFontOrientationDefault, &glyph, NULL, 1);
(CTFontRef)awtfont->fFont, kCTFontOrientationDefault, &glyph, NULL, 1);
CGAffineTransform tx = CGAffineTransformConcat(awtStrike->fTx,
sInverseTX);
bbox = CGRectApplyAffineTransform (bbox, tx);
CFRelease(font);
jfloat *rawRectData =
(*env)->GetPrimitiveArrayCritical(env, rectData, NULL);

View File

@@ -29,7 +29,6 @@
#import "CoreTextSupport.h"
#import "sun_font_CCharToGlyphMapper.h"
#import "sun_font_CCompositeGlyphMapper.h"
/*
* Class: sun_font_CCharToGlyphMapper
@@ -114,28 +113,3 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_font_CCompositeGlyphMapper
* Method: nativeCodePointToGlyph
* Signature: (JI[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL
Java_sun_font_CCompositeGlyphMapper_nativeCodePointToGlyph
(JNIEnv *env, jclass clazz, jlong awtFontPtr, jint codePoint, jobjectArray resultArray)
{
JNI_COCOA_ENTER(env);
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
CFStringRef fontNames[] = {NULL, NULL};
CGGlyph glyph = CTS_CopyGlyphAndFontNamesForCodePoint(awtFont, (UnicodeScalarValue)codePoint, fontNames);
if (glyph > 0) {
jstring fontName = (jstring)NSStringToJavaString(env, (NSString *)fontNames[0]);
(*env)->SetObjectArrayElement(env, resultArray, 0, fontName);
jstring fontFamilyName = (jstring)NSStringToJavaString(env, (NSString *)fontNames[1]);
(*env)->SetObjectArrayElement(env, resultArray, 1, fontFamilyName);
}
if (fontNames[0]) CFRelease(fontNames[0]);
if (fontNames[1]) CFRelease(fontNames[1]);
return glyph;
JNI_COCOA_EXIT(env);
}

View File

@@ -27,7 +27,6 @@
#import "JNIUtilities.h"
#import "CGGlyphImages.h"
#import "CoreTextSupport.h"
#import "fontscalerdefs.h" // contains the definition of GlyphInfo struct
#import "sun_awt_SunHints.h"
@@ -687,6 +686,7 @@ CGGI_CreateImageForGlyph
// clean the canvas
CGGI_ClearCanvas(canvas, info, glyphDescriptor == &argb);
CGContextSetShouldAntialias(canvas->context, strike->fAAStyle != sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_OFF);
// strike the glyph in the upper right corner
CGFloat x = -info->topLeftX;
@@ -758,80 +758,6 @@ CGGI_CreateImageForGlyph
/*
* CoreText path...
*/
static inline GlyphInfo *
CGGI_CreateImageForUnicode
(CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar,
const bool isCatalinaOrAbove)
{
// save the graphics state
CGContextSaveGState(canvas->context);
// text matrix is not considered part of graphics state
CGAffineTransform originalTx = CGContextGetTextMatrix(canvas->context);
// get the glyph, measure it using CG
CGGlyph glyph;
CTFontRef fallback;
if (uniChar > 0xFFFF) {
UTF16Char charRef[2];
CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
CGGlyph glyphTmp[2];
fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
glyph = glyphTmp[0];
} else {
UTF16Char charRef;
charRef = (UTF16Char) uniChar; // truncate.
fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
}
JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, cgFallback);
bool subpixelResolution = mode->subpixelResolution && glyphDescriptor == &grey;
CGRect bbox;
JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &strike->fTx, style, &glyph, 1, &bbox);
CGSize advance;
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
// create the Sun2D GlyphInfo we are going to strike into
GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor, subpixelResolution);
// fix the context size, just in case the substituted character is unexpectedly large
CGGI_SizeCanvas(canvas, info->width * info->subpixelResolutionX, info->height * info->subpixelResolutionY, mode);
// align the transform for the real CoreText strike
CGContextSetTextMatrix(canvas->context, strike->fAltTx);
CGContextSetFont(canvas->context, cgFallback);
CFRelease(cgFallback);
// clean the canvas - align, strike, and copy the glyph from the canvas into the info
CGGI_CreateImageForGlyph(cgFallback, canvas, glyph, info, glyphDescriptor, strike, isCatalinaOrAbove);
// restore graphics state
CGContextRestoreGState(canvas->context);
CGContextSetTextMatrix(canvas->context, originalTx);
CFRelease(fallback);
#ifdef CGGI_DEBUG
DUMP_GLYPHINFO(info);
#endif
#ifdef CGGI_DEBUG_DUMP
DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
#if 0
PRINT_CGSTATES_INFO(NULL);
#endif
#endif
return info;
}
#pragma mark --- GlyphInfo Filling and Canvas Managment ---
@@ -846,7 +772,6 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jlong glyphInfos[],
const UnicodeScalarValue uniChars[],
const CGGlyph glyphs[],
const CFIndex len)
{
@@ -859,13 +784,8 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
CFIndex i;
for (i = 0; i < len; i++) {
GlyphInfo *info = (GlyphInfo *)jlong_to_ptr(glyphInfos[i]);
if (info != NULL) {
CGGI_CreateImageForGlyph(strike->fAWTFont->fNativeCGFont,
canvas, glyphs[i], info, mode->mainFontDescriptor, strike, isMojaveOrAbove);
} else {
info = CGGI_CreateImageForUnicode(canvas, strike, mode, uniChars[i], isMojaveOrAbove);
glyphInfos[i] = ptr_to_jlong(info);
}
CGGI_CreateImageForGlyph(strike->fAWTFont->fNativeCGFont,
canvas, glyphs[i], info, mode->mainFontDescriptor, strike, isMojaveOrAbove);
#ifdef CGGI_DEBUG
DUMP_GLYPHINFO(info);
#endif
@@ -900,7 +820,7 @@ static NSString *threadLocalLCDCanvasKey =
static inline void
CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
const CGGlyph glyphs[],
const size_t maxWidth, const size_t maxHeight,
const CFIndex len)
{
@@ -910,8 +830,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
mode, glyphInfos, uniChars,
glyphs, len);
mode, glyphInfos, glyphs, len);
CGGI_FreeCanvas(tmpCanvas);
[tmpCanvas release];
@@ -931,7 +850,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
glyphInfos, uniChars, glyphs, len);
glyphInfos, glyphs, len);
}
/*
@@ -947,7 +866,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
static inline void
CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
const CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[], const CFIndex len)
{
AWTFont *font = strike->fAWTFont;
@@ -962,12 +881,6 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
CFIndex i;
for (i = 0; i < len; i++)
{
if (uniChars[i] != 0)
{
glyphInfos[i] = 0L;
continue; // will be handled later
}
CGSize advance = advances[i];
CGRect bbox = bboxes[i];
@@ -984,41 +897,29 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
glyphInfos[i] = ptr_to_jlong(glyphInfo);
}
CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
CGGI_FillImagesForGlyphs(glyphInfos, strike, mode,
glyphs, maxWidth, maxHeight, len);
}
#pragma mark --- Temporary Buffer Allocations and Initialization ---
/*
* This stage separates the already valid glyph codes from the unicode values
* that need special handling - the rawGlyphCodes array is no longer used
* after this stage.
*/
static void
CGGI_CreateGlyphsAndScanForComplexities(jlong *glyphInfos,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jint rawGlyphCodes[],
UnicodeScalarValue uniChars[], CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[],
const CFIndex len)
CGGI_CreateGlyphs(jlong *glyphInfos,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jint rawGlyphCodes[],
CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[],
const CFIndex len)
{
CFIndex i;
for (i = 0; i < len; i++) {
jint code = rawGlyphCodes[i];
if (code < 0) {
glyphs[i] = 0;
uniChars[i] = -code;
} else {
glyphs[i] = code;
uniChars[i] = 0;
}
glyphs[i] = rawGlyphCodes[i];
}
CGGI_CreateGlyphInfos(glyphInfos, strike, mode,
uniChars, glyphs, advances, bboxes, len);
glyphs, advances, bboxes, len);
#ifdef CGGI_DEBUG_HIT_COUNT
static size_t hitCount = 0;
@@ -1044,31 +945,29 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
CGRect bboxes[len];
CGSize advances[len];
CGGlyph glyphs[len];
UnicodeScalarValue uniChars[len];
CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
rawGlyphCodes, uniChars, glyphs,
advances, bboxes, len);
CGGI_CreateGlyphs(glyphInfos, strike, &mode,
rawGlyphCodes, glyphs,
advances, bboxes, len);
return;
}
// just do one malloc, and carve it up for all the buffers
void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len);
void *buffer = malloc((sizeof(CGRect) + sizeof(CGSize) + sizeof(CGGlyph)) *
len);
if (buffer == NULL) {
[[NSException exceptionWithName:NSMallocException
reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
}
CGRect *bboxes = (CGRect *)(buffer);
CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len);
CGSize *advances = (CGSize *)(bboxes + len);
CGGlyph *glyphs = (CGGlyph *)(advances + len);
CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
rawGlyphCodes, uniChars, glyphs,
advances, bboxes, len);
CGGI_CreateGlyphs(glyphInfos, strike, &mode,
rawGlyphCodes, glyphs,
advances, bboxes, len);
free(buffer);
}

View File

@@ -31,37 +31,13 @@
#pragma mark --- CoreText Support ---
#define HI_SURROGATE_START 0xD800
#define HI_SURROGATE_END 0xDBFF
#define LO_SURROGATE_START 0xDC00
#define LO_SURROGATE_END 0xDFFF
/*
* Transform Unicode characters into glyphs.
*
* Fills the "glyphsAsInts" array with the glyph codes for the current font,
* or the negative unicode value if we know the character can be hot-substituted.
*
* This is the heart of "Universal Font Substitution" in Java.
* Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count);
// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyph"
CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef);
// Translates a Unicode into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyphRef"
CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count);
// Transform a single Unicode character code into glyph code.
// Names of the relevant font are also returned, if the substitution is used.
// Non-null components of fontNames array should always be released by the calling code, regardless of the returned value.
CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[]);
// Breakup a 32 bit unicode value into the component surrogate pairs
void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]);
// Basic struct that holds everything CoreText is interested in
typedef struct CTS_ProviderStruct {

View File

@@ -88,161 +88,18 @@ ReleaseCTStateDictionary(CFDictionaryRef ctStateDict)
CFRelease(ctStateDict); // GC
}
void GetFontsAndGlyphsForCharacters(CTFontRef font, CTFontRef fallbackBase,
const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[],
CTFontRef actualFonts[], const size_t count)
{
CTFontGetGlyphsForCharacters(font, unicodes, glyphs, count);
if (!fallbackBase) fallbackBase = font;
size_t i;
for (i = 0; i < count; i++) {
UniChar unicode = unicodes[i];
UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0;
bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END
&& nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END;
CGGlyph glyph = glyphs[i];
if (glyph > 0) {
glyphsAsInts[i] = glyph;
if (surrogatePair) i++;
continue;
}
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, &unicodes[i], surrogatePair ? 2 : 1);
if (fallback) {
CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1);
glyph = glyphs[i];
if (actualFonts && glyph > 0) {
actualFonts[i] = fallback;
} else {
CFRelease(fallback);
}
}
if (glyph > 0) {
int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10)
+ nextUnicode - LO_SURROGATE_START + 0x10000 : unicode;
glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value
} else {
glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either
}
if (surrogatePair) i++;
}
}
/*
* Transform Unicode characters into glyphs.
*
* Fills the "glyphsAsInts" array with the glyph codes for the current font,
* or the negative unicode value if we know the character can be hot-substituted.
*
* This is the heart of "Universal Font Substitution" in Java.
* Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters
(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count)
{
GetFontsAndGlyphsForCharacters((CTFontRef)font->fFont, (CTFontRef)font->fFallbackBase,
unicodes, glyphs, glyphsAsInts, NULL, count);
}
CTFontGetGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, count);
/*
* Returns glyph code for a given Unicode character.
* Names of the corresponding substituted font are also returned if substitution is performed.
*/
CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint
(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[])
{
CTFontRef fontRef = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
int count = codePoint >= 0x10000 ? 2 : 1;
UTF16Char unicodes[count];
if (count == 1) {
unicodes[0] = (UTF16Char)codePoint;
} else {
CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, unicodes);
}
CGGlyph glyphs[count];
jint glyphsAsInts[count];
CTFontRef actualFonts[count];
GetFontsAndGlyphsForCharacters(fontRef, fallbackBase, unicodes, glyphs, glyphsAsInts, actualFonts, count);
CGGlyph glyph = glyphs[0];
bool substitutionHappened = glyphsAsInts[0] < 0;
if (glyph > 0 && substitutionHappened) {
CTFontRef actualFont = actualFonts[0];
CFStringRef fontName = CTFontCopyPostScriptName(actualFont);
CFStringRef familyName = CTFontCopyFamilyName(actualFont);
CFRelease(actualFont);
fontNames[0] = fontName;
fontNames[1] = familyName;
if (!fontName || !familyName) glyph = 0;
}
return glyph;
}
/*
* Translates a Unicode into a CGGlyph/CTFontRef pair
* Returns the substituted font, and places the appropriate glyph into "glyphRef"
*/
CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
CTFontRef primary = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
if (fallbackBase) {
CTFontGetGlyphsForCharacters(primary, charRef, glyphRef, count);
if (glyphRef[0] > 0) {
CFRetain(primary);
return primary;
}
} else {
fallbackBase = primary;
}
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, charRef, count);
if (fallback == NULL)
{
// use the original font if we somehow got duped into trying to fallback something we can't
fallback = (CTFontRef)font->fFont;
CFRetain(fallback);
}
CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
return fallback;
}
/*
* Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
* Returns the substituted font, and places the appropriate glyph into "glyphRef"
*/
CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode
(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
{
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
if (glyphCode >= 0)
{
*glyphRef = glyphCode;
CFRetain(font->fFont);
return (CTFontRef)font->fFont;
}
int codePoint = -glyphCode;
if (codePoint >= 0x10000) {
UTF16Char chars[2];
CGGlyph glyphs[2];
CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars);
CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2);
*glyphRef = glyphs[0];
return result;
} else {
UTF16Char character = codePoint;
return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
size_t i;
for (i = 0; i < count; i++) {
glyphsAsInts[i] = glyphs[i];
}
}
// Breakup a 32 bit unicode value into the component surrogate pairs
void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
int value = uniChar - 0x10000;
UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
charRef[0] = high_surrogate;
charRef[1] = low_surrogate;
}

View File

@@ -56,6 +56,7 @@ import sun.font.FontAccess;
import sun.font.FontDesignMetrics;
import sun.font.FontManager;
import sun.font.FontManagerFactory;
import sun.font.FontSubstitution;
import sun.font.FontUtilities;
import sun.font.GlyphLayout;
import sun.font.FontLineMetrics;
@@ -234,6 +235,11 @@ public class Font implements java.io.Serializable
return font.getFont2D();
}
@Override
public Font2D getFont2DWithSubstitution(Font font) {
return font.getFont2DWithSubstitution();
}
public void setFont2D(Font font, Font2DHandle handle) {
font.font2DHandle = handle;
}
@@ -510,6 +516,11 @@ public class Font implements java.io.Serializable
return font2DHandle.font2D;
}
private Font2D getFont2DWithSubstitution() {
Font2D font2D = getFont2D();
return font2D instanceof FontSubstitution ? ((FontSubstitution) font2D).getCompositeFont2D() : font2D;
}
/**
* Creates a new {@code Font} from the specified name, style and
* point size.
@@ -2187,7 +2198,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public boolean canDisplay(char c){
return getFont2D().canDisplay(c);
return getFont2DWithSubstitution().canDisplay(c);
}
/**
@@ -2208,7 +2219,7 @@ public class Font implements java.io.Serializable
throw new IllegalArgumentException("invalid code point: " +
Integer.toHexString(codePoint));
}
return getFont2D().canDisplay(codePoint);
return getFont2DWithSubstitution().canDisplay(codePoint);
}
/**
@@ -2229,7 +2240,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(String str) {
Font2D font2d = getFont2D();
Font2D font2d = getFont2DWithSubstitution();
int len = str.length();
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
@@ -2267,7 +2278,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(char[] text, int start, int limit) {
Font2D font2d = getFont2D();
Font2D font2d = getFont2DWithSubstitution();
for (int i = start; i < limit; i++) {
char c = text[i];
if (font2d.canDisplay(c)) {
@@ -2302,7 +2313,7 @@ public class Font implements java.io.Serializable
* @since 1.2
*/
public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
Font2D font2d = getFont2D();
Font2D font2d = getFont2DWithSubstitution();
char c = iter.setIndex(start);
for (int i = start; i < limit; i++, c = iter.next()) {
if (font2d.canDisplay(c)) {
@@ -2873,12 +2884,6 @@ public class Font implements java.io.Serializable
*/
public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
/**
* A flag to layoutGlyphVector requesting to disable detection of paired characters
* when splitting text into scripts.
*/
public static final int LAYOUT_NO_PAIRED_CHARS_AT_SCRIPT_SPLIT = 8;
private static void applyTransform(AffineTransform trans, AttributeValues values) {
if (trans == null) {
throw new IllegalArgumentException("transform must not be null");

View File

@@ -32,6 +32,8 @@ import java.util.Locale;
import javax.swing.UIManager;
import sun.swing.SwingUtilities2;
import sun.swing.text.GlyphViewAccessor;
import static sun.swing.SwingUtilities2.IMPLIED_CR;
/**
@@ -787,7 +789,17 @@ public class GlyphView extends View implements TabableView, Cloneable {
return breakSpot;
}
protected int[] calcBreakSpots(BreakIterator breaker) {
static {
GlyphViewAccessor.setAccessor(new GlyphViewAccessor() {
@Override
public int[] calcBreakSpots(GlyphView glyphView, BreakIterator breaker) {
return glyphView.calcBreakSpots(breaker);
}
});
}
// TODO: convert to protected method (removing accessor) when upstreaming the fix
int[] calcBreakSpots(BreakIterator breaker) {
int start = getStartOffset();
int end = getEndOffset();
int[] bs = new int[end + 1 - start];

View File

@@ -494,8 +494,10 @@ public class CSS implements Serializable {
/**
* CSS attribute "overflow-wrap".
*
* TODO: make public when upstreaming the fix
*/
public static final Attribute OVERFLOW_WRAP =
static final Attribute OVERFLOW_WRAP =
new Attribute("overflow-wrap", "normal", true);
/**

View File

@@ -24,6 +24,8 @@
*/
package javax.swing.text.html;
import sun.swing.text.GlyphViewAccessor;
import java.awt.*;
import java.text.BreakIterator;
import java.util.Locale;
@@ -242,7 +244,7 @@ public class InlineView extends LabelView {
Container c = getContainer();
Locale locale = (c == null ? Locale.getDefault() : c.getLocale());
BreakIterator breaker = BreakIterator.getCharacterInstance(locale);
int[] breakSpots = calcBreakSpots(breaker);
int[] breakSpots = GlyphViewAccessor.getAccessor().calcBreakSpots(this, breaker);
int lastBreak = endOffset;
for (int breakSpot : breakSpots) {
wrapAnywhereMinimumSpan = Math.max(wrapAnywhereMinimumSpan,

View File

@@ -38,7 +38,7 @@ import java.awt.Font;
* But its probably OK to include it so long as only composites include
* fallbacks. If physicals do then it would be really confusing ..
*/
public class CompositeFont extends Font2D {
public final class CompositeFont extends Font2D {
private boolean[] deferredInitialisation;
String[] componentFileNames;

View File

@@ -108,7 +108,7 @@ public class CompositeGlyphMapper extends CharToGlyphMapper {
return mapper;
}
protected int convertToGlyph(int unicode) {
private int convertToGlyph(int unicode) {
for (int slot = 0; slot < font.numSlots; slot++) {
if (!hasExcludes || !font.isExcludedChar(slot, unicode)) {

View File

@@ -878,8 +878,8 @@ public class FileFontStrike extends PhysicalStrike {
private int getGlyphImageMinX(long ptr, int origMinX) {
int format = StrikeCache.unsafe.getByte(ptr+StrikeCache.formatOffset);
if (format != 3) return origMinX;
byte format = StrikeCache.unsafe.getByte(ptr+StrikeCache.formatOffset);
if (format != StrikeCache.PIXEL_FORMAT_LCD) return origMinX;
int height = StrikeCache.unsafe.getChar(ptr+StrikeCache.heightOffset);
int rowBytes =

View File

@@ -71,8 +71,6 @@ public abstract class Font2D {
private static final FontRenderContext DEFAULT_FRC =
new FontRenderContext(null, false, false);
static final boolean fontSubstitutionEnabled = !Boolean.getBoolean("disable.font.substitution");
public Font2DHandle handle;
protected String familyName; /* Family font name (english) */
protected String fullName; /* Full font name (english) */
@@ -337,7 +335,7 @@ public abstract class Font2D {
return getStrike(desc, true);
}
FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
private FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
/* Before looking in the map, see if the descriptor matches the
* last strike returned from this Font2D. This should often be a win
* since its common for the same font, in the same size to be

View File

@@ -43,6 +43,7 @@ public abstract class FontAccess {
}
public abstract Font2D getFont2D(Font f);
public abstract Font2D getFont2DWithSubstitution(Font f);
public abstract void setFont2D(Font f, Font2DHandle h);
public abstract void setCreatedFont(Font f);
public abstract boolean isCreatedFont(Font f);

View File

@@ -355,7 +355,7 @@ public final class FontDesignMetrics extends FontMetrics {
private void initMatrixAndMetrics() {
Font2D font2D = FontUtilities.getFont2D(font);
Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
fontStrike = font2D.getStrike(font, frc);
StrikeMetrics metrics = fontStrike.getFontMetrics();
this.ascent = metrics.getAscent();

View File

@@ -266,12 +266,12 @@ public class FontFamily {
doSetFont(fontAndStyle.font, fontAndStyle.style);
}
if (italic == null && plain instanceof FontWithDerivedItalic) {
italic = ((FontWithDerivedItalic)plain).createItalic();
italic = ((FontWithDerivedItalic)plain).createItalicVariant();
}
if (bolditalic == null) {
Font2D boldItalicPrototype = bold != null ? bold : plain;
if (boldItalicPrototype instanceof FontWithDerivedItalic) {
bolditalic = ((FontWithDerivedItalic)boldItalicPrototype).createItalic();
bolditalic = ((FontWithDerivedItalic)boldItalicPrototype).createItalicVariant();
}
}
fontSequence.clear();

View File

@@ -111,14 +111,13 @@ public class FontStrikeDesc {
*/
public static int getAAHintIntVal(Object aa, Font2D font2D, int ptSize) {
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
if (FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR ||
aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||
aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR ||
aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB))
{
return INTVAL_TEXT_ANTIALIAS_ON;
return INTVAL_TEXT_ANTIALIAS_ON;
}
if (aa == VALUE_TEXT_ANTIALIAS_OFF ||
@@ -154,14 +153,13 @@ public class FontStrikeDesc {
FontRenderContext frc) {
Object aa = frc.getAntiAliasingHint();
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_OFF ||
aa == VALUE_TEXT_ANTIALIAS_DEFAULT ||
aa == VALUE_TEXT_ANTIALIAS_ON ||
aa == VALUE_TEXT_ANTIALIAS_GASP)))
if (FontUtilities.isMacOSX14 &&
(aa == VALUE_TEXT_ANTIALIAS_LCD_HBGR ||
aa == VALUE_TEXT_ANTIALIAS_LCD_HRGB ||
aa == VALUE_TEXT_ANTIALIAS_LCD_VBGR ||
aa == VALUE_TEXT_ANTIALIAS_LCD_VRGB))
{
return INTVAL_TEXT_ANTIALIAS_ON;
return INTVAL_TEXT_ANTIALIAS_ON;
}
if (aa == VALUE_TEXT_ANTIALIAS_OFF ||

View File

@@ -190,6 +190,10 @@ public final class FontUtilities {
return FontAccess.getFontAccess().getFont2D(font);
}
public static Font2D getFont2DWithSubstitution(Font font) {
return FontAccess.getFontAccess().getFont2DWithSubstitution(font);
}
/**
* Return true if there any characters which would trigger layout.
* This method considers supplementary characters to be simple,

View File

@@ -1,5 +1,5 @@
package sun.font;
interface FontWithDerivedItalic {
Font2D createItalic();
Font2D createItalicVariant();
}

View File

@@ -81,6 +81,14 @@ import java.util.concurrent.ConcurrentHashMap;
import static java.lang.Character.*;
public final class GlyphLayout {
/**
* A flag to layoutGlyphVector requesting to disable detection of paired characters
* when splitting text into scripts.
*
* TODO: move to java.awt.Font when upstreaming the fix
*/
private static final int LAYOUT_NO_PAIRED_CHARS_AT_SCRIPT_SPLIT = 8;
// data for glyph vector
private GVData _gvdata;
@@ -369,7 +377,7 @@ public final class GlyphLayout {
init(count);
boolean handlePairedChars = (flags & Font.LAYOUT_NO_PAIRED_CHARS_AT_SCRIPT_SPLIT) == 0;
boolean handlePairedChars = (flags & LAYOUT_NO_PAIRED_CHARS_AT_SCRIPT_SPLIT) == 0;
// need to set after init
// go through the back door for this
@@ -411,10 +419,7 @@ public final class GlyphLayout {
int lang = -1; // default for now
Font2D font2D = FontUtilities.getFont2D(font);
if (Font2D.fontSubstitutionEnabled && font2D instanceof FontSubstitution) {
font2D = ((FontSubstitution)font2D).getCompositeFont2D();
}
Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
_textRecord.init(text, offset, lim, min, max);
int start = offset;

View File

@@ -509,14 +509,15 @@ public final class GlyphList {
}
/**
* @return 1 for greyscale, 3 for LCD and 4 for BGRA glyph
* @return {@link StrikeCache#PIXEL_FORMAT_GREYSCALE} for greyscale,
* {@link StrikeCache#PIXEL_FORMAT_LCD} for LCD and {@link StrikeCache#PIXEL_FORMAT_BGRA} for BGRA glyph
*/
public int getPixelFormat(int glyphIndex) {
public byte getPixelFormat(int glyphIndex) {
return StrikeCache.unsafe.getByte(images[glyphIndex] + StrikeCache.formatOffset);
}
public boolean isColorGlyph(int glyphIndex) {
return getPixelFormat(glyphIndex) == 4;
return getPixelFormat(glyphIndex) == StrikeCache.PIXEL_FORMAT_BGRA;
}
public SurfaceData getColorGlyphData() {

View File

@@ -195,8 +195,7 @@ public class StandardGlyphVector extends GlyphVector {
// how do we know its a base glyph
// for now, it is if the natural advance of the glyph is non-zero
Font2D f2d = FontUtilities.getFont2D(font);
FontStrike strike = f2d.getStrike(font, frc);
FontStrike strike = font2D.getStrike(font, frc);
float[] deltas = { trackPt.x, trackPt.y };
for (int j = 0; j < deltas.length; ++j) {
@@ -1127,10 +1126,7 @@ public class StandardGlyphVector extends GlyphVector {
}
private void initFontData() {
font2D = FontUtilities.getFont2D(font);
if (Font2D.fontSubstitutionEnabled && font2D instanceof FontSubstitution) {
font2D = ((FontSubstitution)font2D).getCompositeFont2D();
}
font2D = FontUtilities.getFont2DWithSubstitution(font);
float s = font.getSize2D();
if (font.isTransformed()) {
ftx = font.getTransform();
@@ -1749,12 +1745,7 @@ public class StandardGlyphVector extends GlyphVector {
aa, fm);
// Get the strike via the handle. Shouldn't matter
// if we've invalidated the font but its an extra precaution.
// do we want the CompFont from CFont here ?
Font2D f2d = sgv.font2D;
if (f2d instanceof FontSubstitution) {
f2d = ((FontSubstitution)f2d).getCompositeFont2D();
}
FontStrike strike = f2d.handle.font2D.getStrike(desc); // !!! getStrike(desc, false)
FontStrike strike = sgv.font2D.handle.font2D.getStrike(desc); // !!! getStrike(desc, false)
return new GlyphStrike(sgv, strike, dx, dy);
}

View File

@@ -27,6 +27,7 @@ package sun.font;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.lang.annotation.Native;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
@@ -119,6 +120,11 @@ public final class StrikeCache {
static int formatOffset;
static long invisibleGlyphPtr;
@Native public static final byte PIXEL_FORMAT_UNKNOWN = -1;
@Native public static final byte PIXEL_FORMAT_GREYSCALE = 1;
@Native public static final byte PIXEL_FORMAT_LCD = 3;
@Native public static final byte PIXEL_FORMAT_BGRA = 4;
/* Native method used to return information used for unsafe
* access to native data.
* return values as follows:-

View File

@@ -668,7 +668,7 @@ public final class SunGraphics2D
}
}
info.font2D = FontUtilities.getFont2D(font);
info.font2D = FontUtilities.getFont2DWithSubstitution(font);
int fmhint = fractionalMetricsHint;
if (fmhint == SunHints.INTVAL_FRACTIONALMETRICS_DEFAULT) {
@@ -772,12 +772,6 @@ public final class SunGraphics2D
}
}
}
if (FontUtilities.isMacOSX16 ||
(FontUtilities.isMacOSX14 &&
aahint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF))
{
aahint = SunHints.INTVAL_TEXT_ANTIALIAS_ON;
}
info.aaHint = aahint;
info.fontStrike = info.font2D.getStrike(font, devAt, textAt,
aahint, fmhint);

View File

@@ -450,13 +450,9 @@ public abstract class SurfaceData
colorPrimitives = new LoopPipe();
outlineTextRenderer = new OutlineTextRenderer();
solidTextRenderer = new SolidTextRenderer();
aaTextRenderer = new AATextRenderer();
if (FontUtilities.isMacOSX14) {
solidTextRenderer = aaTextRenderer;
} else {
solidTextRenderer = new SolidTextRenderer();
}
if (FontUtilities.isMacOSX16) {
lcdTextRenderer = aaTextRenderer;
} else {
lcdTextRenderer = new LCDTextRenderer();

View File

@@ -26,6 +26,7 @@
package sun.java2d.pipe;
import sun.awt.SunHints;
import sun.font.StrikeCache;
import sun.java2d.SunGraphics2D;
import sun.font.GlyphList;
@@ -41,13 +42,13 @@ public abstract class GlyphListLoopPipe extends GlyphListPipe
protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
int aaHint) {
int prevBorder = 0;
int pixelFormat = -1;
byte pixelFormat = StrikeCache.PIXEL_FORMAT_UNKNOWN;
int len = gl.getNumGlyphs();
gl.startGlyphIteration();
for (int i = 0; i < len; i++) {
int newFormat = gl.getPixelFormat(i);
byte newFormat = gl.getPixelFormat(i);
if (newFormat != pixelFormat) {
if (pixelFormat != -1) drawGlyphListSegment(sg2d, gl, prevBorder, i, aaHint, pixelFormat);
drawGlyphListSegment(sg2d, gl, prevBorder, i, aaHint, pixelFormat);
prevBorder = i;
pixelFormat = newFormat;
}
@@ -56,10 +57,10 @@ public abstract class GlyphListLoopPipe extends GlyphListPipe
}
private void drawGlyphListSegment(SunGraphics2D sg2d, GlyphList gl, int fromglyph, int toGlyph,
int aaHint, int pixelFormat) {
int aaHint, byte pixelFormat) {
if (fromglyph >= toGlyph) return;
switch (pixelFormat) {
case 1:
case StrikeCache.PIXEL_FORMAT_GREYSCALE:
if (aaHint == SunHints.INTVAL_TEXT_ANTIALIAS_OFF) {
sg2d.loops.drawGlyphListLoop.
DrawGlyphList(sg2d, sg2d.surfaceData, gl, fromglyph, toGlyph);
@@ -68,11 +69,11 @@ public abstract class GlyphListLoopPipe extends GlyphListPipe
DrawGlyphListAA(sg2d, sg2d.surfaceData, gl, fromglyph, toGlyph);
}
return;
case 3:
case StrikeCache.PIXEL_FORMAT_LCD:
sg2d.loops.drawGlyphListLCDLoop.
DrawGlyphListLCD(sg2d, sg2d.surfaceData, gl, fromglyph, toGlyph);
return;
case 4:
case StrikeCache.PIXEL_FORMAT_BGRA:
sg2d.loops.drawGlyphListColorLoop.
DrawGlyphListColor(sg2d, sg2d.surfaceData, gl, fromglyph, toGlyph);
return;

View File

@@ -696,7 +696,7 @@ public abstract class PathGraphics extends ProxyGraphics2D {
}
Font font = g.getFont();
Font2D font2D = FontUtilities.getFont2D(font);
Font2D font2D = FontUtilities.getFont2DWithSubstitution(font);
if (font2D.handle.font2D != font2D) {
/* suspicious, may be a bad font. lets bail */
return false;

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2021 JetBrains s.r.o.
* 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.
*/
package sun.swing.text;
import javax.swing.text.GlyphView;
import java.text.BreakIterator;
public abstract class GlyphViewAccessor {
private static GlyphViewAccessor accessor;
public static void setAccessor(GlyphViewAccessor a) {
accessor = a;
}
public static GlyphViewAccessor getAccessor() {
return accessor;
}
public abstract int[] calcBreakSpots(GlyphView glyphView, BreakIterator breaker);
}

View File

@@ -27,6 +27,7 @@
#define FontScalerDefsIncludesDefined
#include "AccelGlyphCache.h"
#include "sun_font_StrikeCache.h"
#ifdef __cplusplus
extern "C" {
@@ -75,7 +76,7 @@ typedef struct GlyphInfo {
UInt16 height;
UInt16 rowBytes;
UInt8 managed;
UInt8 format; // 1-Grayscale, 3-LCD, 4-BGRA
UInt8 format; // sun_font_StrikeCache_PIXEL_FORMAT_*
UInt8 subpixelResolutionX;
UInt8 subpixelResolutionY;
float topLeftX;

View File

@@ -337,7 +337,10 @@ static const char *grayGammaTextShaderSource =
"{"
"float a = src_adj.a;"
"vec3 col = src_adj.rgb;"
// Convert from ARGB_PRE
"if (a > 0.0) {"
"col = col/a;"
"}"
// calculate brightness of the fragment
"float b = dot(col, vec3(1.0/3.0, 1.0/3.0, 1.0/3.0))*a;"
@@ -1436,7 +1439,7 @@ OGLTR_DrawGlyphList(JNIEnv *env, OGLContext *oglc, OGLSDOps *dstOps,
continue;
}
if (ginfo->format == 1) {
if (ginfo->format == sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE) {
OGLMTVertexCache_disable();
// grayscale or monochrome glyph data
int rx = ginfo->subpixelResolutionX;
@@ -1454,7 +1457,7 @@ OGLTR_DrawGlyphList(JNIEnv *env, OGLContext *oglc, OGLSDOps *dstOps,
} else {
ok = OGLTR_DrawGrayscaleGlyphNoCache(oglc, ginfo, x, y, subimage);
}
} else if (ginfo->format == 4) {
} else if (ginfo->format == sun_font_StrikeCache_PIXEL_FORMAT_BGRA) {
OGLMTVertexCache_disable();
// color glyph data
ok = OGLTR_DrawColorGlyphNoCache(oglc, ginfo, x, y);

View File

@@ -572,7 +572,7 @@ GlyphBlitVector* setupLCDBlitVector(JNIEnv *env, jobject glyphlist, jint fromGly
free(gbv);
return (GlyphBlitVector*)NULL;
}
if (ginfo->format != 3) { // Not LCD glyph
if (ginfo->format != sun_font_StrikeCache_PIXEL_FORMAT_LCD) {
subPixPos = JNI_FALSE;
}
}

View File

@@ -1768,10 +1768,10 @@ static jlong
glyphInfo->subpixelResolutionX = subpixelResolutionX;
glyphInfo->subpixelResolutionY = subpixelResolutionY;
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) glyphInfo->format = 4;
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_BGRA;
else if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD ||
ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) glyphInfo->format = 3;
else glyphInfo->format = 1;
ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_LCD;
else glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE;
if (renderImage) {
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD && width > 0) {

View File

@@ -35,6 +35,7 @@ import java.util.Map;
import java.util.Optional;
import sun.awt.IconInfo;
import sun.awt.PeerEvent;
import sun.util.logging.PlatformLogger;
import sun.awt.AWTAccessor;
@@ -1306,7 +1307,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
* WM_TAKE_FOCUS (when FocusIn is generated via XSetInputFocus call) but
* definetely before the Frame gets FocusIn event (when this method is called).
*/
postEvent(new InvocationEvent(target, new Runnable() {
postEvent(new PeerEvent(target, new Runnable() {
public void run() {
XWindowPeer fw = null;
synchronized (getStateLock()) {
@@ -1318,7 +1319,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
}
fw.handleWindowFocusIn_Dispatch();
}
}));
}, PeerEvent.ULTIMATE_PRIORITY_EVENT));
}
}

View File

@@ -105,7 +105,7 @@ public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
{
return KeyboardFocusManagerPeerImpl.deliverFocus(lightweightChild,
target,
false,
true,
cause,
getInstance().getCurrentFocusOwner());
}

View File

@@ -154,6 +154,8 @@ final class XWM
return "Awesome";
case DWM_WM:
return "DWM";
case XWM.I3_WM:
return "I3WM";
case UNDETERMINED_WM:
default:
return "Undetermined WM";
@@ -1484,6 +1486,8 @@ final class XWM
case XWM.ENLIGHTEN_WM:
/* At least E16 is buggy. */
return true;
case XWM.I3_WM:
return true;
default:
return false;
}

View File

@@ -627,20 +627,13 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleWindowFocusIn(long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
/* wrap in Sequenced, then post*/
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
postEvent(wrapInSequenced((AWTEvent) we));
handleWindowFocusInSync(serial, () -> {});
}
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
/* wrap in Sequenced, then post*/
postEvent(wrapInSequenced((AWTEvent) we));
handleWindowFocusOutSync(oppositeWindow, serial);
}
public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);

View File

@@ -199,10 +199,10 @@ public class XRGlyphCacheEntry {
}
public Type getType() {
int format = StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.formatOffset);
if (format == 1) return Type.GRAYSCALE;
else if (format == 3) return Type.LCD;
else if (format == 4) return Type.BGRA;
byte format = StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.formatOffset);
if (format == StrikeCache.PIXEL_FORMAT_GREYSCALE) return Type.GRAYSCALE;
else if (format == StrikeCache.PIXEL_FORMAT_LCD) return Type.LCD;
else if (format == StrikeCache.PIXEL_FORMAT_BGRA) return Type.BGRA;
else throw new IllegalStateException("Unknown glyph format: " + format);
}

View File

@@ -291,7 +291,7 @@ JNIEXPORT jlong JNICALL AWTFontGenerateImage(AWTFont pFont, AWTChar2b* xChar) {
glyphInfo->height = height;
glyphInfo->subpixelResolutionX = 1;
glyphInfo->subpixelResolutionY = 1;
glyphInfo->format = 1;
glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE;
glyphInfo->topLeftX = xcs.lbearing;
glyphInfo->topLeftY = -xcs.ascent;
glyphInfo->advanceX = xcs.width;

View File

@@ -35,6 +35,7 @@ import java.awt.peer.FramePeer;
import java.security.AccessController;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
import sun.awt.im.InputMethodManager;
import sun.security.action.GetPropertyAction;
@@ -124,15 +125,16 @@ class WFramePeer extends WWindowPeer implements FramePeer {
@Override
public void displayChanged() {
super.displayChanged();
updateIcon();
SunToolkit.executeOnEventHandlerThread(target, this::updateIcon);
if (!screenChangedFlag &&
(getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 &&
(getExtendedState() & Frame.ICONIFIED) == 0)
{
(getExtendedState() & Frame.ICONIFIED) == 0) {
// A workaround to update the maximized state of the frame
int state = getExtendedState();
setState(Frame.NORMAL);
setState(state);
SunToolkit.executeOnEventHandlerThread(target, ()->{
int state = getExtendedState();
setState(Frame.NORMAL);
setState(state);
});
}
}

View File

@@ -37,6 +37,7 @@ import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.IllegalComponentStateException;
import java.awt.Image;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
@@ -89,7 +90,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
private TranslucentWindowPainter painter;
private int screenNum;
private int screenNum = 0;
protected boolean screenChangedFlag;
/*
@@ -215,6 +216,13 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
super(target);
// update GC based on the current bounds
updateGC();
try {
screenNum = getScreenImOn();
} catch (IllegalComponentStateException e) {
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
log.warning(e.getMessage());
}
}
}
@Override
@@ -630,9 +638,6 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
public void updateGC() {
int scrn = getScreenImOn();
screenChangedFlag = scrn != screenNum;
screenNum = scrn;
if (screenLog.isLoggable(PlatformLogger.Level.FINER)) {
log.finer("Screen number: " + scrn);
}
@@ -701,6 +706,9 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
*/
@Override
public void displayChanged() {
int scrn = getScreenImOn();
screenChangedFlag = scrn != screenNum;
screenNum = scrn;
SunToolkit.executeOnEventHandlerThread(target, ()->{
updateGC();
adjustBoundsOnDPIChange();

View File

@@ -792,7 +792,7 @@ D3DTR_DrawGlyphList(D3DContext *d3dc, D3DSDOps *dstOps,
break;
}
grayscale = (ginfo->format == 1);
grayscale = (ginfo->format == sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE);
if (usePositions) {
jfloat posx = NEXT_FLOAT(positions);

View File

@@ -94,7 +94,6 @@ HWND AwtComponent::sm_focusOwner = NULL;
HWND AwtComponent::sm_focusedWindow = NULL;
BOOL AwtComponent::sm_bMenuLoop = FALSE;
BOOL AwtComponent::sm_inSynthesizeFocus = FALSE;
BOOL AwtComponent::sm_priorityFocusEvents = FALSE;
/************************************************************************/
// Struct for _Reshape() and ReshapeNoCheck() methods
@@ -981,8 +980,8 @@ void AwtComponent::ReshapeNoScale(int x, int y, int w, int h)
int usrY = y;
AwtWin32GraphicsDevice* device = UGetDeviceByBounds(URectBounds(x, y, w, h, USER_SPACE), this);
x = device->ScaleUpX(x, RELATIVITY_FOR_COMP_XY(this));
y = device->ScaleUpY(y, RELATIVITY_FOR_COMP_XY(this));
x = device->ScaleUpX(x);
y = device->ScaleUpY(y);
w = device->ScaleUpX(w);
h = device->ScaleUpY(h);
@@ -2027,38 +2026,28 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
* there.
*/
case WM_AWT_COMPONENT_SHOW:
sm_priorityFocusEvents = TRUE;
Show();
sm_priorityFocusEvents = FALSE;
mr = mrConsume;
break;
case WM_AWT_COMPONENT_HIDE:
sm_priorityFocusEvents = TRUE;
Hide();
sm_priorityFocusEvents = FALSE;
mr = mrConsume;
break;
case WM_AWT_COMPONENT_SETFOCUS:
sm_priorityFocusEvents = TRUE;
if ((BOOL)wParam) {
retValue = SynthesizeWmSetFocus(GetHWnd(), NULL);
} else {
retValue = SynthesizeWmKillFocus(GetHWnd(), NULL);
}
sm_priorityFocusEvents = FALSE;
mr = mrConsume;
break;
case WM_AWT_WINDOW_SETACTIVE:
sm_priorityFocusEvents = TRUE;
retValue = (LRESULT)((AwtWindow*)this)->AwtSetActiveWindow((BOOL)wParam);
sm_priorityFocusEvents = FALSE;
mr = mrConsume;
break;
case WM_AWT_WINDOW_TOFRONT:
sm_priorityFocusEvents = TRUE;
((AwtWindow*)this)->ToFront();
sm_priorityFocusEvents = FALSE;
mr = mrConsume;
break;
@@ -2484,7 +2473,7 @@ void AwtComponent::WmTouchHandler(const TOUCHINPUT& touchInput)
const jint scrollModifiers = modifiers & ~java_awt_event_InputEvent_SHIFT_DOWN_MASK;
SendMouseWheelEventFromTouch(p, scrollModifiers, sun_awt_event_TouchEvent_TOUCH_UPDATE, deltaY);
}
const jint deltaX = ScaleDownX(static_cast<int>(m_lastTouchPoint.x - p.x));
if (deltaX != 0) {
const jint scrollModifiers = modifiers | java_awt_event_InputEvent_SHIFT_DOWN_MASK;

View File

@@ -699,7 +699,6 @@ public:
static void *GetNativeFocusOwner();
static BOOL sm_inSynthesizeFocus;
static BOOL sm_priorityFocusEvents;
// Execute on Toolkit only.
INLINE static LRESULT SynthesizeWmSetFocus(HWND targetHWnd, HWND oppositeHWnd) {

View File

@@ -519,9 +519,7 @@ MsgRouting AwtDialog::WmEndModal()
jobject peer = GetPeer(env);
jobject target = GetTarget(env);
if (::GetForegroundWindow() == GetHWnd()) {
sm_priorityFocusEvents = TRUE;
ModalActivateNextWindow(GetHWnd(), target, peer);
sm_priorityFocusEvents = FALSE;
}
// hide the dialog
SendMessage(WM_AWT_COMPONENT_HIDE);

View File

@@ -1251,7 +1251,7 @@ MsgRouting AwtFrame::WmSysCommand(UINT uCmdType, int xPos, int yPos)
}
MsgRouting AwtFrame::WmDPIChanged(UINT xDPI, UINT yDPI, RECT* bounds) {
if (isZoomed()) {
if (isZoomed() && !m_maxBoundsSet) {
Devices::InstanceAccess devices;
AwtWin32GraphicsDevice* device = devices->GetDevice(AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd()));
if (device) {

View File

@@ -84,9 +84,10 @@ RECT AwtWin32GraphicsConfig::getMonitorBounds(int screen, const UCoordSpace& spa
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
// don't scale xy to avoid overlapping of the multi-dpi-monitors bounds in the user space
int x = rRW.left;
int y = rRW.top;
int x = (device == NULL || space == DEVICE_SPACE) ? rRW.left
: device->ScaleDownX(rRW.left);
int y = (device == NULL || space == DEVICE_SPACE) ? rRW.top
: device->ScaleDownY(rRW.top);
int w = (device == NULL || space == DEVICE_SPACE) ? rRW.right - rRW.left
: device->ScaleDownX(rRW.right - rRW.left);
int h = (device == NULL || space == DEVICE_SPACE) ? rRW.bottom - rRW.top

View File

@@ -1725,9 +1725,8 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
env->DeleteLocalRef(target); target = NULL;
CHECK_NULL(event);
if (AwtComponent::sm_priorityFocusEvents &&
(id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS))
if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
{
SendPriorityEvent(event);
} else {
@@ -1920,8 +1919,8 @@ MsgRouting AwtWindow::WmMove(int x, int y)
URectBounds rect = UGetWindowRectBounds(GetHWnd());
AwtWin32GraphicsDevice* device = UGetDeviceByBounds(rect, this);
int usrX = device->ScaleDownDX(rect.x);
int usrY = device->ScaleDownDY(rect.y);
int usrX = device->ScaleDownX(rect.x);
int usrY = device->ScaleDownY(rect.y);
// [tav] Convert x/y to user space, asymmetrically to AwtComponent::Reshape.
AwtComponent* parent = GetParent();

View File

@@ -457,7 +457,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
glyphInfo->height = height;
glyphInfo->subpixelResolutionX = 1;
glyphInfo->subpixelResolutionY = 1;
glyphInfo->format = 3;
glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_LCD;
glyphInfo->advanceX = advanceX;
glyphInfo->advanceY = advanceY;
glyphInfo->topLeftX = (float)(topLeftX-1);

View File

@@ -266,7 +266,7 @@ Java_sun_font_FileFontStrike__1getGlyphImageFromWindowsUsingDirectWrite
glyphInfo->height = glyphHeight;
glyphInfo->subpixelResolutionX = 1;
glyphInfo->subpixelResolutionY = 1;
glyphInfo->format = 3;
glyphInfo->format = sun_font_StrikeCache_PIXEL_FORMAT_LCD;
glyphInfo->advanceX = rotation == 0 ? advance : rotation == 2 ? -advance : 0;
glyphInfo->advanceY = rotation == 3 ? advance : rotation == 1 ? -advance : 0;
glyphInfo->topLeftX = bbRect.left - xTransformed;

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, JetBrains s.r.o.. 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 Verify that C1 compiler does not crash on a particular
* Kotlin suspend fun
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @compile Test.java
* @run main Test
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
String jarFile = System.getProperty("test.src") + "/testcase.jar";
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile,
"-XX:+UnlockDiagnosticVMOptions",
"-Xcomp",
"-XX:CompileCommand=compileonly,MainKt::test",
"MainKt");
new OutputAnalyzer(pb.start())
.shouldContain("Success")
.shouldNotContain("Internal Error")
.shouldHaveExitValue(0);
}
}
/*
* The code in testcase.jar is produced by running
* $ kotlinc Main.kt -include-runtime -d testcase.jar
* on this Kotlin code:
suspend fun yield(s: String) {
println("Success");
System.exit(0)
}
suspend fun test(s: String) {
while (true) {
yield(s)
}
}
suspend fun main() {
test("")
}
*/

Binary file not shown.

View File

@@ -1,6 +1,6 @@
###########################################################################
#
# Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2021, 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
@@ -42,10 +42,11 @@
# List items are testnames followed by labels, all MUST BE commented
# as to why they are here and use a label:
# generic-all Problems on all platforms
# generic-ARCH Where ARCH is one of: x64, i586, ppc64, ppc64le, s390x, aarch64 etc.
# OSNAME-all Where OSNAME is one of: linux, windows, macosx, aix
# OSNAME-ARCH Specific on to one OSNAME and ARCH, e.g. macosx-x64
# OSNAME-REV Specific on to one OSNAME and REV, e.g. macosx-10.7.4
# generic-ARCH Where ARCH is one of: sparc, sparcv9, x64, i586, ppc64,
# ppc64le, s390x etc.
# OSNAME-all Where OSNAME is one of: solaris, linux, windows, macosx, aix
# OSNAME-ARCH Specific on to one OSNAME and ARCH, e.g. solaris-amd64
# OSNAME-REV Specific on to one OSNAME and REV, e.g. solaris-5.8
#
# More than one label is allowed but must be on the same line comma seperated,
# without spaces.
@@ -685,8 +686,6 @@ sun/security/pkcs11/KeyStore/SecretKeysBasic.sh 8209398 generic-
security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all
security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 8243543 generic-all
security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 8263059 generic-all
security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 8248899 generic-all
security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java 8270280 generic-all
sun/security/smartcardio/TestChannel.java 8039280 generic-all
sun/security/smartcardio/TestConnect.java 8039280 generic-all

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2021 JetBrains s.r.o.
* 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @test
* @summary Regression test for JBR-3989 Broken focus state after a quick succession of activation/deactivation events
* on Windows
* @key headful
*/
public class ActivationEventsOrder {
private static final CompletableFuture<Boolean> success = new CompletableFuture<>();
private static Robot robot;
private static JFrame frame1;
private static JFrame frame2;
private static JTextField field1;
private static JTextField field2;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(ActivationEventsOrder::initUI);
robot.delay(1000); // wait for windows to appear
SwingUtilities.invokeLater(ActivationEventsOrder::delayedFocusRequest);
robot.delay(1000); // wait for EDT to be frozen in Thread.sleep
clickOn(field1);
robot.delay(2000); // wait for freeze to be over
clickOn(field2);
robot.delay(1000); // wait for focus to settle down
pressAndRelease(KeyEvent.VK_ENTER);
success.get(5, TimeUnit.SECONDS);
}
finally {
SwingUtilities.invokeAndWait(ActivationEventsOrder::disposeUI);
}
}
private static void initUI() {
frame1 = new JFrame("ActivationEventsOrder 1");
field1 = new JTextField();
frame1.add(field1);
frame1.setBounds(100, 100, 200, 100);
frame1.setVisible(true);
frame2 = new JFrame("ActivationEventsOrder 2");
field2 = new JTextField();
frame2.add(field2);
frame2.setBounds(100, 300, 200, 100);
frame2.setVisible(true);
field2.addActionListener(e -> success.complete(true));
}
private static void disposeUI() {
if (frame1 != null) frame1.dispose();
if (frame2 != null) frame2.dispose();
}
private static void delayedFocusRequest() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
frame2.toFront();
}
private static void pressAndRelease(int keyCode) {
robot.keyPress(keyCode);
robot.keyRelease(keyCode);
}
private static void clickAt(int x, int y) {
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
private static void clickOn(Component component) {
Point location = component.getLocationOnScreen();
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2021 JetBrains s.r.o.
* 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @test
* @summary Regression test for JBR-4021 Unexpected focus event order on window showing
* @key headful
*/
public class EventsOnPopupShowing {
private static final AtomicInteger gainedCount = new AtomicInteger();
private static Robot robot;
private static JFrame frame;
private static JButton button;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(EventsOnPopupShowing::initUI);
robot.delay(1000);
clickOn(button);
robot.delay(3000);
if (gainedCount.get() != 1) {
throw new RuntimeException("Unexpected 'focus gained' count: " + gainedCount);
}
} finally {
SwingUtilities.invokeAndWait(EventsOnPopupShowing::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("EventsOnPopupShowing");
button = new JButton("Start");
button.addActionListener(e -> {
JDialog d = new JDialog(frame, "Dialog", true);
d.setBounds(300, 300, 200, 200);
new Timer(1000, ee -> d.dispose()) {{ setRepeats(false); }}.start();
d.setVisible(true);
JWindow w = new JWindow(frame);
w.add(new JTextField());
w.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e) {
gainedCount.incrementAndGet();
}
});
w.setBounds(300, 300, 200, 200);
w.setVisible(true);
try {
Thread.sleep(1000); // make sure all native events are processed
} catch (InterruptedException ex) {
ex.printStackTrace();
}
});
frame.add(button);
frame.setBounds(200, 200, 200, 200);
frame.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
private static void clickAt(int x, int y) {
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
private static void clickOn(Component component) {
Point location = component.getLocationOnScreen();
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2021 JetBrains s.r.o.
* 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
* @test
* @summary Regression test for JBR-3979 Focus is not transferred to parent window
* @key headful
*/
public class RequestFocusInParent {
private static CompletableFuture<Boolean> result;
private static Robot robot;
private static JFrame frame;
private static JButton button1;
private static JButton button2;
public static void main(String[] args) throws Exception {
robot = new Robot();
try {
SwingUtilities.invokeAndWait(RequestFocusInParent::initUI);
robot.delay(1000); // wait for frame to appear
clickOn(button1);
robot.delay(1000); // wait for popup to appear
SwingUtilities.invokeAndWait(() -> result = new CompletableFuture<>());
clickOn(button2);
result.get(5, TimeUnit.SECONDS);
} finally {
SwingUtilities.invokeAndWait(RequestFocusInParent::disposeUI);
}
}
private static void initUI() {
frame = new JFrame("RequestFocusInParent");
button1 = new JButton("Open popup");
button1.addActionListener(e -> {
JWindow popup = new JWindow(frame);
button2 = new JButton("Return focus");
button2.addActionListener(ee -> button1.requestFocus());
popup.add(button2);
popup.setSize(100, 100);
popup.setLocation(100, 400);
popup.setVisible(true);
});
button1.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
if (result != null) result.complete(true);
}
});
frame.add(button1);
frame.setSize(100, 100);
frame.setLocation(100, 100);
frame.setVisible(true);
}
private static void disposeUI() {
if (frame != null) frame.dispose();
}
private static void clickAt(int x, int y) {
robot.mouseMove(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
private static void clickOn(Component component) {
Point location = component.getLocationOnScreen();
clickAt(location.x + component.getWidth() / 2, location.y + component.getHeight() / 2);
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright 2021 JetBrains s.r.o.
* 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.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static java.awt.Color.*;
/**
* @test
* @key headful
* @summary Check that increasing alpha of text on white background produces letters with decreasing brightness.
* @run main AlphaTextRender
*/
public class AlphaTextRender {
final static int WIDTH = 150;
final static int HEIGHT = 200;
final static File img = new File("t-alpha.png");
public static void main(final String[] args) throws IOException {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc =
ge.getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(WIDTH, HEIGHT);
BufferedImage bi = gc.createCompatibleImage(WIDTH, HEIGHT);
BufferedImage br = gc.createCompatibleImage(WIDTH, HEIGHT);
Color[] colors = {
WHITE, LIGHT_GRAY, GRAY, DARK_GRAY, BLACK, RED, PINK, ORANGE, YELLOW, MAGENTA,
CYAN, BLUE
};
int c = 10;
int maxAscent;
do {
Graphics2D g2d = vi.createGraphics();
maxAscent = g2d.getFontMetrics().getMaxAscent();
Font font = new Font("Serif", Font.PLAIN, 10);
g2d.setFont(font);
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, WIDTH, HEIGHT);
int posy = maxAscent;
for (Color col : colors) {
g2d.setColor(col);
int posx = 10;
for (int j = 0; j < 20; j++) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, j/(float)20));
g2d.drawString(String.valueOf('|'), posx, posy);
posx += g2d.getFontMetrics().charWidth('|') + 1;
}
posy += maxAscent;
}
g2d.dispose();
} while (vi.contentsLost() && (--c > 0));
Graphics2D g2d = bi.createGraphics();
g2d.drawImage(vi, 0, 0, null);
g2d.dispose();
g2d = br.createGraphics();
g2d.drawImage(vi, 0, 0, null);
g2d.dispose();
int posy = 0;
int errors = 0;
for (Color color : colors) {
int r0 = 255;
int g0 = 255;
int b0 = 255;
int lmr = 0;
int lmg = 0;
int lmb = 0;
int curErrors = 0;
boolean spike = false;
for (int j = 0; j < WIDTH; j++) {
Color c1 = new Color(bi.getRGB(j, posy + maxAscent / 2));
int dr = Math.abs(c1.getRed() - WHITE.getRed());
int dg = Math.abs(c1.getGreen() - WHITE.getGreen());
int db = Math.abs(c1.getBlue() - WHITE.getBlue());
// Skip background and pick color with maximal local brightness
if (dr + dg + db > 0) {
if (!spike) {
lmr = c1.getRed();
lmg = c1.getGreen();
lmb = c1.getBlue();
spike = true;
} else {
lmr = Math.max(lmr, c1.getRed());
lmg = Math.max(lmg, c1.getGreen());
lmb = Math.max(lmb, c1.getBlue());
}
} else if (spike) { // Compare current spike with the previous one
if (getColorValue(r0, g0, b0) < getColorValue(lmr, lmg, lmb)) {
curErrors++;
br.setRGB(j, posy + maxAscent / 2 - 2, BLACK.getRGB());
br.setRGB(j, posy + maxAscent / 2 - 1, BLACK.getRGB());
br.setRGB(j, posy + maxAscent / 2, BLACK.getRGB());
br.setRGB(j, posy + maxAscent / 2 + 1, BLACK.getRGB());
br.setRGB(j, posy + maxAscent / 2 + 2, BLACK.getRGB());
}
r0 = lmr;
g0 = lmg;
b0 = lmb;
spike = false;
}
}
if (curErrors > 0) {
System.err.println("Error with color:" + color);
errors += curErrors;
}
posy += maxAscent;
}
if (errors > 0) {
ImageIO.write(br, "png", img);
throw new RuntimeException("Translucent text errors found: " + errors);
}
}
private static double getColorValue(int r0, int g0, int b0) {
// Use simple addition for normalized color components
return r0 / 255.0 + g0 / 255.0 + b0 / 255.0;
}
}

View File

@@ -853,8 +853,6 @@ sun/security/tools/keytool/ListKeychainStore.sh
security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all
security/infra/java/security/cert/CertPathValidator/certification/BuypassCA.java 8243543 generic-all
security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java 8263059 generic-all
security/infra/java/security/cert/CertPathValidator/certification/LetsEncryptCA.java 8268678 generic-all
security/infra/java/security/cert/CertPathValidator/certification/QuoVadisCA.java 8248899 generic-all
############################################################################

View File

@@ -116,38 +116,38 @@ public class LetsEncryptCA {
// Owner: CN=revoked-isrgrootx1.letsencrypt.org
// Issuer: CN=R3, O=Let's Encrypt, C=US
// Serial number: 3626488cf28e94f1719074128bbb58a7829
// Valid from: Thu Apr 08 15:58:32 PDT 2021 until: Wed Jul 07 15:58:32 PDT 2021
// Serial number: 4f1333011635d76d6356c5f1fb8a7273617
// Valid from: Fri Jun 25 08:18:10 PDT 2021 until: Thu Sep 23 08:18:09 PDT 2021
private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
"MIIFSjCCBDKgAwIBAgISA2JkiM8o6U8XGQdBKLu1ingpMA0GCSqGSIb3DQEBCwUA\n" +
"MIIFSTCCBDGgAwIBAgISBPEzMBFjXXbWNWxfH7inJzYXMA0GCSqGSIb3DQEBCwUA\n" +
"MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n" +
"EwJSMzAeFw0yMTA0MDgyMjU4MzJaFw0yMTA3MDcyMjU4MzJaMC0xKzApBgNVBAMT\n" +
"EwJSMzAeFw0yMTA2MjUxNTE4MTBaFw0yMTA5MjMxNTE4MDlaMC0xKzApBgNVBAMT\n" +
"InJldm9rZWQtaXNyZ3Jvb3R4MS5sZXRzZW5jcnlwdC5vcmcwggEiMA0GCSqGSIb3\n" +
"DQEBAQUAA4IBDwAwggEKAoIBAQC1NecSgcQLX4K94pR0HBaUun8wi++lyNTGkpoY\n" +
"4xGB7M/WMnJpR8Y+49sO6QSe7fyU18zMjunT3Z5ahQtQi27dGU+xS7KUJUZl2NSJ\n" +
"4MLf717cSbBmDBvZiqmuXmUuy5Ehhabk1jBx1NgsR9uqsJFyILPc9sEAKq6MwT7N\n" +
"CnaVW1QhpUB9F5Zlc8cmHuhMsyrxGTM3h6P7QeVpqBT91mBEukvWUb01eifk134v\n" +
"Sv1gXblr2bksHd9fiIoQvEUnSK9hXcRilDpOjaF5qkiNsQPpuEZqM56XyfOSeaCr\n" +
"1HtEYa5Y+SXZ4G4Jt4AZt44WKoDwika9Iex826rETvAFaiTFAgMBAAGjggJdMIIC\n" +
"WTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" +
"MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFEwvrwbqSUpGjtFPPpoXpNO77gJuMB8G\n" +
"DQEBAQUAA4IBDwAwggEKAoIBAQCkCp4fq7FnN5lfAWX0vhCcyC5WO9TuU6ckuYYj\n" +
"8/wQ8GQ/FIl+vXCAmHIfIX14irQN8TISeVdMOP0C7sa73d3GSawX7qMaRhddXn7V\n" +
"EL+4CbHQ6qit5YkakwhHz9tKbYX16wPj+inn22kJVwi8iLbhYB9WWSvv7OyiNSHv\n" +
"nmlYUkMv8+9UhgPT4yCKF1OEI5ajUOuecjOKc+EzsT/JqPRErvBOIKn3PRn4h8UM\n" +
"0BJDrDtZMpkvD4/lyRs3g/BLsf3DQjlEgKit0hvc72yyhiDbKd41EmBoQC5rNF7o\n" +
"B0CnBXhDLHbC/YRunVrYGsF0h2J9hw4055BdaXbS2BJnPEFnAgMBAAGjggJcMIIC\n" +
"WDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\n" +
"MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJBkf3Z/ICoCTUx3JCgrBeoMyedQMB8G\n" +
"A1UdIwQYMBaAFBQusxe3WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAh\n" +
"BggrBgEFBQcwAYYVaHR0cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZo\n" +
"dHRwOi8vcjMuaS5sZW5jci5vcmcvMC0GA1UdEQQmMCSCInJldm9rZWQtaXNyZ3Jv\n" +
"b3R4MS5sZXRzZW5jcnlwdC5vcmcwTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYB\n" +
"BAGC3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5v\n" +
"cmcwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgBElGUusO7Or8RAB9io/ijA2uaC\n" +
"vtjLMbU/0zOWtbaBqAAAAXiz7FLbAAAEAwBHMEUCIA8aoTszzeBJMP0aOhnMVizJ\n" +
"mQe6c+OHAjG+dP1y9bD2AiEA0oJOb9ZKys+OE0JP5JT0kjdYH8U3ibJ+k6nHKMOI\n" +
"CdgAdgD2XJQv0XcwIhRUGAgwlFaO400TGTO/3wwvIAvMTvFk4wAAAXiz7FLQAAAE\n" +
"AwBHMEUCIGTdYSTO0IXQ6HSLwwGw1rlkH+lmg7EFpC+A25lhgtWCAiEAgi/7FtTG\n" +
"KWKkWLU7ZP1AqIaaWlyXzRK2myrYKcBE804wDQYJKoZIhvcNAQELBQADggEBAByr\n" +
"Q4mfzlT+4OBDI4hFjdrPHeHgePUK0HsmQ7GPNwe3pIxTQYs6fKIv+jb4mzKiggLy\n" +
"882L+cYLfafggIpRjcoV9bAR2ceea+7uiyat54w5UZYLAmHgAdd4Y7OAUcrTL8rg\n" +
"SAXNECrCGIfh0PwxyoJEgxcJnOoGgD5lVAycspUl3u3itmu9tcjcZA7CD5t2xPTQ\n" +
"j/eoqH+5fHGXIvZuZxRVllWRwtLHRNafYiotLAW0P1i0i3wevTqmQ8ABVUuzYmJE\n" +
"hjTktcZqbYIZqkDalLcGXJm8FFILQHv/vhXd/G2IbPODYgjTS7e4jCTXg2eIf17Z\n" +
"yzs5yR8FPDdK48UWPgU=\n" +
"cmcwggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdQCUILwejtWNbIhzH4KLIiwN0dpN\n" +
"XmxPlD1h204vWE2iwgAAAXpD9t6nAAAEAwBGMEQCIHwF9NcPqsovYp56lhqFkWYj\n" +
"QCATATrLzzxgUoLDYRwgAiBBecqe5Ub32I+q9oqH1nbK/s8QadcafIL3bkrRVbFB\n" +
"TAB2AH0+8viP/4hVaCTCwMqeUol5K8UOeAl/LmqXaJl+IvDXAAABekP23sYAAAQD\n" +
"AEcwRQIgGli/1mmKKnZ0uxDIX7ySqAyD2C7FTf+y3py2S0Xcv4YCIQCZve3cqKZ2\n" +
"lrEyyaMeLZA+PIxUMniHx3gDkro0sKLzOzANBgkqhkiG9w0BAQsFAAOCAQEAle42\n" +
"p58OTusm7DAOcdK4ld+pJu2bz9F940Wrnql08rciRjGIVpp5PhMNFm9AOaptKPNY\n" +
"h62V2GEOVaLxmvr9/8EDFcCCPAGV1DNYrG9aTKaiXk7IzO4UxKbzox4iUcuop/zB\n" +
"uofxT8uBLmT4XYZrQXXKj1KdfJGzgeoXqBv5PPCiP3hmBQixoJnSKImnUIXWh4O8\n" +
"kBtmgII5ug0q+jI3LvpJuv7xQsaNYFBcmFiQQ7YRt4W99GMdbYGjhzT8iBDEH7nG\n" +
"MsqWuwB5TN5vIuw2aWxcfaqKayq7UPA4rJePWdD/5RzKlQKLQx0BA3AL+3Nnj1fT\n" +
"NEKwCWWylIND6z/9Xw==\n" +
"-----END CERTIFICATE-----";
public static void main(String[] args) throws Exception {
@@ -168,9 +168,6 @@ public class LetsEncryptCA {
ValidatePathWithParams pathValidator = new ValidatePathWithParams(new String[]{INT});
pathValidator.enableOCSPCheck();
// Perform backdate check as test artifacts expire in July 2021
pathValidator.setValidationDate("June 15, 2021");
// Validate valid
pathValidator.validate(new String[]{VALID},
ValidatePathWithParams.Status.GOOD, null, System.out);
@@ -178,6 +175,6 @@ public class LetsEncryptCA {
// Validate Revoked
pathValidator.validate(new String[]{REVOKED},
ValidatePathWithParams.Status.REVOKED,
"Thu Apr 08 17:05:26 PDT 2021", System.out);
"Fri Jun 25 09:18:12 PDT 2021", System.out);
}
}