Merge
This commit is contained in:
commit
15d051e851
@ -274,11 +274,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java \
|
||||
$(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
|
||||
|
||||
# JObjC.jar contains 1.5 byte-code...so skip it here :-(
|
||||
# MACOSX_SRC_DIRS += $(JDK_TOPDIR)/src/macosx/native/jobjc/src
|
||||
# EXCLUDES += tests/java/com/apple/jobjc
|
||||
|
||||
EXCLUDES += com/apple/jobjc
|
||||
endif
|
||||
|
||||
# The security classes should not end up in the classes directory as that will prevent them
|
||||
@ -354,44 +349,6 @@ $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin:
|
||||
|
||||
##########################################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
#
|
||||
# JObjC.jar is compiled with BOOT_JAVAC which (may) not support the "-h" flag.
|
||||
# so we first compile classes with BOOT_JAVAC and then with JDK_JAVAC :-(
|
||||
#
|
||||
$(eval $(call SetupJavaCompiler,GENERATE_15BYTECODE, \
|
||||
JAVAC := $(JAVAC), \
|
||||
FLAGS := -source 1.5 -target 1.5 -g -bootclasspath $(BOOT_RTJAR) -cp $(JDK_OUTPUTDIR)/../langtools/dist/lib/classes.jar $(DISABLE_WARNINGS), \
|
||||
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
|
||||
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
|
||||
|
||||
$(eval $(call SetupJavaCompilation,BUILD_JOBJC, \
|
||||
SETUP := GENERATE_15BYTECODE, \
|
||||
DISABLE_SJAVAC := true, \
|
||||
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||
INCLUDES := com/apple/jobjc, \
|
||||
EXCLUDES := tests/java/com/apple/jobjc, \
|
||||
BIN := $(JDK_OUTPUTDIR)/jobjc_classes, \
|
||||
JAR := $(JDK_OUTPUTDIR)/lib/JObjC.jar, \
|
||||
JARINDEX := true))
|
||||
|
||||
$(BUILD_JOBJC): $(BUILD_JDK)
|
||||
|
||||
$(eval $(call SetupJavaCompilation,BUILD_JOBJC_HEADERS, \
|
||||
SETUP := GENERATE_JDKBYTECODE, \
|
||||
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/java \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/java \
|
||||
$(JDK_OUTPUTDIR)/gensrc_jobjc/src, \
|
||||
INCLUDES := com/apple/jobjc, \
|
||||
EXCLUDES := tests/java/com/apple/jobjc, \
|
||||
BIN := $(JDK_OUTPUTDIR)/jobjc_classes_headers, \
|
||||
HEADERS := $(JDK_OUTPUTDIR)/gensrc_headers_jobjc))
|
||||
|
||||
$(BUILD_JOBJC_HEADERS): $(BUILD_JDK)
|
||||
|
||||
endif
|
||||
|
||||
##########################################################################################
|
||||
|
||||
|
@ -693,13 +693,6 @@ $(IMAGES_OUTPUTDIR)/lib/ext/zipfs.jar: $(JDK_OUTPUTDIR)/demo/nio/zipfs/zipfs.jar
|
||||
|
||||
##########################################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(eval $(call SetupArchive,BUILD_JOBJC_JAR, , \
|
||||
SRCS := $(JDK_OUTPUTDIR)/jobjc_classes, \
|
||||
JAR := $(IMAGES_OUTPUTDIR)/lib/JObjC.jar, \
|
||||
JARINDEX := true))
|
||||
endif
|
||||
|
||||
# This file is imported from hotspot in Import.gmk. Copying it into images/lib so that
|
||||
# all jars can be found in one place when creating images in Images.gmk. It needs to be
|
||||
# done here so that clean targets can be simple and accurate.
|
||||
|
@ -85,11 +85,6 @@ GENSRC += $(GENSRC_CLDR)
|
||||
include gensrc/GensrcSwing.gmk
|
||||
GENSRC += $(GENSRC_SWING_BEANINFO) $(GENSRC_SWING_NIMBUS)
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
include gensrc/GensrcJObjC.gmk
|
||||
GENSRC += $(GENSRC_JOBJC)
|
||||
endif
|
||||
|
||||
$(GENSRC): $(BUILD_TOOLS)
|
||||
|
||||
all: $(GENSRC)
|
||||
|
@ -303,14 +303,13 @@ $(JDK_IMAGE_DIR)/jre/lib/applet:
|
||||
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
|
||||
$(MKDIR) -p $@
|
||||
|
||||
# In the old build, JObjC.jar is not part of the meta-index
|
||||
$(JRE_IMAGE_DIR)/lib/meta-index: $(JRE_LIB_TARGETS)
|
||||
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
|
||||
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
|
||||
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
|
||||
|
||||
$(JDK_IMAGE_DIR)/jre/lib/meta-index: $(JDKJRE_LIB_TARGETS)
|
||||
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
|
||||
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index `$(LS) *.jar | $(SED) 's/JObjC\.jar//g'`
|
||||
$(CD) $(@D) && $(TOOL_BUILDMETAINDEX) -o meta-index *.jar
|
||||
|
||||
$(JRE_IMAGE_DIR)/lib/ext/meta-index: $(JRE_LIB_TARGETS)
|
||||
$(ECHO) $(LOG_INFO) Generating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
|
||||
|
@ -105,10 +105,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
|
||||
endif
|
||||
|
||||
ifeq ($(PROFILE), profile_1)
|
||||
PROFILE_JARS := $(PROFILE_1_JARS)
|
||||
else ifeq ($(PROFILE), profile_2)
|
||||
|
@ -136,64 +136,6 @@ endif
|
||||
|
||||
##########################################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC32, \
|
||||
LIBRARY := JObjC, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
|
||||
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := -fpascal-strings \
|
||||
-fobjc-gc \
|
||||
-gdwarf-2 \
|
||||
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
|
||||
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
|
||||
-m32, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
-m32, \
|
||||
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
|
||||
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
|
||||
-framework JavaNativeFoundation \
|
||||
-lffi, \
|
||||
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc32, \
|
||||
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJOBJC64, \
|
||||
LIBRARY := JObjC, \
|
||||
OUTPUT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
|
||||
SRC := $(JDK_TOPDIR)/src/macosx/native/jobjc/src/core/native \
|
||||
$(JDK_TOPDIR)/src/macosx/native/jobjc/src/runtime-additions/native, \
|
||||
LANG := C, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := -fpascal-strings \
|
||||
-fobjc-gc \
|
||||
-gdwarf-2 \
|
||||
$(CFLAGS_JDKLIB) -I$(JDK_OUTPUTDIR)/gensrc_headers_jobjc \
|
||||
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
|
||||
, \
|
||||
LDFLAGS := -fpascal-strings \
|
||||
-fobjc-gc \
|
||||
-gdwarf-2 \
|
||||
$(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LDFLAGS_SUFFIX := -framework Foundation -framework JavaVM \
|
||||
-F/System/Library/Frameworks/JavaVM.framework/Frameworks \
|
||||
-framework JavaNativeFoundation \
|
||||
-lffi, \
|
||||
OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libjobjc64, \
|
||||
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
|
||||
|
||||
$(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX): $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
|
||||
$(LIPO) -create -output $@ $(BUILD_LIBJOBJC32) $(BUILD_LIBJOBJC64)
|
||||
|
||||
BUILD_LIBRARIES += $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)JObjC$(SHARED_LIBRARY_SUFFIX)
|
||||
|
||||
endif
|
||||
|
||||
##########################################################################################
|
||||
|
||||
ifndef OPENJDK
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
|
||||
|
@ -290,8 +290,8 @@ SplashEventLoop(Splash * splash) {
|
||||
SplashUnlock(splash);
|
||||
rc = poll(pfd, 1, timeout);
|
||||
SplashLock(splash);
|
||||
if (splash->isVisible>0 && SplashTime() >= splash->time +
|
||||
splash->frames[splash->currentFrame].delay) {
|
||||
if (splash->isVisible > 0 && splash->currentFrame >= 0 &&
|
||||
SplashTime() >= splash->time + splash->frames[splash->currentFrame].delay) {
|
||||
SplashNextFrame(splash);
|
||||
SplashRedrawWindow(splash);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import com.sun.beans.finder.ClassFinder;
|
||||
import java.beans.ExceptionListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
@ -245,6 +246,14 @@ public final class DocumentHandler extends DefaultHandler {
|
||||
this.objects.add(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables any external entities.
|
||||
*/
|
||||
@Override
|
||||
public InputSource resolveEntity(String publicId, String systemId) {
|
||||
return new InputSource(new StringReader(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares this handler to read objects from XML document.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -72,13 +72,17 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
|
||||
throw new IllegalStateException(
|
||||
"TlsRsaPremasterSecretGenerator must be initialized");
|
||||
}
|
||||
if (random == null) {
|
||||
random = new SecureRandom();
|
||||
byte[] b = spec.getEncodedSecret();
|
||||
if (b == null) {
|
||||
if (random == null) {
|
||||
random = new SecureRandom();
|
||||
}
|
||||
b = new byte[48];
|
||||
random.nextBytes(b);
|
||||
b[0] = (byte)spec.getMajorVersion();
|
||||
b[1] = (byte)spec.getMinorVersion();
|
||||
}
|
||||
byte[] b = new byte[48];
|
||||
random.nextBytes(b);
|
||||
b[0] = (byte)spec.getMajorVersion();
|
||||
b[1] = (byte)spec.getMinorVersion();
|
||||
|
||||
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
|
||||
}
|
||||
|
||||
|
@ -27,17 +27,9 @@ package com.sun.jmx.snmp.agent;
|
||||
|
||||
// java imports
|
||||
//
|
||||
import com.sun.jmx.snmp.SnmpDefinitions;
|
||||
import java.io.Serializable;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
|
||||
// jmx imports
|
||||
//
|
||||
import com.sun.jmx.snmp.SnmpValue;
|
||||
import com.sun.jmx.snmp.SnmpVarBind;
|
||||
import com.sun.jmx.snmp.SnmpStatusException;
|
||||
import com.sun.jmx.snmp.agent.SnmpMibOid;
|
||||
import com.sun.jmx.snmp.agent.SnmpMibNode;
|
||||
|
||||
/**
|
||||
* Represents a node in an SNMP MIB which corresponds to a table entry
|
||||
@ -99,7 +91,9 @@ public abstract class SnmpMibEntry extends SnmpMibNode
|
||||
*/
|
||||
public void validateVarId(long arc, Object userData)
|
||||
throws SnmpStatusException {
|
||||
if (isVariable(arc) == false) throw noSuchNameException;
|
||||
if (isVariable(arc) == false) {
|
||||
throw new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,8 +108,9 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
*/
|
||||
public void validateVarId(long arc, Object userData)
|
||||
throws SnmpStatusException {
|
||||
if (isVariable(arc) == false)
|
||||
throw noSuchObjectException;
|
||||
if (isVariable(arc) == false) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -360,17 +361,20 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
validateVarId(arc, data);
|
||||
|
||||
// The trailing .0 is missing in the OID
|
||||
if (depth+2 > length)
|
||||
throw noSuchInstanceException;
|
||||
if (depth+2 > length) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
// There are too many arcs left in the OID (there should remain
|
||||
// a single trailing .0)
|
||||
if (depth+2 < length)
|
||||
throw noSuchInstanceException;
|
||||
if (depth+2 < length) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
// The last trailing arc is not .0
|
||||
if (oid[depth+1] != 0L)
|
||||
throw noSuchInstanceException;
|
||||
if (oid[depth+1] != 0L) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
// It's one of our variable, register this node.
|
||||
handlers.add(this,depth,varbind);
|
||||
@ -389,12 +393,13 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
int length = oid.length;
|
||||
SnmpMibNode node = null;
|
||||
|
||||
if (handlers == null)
|
||||
if (handlers == null) {
|
||||
// This should be considered as a genErr, but we do not want to
|
||||
// abort the whole request, so we're going to throw
|
||||
// a noSuchObject...
|
||||
//
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
final Object data = handlers.getUserData();
|
||||
final int pduVersion = handlers.getRequestPduVersion();
|
||||
@ -430,7 +435,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
depth+1,handlers,
|
||||
checker);
|
||||
}catch(SnmpStatusException ex) {
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
} finally {
|
||||
checker.remove(depth);
|
||||
}
|
||||
@ -455,7 +460,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
try {
|
||||
checker.checkCurrentOid();
|
||||
} catch(SnmpStatusException e) {
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
} finally {
|
||||
checker.remove(depth,2);
|
||||
}
|
||||
@ -500,7 +505,7 @@ public abstract class SnmpMibGroup extends SnmpMibOid
|
||||
// The oid is not valid, we will throw an exception in order
|
||||
// to try with the next valid identifier...
|
||||
//
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
|
||||
} catch (SnmpStatusException e) {
|
||||
// We didn't find anything at the given arc, so we're going
|
||||
|
@ -155,7 +155,7 @@ public abstract class SnmpMibNode implements Serializable {
|
||||
long[] oid, int depth,
|
||||
SnmpRequestTree handlers)
|
||||
throws SnmpStatusException {
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,7 +183,7 @@ public abstract class SnmpMibNode implements Serializable {
|
||||
long[] oid, int pos, int depth,
|
||||
SnmpRequestTree handlers, AcmChecker checker)
|
||||
throws SnmpStatusException {
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -346,8 +346,9 @@ public abstract class SnmpMibNode implements Serializable {
|
||||
final int[] a = table;
|
||||
final int val= (int) value;
|
||||
|
||||
if (a == null)
|
||||
throw noSuchObjectException;
|
||||
if (a == null) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
int low= 0;
|
||||
int max= a.length;
|
||||
@ -356,11 +357,13 @@ public abstract class SnmpMibNode implements Serializable {
|
||||
|
||||
// Basic check
|
||||
//
|
||||
if (max < 1)
|
||||
throw noSuchObjectException;
|
||||
if (max < 1) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
if (a[max-1] <= val)
|
||||
throw noSuchObjectException;
|
||||
if (a[max-1] <= val) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
while (low <= max) {
|
||||
elmt= a[curr];
|
||||
@ -400,15 +403,4 @@ public abstract class SnmpMibNode implements Serializable {
|
||||
* Contains the list of variable identifiers.
|
||||
*/
|
||||
protected int[] varList;
|
||||
|
||||
/**
|
||||
* Contains a predefined exception that is often fired when an
|
||||
* object is not found in the MIB.
|
||||
*/
|
||||
static final protected SnmpStatusException noSuchInstanceException =
|
||||
new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
static final protected SnmpStatusException noSuchObjectException =
|
||||
new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
static final protected SnmpStatusException noSuchNameException =
|
||||
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName);
|
||||
}
|
||||
|
@ -160,12 +160,10 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
|
||||
|
||||
if (depth > length) {
|
||||
// Nothing is left... the oid is not valid
|
||||
throw noSuchObjectException;
|
||||
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
} else if (depth == length) {
|
||||
// The oid is not complete...
|
||||
throw noSuchInstanceException;
|
||||
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
} else {
|
||||
// Some children variable or subobject is being querried
|
||||
// getChild() will raise an exception if no child is found.
|
||||
@ -205,12 +203,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
|
||||
final int length = oid.length;
|
||||
SnmpMibNode node = null;
|
||||
long[] result = null;
|
||||
if (handlers == null)
|
||||
if (handlers == null) {
|
||||
// This should be considered as a genErr, but we do not want to
|
||||
// abort the whole request, so we're going to throw
|
||||
// a noSuchObject...
|
||||
//
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
final Object data = handlers.getUserData();
|
||||
final int pduVersion = handlers.getRequestPduVersion();
|
||||
@ -235,7 +234,7 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
|
||||
// SnmpOid result = null;
|
||||
if (child == null) {
|
||||
// shouldn't happen
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
// validateVarId(index);
|
||||
// handlers.add(this,varbind,depth);
|
||||
// result = new SnmpOid(0);
|
||||
@ -444,11 +443,13 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
|
||||
// first we need to retrieve the identifier in the list of children
|
||||
//
|
||||
final int pos= getInsertAt(id);
|
||||
if (pos >= nbChildren)
|
||||
throw noSuchObjectException;
|
||||
if (pos >= nbChildren) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
if (varList[pos] != (int) id)
|
||||
throw noSuchObjectException;
|
||||
if (varList[pos] != (int) id) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
// Access the node
|
||||
//
|
||||
@ -456,10 +457,11 @@ public class SnmpMibOid extends SnmpMibNode implements Serializable {
|
||||
try {
|
||||
child = children.elementAtNonSync(pos);
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
if (child == null) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
if (child == null)
|
||||
throw noSuchInstanceException;
|
||||
return child;
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
SnmpVarBind var;
|
||||
for (Enumeration<SnmpVarBind> e= r.getElements(); e.hasMoreElements();) {
|
||||
var = e.nextElement();
|
||||
r.registerGetException(var,noSuchInstanceException);
|
||||
r.registerGetException(var,new SnmpStatusException(SnmpStatusException.noSuchInstance));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1607,8 +1607,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
protected SnmpOid getNextOid(SnmpOid oid, Object userData)
|
||||
throws SnmpStatusException {
|
||||
|
||||
if (size == 0)
|
||||
throw noSuchInstanceException;
|
||||
if (size == 0) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
final SnmpOid resOid = oid;
|
||||
|
||||
@ -1619,7 +1620,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
if (last.equals(resOid)) {
|
||||
// Last element of the table ...
|
||||
//
|
||||
throw noSuchInstanceException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
// First find the oid. This will allow to speed up retrieval process
|
||||
@ -1641,12 +1642,12 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// XX last = (SnmpOid) oids.elementAt(newPos);
|
||||
last = tableoids[newPos];
|
||||
} catch(ArrayIndexOutOfBoundsException e) {
|
||||
throw noSuchInstanceException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
} else {
|
||||
// We are dealing with the last element of the table ..
|
||||
//
|
||||
throw noSuchInstanceException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
|
||||
@ -1668,8 +1669,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
*/
|
||||
protected SnmpOid getNextOid(Object userData)
|
||||
throws SnmpStatusException {
|
||||
if (size == 0)
|
||||
throw noSuchInstanceException;
|
||||
if (size == 0) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
// XX return (SnmpOid) oids.firstElement();
|
||||
return tableoids[0];
|
||||
}
|
||||
@ -1875,10 +1877,10 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// not support creation.
|
||||
// We know that the entry does not exists if (isentry == false).
|
||||
if (!hasEntry) {
|
||||
if (!handlers.isCreationAllowed())
|
||||
if (!handlers.isCreationAllowed()) {
|
||||
// we're not doing a set
|
||||
throw noSuchInstanceException;
|
||||
else if (!isCreationEnabled())
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
} else if (!isCreationEnabled())
|
||||
// we're doing a set but creation is disabled.
|
||||
throw new
|
||||
SnmpStatusException(SnmpStatusException.snmpRspNoAccess);
|
||||
@ -1922,12 +1924,13 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
|
||||
int length = oid.length;
|
||||
|
||||
if (handlers == null)
|
||||
// This should be considered as a genErr, but we do not want to
|
||||
// abort the whole request, so we're going to throw
|
||||
// a noSuchObject...
|
||||
//
|
||||
throw noSuchObjectException;
|
||||
if (handlers == null) {
|
||||
// This should be considered as a genErr, but we do not want to
|
||||
// abort the whole request, so we're going to throw
|
||||
// a noSuchObject...
|
||||
//
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
final Object data = handlers.getUserData();
|
||||
final int pduVersion = handlers.getRequestPduVersion();
|
||||
@ -1961,7 +1964,7 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// so we won't find the next element in this table... (any
|
||||
// element in this table will have a smaller OID)
|
||||
//
|
||||
throw noSuchObjectException;
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
} else if (oid[pos] < nodeId) {
|
||||
// we must return the first leaf under the first columnar
|
||||
// object, so we are back to our first case where pos was
|
||||
@ -2051,8 +2054,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// in tables can't be properly supported (all rows
|
||||
// must have the same holes)
|
||||
//
|
||||
if (skipEntryVariable(entryoid,var,data,pduVersion))
|
||||
throw noSuchObjectException;
|
||||
if (skipEntryVariable(entryoid,var,data,pduVersion)) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
} catch(SnmpStatusException se) {
|
||||
entryoid = getNextOid(data);
|
||||
var = getNextVarEntryId(entryoid,var,data,pduVersion);
|
||||
@ -2085,8 +2089,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// So we throw the exception.
|
||||
// => will skip to next node in the MIB tree.
|
||||
//
|
||||
if (entryoid == null || var == -1 ) throw noSuchObjectException;
|
||||
|
||||
if (entryoid == null || var == -1 ) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
// So here we know both the row (entryoid) and the column (var)
|
||||
//
|
||||
@ -2097,8 +2102,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// for this specific entry, it is not readable for any
|
||||
// other entry => skip to next column.
|
||||
//
|
||||
if (!isReadableEntryId(entryoid,var,data))
|
||||
throw noSuchObjectException;
|
||||
if (!isReadableEntryId(entryoid,var,data)) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
|
||||
// Prepare the result and the ACM checker.
|
||||
//
|
||||
@ -2161,8 +2167,9 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
// No need to continue, we throw an exception.
|
||||
// => will skip to next node in the MIB tree.
|
||||
//
|
||||
if (entryoid == null || var == -1 )
|
||||
throw noSuchObjectException;
|
||||
if (entryoid == null || var == -1 ) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2182,14 +2189,15 @@ public abstract class SnmpMibTable extends SnmpMibNode
|
||||
|
||||
// Control the length of the oid
|
||||
//
|
||||
if (pos +2 >= length)
|
||||
throw noSuchInstanceException;
|
||||
if (pos +2 >= length) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchInstance);
|
||||
}
|
||||
|
||||
// Check that the entry identifier is specified
|
||||
//
|
||||
if (oid[pos] != nodeId)
|
||||
throw noSuchObjectException;
|
||||
|
||||
if (oid[pos] != nodeId) {
|
||||
throw new SnmpStatusException(SnmpStatusException.noSuchObject);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -1146,7 +1146,4 @@ class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions {
|
||||
|
||||
static final private String InterruptSysCallMsg =
|
||||
"Interrupted system call";
|
||||
|
||||
static final private SnmpStatusException noSuchNameException =
|
||||
new SnmpStatusException(SnmpDefinitions.snmpRspNoSuchName) ;
|
||||
}
|
||||
|
@ -56,9 +56,12 @@ public final class FactoryEnumeration {
|
||||
* references so as not to prevent GC of the class loader. Each
|
||||
* weak reference is tagged with the factory's class name so the
|
||||
* class can be reloaded if the reference is cleared.
|
||||
|
||||
*
|
||||
* @param factories A non-null list
|
||||
* @param loader The class loader of the list's contents
|
||||
*
|
||||
* This internal method is used with Thread Context Class Loader (TCCL),
|
||||
* please don't expose this method as public.
|
||||
*/
|
||||
FactoryEnumeration(List<NamedWeakReference<Object>> factories,
|
||||
ClassLoader loader) {
|
||||
@ -79,7 +82,9 @@ public final class FactoryEnumeration {
|
||||
|
||||
try {
|
||||
if (answer == null) { // reload class if weak ref cleared
|
||||
answer = Class.forName(className, true, loader);
|
||||
Class<?> cls = Class.forName(className, true, loader);
|
||||
VersionHelper12.checkPackageAccess(cls);
|
||||
answer = cls;
|
||||
}
|
||||
// Instantiate Class to get factory
|
||||
answer = ((Class) answer).newInstance();
|
||||
|
@ -39,6 +39,7 @@ import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.*;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* VersionHelper was used by JNDI to accommodate differences between
|
||||
@ -53,21 +54,39 @@ import javax.naming.*;
|
||||
|
||||
final class VersionHelper12 extends VersionHelper {
|
||||
|
||||
private boolean getSystemPropsFailed = false;
|
||||
// workaround to disable additional package access control with
|
||||
// Thread Context Class Loader (TCCL).
|
||||
private final static boolean noPackageAccessWithTCCL = "true".equals(
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(
|
||||
"com.sun.naming.untieAccessContextWithTCCL");
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
VersionHelper12() {} // Disallow external from creating one of these.
|
||||
// Disallow external from creating one of these.
|
||||
VersionHelper12() {
|
||||
}
|
||||
|
||||
public Class<?> loadClass(String className) throws ClassNotFoundException {
|
||||
ClassLoader cl = getContextClassLoader();
|
||||
return Class.forName(className, true, cl);
|
||||
return loadClass(className, getContextClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Package private.
|
||||
*/
|
||||
* Package private.
|
||||
*
|
||||
* This internal method is used with Thread Context Class Loader (TCCL),
|
||||
* please don't expose this method as public.
|
||||
*/
|
||||
Class<?> loadClass(String className, ClassLoader cl)
|
||||
throws ClassNotFoundException {
|
||||
return Class.forName(className, true, cl);
|
||||
Class<?> cls = Class.forName(className, true, cl);
|
||||
if (!noPackageAccessWithTCCL) {
|
||||
checkPackageAccess(cls);
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,13 +94,42 @@ final class VersionHelper12 extends VersionHelper {
|
||||
* @param codebase A non-null, space-separated list of URL strings.
|
||||
*/
|
||||
public Class<?> loadClass(String className, String codebase)
|
||||
throws ClassNotFoundException, MalformedURLException {
|
||||
ClassLoader cl;
|
||||
throws ClassNotFoundException, MalformedURLException {
|
||||
|
||||
ClassLoader parent = getContextClassLoader();
|
||||
cl = URLClassLoader.newInstance(getUrlArray(codebase), parent);
|
||||
ClassLoader cl =
|
||||
URLClassLoader.newInstance(getUrlArray(codebase), parent);
|
||||
|
||||
return Class.forName(className, true, cl);
|
||||
return loadClass(className, cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* check package access of a class that is loaded with Thread Context
|
||||
* Class Loader (TCCL).
|
||||
*
|
||||
* Similar to java.lang.ClassLoader.checkPackageAccess()
|
||||
*/
|
||||
static void checkPackageAccess(Class<?> cls) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
if (ReflectUtil.isNonPublicProxyClass(cls)) {
|
||||
for (Class<?> intf: cls.getInterfaces()) {
|
||||
checkPackageAccess(intf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = cls.getName();
|
||||
final int i = name.lastIndexOf('.');
|
||||
if (i != -1) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
sm.checkPackageAccess(name.substring(0, i));
|
||||
return null;
|
||||
}
|
||||
}, AccessController.getContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getJndiProperty(final int i) {
|
||||
@ -99,16 +147,12 @@ final class VersionHelper12 extends VersionHelper {
|
||||
}
|
||||
|
||||
String[] getJndiProperties() {
|
||||
if (getSystemPropsFailed) {
|
||||
return null; // after one failure, don't bother trying again
|
||||
}
|
||||
Properties sysProps = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Properties>() {
|
||||
public Properties run() {
|
||||
try {
|
||||
return System.getProperties();
|
||||
} catch (SecurityException e) {
|
||||
getSystemPropsFailed = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -173,7 +217,17 @@ final class VersionHelper12 extends VersionHelper {
|
||||
return new InputStreamEnumeration(urls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Package private.
|
||||
*
|
||||
* This internal method makes use of Thread Context Class Loader (TCCL),
|
||||
* please don't expose this method as public.
|
||||
*
|
||||
* Please take care of package access control on the current context
|
||||
* whenever using TCCL.
|
||||
*/
|
||||
ClassLoader getContextClassLoader() {
|
||||
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
@ -183,7 +237,6 @@ final class VersionHelper12 extends VersionHelper {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an enumeration of URLs, an instance of this class represents
|
||||
* an enumeration of their InputStreams. Each operation on the URL
|
||||
|
@ -382,7 +382,8 @@ public abstract class Canonicalizer11 extends CanonicalizerBase {
|
||||
} else if (!isVisible(xmlns)) {
|
||||
//There is a definition but the xmlns is not selected by the xpath.
|
||||
//then xmlns=""
|
||||
n = ns.addMappingAndRender(XMLNS, "", nullNode);
|
||||
n = ns.addMappingAndRender(
|
||||
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
|
||||
}
|
||||
//output the xmlns def if needed.
|
||||
if (n != null) {
|
||||
|
@ -327,7 +327,8 @@ public abstract class Canonicalizer20010315 extends CanonicalizerBase {
|
||||
} else if (!isVisible(xmlns)) {
|
||||
//There is a definition but the xmlns is not selected by the xpath.
|
||||
//then xmlns=""
|
||||
n = ns.addMappingAndRender(XMLNS, "", nullNode);
|
||||
n = ns.addMappingAndRender(
|
||||
XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
|
||||
}
|
||||
//output the xmlns def if needed.
|
||||
if (n != null) {
|
||||
|
@ -292,7 +292,7 @@ public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
|
||||
if (xmlns != null && !isVisible(xmlns)) {
|
||||
// There is a definition but the xmlns is not selected by the
|
||||
// xpath. then xmlns=""
|
||||
ns.addMapping(XMLNS, "", nullNode);
|
||||
ns.addMapping(XMLNS, "", getNullNode(xmlns.getOwnerDocument()));
|
||||
}
|
||||
|
||||
String prefix = null;
|
||||
|
@ -34,8 +34,6 @@ import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
|
||||
@ -49,6 +47,7 @@ import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Comment;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.ProcessingInstruction;
|
||||
@ -64,7 +63,6 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
|
||||
public static final String XMLNS = "xmlns";
|
||||
|
||||
protected static final AttrCompare COMPARE = new AttrCompare();
|
||||
protected static final Attr nullNode;
|
||||
|
||||
private static final byte[] END_PI = {'?','>'};
|
||||
private static final byte[] BEGIN_PI = {'<','?'};
|
||||
@ -84,21 +82,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
|
||||
protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
|
||||
protected static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
|
||||
|
||||
static {
|
||||
// The null xmlns definition.
|
||||
try {
|
||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
nullNode = documentBuilder.newDocument().createAttributeNS(Constants.NamespaceSpecNS, XMLNS);
|
||||
nullNode.setValue("");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to create nullNode: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<NodeFilter> nodeFilter;
|
||||
|
||||
private boolean includeComments;
|
||||
private Set<Node> xpathNodeSet;
|
||||
|
||||
/**
|
||||
* The node to be skipped/excluded from the DOM tree
|
||||
* in subtree canonicalizations.
|
||||
@ -106,6 +94,11 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
|
||||
private Node excludeNode;
|
||||
private OutputStream writer = new ByteArrayOutputStream();
|
||||
|
||||
/**
|
||||
* The null xmlns definition.
|
||||
*/
|
||||
private Attr nullNode;
|
||||
|
||||
/**
|
||||
* Constructor CanonicalizerBase
|
||||
*
|
||||
@ -641,8 +634,9 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
|
||||
parents.clear();
|
||||
Attr nsprefix;
|
||||
if (((nsprefix = ns.getMappingWithoutRendered(XMLNS)) != null)
|
||||
&& "".equals(nsprefix.getValue())) {
|
||||
ns.addMappingAndRender(XMLNS, "", nullNode);
|
||||
&& "".equals(nsprefix.getValue())) {
|
||||
ns.addMappingAndRender(
|
||||
XMLNS, "", getNullNode(nsprefix.getOwnerDocument()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,4 +873,18 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
|
||||
}
|
||||
}
|
||||
|
||||
// The null xmlns definition.
|
||||
protected Attr getNullNode(Document ownerDocument) {
|
||||
if (nullNode == null) {
|
||||
try {
|
||||
nullNode = ownerDocument.createAttributeNS(
|
||||
Constants.NamespaceSpecNS, XMLNS);
|
||||
nullNode.setValue("");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to create nullNode: " + e);
|
||||
}
|
||||
}
|
||||
return nullNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -660,7 +660,7 @@ public class XmlReaderContentHandler extends DefaultHandler {
|
||||
//Added the handling for Class tags to take care of maps
|
||||
//Makes an entry into the map upon end of class tag
|
||||
try{
|
||||
typeMap.put(Key_map,Class.forName(Value_map));
|
||||
typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));
|
||||
|
||||
}catch(ClassNotFoundException ex) {
|
||||
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));
|
||||
|
@ -53,6 +53,13 @@ import sun.misc.SharedSecrets;
|
||||
* or method in this class will cause a {@link NullPointerException} to be
|
||||
* thrown.
|
||||
*
|
||||
* If the verify flag is on when opening a signed jar file, the content of the
|
||||
* file is verified against its signature embedded inside the file. Please note
|
||||
* that the verification process does not include validating the signer's
|
||||
* certificate. A caller should inspect the return value of
|
||||
* {@link JarEntry#getCodeSigners()} to further determine if the signature
|
||||
* can be trusted.
|
||||
*
|
||||
* @author David Connelly
|
||||
* @see Manifest
|
||||
* @see java.util.zip.ZipFile
|
||||
|
@ -179,7 +179,9 @@ class JarVerifier {
|
||||
name = name.substring(1);
|
||||
|
||||
// only set the jev object for entries that have a signature
|
||||
if (sigFileSigners.get(name) != null) {
|
||||
// (either verified or not)
|
||||
if (sigFileSigners.get(name) != null ||
|
||||
verifiedSigners.get(name) != null) {
|
||||
mev.setEntry(name, je);
|
||||
return;
|
||||
}
|
||||
|
@ -241,6 +241,11 @@ public class LogManager {
|
||||
* retrieved by calling LogManager.getLogManager.
|
||||
*/
|
||||
protected LogManager() {
|
||||
this(checkSubclassPermissions());
|
||||
}
|
||||
|
||||
private LogManager(Void checked) {
|
||||
|
||||
// Add a shutdown hook to close the global handlers.
|
||||
try {
|
||||
Runtime.getRuntime().addShutdownHook(new Cleaner());
|
||||
@ -250,6 +255,19 @@ public class LogManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static Void checkSubclassPermissions() {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
// These permission will be checked in the LogManager constructor,
|
||||
// in order to register the Cleaner() thread as a shutdown hook.
|
||||
// Check them here to avoid the penalty of constructing the object
|
||||
// etc...
|
||||
sm.checkPermission(new RuntimePermission("shutdownHooks"));
|
||||
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy initialization: if this instance of manager is the global
|
||||
* manager then this method will read the initial configuration and
|
||||
|
@ -91,7 +91,10 @@ public final class SimpleDoc implements Doc {
|
||||
|
||||
Class repClass = null;
|
||||
try {
|
||||
repClass = Class.forName(flavor.getRepresentationClassName());
|
||||
String className = flavor.getRepresentationClassName();
|
||||
sun.reflect.misc.ReflectUtil.checkPackageAccess(className);
|
||||
repClass = Class.forName(className, false,
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalArgumentException("unknown representation class");
|
||||
}
|
||||
|
@ -26,6 +26,10 @@
|
||||
package javax.security.auth;
|
||||
|
||||
import java.security.Security;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Objects;
|
||||
import sun.security.util.Debug;
|
||||
|
||||
/**
|
||||
@ -155,22 +159,15 @@ import sun.security.util.Debug;
|
||||
public abstract class Policy {
|
||||
|
||||
private static Policy policy;
|
||||
private static ClassLoader contextClassLoader;
|
||||
private final static String AUTH_POLICY =
|
||||
"sun.security.provider.AuthPolicyFile";
|
||||
|
||||
private final java.security.AccessControlContext acc =
|
||||
java.security.AccessController.getContext();
|
||||
|
||||
// true if a custom (not AUTH_POLICY) system-wide policy object is set
|
||||
private static boolean isCustomPolicy;
|
||||
|
||||
static {
|
||||
contextClassLoader = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sole constructor. (For invocation by subclass constructors, typically
|
||||
* implicit.)
|
||||
@ -213,8 +210,8 @@ public abstract class Policy {
|
||||
|
||||
if (policy == null) {
|
||||
String policy_class = null;
|
||||
policy_class = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<String>() {
|
||||
policy_class = AccessController.doPrivileged
|
||||
(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return java.security.Security.getProperty
|
||||
("auth.policy.provider");
|
||||
@ -226,18 +223,28 @@ public abstract class Policy {
|
||||
|
||||
try {
|
||||
final String finalClass = policy_class;
|
||||
policy = java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedExceptionAction<Policy>() {
|
||||
public Policy run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
return (Policy) Class.forName
|
||||
(finalClass,
|
||||
true,
|
||||
contextClassLoader).newInstance();
|
||||
}
|
||||
});
|
||||
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
|
||||
|
||||
Policy untrustedImpl = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Policy>() {
|
||||
public Policy run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
Class<? extends Policy> implClass = Class.forName(
|
||||
finalClass, false,
|
||||
Thread.currentThread().getContextClassLoader()
|
||||
).asSubclass(Policy.class);
|
||||
return implClass.newInstance();
|
||||
}
|
||||
});
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() {
|
||||
setPolicy(untrustedImpl);
|
||||
isCustomPolicy = !finalClass.equals(AUTH_POLICY);
|
||||
return null;
|
||||
}
|
||||
}, Objects.requireNonNull(untrustedImpl.acc)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException
|
||||
(sun.security.util.ResourcesMgr.getString
|
||||
|
@ -964,6 +964,10 @@ public final class Subject implements java.io.Serializable {
|
||||
|
||||
s.defaultReadObject();
|
||||
|
||||
// Rewrap the principals into a SecureSet
|
||||
principals = Collections.synchronizedSet(new SecureSet<Principal>
|
||||
(this, PRINCIPAL_SET, principals));
|
||||
|
||||
// The Credential {@code Set} is not serialized, but we do not
|
||||
// want the default deserialization routine to set it to null.
|
||||
this.pubCredentials = Collections.synchronizedSet
|
||||
|
@ -27,9 +27,6 @@ package javax.security.auth.login;
|
||||
|
||||
import javax.security.auth.AuthPermission;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.net.URI;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
@ -38,7 +35,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.SecurityPermission;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.security.jca.GetInstance;
|
||||
|
||||
@ -191,16 +188,9 @@ import sun.security.jca.GetInstance;
|
||||
public abstract class Configuration {
|
||||
|
||||
private static Configuration configuration;
|
||||
private static ClassLoader contextClassLoader;
|
||||
|
||||
static {
|
||||
contextClassLoader = AccessController.doPrivileged
|
||||
(new PrivilegedAction<ClassLoader>() {
|
||||
public ClassLoader run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
};
|
||||
private final java.security.AccessControlContext acc =
|
||||
java.security.AccessController.getContext();
|
||||
|
||||
private static void checkPermission(String type) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
@ -253,17 +243,26 @@ public abstract class Configuration {
|
||||
|
||||
try {
|
||||
final String finalClass = config_class;
|
||||
configuration = AccessController.doPrivileged
|
||||
(new PrivilegedExceptionAction<Configuration>() {
|
||||
public Configuration run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
return (Configuration)Class.forName
|
||||
(finalClass,
|
||||
true,
|
||||
contextClassLoader).newInstance();
|
||||
}
|
||||
});
|
||||
Configuration untrustedImpl = AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Configuration>() {
|
||||
public Configuration run() throws ClassNotFoundException,
|
||||
InstantiationException,
|
||||
IllegalAccessException {
|
||||
Class<? extends Configuration> implClass = Class.forName(
|
||||
finalClass, false,
|
||||
Thread.currentThread().getContextClassLoader()
|
||||
).asSubclass(Configuration.class);
|
||||
return implClass.newInstance();
|
||||
}
|
||||
});
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() {
|
||||
setConfiguration(untrustedImpl);
|
||||
return null;
|
||||
}
|
||||
}, Objects.requireNonNull(untrustedImpl.acc)
|
||||
);
|
||||
} catch (PrivilegedActionException e) {
|
||||
Exception ee = e.getException();
|
||||
if (ee instanceof InstantiationException) {
|
||||
|
@ -37,8 +37,10 @@ import javax.security.auth.AuthPermission;
|
||||
import javax.security.auth.callback.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.PrivilegedAction;
|
||||
import sun.security.util.PendingException;
|
||||
import sun.security.util.ResourcesMgr;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* <p> The {@code LoginContext} class describes the basic methods used
|
||||
@ -209,8 +211,7 @@ public class LoginContext {
|
||||
private Map<String,?> state = new HashMap<String,Object>();
|
||||
|
||||
private Configuration config;
|
||||
private boolean configProvided = false;
|
||||
private AccessControlContext creatorAcc = null;
|
||||
private AccessControlContext creatorAcc = null; // customized config only
|
||||
private ModuleInfo[] moduleStack;
|
||||
private ClassLoader contextClassLoader = null;
|
||||
private static final Class<?>[] PARAMS = { };
|
||||
@ -226,10 +227,23 @@ public class LoginContext {
|
||||
private static final sun.security.util.Debug debug =
|
||||
sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]");
|
||||
|
||||
// workaround to disable additional package access control with
|
||||
// Thread Context Class Loader (TCCL).
|
||||
private static final boolean noPackageAccessWithTCCL = "true".equals(
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(
|
||||
"auth.login.untieAccessContextWithTCCL");
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
private void init(String name) throws LoginException {
|
||||
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && !configProvided) {
|
||||
if (sm != null && creatorAcc == null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("createLoginContext." + name));
|
||||
}
|
||||
@ -252,7 +266,7 @@ public class LoginContext {
|
||||
AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name);
|
||||
if (entries == null) {
|
||||
|
||||
if (sm != null && !configProvided) {
|
||||
if (sm != null && creatorAcc == null) {
|
||||
sm.checkPermission(new AuthPermission
|
||||
("createLoginContext." + OTHER));
|
||||
}
|
||||
@ -298,10 +312,10 @@ public class LoginContext {
|
||||
(DEFAULT_HANDLER);
|
||||
if (defaultHandler == null || defaultHandler.length() == 0)
|
||||
return null;
|
||||
Class<?> c = Class.forName(defaultHandler,
|
||||
true,
|
||||
finalLoader);
|
||||
return (CallbackHandler)c.newInstance();
|
||||
Class<? extends CallbackHandler> c = Class.forName(
|
||||
defaultHandler, true,
|
||||
finalLoader).asSubclass(CallbackHandler.class);
|
||||
return c.newInstance();
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
@ -309,7 +323,7 @@ public class LoginContext {
|
||||
}
|
||||
|
||||
// secure it with the caller's ACC
|
||||
if (this.callbackHandler != null && !configProvided) {
|
||||
if (this.callbackHandler != null && creatorAcc == null) {
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
this.callbackHandler);
|
||||
@ -498,8 +512,7 @@ public class LoginContext {
|
||||
CallbackHandler callbackHandler,
|
||||
Configuration config) throws LoginException {
|
||||
this.config = config;
|
||||
configProvided = (config != null) ? true : false;
|
||||
if (configProvided) {
|
||||
if (config != null) {
|
||||
creatorAcc = java.security.AccessController.getContext();
|
||||
}
|
||||
|
||||
@ -510,7 +523,7 @@ public class LoginContext {
|
||||
}
|
||||
if (callbackHandler == null) {
|
||||
loadDefaultCallbackHandler();
|
||||
} else if (!configProvided) {
|
||||
} else if (creatorAcc == null) {
|
||||
this.callbackHandler = new SecureCallbackHandler
|
||||
(java.security.AccessController.getContext(),
|
||||
callbackHandler);
|
||||
@ -577,23 +590,13 @@ public class LoginContext {
|
||||
}
|
||||
|
||||
try {
|
||||
if (configProvided) {
|
||||
// module invoked in doPrivileged with creatorAcc
|
||||
invokeCreatorPriv(LOGIN_METHOD);
|
||||
invokeCreatorPriv(COMMIT_METHOD);
|
||||
} else {
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGIN_METHOD);
|
||||
invokePriv(COMMIT_METHOD);
|
||||
}
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGIN_METHOD);
|
||||
invokePriv(COMMIT_METHOD);
|
||||
loginSucceeded = true;
|
||||
} catch (LoginException le) {
|
||||
try {
|
||||
if (configProvided) {
|
||||
invokeCreatorPriv(ABORT_METHOD);
|
||||
} else {
|
||||
invokePriv(ABORT_METHOD);
|
||||
}
|
||||
invokePriv(ABORT_METHOD);
|
||||
} catch (LoginException le2) {
|
||||
throw le;
|
||||
}
|
||||
@ -628,13 +631,8 @@ public class LoginContext {
|
||||
("null.subject.logout.called.before.login"));
|
||||
}
|
||||
|
||||
if (configProvided) {
|
||||
// module invoked in doPrivileged with creatorAcc
|
||||
invokeCreatorPriv(LOGOUT_METHOD);
|
||||
} else {
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGOUT_METHOD);
|
||||
}
|
||||
// module invoked in doPrivileged
|
||||
invokePriv(LOGOUT_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -677,35 +675,13 @@ public class LoginContext {
|
||||
|
||||
/**
|
||||
* Invokes the login, commit, and logout methods
|
||||
* from a LoginModule inside a doPrivileged block.
|
||||
* from a LoginModule inside a doPrivileged block restricted
|
||||
* by creatorAcc (may be null).
|
||||
*
|
||||
* This version is called if the caller did not instantiate
|
||||
* the LoginContext with a Configuration object.
|
||||
*/
|
||||
private void invokePriv(final String methodName) throws LoginException {
|
||||
try {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws LoginException {
|
||||
invoke(methodName);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (java.security.PrivilegedActionException pae) {
|
||||
throw (LoginException)pae.getException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the login, commit, and logout methods
|
||||
* from a LoginModule inside a doPrivileged block restricted
|
||||
* by creatorAcc
|
||||
*
|
||||
* This version is called if the caller instantiated
|
||||
* the LoginContext with a Configuration object.
|
||||
*/
|
||||
private void invokeCreatorPriv(final String methodName)
|
||||
throws LoginException {
|
||||
try {
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedExceptionAction<Void>() {
|
||||
@ -735,24 +711,30 @@ public class LoginContext {
|
||||
} else {
|
||||
|
||||
// instantiate the LoginModule
|
||||
Class<?> c = Class.forName
|
||||
(moduleStack[i].entry.getLoginModuleName(),
|
||||
//
|
||||
// Allow any object to be a LoginModule as long as it
|
||||
// conforms to the interface if no customized config or
|
||||
// noPackageAccessWithTCCL is true.
|
||||
Class<?> c = Class.forName(
|
||||
moduleStack[i].entry.getLoginModuleName(),
|
||||
true,
|
||||
contextClassLoader);
|
||||
// check package access for customized config
|
||||
if (!noPackageAccessWithTCCL && creatorAcc != null) {
|
||||
c.asSubclass(javax.security.auth.spi.LoginModule.class);
|
||||
checkPackageAccess(c, creatorAcc);
|
||||
}
|
||||
|
||||
Constructor<?> constructor = c.getConstructor(PARAMS);
|
||||
Object[] args = { };
|
||||
|
||||
// allow any object to be a LoginModule
|
||||
// as long as it conforms to the interface
|
||||
moduleStack[i].module = constructor.newInstance(args);
|
||||
|
||||
methods = moduleStack[i].module.getClass().getMethods();
|
||||
|
||||
// call the LoginModule's initialize method
|
||||
methods = moduleStack[i].module.getClass().getMethods();
|
||||
for (mIndex = 0; mIndex < methods.length; mIndex++) {
|
||||
if (methods[mIndex].getName().equals(INIT_METHOD))
|
||||
if (methods[mIndex].getName().equals(INIT_METHOD)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Object[] initArgs = {subject,
|
||||
@ -760,19 +742,28 @@ public class LoginContext {
|
||||
state,
|
||||
moduleStack[i].entry.getOptions() };
|
||||
// invoke the LoginModule initialize method
|
||||
//
|
||||
// Throws ArrayIndexOutOfBoundsException if no such
|
||||
// method defined. May improve to use LoginException in
|
||||
// the future.
|
||||
methods[mIndex].invoke(moduleStack[i].module, initArgs);
|
||||
}
|
||||
|
||||
// find the requested method in the LoginModule
|
||||
for (mIndex = 0; mIndex < methods.length; mIndex++) {
|
||||
if (methods[mIndex].getName().equals(methodName))
|
||||
if (methods[mIndex].getName().equals(methodName)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set up the arguments to be passed to the LoginModule method
|
||||
Object[] args = { };
|
||||
|
||||
// invoke the LoginModule method
|
||||
//
|
||||
// Throws ArrayIndexOutOfBoundsException if no such
|
||||
// method defined. May improve to use LoginException in
|
||||
// the future.
|
||||
boolean status = ((Boolean)methods[mIndex].invoke
|
||||
(moduleStack[i].module, args)).booleanValue();
|
||||
|
||||
@ -935,6 +926,35 @@ public class LoginContext {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check package access of a class that is loaded with Thread Context
|
||||
* Class Loader (TCCL) with specified access control context.
|
||||
*
|
||||
* Similar to java.lang.ClassLoader.checkPackageAccess()
|
||||
*/
|
||||
static void checkPackageAccess(Class<?> cls, AccessControlContext context) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
if (ReflectUtil.isNonPublicProxyClass(cls)) {
|
||||
for (Class<?> intf: cls.getInterfaces()) {
|
||||
checkPackageAccess(intf, context);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = cls.getName();
|
||||
final int i = name.lastIndexOf('.');
|
||||
if (i != -1) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
sm.checkPackageAccess(name.substring(0, i));
|
||||
return null;
|
||||
}
|
||||
}, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the caller-specified CallbackHandler in our own
|
||||
* and invoke it within a privileged block, constrained by
|
||||
|
@ -35,6 +35,8 @@ import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import javax.naming.*;
|
||||
|
||||
@ -348,7 +350,17 @@ public class SyncFactory {
|
||||
/*
|
||||
* Dependent on application
|
||||
*/
|
||||
String strRowsetProperties = System.getProperty("rowset.properties");
|
||||
String strRowsetProperties;
|
||||
try {
|
||||
strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty("rowset.properties");
|
||||
}
|
||||
}, null, new PropertyPermission("rowset.properties","read"));
|
||||
} catch (Exception ex) {
|
||||
strRowsetProperties = null;
|
||||
}
|
||||
|
||||
if (strRowsetProperties != null) {
|
||||
// Load user's implementation of SyncProvider
|
||||
// here. -Drowset.properties=/abc/def/pqr.txt
|
||||
@ -393,7 +405,16 @@ public class SyncFactory {
|
||||
* load additional properties from -D command line
|
||||
*/
|
||||
properties.clear();
|
||||
String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER);
|
||||
String providerImpls;
|
||||
try {
|
||||
providerImpls = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(ROWSET_SYNC_PROVIDER);
|
||||
}
|
||||
}, null, new PropertyPermission(ROWSET_SYNC_PROVIDER,"read"));
|
||||
} catch (Exception ex) {
|
||||
providerImpls = null;
|
||||
}
|
||||
|
||||
if (providerImpls != null) {
|
||||
int i = 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
package javax.swing;
|
||||
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.swing.SwingUtilities2;
|
||||
import sun.swing.UIAction;
|
||||
|
||||
@ -33,9 +34,6 @@ import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.dnd.DropTarget;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
@ -1872,6 +1870,7 @@ public class SwingUtilities implements SwingConstants
|
||||
|
||||
|
||||
static Class<?> loadSystemClass(String className) throws ClassNotFoundException {
|
||||
ReflectUtil.checkPackageAccess(className);
|
||||
return Class.forName(className, true, Thread.currentThread().
|
||||
getContextClassLoader());
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ package javax.swing.event;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.Array;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* A class that holds a list of EventListeners. A single instance
|
||||
@ -271,7 +272,9 @@ public class EventListenerList implements Serializable {
|
||||
while (null != (listenerTypeOrNull = s.readObject())) {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
EventListener l = (EventListener)s.readObject();
|
||||
add((Class<EventListener>)Class.forName((String)listenerTypeOrNull, true, cl), l);
|
||||
String name = (String) listenerTypeOrNull;
|
||||
ReflectUtil.checkPackageAccess(name);
|
||||
add((Class<EventListener>)Class.forName(name, true, cl), l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,10 @@ package sun.reflect.generics.reflectiveObjects;
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.GenericDeclaration;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -40,6 +43,7 @@ import sun.reflect.annotation.AnnotationType;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
|
||||
@ -95,6 +99,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
TypeVariableImpl<T> make(T decl, String name,
|
||||
FieldTypeSignature[] bs,
|
||||
GenericsFactory f) {
|
||||
|
||||
if (!((decl instanceof Class) ||
|
||||
(decl instanceof Method) ||
|
||||
(decl instanceof Constructor))) {
|
||||
throw new AssertionError("Unexpected kind of GenericDeclaration" +
|
||||
decl.getClass().toString());
|
||||
}
|
||||
return new TypeVariableImpl<T>(decl, name, bs, f);
|
||||
}
|
||||
|
||||
@ -149,6 +160,13 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
* @since 1.5
|
||||
*/
|
||||
public D getGenericDeclaration(){
|
||||
if (genericDeclaration instanceof Class)
|
||||
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
|
||||
else if ((genericDeclaration instanceof Method) ||
|
||||
(genericDeclaration instanceof Constructor))
|
||||
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
|
||||
else
|
||||
throw new AssertionError("Unexpected kind of GenericDeclaration");
|
||||
return genericDeclaration;
|
||||
}
|
||||
|
||||
@ -164,7 +182,8 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof TypeVariable) {
|
||||
if (o instanceof TypeVariable &&
|
||||
o.getClass() == TypeVariableImpl.class) {
|
||||
TypeVariable<?> that = (TypeVariable<?>) o;
|
||||
|
||||
GenericDeclaration thatDecl = that.getGenericDeclaration();
|
||||
|
@ -26,11 +26,13 @@
|
||||
|
||||
package sun.reflect.misc;
|
||||
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
public final class ReflectUtil {
|
||||
|
||||
@ -117,6 +119,40 @@ public final class ReflectUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a conservative approximation of member access check. Use this if
|
||||
* you don't have an actual 'userland' caller Class/ClassLoader available.
|
||||
* This might be more restrictive than a precise member access check where
|
||||
* you have a caller, but should never allow a member access that is
|
||||
* forbidden.
|
||||
*
|
||||
* @param m the {@code Member} about to be accessed
|
||||
*/
|
||||
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null)
|
||||
return;
|
||||
|
||||
// Check for package access on the declaring class.
|
||||
//
|
||||
// In addition, unless the member and the declaring class are both
|
||||
// public check for access declared member permissions.
|
||||
//
|
||||
// This is done regardless of ClassLoader relations between the {@code
|
||||
// Member m} and any potential caller.
|
||||
|
||||
final Class<?> declaringClass = m.getDeclaringClass();
|
||||
|
||||
checkPackageAccess(declaringClass);
|
||||
|
||||
if (Modifier.isPublic(m.getModifiers()) &&
|
||||
Modifier.isPublic(declaringClass.getModifiers()))
|
||||
return;
|
||||
|
||||
// Check for declared member access.
|
||||
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks package access on the given class.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -45,11 +45,12 @@ public class TlsRsaPremasterSecretParameterSpec
|
||||
|
||||
private final int majorVersion;
|
||||
private final int minorVersion;
|
||||
private final byte[] encodedSecret;
|
||||
|
||||
/**
|
||||
* Constructs a new TlsRsaPremasterSecretParameterSpec.
|
||||
*
|
||||
* <p>The version numbers will be placed inside the premaster secret to
|
||||
* <P>
|
||||
* The version numbers will be placed inside the premaster secret to
|
||||
* detect version rollbacks attacks as described in the TLS specification.
|
||||
* Note that they do not indicate the protocol version negotiated for
|
||||
* the handshake.
|
||||
@ -65,7 +66,42 @@ public class TlsRsaPremasterSecretParameterSpec
|
||||
this.majorVersion =
|
||||
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
|
||||
this.minorVersion =
|
||||
TlsMasterSecretParameterSpec.checkVersion(minorVersion); }
|
||||
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
|
||||
this.encodedSecret = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new TlsRsaPremasterSecretParameterSpec.
|
||||
* <P>
|
||||
* The version numbers will be placed inside the premaster secret to
|
||||
* detect version rollbacks attacks as described in the TLS specification.
|
||||
* Note that they do not indicate the protocol version negotiated for
|
||||
* the handshake.
|
||||
* <P>
|
||||
* Usually, the encoded secret key is a random number that acts as
|
||||
* dummy pre_master_secret to avoid vulnerabilities described by
|
||||
* section 7.4.7.1, RFC 5246.
|
||||
*
|
||||
* @param majorVersion the major number of the protocol version
|
||||
* @param minorVersion the minor number of the protocol version
|
||||
* @param encodedSecret the encoded secret key
|
||||
*
|
||||
* @throws IllegalArgumentException if minorVersion or majorVersion are
|
||||
* negative or larger than 255, or encodedSecret is not exactly 48 bytes.
|
||||
*/
|
||||
public TlsRsaPremasterSecretParameterSpec(int majorVersion,
|
||||
int minorVersion, byte[] encodedSecret) {
|
||||
this.majorVersion =
|
||||
TlsMasterSecretParameterSpec.checkVersion(majorVersion);
|
||||
this.minorVersion =
|
||||
TlsMasterSecretParameterSpec.checkVersion(minorVersion);
|
||||
|
||||
if (encodedSecret == null || encodedSecret.length != 48) {
|
||||
throw new IllegalArgumentException(
|
||||
"Encoded secret is not exactly 48 bytes");
|
||||
}
|
||||
this.encodedSecret = encodedSecret.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the major version.
|
||||
@ -84,4 +120,13 @@ public class TlsRsaPremasterSecretParameterSpec
|
||||
public int getMinorVersion() {
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded secret.
|
||||
*
|
||||
* @return the encoded secret, may be null if no encoded secret.
|
||||
*/
|
||||
public byte[] getEncodedSecret() {
|
||||
return encodedSecret == null ? null : encodedSecret.clone();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -451,30 +451,7 @@ final class P11RSACipher extends CipherSpi {
|
||||
// see JCE spec
|
||||
protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
|
||||
int type) throws InvalidKeyException, NoSuchAlgorithmException {
|
||||
if (algorithm.equals("TlsRsaPremasterSecret")) {
|
||||
// the instance variable "session" has been initialized for
|
||||
// decrypt mode, so use a local variable instead.
|
||||
Session s = null;
|
||||
try {
|
||||
s = token.getObjSession();
|
||||
long keyType = CKK_GENERIC_SECRET;
|
||||
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
|
||||
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
|
||||
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
|
||||
};
|
||||
attributes = token.getAttributes
|
||||
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
|
||||
long keyID = token.p11.C_UnwrapKey(s.id(),
|
||||
new CK_MECHANISM(mechanism), p11Key.keyID, wrappedKey,
|
||||
attributes);
|
||||
return P11Key.secretKey(s, keyID, algorithm, 48 << 3,
|
||||
attributes);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeyException("unwrap() failed", e);
|
||||
} finally {
|
||||
token.releaseSession(s);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX implement unwrap using C_Unwrap() for all keys
|
||||
implInit(Cipher.DECRYPT_MODE, p11Key);
|
||||
if (wrappedKey.length > maxInputSize) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -88,23 +88,33 @@ final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
|
||||
throw new IllegalStateException
|
||||
("TlsRsaPremasterSecretGenerator must be initialized");
|
||||
}
|
||||
CK_VERSION version =
|
||||
new CK_VERSION(spec.getMajorVersion(), spec.getMinorVersion());
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getObjSession();
|
||||
CK_ATTRIBUTE[] attributes = token.getAttributes
|
||||
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
|
||||
long keyID = token.p11.C_GenerateKey
|
||||
(session.id(), new CK_MECHANISM(mechanism, version), attributes);
|
||||
SecretKey key = P11Key.secretKey
|
||||
(session, keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
|
||||
return key;
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException("Could not generate premaster secret", e);
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
|
||||
byte[] b = spec.getEncodedSecret();
|
||||
if (b == null) {
|
||||
CK_VERSION version = new CK_VERSION(
|
||||
spec.getMajorVersion(), spec.getMinorVersion());
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getObjSession();
|
||||
CK_ATTRIBUTE[] attributes = token.getAttributes(
|
||||
O_GENERATE, CKO_SECRET_KEY,
|
||||
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
|
||||
long keyID = token.p11.C_GenerateKey(session.id(),
|
||||
new CK_MECHANISM(mechanism, version), attributes);
|
||||
SecretKey key = P11Key.secretKey(session,
|
||||
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
|
||||
return key;
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException(
|
||||
"Could not generate premaster secret", e);
|
||||
} finally {
|
||||
token.releaseSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
// Won't worry, the TlsRsaPremasterSecret will be soon converted to
|
||||
// TlsMasterSecret.
|
||||
return new SecretKeySpec(b, "TlsRsaPremasterSecret");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,10 +43,8 @@ import sun.misc.Unsafe;
|
||||
* These are the only platforms we currently support, but other optimized
|
||||
* variants could be added as needed.
|
||||
*
|
||||
* NOTE that because this code performs unchecked direct memory access, it
|
||||
* MUST be restricted to trusted code. It is imperative that the caller protects
|
||||
* against out of bounds memory access by performing the necessary bounds
|
||||
* checks before calling methods in this class.
|
||||
* NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
|
||||
* failed.
|
||||
*
|
||||
* This class may also be helpful in improving the performance of the
|
||||
* crypto code in the SunJCE provider. However, for now it is only accessible by
|
||||
@ -103,6 +101,10 @@ final class ByteArrayAccess {
|
||||
* byte[] to int[] conversion, little endian byte order.
|
||||
*/
|
||||
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
len += inOfs;
|
||||
@ -131,6 +133,10 @@ final class ByteArrayAccess {
|
||||
|
||||
// Special optimization of b2iLittle(in, inOfs, out, 0, 64)
|
||||
static void b2iLittle64(byte[] in, int inOfs, int[] out) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
|
||||
(out.length < 16)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
out[ 0] = unsafe.getInt(in, (long)(inOfs ));
|
||||
@ -176,6 +182,10 @@ final class ByteArrayAccess {
|
||||
* int[] to byte[] conversion, little endian byte order.
|
||||
*/
|
||||
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
outOfs += byteArrayOfs;
|
||||
len += outOfs;
|
||||
@ -204,6 +214,9 @@ final class ByteArrayAccess {
|
||||
|
||||
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
|
||||
static void i2bLittle4(int val, byte[] out, int outOfs) {
|
||||
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
|
||||
} else if (bigEndian && ((outOfs & 3) == 0)) {
|
||||
@ -220,6 +233,10 @@ final class ByteArrayAccess {
|
||||
* byte[] to int[] conversion, big endian byte order.
|
||||
*/
|
||||
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
len += inOfs;
|
||||
@ -248,6 +265,10 @@ final class ByteArrayAccess {
|
||||
|
||||
// Special optimization of b2iBig(in, inOfs, out, 0, 64)
|
||||
static void b2iBig64(byte[] in, int inOfs, int[] out) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
|
||||
(out.length < 16)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
|
||||
@ -293,6 +314,10 @@ final class ByteArrayAccess {
|
||||
* int[] to byte[] conversion, big endian byte order.
|
||||
*/
|
||||
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
outOfs += byteArrayOfs;
|
||||
len += outOfs;
|
||||
@ -321,6 +346,9 @@ final class ByteArrayAccess {
|
||||
|
||||
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
|
||||
static void i2bBig4(int val, byte[] out, int outOfs) {
|
||||
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
|
||||
} else if (bigEndian && ((outOfs & 3) == 0)) {
|
||||
@ -337,6 +365,10 @@ final class ByteArrayAccess {
|
||||
* byte[] to long[] conversion, big endian byte order.
|
||||
*/
|
||||
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len/8)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
len += inOfs;
|
||||
@ -378,6 +410,10 @@ final class ByteArrayAccess {
|
||||
|
||||
// Special optimization of b2lBig(in, inOfs, out, 0, 128)
|
||||
static void b2lBig128(byte[] in, int inOfs, long[] out) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
|
||||
(out.length < 16)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (littleEndianUnaligned) {
|
||||
inOfs += byteArrayOfs;
|
||||
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
|
||||
@ -406,6 +442,10 @@ final class ByteArrayAccess {
|
||||
* long[] to byte[] conversion, big endian byte order.
|
||||
*/
|
||||
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
|
||||
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
|
||||
(outOfs < 0) || ((out.length - outOfs) < len)) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
len += outOfs;
|
||||
while (outOfs < len) {
|
||||
long i = in[inOfs++];
|
||||
@ -419,5 +459,4 @@ final class ByteArrayAccess {
|
||||
out[outOfs++] = (byte)(i );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -318,33 +318,53 @@ public final class RSAPadding {
|
||||
|
||||
/**
|
||||
* PKCS#1 v1.5 unpadding (blocktype 1 and 2).
|
||||
*
|
||||
* Note that we want to make it a constant-time operation
|
||||
*/
|
||||
private byte[] unpadV15(byte[] padded) throws BadPaddingException {
|
||||
int k = 0;
|
||||
BadPaddingException bpe = null;
|
||||
|
||||
if (padded[k++] != 0) {
|
||||
throw new BadPaddingException("Data must start with zero");
|
||||
bpe = new BadPaddingException("Data must start with zero");
|
||||
}
|
||||
if (padded[k++] != type) {
|
||||
throw new BadPaddingException("Blocktype mismatch: " + padded[1]);
|
||||
if (padded[k++] != type && bpe == null) {
|
||||
bpe = new BadPaddingException("Blocktype mismatch: " + padded[1]);
|
||||
}
|
||||
while (true) {
|
||||
int p = 0;
|
||||
while (k < padded.length) {
|
||||
int b = padded[k++] & 0xff;
|
||||
if (b == 0) {
|
||||
break;
|
||||
if (b == 0 && p == 0) {
|
||||
p = k;
|
||||
}
|
||||
if (k == padded.length) {
|
||||
throw new BadPaddingException("Padding string not terminated");
|
||||
if (k == padded.length && p == 0 && bpe == null) {
|
||||
bpe = new BadPaddingException("Padding string not terminated");
|
||||
}
|
||||
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff)) {
|
||||
throw new BadPaddingException("Padding byte not 0xff: " + b);
|
||||
if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
|
||||
p == 0 && bpe == null) {
|
||||
bpe = new BadPaddingException("Padding byte not 0xff: " + b);
|
||||
}
|
||||
}
|
||||
int n = padded.length - k;
|
||||
if (n > maxDataSize) {
|
||||
throw new BadPaddingException("Padding string too short");
|
||||
int n = padded.length - p;
|
||||
if (n > maxDataSize && bpe == null) {
|
||||
bpe = new BadPaddingException("Padding string too short");
|
||||
}
|
||||
|
||||
// copy useless padding array for a constant-time method
|
||||
//
|
||||
// Is it necessary?
|
||||
byte[] padding = new byte[p];
|
||||
System.arraycopy(padded, 0, padding, 0, p);
|
||||
|
||||
byte[] data = new byte[n];
|
||||
System.arraycopy(padded, padded.length - n, data, 0, n);
|
||||
System.arraycopy(padded, p, data, 0, n);
|
||||
|
||||
if (bpe == null) {
|
||||
bpe = new BadPaddingException("Unused exception");
|
||||
} else {
|
||||
throw bpe;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -1104,94 +1104,23 @@ abstract class Handshaker {
|
||||
clnt_random.random_bytes, svr_random.random_bytes,
|
||||
prfHashAlg, prfHashLength, prfBlockSize);
|
||||
|
||||
SecretKey masterSecret;
|
||||
try {
|
||||
KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
|
||||
kg.init(spec);
|
||||
masterSecret = kg.generateKey();
|
||||
} catch (GeneralSecurityException e) {
|
||||
return kg.generateKey();
|
||||
} catch (InvalidAlgorithmParameterException |
|
||||
NoSuchAlgorithmException iae) {
|
||||
// unlikely to happen, otherwise, must be a provider exception
|
||||
//
|
||||
// For RSA premaster secrets, do not signal a protocol error
|
||||
// due to the Bleichenbacher attack. See comments further down.
|
||||
if (!preMasterSecret.getAlgorithm().equals(
|
||||
"TlsRsaPremasterSecret")) {
|
||||
throw new ProviderException(e);
|
||||
}
|
||||
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("RSA master secret generation error:");
|
||||
e.printStackTrace(System.out);
|
||||
iae.printStackTrace(System.out);
|
||||
}
|
||||
throw new ProviderException(iae);
|
||||
|
||||
if (requestedVersion != null) {
|
||||
preMasterSecret =
|
||||
RSAClientKeyExchange.generateDummySecret(requestedVersion);
|
||||
} else {
|
||||
preMasterSecret =
|
||||
RSAClientKeyExchange.generateDummySecret(protocolVersion);
|
||||
}
|
||||
|
||||
// recursive call with new premaster secret
|
||||
return calculateMasterSecret(preMasterSecret, null);
|
||||
}
|
||||
|
||||
// if no version check requested (client side handshake), or version
|
||||
// information is not available (not an RSA premaster secret),
|
||||
// return master secret immediately.
|
||||
if ((requestedVersion == null) ||
|
||||
!(masterSecret instanceof TlsMasterSecret)) {
|
||||
return masterSecret;
|
||||
}
|
||||
|
||||
// we have checked the ClientKeyExchange message when reading TLS
|
||||
// record, the following check is necessary to ensure that
|
||||
// JCE provider does not ignore the checking, or the previous
|
||||
// checking process bypassed the premaster secret version checking.
|
||||
TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
|
||||
int major = tlsKey.getMajorVersion();
|
||||
int minor = tlsKey.getMinorVersion();
|
||||
if ((major < 0) || (minor < 0)) {
|
||||
return masterSecret;
|
||||
}
|
||||
|
||||
// check if the premaster secret version is ok
|
||||
// the specification says that it must be the maximum version supported
|
||||
// by the client from its ClientHello message. However, many
|
||||
// implementations send the negotiated version, so accept both
|
||||
// for SSL v3.0 and TLS v1.0.
|
||||
// NOTE that we may be comparing two unsupported version numbers, which
|
||||
// is why we cannot use object reference equality in this special case.
|
||||
ProtocolVersion premasterVersion =
|
||||
ProtocolVersion.valueOf(major, minor);
|
||||
boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
|
||||
|
||||
/*
|
||||
* we never checked the client_version in server side
|
||||
* for TLS v1.0 and SSL v3.0. For compatibility, we
|
||||
* maintain this behavior.
|
||||
*/
|
||||
if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
|
||||
versionMismatch = (premasterVersion.v != protocolVersion.v);
|
||||
}
|
||||
|
||||
if (versionMismatch == false) {
|
||||
// check passed, return key
|
||||
return masterSecret;
|
||||
}
|
||||
|
||||
// Due to the Bleichenbacher attack, do not signal a protocol error.
|
||||
// Generate a random premaster secret and continue with the handshake,
|
||||
// which will fail when verifying the finished messages.
|
||||
// For more information, see comments in PreMasterSecret.
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("RSA PreMasterSecret version error: expected"
|
||||
+ protocolVersion + " or " + requestedVersion + ", decrypted: "
|
||||
+ premasterVersion);
|
||||
}
|
||||
preMasterSecret =
|
||||
RSAClientKeyExchange.generateDummySecret(requestedVersion);
|
||||
|
||||
// recursive call with new premaster secret
|
||||
return calculateMasterSecret(preMasterSecret, null);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -133,26 +133,37 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
} else {
|
||||
encrypted = new byte [messageSize];
|
||||
if (input.read(encrypted) != messageSize) {
|
||||
throw new SSLProtocolException
|
||||
("SSL: read PreMasterSecret: short read");
|
||||
throw new SSLProtocolException(
|
||||
"SSL: read PreMasterSecret: short read");
|
||||
}
|
||||
}
|
||||
|
||||
Exception failover = null;
|
||||
byte[] encoded = null;
|
||||
try {
|
||||
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
|
||||
cipher.init(Cipher.UNWRAP_MODE, privateKey);
|
||||
preMaster = (SecretKey)cipher.unwrap(encrypted,
|
||||
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
|
||||
|
||||
// polish the premaster secret
|
||||
preMaster = polishPreMasterSecretKey(currentVersion, maxVersion,
|
||||
generator, preMaster, null);
|
||||
// Cannot generate key here, please don't use Cipher.UNWRAP_MODE!
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
encoded = cipher.doFinal(encrypted);
|
||||
} catch (BadPaddingException bpe) {
|
||||
failover = bpe;
|
||||
encoded = null;
|
||||
} catch (IllegalBlockSizeException ibse) {
|
||||
// the message it too big to process with RSA
|
||||
throw new SSLProtocolException(
|
||||
"Unable to process PreMasterSecret, may be too big");
|
||||
} catch (Exception e) {
|
||||
// polish the premaster secret
|
||||
preMaster =
|
||||
polishPreMasterSecretKey(currentVersion, maxVersion,
|
||||
generator, null, e);
|
||||
// unlikely to happen, otherwise, must be a provider exception
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("RSA premaster secret decryption error:");
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
throw new RuntimeException("Could not generate dummy secret", e);
|
||||
}
|
||||
|
||||
// polish the premaster secret
|
||||
preMaster = polishPreMasterSecretKey(
|
||||
currentVersion, maxVersion, generator, encoded, failover);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,85 +174,74 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
*
|
||||
* RFC 5246 describes the approach as :
|
||||
*
|
||||
* 1. Generate a string R of 46 random bytes
|
||||
* 1. Generate a string R of 48 random bytes
|
||||
*
|
||||
* 2. Decrypt the message to recover the plaintext M
|
||||
*
|
||||
* 3. If the PKCS#1 padding is not correct, or the length of message
|
||||
* M is not exactly 48 bytes:
|
||||
* pre_master_secret = ClientHello.client_version || R
|
||||
* pre_master_secret = R
|
||||
* else If ClientHello.client_version <= TLS 1.0, and version
|
||||
* number check is explicitly disabled:
|
||||
* pre_master_secret = M
|
||||
* premaster secret = M
|
||||
* else If M[0..1] != ClientHello.client_version:
|
||||
* premaster secret = R
|
||||
* else:
|
||||
* pre_master_secret = ClientHello.client_version || M[2..47]
|
||||
* premaster secret = M
|
||||
*
|
||||
* Note that #2 has completed before the call of this method.
|
||||
*/
|
||||
private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
|
||||
ProtocolVersion clientHelloVersion, SecureRandom generator,
|
||||
SecretKey secretKey, Exception failoverException) {
|
||||
byte[] encoded, Exception failoverException) {
|
||||
|
||||
this.protocolVersion = clientHelloVersion;
|
||||
if (generator == null) {
|
||||
generator = new SecureRandom();
|
||||
}
|
||||
byte[] random = new byte[48];
|
||||
generator.nextBytes(random);
|
||||
|
||||
if (failoverException == null && secretKey != null) {
|
||||
if (failoverException == null && encoded != null) {
|
||||
// check the length
|
||||
byte[] encoded = secretKey.getEncoded();
|
||||
if (encoded == null) { // unable to get the encoded key
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println(
|
||||
"unable to get the plaintext of the premaster secret");
|
||||
}
|
||||
|
||||
int keySize = KeyUtil.getKeySize(secretKey);
|
||||
if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println(
|
||||
"incorrect length of premaster secret: " +
|
||||
(keySize/8));
|
||||
}
|
||||
|
||||
return generateDummySecret(clientHelloVersion);
|
||||
}
|
||||
|
||||
// The key size is exactly 48 bytes or not accessible.
|
||||
//
|
||||
// Conservatively, pass the checking to master secret
|
||||
// calculation.
|
||||
return secretKey;
|
||||
} else if (encoded.length == 48) {
|
||||
// check the version
|
||||
if (clientHelloVersion.major == encoded[0] &&
|
||||
clientHelloVersion.minor == encoded[1]) {
|
||||
|
||||
return secretKey;
|
||||
} else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
|
||||
currentVersion.major == encoded[0] &&
|
||||
currentVersion.minor == encoded[1]) {
|
||||
/*
|
||||
* For compatibility, we maintain the behavior that the
|
||||
* version in pre_master_secret can be the negotiated
|
||||
* version for TLS v1.0 and SSL v3.0.
|
||||
*/
|
||||
this.protocolVersion = currentVersion;
|
||||
return secretKey;
|
||||
}
|
||||
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("Mismatching Protocol Versions, " +
|
||||
"ClientHello.client_version is " + clientHelloVersion +
|
||||
", while PreMasterSecret.client_version is " +
|
||||
ProtocolVersion.valueOf(encoded[0], encoded[1]));
|
||||
}
|
||||
|
||||
return generateDummySecret(clientHelloVersion);
|
||||
} else {
|
||||
if (encoded.length != 48) {
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println(
|
||||
"incorrect length of premaster secret: " +
|
||||
encoded.length);
|
||||
}
|
||||
|
||||
return generateDummySecret(clientHelloVersion);
|
||||
return generatePreMasterSecret(
|
||||
clientHelloVersion, random, generator);
|
||||
}
|
||||
|
||||
if (clientHelloVersion.major != encoded[0] ||
|
||||
clientHelloVersion.minor != encoded[1]) {
|
||||
|
||||
if (clientHelloVersion.v <= ProtocolVersion.TLS10.v &&
|
||||
currentVersion.major == encoded[0] &&
|
||||
currentVersion.minor == encoded[1]) {
|
||||
/*
|
||||
* For compatibility, we maintain the behavior that the
|
||||
* version in pre_master_secret can be the negotiated
|
||||
* version for TLS v1.0 and SSL v3.0.
|
||||
*/
|
||||
this.protocolVersion = currentVersion;
|
||||
} else {
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("Mismatching Protocol Versions, " +
|
||||
"ClientHello.client_version is " +
|
||||
clientHelloVersion +
|
||||
", while PreMasterSecret.client_version is " +
|
||||
ProtocolVersion.valueOf(encoded[0], encoded[1]));
|
||||
}
|
||||
|
||||
encoded = random;
|
||||
}
|
||||
}
|
||||
|
||||
return generatePreMasterSecret(
|
||||
clientHelloVersion, encoded, generator);
|
||||
}
|
||||
|
||||
if (debug != null && Debug.isOn("handshake") &&
|
||||
@ -250,11 +250,14 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
failoverException.printStackTrace(System.out);
|
||||
}
|
||||
|
||||
return generateDummySecret(clientHelloVersion);
|
||||
return generatePreMasterSecret(clientHelloVersion, random, generator);
|
||||
}
|
||||
|
||||
// generate a premaster secret with the specified version number
|
||||
static SecretKey generateDummySecret(ProtocolVersion version) {
|
||||
private static SecretKey generatePreMasterSecret(
|
||||
ProtocolVersion version, byte[] encodedSecret,
|
||||
SecureRandom generator) {
|
||||
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("Generating a random fake premaster secret");
|
||||
}
|
||||
@ -263,11 +266,17 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
String s = ((version.v >= ProtocolVersion.TLS12.v) ?
|
||||
"SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
|
||||
KeyGenerator kg = JsseJce.getKeyGenerator(s);
|
||||
kg.init(new TlsRsaPremasterSecretParameterSpec
|
||||
(version.major, version.minor));
|
||||
kg.init(new TlsRsaPremasterSecretParameterSpec(
|
||||
version.major, version.minor, encodedSecret), generator);
|
||||
return kg.generateKey();
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException("Could not generate dummy secret", e);
|
||||
} catch (InvalidAlgorithmParameterException |
|
||||
NoSuchAlgorithmException iae) {
|
||||
// unlikely to happen, otherwise, must be a provider exception
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("RSA premaster secret generation error:");
|
||||
iae.printStackTrace(System.out);
|
||||
}
|
||||
throw new RuntimeException("Could not generate dummy secret", iae);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,8 +158,13 @@ public class Main {
|
||||
private String altSignerClasspath = null;
|
||||
private ZipFile zipFile = null;
|
||||
|
||||
private boolean hasExpiredCert = false;
|
||||
// Informational warnings
|
||||
private boolean hasExpiringCert = false;
|
||||
private boolean noTimestamp = false;
|
||||
private Date expireDate = new Date(0L); // used in noTimestamp warning
|
||||
|
||||
// Severe warnings
|
||||
private boolean hasExpiredCert = false;
|
||||
private boolean notYetValidCert = false;
|
||||
private boolean chainNotValidated = false;
|
||||
private boolean notSignedByAlias = false;
|
||||
@ -258,9 +263,6 @@ public class Main {
|
||||
|
||||
if (strict) {
|
||||
int exitCode = 0;
|
||||
if (hasExpiringCert) {
|
||||
exitCode |= 2;
|
||||
}
|
||||
if (chainNotValidated || hasExpiredCert || notYetValidCert) {
|
||||
exitCode |= 4;
|
||||
}
|
||||
@ -754,14 +756,25 @@ public class Main {
|
||||
System.out.println(rb.getString(
|
||||
"jar.is.unsigned.signatures.missing.or.not.parsable."));
|
||||
} else {
|
||||
System.out.println(rb.getString("jar.verified."));
|
||||
if (hasUnsignedEntry || hasExpiredCert || hasExpiringCert ||
|
||||
badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
|
||||
notYetValidCert || chainNotValidated ||
|
||||
aliasNotInStore || notSignedByAlias) {
|
||||
boolean warningAppeared = false;
|
||||
boolean errorAppeared = false;
|
||||
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
|
||||
notYetValidCert || chainNotValidated || hasExpiredCert ||
|
||||
hasUnsignedEntry ||
|
||||
aliasNotInStore || notSignedByAlias) {
|
||||
|
||||
if (strict) {
|
||||
System.out.println(rb.getString("jar.verified.with.signer.errors."));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Error."));
|
||||
errorAppeared = true;
|
||||
} else {
|
||||
System.out.println(rb.getString("jar.verified."));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Warning."));
|
||||
warningAppeared = true;
|
||||
}
|
||||
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Warning."));
|
||||
if (badKeyUsage) {
|
||||
System.out.println(
|
||||
rb.getString("This.jar.contains.entries.whose.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
|
||||
@ -785,10 +798,6 @@ public class Main {
|
||||
System.out.println(rb.getString(
|
||||
"This.jar.contains.entries.whose.signer.certificate.has.expired."));
|
||||
}
|
||||
if (hasExpiringCert) {
|
||||
System.out.println(rb.getString(
|
||||
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
|
||||
}
|
||||
if (notYetValidCert) {
|
||||
System.out.println(rb.getString(
|
||||
"This.jar.contains.entries.whose.signer.certificate.is.not.yet.valid."));
|
||||
@ -807,10 +816,29 @@ public class Main {
|
||||
if (aliasNotInStore) {
|
||||
System.out.println(rb.getString("This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore."));
|
||||
}
|
||||
} else {
|
||||
System.out.println(rb.getString("jar.verified."));
|
||||
}
|
||||
if (hasExpiringCert || noTimestamp) {
|
||||
if (!warningAppeared) {
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Warning."));
|
||||
warningAppeared = true;
|
||||
}
|
||||
if (hasExpiringCert) {
|
||||
System.out.println(rb.getString(
|
||||
"This.jar.contains.entries.whose.signer.certificate.will.expire.within.six.months."));
|
||||
}
|
||||
if (noTimestamp) {
|
||||
System.out.println(
|
||||
String.format(rb.getString("no.timestamp.verifying"), expireDate));
|
||||
}
|
||||
}
|
||||
if (warningAppeared || errorAppeared) {
|
||||
if (! (verbose != null && showcerts)) {
|
||||
System.out.println();
|
||||
System.out.println(rb.getString(
|
||||
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
|
||||
"Re.run.with.the.verbose.and.certs.options.for.more.details."));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -870,6 +898,9 @@ public class Main {
|
||||
try {
|
||||
boolean printValidity = true;
|
||||
if (timestamp == null) {
|
||||
if (expireDate.getTime() == 0 || expireDate.after(notAfter)) {
|
||||
expireDate = notAfter;
|
||||
}
|
||||
x509Cert.checkValidity();
|
||||
// test if cert will expire within six months
|
||||
if (notAfter.getTime() < System.currentTimeMillis() + SIX_MONTHS) {
|
||||
@ -1233,6 +1264,10 @@ public class Main {
|
||||
tsaCert = getTsaCert(tsaAlias);
|
||||
}
|
||||
|
||||
if (tsaUrl == null && tsaCert == null) {
|
||||
noTimestamp = true;
|
||||
}
|
||||
|
||||
SignatureFile.Block block = null;
|
||||
|
||||
try {
|
||||
@ -1380,12 +1415,20 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasExpiredCert || hasExpiringCert || notYetValidCert
|
||||
|| badKeyUsage || badExtendedKeyUsage
|
||||
|| badNetscapeCertType || chainNotValidated) {
|
||||
System.out.println();
|
||||
boolean warningAppeared = false;
|
||||
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
|
||||
notYetValidCert || chainNotValidated || hasExpiredCert) {
|
||||
if (strict) {
|
||||
System.out.println(rb.getString("jar.signed.with.signer.errors."));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Error."));
|
||||
} else {
|
||||
System.out.println(rb.getString("jar.signed."));
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Warning."));
|
||||
warningAppeared = true;
|
||||
}
|
||||
|
||||
System.out.println(rb.getString("Warning."));
|
||||
if (badKeyUsage) {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.certificate.s.KeyUsage.extension.doesn.t.allow.code.signing."));
|
||||
@ -1404,9 +1447,6 @@ public class Main {
|
||||
if (hasExpiredCert) {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.certificate.has.expired."));
|
||||
} else if (hasExpiringCert) {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.certificate.will.expire.within.six.months."));
|
||||
} else if (notYetValidCert) {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.certificate.is.not.yet.valid."));
|
||||
@ -1416,6 +1456,24 @@ public class Main {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.s.certificate.chain.is.not.validated."));
|
||||
}
|
||||
} else {
|
||||
System.out.println(rb.getString("jar.signed."));
|
||||
}
|
||||
if (hasExpiringCert || noTimestamp) {
|
||||
if (!warningAppeared) {
|
||||
System.out.println();
|
||||
System.out.println(rb.getString("Warning."));
|
||||
}
|
||||
|
||||
if (hasExpiringCert) {
|
||||
System.out.println(
|
||||
rb.getString("The.signer.certificate.will.expire.within.six.months."));
|
||||
}
|
||||
|
||||
if (noTimestamp) {
|
||||
System.out.println(
|
||||
String.format(rb.getString("no.timestamp.signing"), expireDate));
|
||||
}
|
||||
}
|
||||
|
||||
// no IOException thrown in the above try clause, so disable
|
||||
@ -1502,6 +1560,7 @@ public class Main {
|
||||
timestamp = ts.getTimestamp();
|
||||
} else {
|
||||
timestamp = null;
|
||||
noTimestamp = true;
|
||||
}
|
||||
// display the certificate(s). The first one is end-entity cert and
|
||||
// its KeyUsage should be checked.
|
||||
|
@ -112,9 +112,9 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"Please.specify.alias.name", "Please specify alias name"},
|
||||
{"Only.one.alias.can.be.specified", "Only one alias can be specified"},
|
||||
{"This.jar.contains.signed.entries.which.is.not.signed.by.the.specified.alias.es.",
|
||||
"This jar contains signed entries which is not signed by the specified alias(es)."},
|
||||
"This jar contains signed entries which are not signed by the specified alias(es)."},
|
||||
{"This.jar.contains.signed.entries.that.s.not.signed.by.alias.in.this.keystore.",
|
||||
"This jar contains signed entries that's not signed by alias in this keystore."},
|
||||
"This jar contains signed entries that are not signed by alias in this keystore."},
|
||||
{"s", "s"},
|
||||
{"m", "m"},
|
||||
{"k", "k"},
|
||||
@ -135,7 +135,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{".Unsigned.entries.", "(Unsigned entries)"},
|
||||
{"jar.is.unsigned.signatures.missing.or.not.parsable.",
|
||||
"jar is unsigned. (signatures missing or not parsable)"},
|
||||
{"jar.signed.", "jar signed."},
|
||||
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
|
||||
{"jar.verified.", "jar verified."},
|
||||
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
|
||||
{"jarsigner.", "jarsigner: "},
|
||||
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
|
||||
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
|
||||
@ -193,6 +196,7 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
"using an alternative signing mechanism"},
|
||||
{"entry.was.signed.on", "entry was signed on {0}"},
|
||||
{"Warning.", "Warning: "},
|
||||
{"Error.", "Error: "},
|
||||
{"This.jar.contains.unsigned.entries.which.have.not.been.integrity.checked.",
|
||||
"This jar contains unsigned entries which have not been integrity-checked. "},
|
||||
{"This.jar.contains.entries.whose.signer.certificate.has.expired.",
|
||||
@ -229,6 +233,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
"The signer's certificate chain is not validated."},
|
||||
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.",
|
||||
"This jar contains entries whose certificate chain is not validated."},
|
||||
{"no.timestamp.signing",
|
||||
"No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
|
||||
{"no.timestamp.verifying",
|
||||
"This jar contains signatures that does not include a timestamp. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (%1$tY-%1$tm-%1$td) or after any future revocation date."},
|
||||
{"Unknown.password.type.", "Unknown password type: "},
|
||||
{"Cannot.find.environment.variable.",
|
||||
"Cannot find environment variable: "},
|
||||
|
@ -182,6 +182,7 @@ package.access=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -205,7 +206,7 @@ package.access=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
@ -228,6 +229,7 @@ package.definition=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -251,7 +253,7 @@ package.definition=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
|
@ -183,6 +183,7 @@ package.access=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -229,6 +230,7 @@ package.definition=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
|
@ -184,6 +184,7 @@ package.access=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -207,7 +208,7 @@ package.access=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
@ -229,6 +230,7 @@ package.definition=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -252,7 +254,7 @@ package.definition=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
|
@ -183,6 +183,7 @@ package.access=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -206,7 +207,7 @@ package.access=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
@ -229,6 +230,7 @@ package.definition=sun.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
@ -252,7 +254,7 @@ package.definition=sun.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
|
@ -111,8 +111,9 @@ SplashDone(Splash * splash)
|
||||
int
|
||||
SplashIsStillLooping(Splash * splash)
|
||||
{
|
||||
if (splash->currentFrame < 0)
|
||||
if (splash->currentFrame < 0) {
|
||||
return 0;
|
||||
}
|
||||
return splash->loopCount != 1 ||
|
||||
splash->currentFrame + 1 < splash->frameCount;
|
||||
}
|
||||
@ -121,17 +122,22 @@ void
|
||||
SplashUpdateScreenData(Splash * splash)
|
||||
{
|
||||
ImageRect srcRect, dstRect;
|
||||
if (splash->currentFrame < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
|
||||
splash->width * sizeof(rgbquad_t),
|
||||
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
|
||||
if (splash->screenData)
|
||||
if (splash->screenData) {
|
||||
free(splash->screenData);
|
||||
}
|
||||
splash->screenStride = splash->width * splash->screenFormat.depthBytes;
|
||||
if (splash->byteAlignment > 1)
|
||||
if (splash->byteAlignment > 1) {
|
||||
splash->screenStride =
|
||||
(splash->screenStride + splash->byteAlignment - 1) &
|
||||
~(splash->byteAlignment - 1);
|
||||
}
|
||||
splash->screenData = malloc(splash->height * splash->screenStride);
|
||||
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
|
||||
splash->screenStride, splash->screenData, &splash->screenFormat);
|
||||
@ -146,16 +152,19 @@ SplashUpdateScreenData(Splash * splash)
|
||||
void
|
||||
SplashNextFrame(Splash * splash)
|
||||
{
|
||||
if (splash->currentFrame < 0)
|
||||
if (splash->currentFrame < 0) {
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (!SplashIsStillLooping(splash))
|
||||
if (!SplashIsStillLooping(splash)) {
|
||||
return;
|
||||
}
|
||||
splash->time += splash->frames[splash->currentFrame].delay;
|
||||
if (++splash->currentFrame >= splash->frameCount) {
|
||||
splash->currentFrame = 0;
|
||||
if (splash->loopCount > 0)
|
||||
if (splash->loopCount > 0) {
|
||||
splash->loopCount--;
|
||||
}
|
||||
}
|
||||
} while (splash->time + splash->frames[splash->currentFrame].delay -
|
||||
SplashTime() <= 0);
|
||||
@ -183,8 +192,9 @@ BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out)
|
||||
pSrc += pSrcRect->depthBytes;
|
||||
++i;
|
||||
}
|
||||
if (i >= pSrcRect->numSamples)
|
||||
if (i >= pSrcRect->numSamples) {
|
||||
break;
|
||||
}
|
||||
i0 = i;
|
||||
while (i < pSrcRect->numSamples &&
|
||||
getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) {
|
||||
|
@ -55,7 +55,7 @@ le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSu
|
||||
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
|
||||
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
|
||||
|
||||
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
|
||||
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate), success)) {
|
||||
glyphIterator->setCurrGlyphID(SWAPW(alternateSetTable->alternateArray[0]));
|
||||
}
|
||||
|
||||
|
@ -37,55 +37,54 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const
|
||||
void AnchorTable::getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const
|
||||
{
|
||||
switch(SWAPW(anchorFormat)) {
|
||||
switch(SWAPW(anchorFormat)) {
|
||||
case 1:
|
||||
{
|
||||
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
|
||||
|
||||
f1->getAnchor(fontInstance, anchor);
|
||||
LEReferenceTo<Format1AnchorTable> f1(base, success);
|
||||
f1->getAnchor(f1, fontInstance, anchor, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const Format2AnchorTable *f2 = (const Format2AnchorTable *) this;
|
||||
|
||||
f2->getAnchor(glyphID, fontInstance, anchor);
|
||||
LEReferenceTo<Format2AnchorTable> f2(base, success);
|
||||
f2->getAnchor(f2, glyphID, fontInstance, anchor, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const Format3AnchorTable *f3 = (const Format3AnchorTable *) this;
|
||||
|
||||
f3->getAnchor(fontInstance, anchor);
|
||||
LEReferenceTo<Format3AnchorTable> f3(base, success);
|
||||
f3->getAnchor(f3, fontInstance, anchor, success);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// unknown format: just use x, y coordinate, like format 1...
|
||||
const Format1AnchorTable *f1 = (const Format1AnchorTable *) this;
|
||||
|
||||
f1->getAnchor(fontInstance, anchor);
|
||||
LEReferenceTo<Format1AnchorTable> f1(base, success);
|
||||
f1->getAnchor(f1, fontInstance, anchor, success);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Format1AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
void Format1AnchorTable::getAnchor(const LEReferenceTo<Format1AnchorTable>& base, const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const
|
||||
{
|
||||
le_int16 x = SWAPW(xCoordinate);
|
||||
le_int16 y = SWAPW(yCoordinate);
|
||||
LEPoint pixels;
|
||||
|
||||
fontInstance->transformFunits(x, y, pixels);
|
||||
|
||||
fontInstance->pixelsToUnits(pixels, anchor);
|
||||
}
|
||||
|
||||
void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
void Format2AnchorTable::getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
|
||||
LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor
|
||||
, LEErrorCode &success) const
|
||||
{
|
||||
LEPoint point;
|
||||
|
||||
@ -100,7 +99,8 @@ void Format2AnchorTable::getAnchor(LEGlyphID glyphID, const LEFontInstance *font
|
||||
fontInstance->pixelsToUnits(point, anchor);
|
||||
}
|
||||
|
||||
void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const
|
||||
void Format3AnchorTable::getAnchor(const LEReferenceTo<Format3AnchorTable> &base, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const
|
||||
{
|
||||
le_int16 x = SWAPW(xCoordinate);
|
||||
le_int16 y = SWAPW(yCoordinate);
|
||||
@ -111,15 +111,15 @@ void Format3AnchorTable::getAnchor(const LEFontInstance *fontInstance, LEPoint &
|
||||
fontInstance->transformFunits(x, y, pixels);
|
||||
|
||||
if (dtxOffset != 0) {
|
||||
const DeviceTable *dtx = (const DeviceTable *) ((char *) this + dtxOffset);
|
||||
le_int16 adjx = dtx->getAdjustment((le_int16) fontInstance->getXPixelsPerEm());
|
||||
LEReferenceTo<DeviceTable> dt(base, success, dtxOffset);
|
||||
le_int16 adjx = dt->getAdjustment(dt, (le_int16) fontInstance->getXPixelsPerEm(), success);
|
||||
|
||||
pixels.fX += adjx;
|
||||
}
|
||||
|
||||
if (dtyOffset != 0) {
|
||||
const DeviceTable *dty = (const DeviceTable *) ((char *) this + dtyOffset);
|
||||
le_int16 adjy = dty->getAdjustment((le_int16) fontInstance->getYPixelsPerEm());
|
||||
LEReferenceTo<DeviceTable> dt(base, success, dtyOffset);
|
||||
le_int16 adjy = dt->getAdjustment(dt, (le_int16) fontInstance->getYPixelsPerEm(), success);
|
||||
|
||||
pixels.fY += adjy;
|
||||
}
|
||||
|
@ -49,20 +49,23 @@ struct AnchorTable
|
||||
le_int16 xCoordinate;
|
||||
le_int16 yCoordinate;
|
||||
|
||||
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const;
|
||||
void getAnchor(const LETableReference &base, LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
struct Format1AnchorTable : AnchorTable
|
||||
{
|
||||
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
void getAnchor(const LEReferenceTo<Format1AnchorTable>& base,
|
||||
const LEFontInstance *fontInstance, LEPoint &anchor, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
struct Format2AnchorTable : AnchorTable
|
||||
{
|
||||
le_uint16 anchorPoint;
|
||||
|
||||
void getAnchor(LEGlyphID glyphID, const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
void getAnchor(const LEReferenceTo<Format2AnchorTable>& base,
|
||||
LEGlyphID glyphID, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
struct Format3AnchorTable : AnchorTable
|
||||
@ -70,7 +73,9 @@ struct Format3AnchorTable : AnchorTable
|
||||
Offset xDeviceTableOffset;
|
||||
Offset yDeviceTableOffset;
|
||||
|
||||
void getAnchor(const LEFontInstance *fontInstance, LEPoint &anchor) const;
|
||||
void getAnchor(const LEReferenceTo<Format3AnchorTable>& base,
|
||||
const LEFontInstance *fontInstance, LEPoint &anchor,
|
||||
LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
|
||||
le_bool CharSubstitutionFilter::accept(LEGlyphID glyph, LEErrorCode &/*success*/) const
|
||||
{
|
||||
return fFontInstance->canDisplay((LEUnicode) glyph);
|
||||
}
|
||||
@ -147,7 +147,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
|
||||
GDEFMarkFilter filter(fGDEFTable, success);
|
||||
adjustMarkGlyphs(glyphStorage, &filter, success);
|
||||
} else {
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData,
|
||||
CanonShaping::glyphDefinitionTable,
|
||||
CanonShaping::glyphDefinitionTableLen);
|
||||
GDEFMarkFilter filter(gdefTable, success);
|
||||
|
||||
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
|
||||
@ -157,9 +159,9 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
|
||||
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
|
||||
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
|
||||
{
|
||||
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
|
||||
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
|
||||
/* OpenTypeLayoutEngine will allocate a substitution filter */
|
||||
fGSUBTable.setTo(LETableReference::kStaticData, (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable, CanonShaping::glyphSubstitutionTableLen);
|
||||
fGDEFTable.setTo(LETableReference::kStaticData, (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
/* OpenTypeLayoutEngine will allocate a substitution filter */
|
||||
}
|
||||
|
||||
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
|
||||
|
@ -59,7 +59,8 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
|
||||
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
|
||||
const LEReferenceTo<ClassDefinitionTable> joiningTypes(LETableReference::kStaticData,
|
||||
(const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
|
||||
ArabicShaping::shapingTypeTableLen);
|
||||
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
|
||||
|
||||
|
@ -60,7 +60,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
|
||||
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
|
||||
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
|
||||
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
|
||||
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
|
||||
|
@ -43,6 +43,8 @@ class LEFontInstance;
|
||||
* This filter is used by character-based GSUB processors. It
|
||||
* accepts only those characters which the given font can display.
|
||||
*
|
||||
* Note: Implementation is in ArabicLayoutEngine.cpp
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class CharSubstitutionFilter : public UMemory, public LEGlyphFilter
|
||||
@ -97,7 +99,7 @@ public:
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
le_bool accept(LEGlyphID glyph) const;
|
||||
le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -49,6 +49,7 @@ struct ClassDefinitionTable
|
||||
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
|
||||
|
||||
#if LE_ENABLE_RAW
|
||||
le_int32 getGlyphClass(LEGlyphID glyphID) const {
|
||||
LETableReference base((const le_uint8*)this);
|
||||
LEErrorCode ignored = LE_NO_ERROR;
|
||||
@ -60,6 +61,7 @@ struct ClassDefinitionTable
|
||||
LEErrorCode ignored = LE_NO_ERROR;
|
||||
return hasGlyphClass(base,glyphClass,ignored);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ClassDefFormat1Table : ClassDefinitionTable
|
||||
|
@ -48,7 +48,7 @@ U_NAMESPACE_BEGIN
|
||||
*/
|
||||
void ContextualSubstitutionBase::applySubstitutionLookups(
|
||||
const LookupProcessor *lookupProcessor,
|
||||
const SubstitutionLookupRecord *substLookupRecordArray,
|
||||
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
|
||||
le_uint16 substCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
@ -60,10 +60,11 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
|
||||
}
|
||||
|
||||
GlyphIterator tempIterator(*glyphIterator);
|
||||
const SubstitutionLookupRecord *substLookupRecordArrayPtr = substLookupRecordArray.getAlias(); // OK to dereference, range checked against substCount below.
|
||||
|
||||
for (le_int16 subst = 0; subst < substCount && LE_SUCCESS(success); subst += 1) {
|
||||
le_uint16 sequenceIndex = SWAPW(substLookupRecordArray[subst].sequenceIndex);
|
||||
le_uint16 lookupListIndex = SWAPW(substLookupRecordArray[subst].lookupListIndex);
|
||||
le_uint16 sequenceIndex = SWAPW(substLookupRecordArrayPtr[subst].sequenceIndex);
|
||||
le_uint16 lookupListIndex = SWAPW(substLookupRecordArrayPtr[subst].lookupListIndex);
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(sequenceIndex);
|
||||
@ -72,7 +73,7 @@ void ContextualSubstitutionBase::applySubstitutionLookups(
|
||||
}
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, le_uint16 glyphCount,
|
||||
le_bool ContextualSubstitutionBase::matchGlyphIDs(const LEReferenceToArrayOf<TTGlyphID>& glyphArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
@ -101,10 +102,13 @@ le_bool ContextualSubstitutionBase::matchGlyphIDs(const TTGlyphID *glyphArray, l
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const ClassDefinitionTable *classDefinitionTable,
|
||||
le_bool backtrack)
|
||||
le_bool ContextualSubstitutionBase::matchGlyphClasses(
|
||||
const LEReferenceToArrayOf<le_uint16> &classArray,
|
||||
le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable,
|
||||
LEErrorCode &success,
|
||||
le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
le_int32 match = 0;
|
||||
@ -120,7 +124,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
|
||||
}
|
||||
|
||||
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 glyphClass = classDefinitionTable->getGlyphClass(glyph);
|
||||
le_int32 glyphClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyph, success);
|
||||
le_int32 matchClass = SWAPW(classArray[match]);
|
||||
|
||||
if (glyphClass != matchClass) {
|
||||
@ -128,7 +132,7 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
|
||||
// in the class array which aren't in the class definition
|
||||
// table. If we're looking for such a class, pretend that
|
||||
// we found it.
|
||||
if (classDefinitionTable->hasGlyphClass(matchClass)) {
|
||||
if (classDefinitionTable->hasGlyphClass(classDefinitionTable, matchClass, success)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -140,8 +144,8 @@ le_bool ContextualSubstitutionBase::matchGlyphClasses(const le_uint16 *classArra
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack)
|
||||
le_bool ContextualSubstitutionBase::matchGlyphCoverages(const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const LETableReference &offsetBase, LEErrorCode &success, le_bool backtrack)
|
||||
{
|
||||
le_int32 direction = 1;
|
||||
le_int32 glyph = 0;
|
||||
@ -153,13 +157,15 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
|
||||
|
||||
while (glyphCount > 0) {
|
||||
Offset coverageTableOffset = SWAPW(coverageTableOffsetArray[glyph]);
|
||||
const CoverageTable *coverageTable = (const CoverageTable *) (offsetBase + coverageTableOffset);
|
||||
LEReferenceTo<CoverageTable> coverageTable(offsetBase, success, coverageTableOffset);
|
||||
|
||||
if (! glyphIterator->next()) {
|
||||
if (LE_FAILURE(success) || ! glyphIterator->next()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (coverageTable->getGlyphCoverage((LEGlyphID) glyphIterator->getCurrGlyphID()) < 0) {
|
||||
if (coverageTable->getGlyphCoverage(coverageTable,
|
||||
(LEGlyphID) glyphIterator->getCurrGlyphID(),
|
||||
success) < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -170,7 +176,7 @@ le_bool ContextualSubstitutionBase::matchGlyphCoverages(const Offset *coverageTa
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ContextualSubstitutionSubtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
@ -186,20 +192,29 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
|
||||
|
||||
case 1:
|
||||
{
|
||||
const ContextualSubstitutionFormat1Subtable *subtable = (const ContextualSubstitutionFormat1Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ContextualSubstitutionFormat1Subtable> subtable(base, success, (const ContextualSubstitutionFormat1Subtable *) this);
|
||||
if( LE_FAILURE(success) ) {
|
||||
return 0;
|
||||
}
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const ContextualSubstitutionFormat2Subtable *subtable = (const ContextualSubstitutionFormat2Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ContextualSubstitutionFormat2Subtable> subtable(base, success, (const ContextualSubstitutionFormat2Subtable *) this);
|
||||
if( LE_FAILURE(success) ) {
|
||||
return 0;
|
||||
}
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const ContextualSubstitutionFormat3Subtable *subtable = (const ContextualSubstitutionFormat3Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ContextualSubstitutionFormat3Subtable> subtable(base, success, (const ContextualSubstitutionFormat3Subtable *) this);
|
||||
if( LE_FAILURE(success) ) {
|
||||
return 0;
|
||||
}
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
default:
|
||||
@ -207,7 +222,7 @@ le_uint32 ContextualSubstitutionSubtable::process(const LookupProcessor *lookupP
|
||||
}
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
@ -227,22 +242,22 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
|
||||
|
||||
if (coverageIndex < srSetCount) {
|
||||
Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
|
||||
const SubRuleSetTable *subRuleSetTable =
|
||||
(const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset);
|
||||
LEReferenceTo<SubRuleSetTable>
|
||||
subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset));
|
||||
le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
|
||||
for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
|
||||
Offset subRuleTableOffset =
|
||||
SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
|
||||
const SubRuleTable *subRuleTable =
|
||||
(const SubRuleTable *) ((char *) subRuleSetTable + subRuleTableOffset);
|
||||
LEReferenceTo<SubRuleTable>
|
||||
subRuleTable(subRuleSetTable, success, subRuleTableOffset);
|
||||
le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1;
|
||||
le_uint16 substCount = SWAPW(subRuleTable->substCount);
|
||||
|
||||
if (matchGlyphIDs(subRuleTable->inputGlyphArray, matchCount, glyphIterator)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount];
|
||||
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2);
|
||||
if (matchGlyphIDs(inputGlyphArray, matchCount, glyphIterator)) {
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subRuleTable->inputGlyphArray[matchCount], substCount);
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
@ -259,10 +274,11 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LookupProcessor *
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference &base,
|
||||
const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
{
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
@ -275,29 +291,33 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
|
||||
}
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
const ClassDefinitionTable *classDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset));
|
||||
LEReferenceTo<ClassDefinitionTable> classDefinitionTable(base, success,
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset)));
|
||||
le_uint16 scSetCount = SWAPW(subClassSetCount);
|
||||
le_int32 setClass = classDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
|
||||
le_int32 setClass = classDefinitionTable->getGlyphClass(classDefinitionTable,
|
||||
glyphIterator->getCurrGlyphID(),
|
||||
success);
|
||||
|
||||
if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
|
||||
Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
|
||||
const SubClassSetTable *subClassSetTable =
|
||||
(const SubClassSetTable *) ((char *) this + subClassSetTableOffset);
|
||||
LEReferenceTo<SubClassSetTable>
|
||||
subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset));
|
||||
le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
|
||||
for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
|
||||
Offset subClassRuleTableOffset =
|
||||
SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
|
||||
const SubClassRuleTable *subClassRuleTable =
|
||||
(const SubClassRuleTable *) ((char *) subClassSetTable + subClassRuleTableOffset);
|
||||
LEReferenceTo<SubClassRuleTable>
|
||||
subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset);
|
||||
le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1;
|
||||
le_uint16 substCount = SWAPW(subClassRuleTable->substCount);
|
||||
|
||||
if (matchGlyphClasses(subClassRuleTable->classArray, matchCount, glyphIterator, classDefinitionTable)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount];
|
||||
LEReferenceToArrayOf<le_uint16> classArray(base, success, subClassRuleTable->classArray, matchCount+1);
|
||||
|
||||
if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) {
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount);
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
@ -314,7 +334,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LookupProcessor *
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ContextualSubstitutionFormat3Subtable::process(const LETableReference &base,
|
||||
const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success)const
|
||||
@ -333,9 +354,13 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
|
||||
// that matched when we're done.
|
||||
glyphIterator->prev();
|
||||
|
||||
if (ContextualSubstitutionBase::matchGlyphCoverages(coverageTableOffsetArray, gCount, glyphIterator, (const char *) this)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount];
|
||||
LEReferenceToArrayOf<Offset> covTableOffsetArray(base, success, coverageTableOffsetArray, gCount);
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
|
||||
if (ContextualSubstitutionBase::matchGlyphCoverages(covTableOffsetArray, gCount, glyphIterator, base, success)) {
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &coverageTableOffsetArray[gCount], subCount);
|
||||
|
||||
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, subCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
@ -347,7 +372,8 @@ le_uint32 ContextualSubstitutionFormat3Subtable::process(const LookupProcessor *
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ChainingContextualSubstitutionSubtable::process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base,
|
||||
const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
@ -363,20 +389,23 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
|
||||
|
||||
case 1:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat1Subtable *subtable = (const ChainingContextualSubstitutionFormat1Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ChainingContextualSubstitutionFormat1Subtable> subtable(base, success, (ChainingContextualSubstitutionFormat1Subtable *) this);
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat2Subtable *subtable = (const ChainingContextualSubstitutionFormat2Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ChainingContextualSubstitutionFormat2Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat2Subtable *) this);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
const ChainingContextualSubstitutionFormat3Subtable *subtable = (const ChainingContextualSubstitutionFormat3Subtable *) this;
|
||||
return subtable->process(lookupProcessor, glyphIterator, fontInstance, success);
|
||||
LEReferenceTo<ChainingContextualSubstitutionFormat3Subtable> subtable(base, success, (const ChainingContextualSubstitutionFormat3Subtable *) this);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
return subtable->process(subtable, lookupProcessor, glyphIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
default:
|
||||
@ -390,7 +419,7 @@ le_uint32 ChainingContextualSubstitutionSubtable::process(const LookupProcessor
|
||||
// emptyFeatureList matches an le_uint32 or an le_uint16...
|
||||
static const FeatureMask emptyFeatureList = 0x00000000UL;
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
@ -410,8 +439,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
|
||||
|
||||
if (coverageIndex < srSetCount) {
|
||||
Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
|
||||
const ChainSubRuleSetTable *chainSubRuleSetTable =
|
||||
(const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset);
|
||||
LEReferenceTo<ChainSubRuleSetTable>
|
||||
chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset));
|
||||
le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
@ -419,13 +448,19 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
|
||||
for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
|
||||
Offset chainSubRuleTableOffset =
|
||||
SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
|
||||
const ChainSubRuleTable *chainSubRuleTable =
|
||||
(const ChainSubRuleTable *) ((char *) chainSubRuleSetTable + chainSubRuleTableOffset);
|
||||
LEReferenceTo<ChainSubRuleTable>
|
||||
chainSubRuleTable = LEReferenceTo<ChainSubRuleTable>(chainSubRuleSetTable, success, chainSubRuleTableOffset);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 backtrackGlyphCount = SWAPW(chainSubRuleTable->backtrackGlyphCount);
|
||||
LEReferenceToArrayOf<TTGlyphID> backtrackGlyphArray(base, success, chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 inputGlyphCount = (le_uint16) SWAPW(chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount]) - 1;
|
||||
const TTGlyphID *inputGlyphArray = &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1];
|
||||
LEReferenceToArrayOf<TTGlyphID> inputGlyphArray(base, success, &chainSubRuleTable->backtrackGlyphArray[backtrackGlyphCount + 1], inputGlyphCount+2);
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputGlyphArray[inputGlyphCount]);
|
||||
const TTGlyphID *lookaheadGlyphArray = &inputGlyphArray[inputGlyphCount + 1];
|
||||
LEReferenceToArrayOf<TTGlyphID> lookaheadGlyphArray(base, success, inputGlyphArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 substCount = (le_uint16) SWAPW(lookaheadGlyphArray[lookaheadGlyphCount]);
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
@ -435,7 +470,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
|
||||
}
|
||||
|
||||
tempIterator.prev();
|
||||
if (! matchGlyphIDs(chainSubRuleTable->backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
|
||||
|
||||
if (! matchGlyphIDs(backtrackGlyphArray, backtrackGlyphCount, &tempIterator, TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -446,8 +482,8 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
|
||||
}
|
||||
|
||||
if (matchGlyphIDs(inputGlyphArray, inputGlyphCount, glyphIterator)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadGlyphArray[lookaheadGlyphCount + 1];
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadGlyphArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
@ -464,7 +500,7 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LookupPro
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode& success) const
|
||||
@ -480,19 +516,21 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
|
||||
}
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
const ClassDefinitionTable *backtrackClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset));
|
||||
const ClassDefinitionTable *inputClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset));
|
||||
const ClassDefinitionTable *lookaheadClassDefinitionTable =
|
||||
(const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset));
|
||||
LEReferenceTo<ClassDefinitionTable>
|
||||
backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset)));
|
||||
LEReferenceTo<ClassDefinitionTable>
|
||||
inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset)));
|
||||
LEReferenceTo<ClassDefinitionTable>
|
||||
lookaheadClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset)));
|
||||
le_uint16 scSetCount = SWAPW(chainSubClassSetCount);
|
||||
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(glyphIterator->getCurrGlyphID());
|
||||
le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable,
|
||||
glyphIterator->getCurrGlyphID(),
|
||||
success);
|
||||
|
||||
if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
|
||||
Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
|
||||
const ChainSubClassSetTable *chainSubClassSetTable =
|
||||
(const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset);
|
||||
LEReferenceTo<ChainSubClassSetTable>
|
||||
chainSubClassSetTable(base, success, (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset));
|
||||
le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
@ -500,13 +538,15 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
|
||||
for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
|
||||
Offset chainSubClassRuleTableOffset =
|
||||
SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
|
||||
const ChainSubClassRuleTable *chainSubClassRuleTable =
|
||||
(const ChainSubClassRuleTable *) ((char *) chainSubClassSetTable + chainSubClassRuleTableOffset);
|
||||
LEReferenceTo<ChainSubClassRuleTable>
|
||||
chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset);
|
||||
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
|
||||
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
|
||||
const le_uint16 *inputClassArray = &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1];
|
||||
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray[inputGlyphCount]);
|
||||
const le_uint16 *lookaheadClassArray = &inputClassArray[inputGlyphCount + 1];
|
||||
LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count
|
||||
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success));
|
||||
LEReferenceToArrayOf<le_uint16> lookaheadClassArray(base, success, inputClassArray.getAlias(inputGlyphCount + 1,success), lookaheadGlyphCount+2); // +2 for the substCount
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 substCount = SWAPW(lookaheadClassArray[lookaheadGlyphCount]);
|
||||
|
||||
|
||||
@ -517,20 +557,22 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
|
||||
}
|
||||
|
||||
tempIterator.prev();
|
||||
if (! matchGlyphClasses(chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount,
|
||||
&tempIterator, backtrackClassDefinitionTable, TRUE)) {
|
||||
LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount,
|
||||
&tempIterator, backtrackClassDefinitionTable, success, TRUE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(inputGlyphCount);
|
||||
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable)) {
|
||||
if (! matchGlyphClasses(lookaheadClassArray, lookaheadGlyphCount, &tempIterator, lookaheadClassDefinitionTable, success)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadClassArray[lookaheadGlyphCount + 1];
|
||||
if (matchGlyphClasses(inputClassArray, inputGlyphCount, glyphIterator, inputClassDefinitionTable, success)) {
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) lookaheadClassArray.getAlias(lookaheadGlyphCount + 1, success), substCount);
|
||||
|
||||
applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
@ -547,7 +589,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LookupPro
|
||||
return 0;
|
||||
}
|
||||
|
||||
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupProcessor *lookupProcessor,
|
||||
le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
LEErrorCode & success) const
|
||||
@ -558,9 +600,13 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
|
||||
|
||||
le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
|
||||
le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
|
||||
const Offset *inputCoverageTableOffsetArray = &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1];
|
||||
LEReferenceToArrayOf<Offset> inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset
|
||||
const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
|
||||
const Offset *lookaheadCoverageTableOffsetArray = &inputCoverageTableOffsetArray[inputGlyphCount + 1];
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
LEReferenceToArrayOf<Offset> lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2);
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 substCount = (le_uint16) SWAPW(lookaheadCoverageTableOffsetArray[lookaheadGlyphCount]);
|
||||
le_int32 position = glyphIterator->getCurrStreamPosition();
|
||||
GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
|
||||
@ -571,14 +617,14 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
|
||||
|
||||
tempIterator.prev();
|
||||
if (! ContextualSubstitutionBase::matchGlyphCoverages(backtrackCoverageTableOffsetArray,
|
||||
backtrkGlyphCount, &tempIterator, (const char *) this, TRUE)) {
|
||||
backtrkGlyphCount, &tempIterator, base, success, TRUE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tempIterator.setCurrStreamPosition(position);
|
||||
tempIterator.next(inputGlyphCount - 1);
|
||||
if (! ContextualSubstitutionBase::matchGlyphCoverages(lookaheadCoverageTableOffsetArray,
|
||||
lookaheadGlyphCount, &tempIterator, (const char *) this)) {
|
||||
lookaheadGlyphCount, &tempIterator, base, success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -589,9 +635,10 @@ le_uint32 ChainingContextualSubstitutionFormat3Subtable::process(const LookupPro
|
||||
glyphIterator->prev();
|
||||
|
||||
if (ContextualSubstitutionBase::matchGlyphCoverages(inputCoverageTableOffsetArray,
|
||||
inputGlyphCount, glyphIterator, (const char *) this)) {
|
||||
const SubstitutionLookupRecord *substLookupRecordArray =
|
||||
(const SubstitutionLookupRecord *) &lookaheadCoverageTableOffsetArray[lookaheadGlyphCount + 1];
|
||||
inputGlyphCount, glyphIterator, base, success)) {
|
||||
LEReferenceToArrayOf<SubstitutionLookupRecord>
|
||||
substLookupRecordArray(base, success,
|
||||
(const SubstitutionLookupRecord *) lookaheadCoverageTableOffsetArray.getAlias(lookaheadGlyphCount + 1,success), substCount);
|
||||
|
||||
ContextualSubstitutionBase::applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success);
|
||||
|
||||
|
@ -56,20 +56,32 @@ struct SubstitutionLookupRecord
|
||||
struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
|
||||
{
|
||||
static le_bool matchGlyphIDs(
|
||||
const TTGlyphID *glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
const LEReferenceToArrayOf<TTGlyphID> &glyphArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
le_bool backtrack = FALSE);
|
||||
|
||||
static le_bool matchGlyphClasses(
|
||||
const le_uint16 *classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
const ClassDefinitionTable *classDefinitionTable, le_bool backtrack = FALSE);
|
||||
const LEReferenceToArrayOf<le_uint16> &classArray, le_uint16 glyphCount, GlyphIterator *glyphIterator,
|
||||
const LEReferenceTo<ClassDefinitionTable> &classDefinitionTable, LEErrorCode &success, le_bool backtrack = FALSE);
|
||||
|
||||
static le_bool matchGlyphCoverages(
|
||||
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const char *offsetBase, le_bool backtrack = FALSE);
|
||||
const LEReferenceToArrayOf<Offset> &coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE);
|
||||
|
||||
/**
|
||||
* little shim to wrap the Offset array in range checking
|
||||
* @private
|
||||
*/
|
||||
static le_bool matchGlyphCoverages(
|
||||
const Offset *coverageTableOffsetArray, le_uint16 glyphCount,
|
||||
GlyphIterator *glyphIterator, const LETableReference& offsetBase, LEErrorCode &success, le_bool backtrack = FALSE) {
|
||||
LEReferenceToArrayOf<Offset> ref(offsetBase, success, coverageTableOffsetArray, glyphCount);
|
||||
if( LE_FAILURE(success) ) { return FALSE; }
|
||||
return matchGlyphCoverages(ref, glyphCount, glyphIterator, offsetBase, success, backtrack);
|
||||
}
|
||||
|
||||
static void applySubstitutionLookups(
|
||||
const LookupProcessor *lookupProcessor,
|
||||
const SubstitutionLookupRecord *substLookupRecordArray,
|
||||
const LEReferenceToArrayOf<SubstitutionLookupRecord>& substLookupRecordArray,
|
||||
le_uint16 substCount,
|
||||
GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance,
|
||||
@ -79,7 +91,8 @@ struct ContextualSubstitutionBase : GlyphSubstitutionSubtable
|
||||
|
||||
struct ContextualSubstitutionSubtable : ContextualSubstitutionBase
|
||||
{
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
|
||||
@ -87,7 +100,8 @@ struct ContextualSubstitutionFormat1Subtable : ContextualSubstitutionSubtable
|
||||
le_uint16 subRuleSetCount;
|
||||
Offset subRuleSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
|
||||
|
||||
@ -116,7 +130,7 @@ struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
|
||||
le_uint16 subClassSetCount;
|
||||
Offset subClassSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
|
||||
|
||||
@ -152,13 +166,15 @@ struct ContextualSubstitutionFormat3Subtable
|
||||
Offset coverageTableOffsetArray[ANY_NUMBER];
|
||||
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
|
||||
|
||||
struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
|
||||
{
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LEReferenceTo<ChainingContextualSubstitutionSubtable> &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstitutionSubtable
|
||||
@ -166,7 +182,8 @@ struct ChainingContextualSubstitutionFormat1Subtable : ChainingContextualSubstit
|
||||
le_uint16 chainSubRuleSetCount;
|
||||
Offset chainSubRuleSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
|
||||
|
||||
@ -201,7 +218,8 @@ struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstit
|
||||
le_uint16 chainSubClassSetCount;
|
||||
Offset chainSubClassSetTableOffsetArray[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator,
|
||||
const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
|
||||
|
||||
@ -243,7 +261,8 @@ struct ChainingContextualSubstitutionFormat3Subtable
|
||||
//le_uint16 substCount;
|
||||
//SubstitutionLookupRecord substLookupRecord[ANY_NUMBER];
|
||||
|
||||
le_uint32 process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
le_uint32 process(const LETableReference &base, const LookupProcessor *lookupProcessor,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
|
||||
|
||||
|
@ -37,8 +37,10 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
le_int32 CoverageTable::getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return -1;
|
||||
|
||||
switch(SWAPW(coverageFormat))
|
||||
{
|
||||
case 0:
|
||||
@ -46,16 +48,16 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
|
||||
case 1:
|
||||
{
|
||||
const CoverageFormat1Table *f1Table = (const CoverageFormat1Table *) this;
|
||||
LEReferenceTo<CoverageFormat1Table> f1Table(base, success);
|
||||
|
||||
return f1Table->getGlyphCoverage(glyphID);
|
||||
return f1Table->getGlyphCoverage(f1Table, glyphID, success);
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
const CoverageFormat2Table *f2Table = (const CoverageFormat2Table *) this;
|
||||
LEReferenceTo<CoverageFormat2Table> f2Table(base, success);
|
||||
|
||||
return f2Table->getGlyphCoverage(glyphID);
|
||||
return f2Table->getGlyphCoverage(f2Table, glyphID, success);
|
||||
}
|
||||
|
||||
default:
|
||||
@ -63,8 +65,10 @@ le_int32 CoverageTable::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
le_int32 CoverageFormat1Table::getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return -1;
|
||||
|
||||
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
le_uint16 count = SWAPW(glyphCount);
|
||||
le_uint8 bit = OpenTypeUtilities::highBit(count);
|
||||
@ -73,37 +77,45 @@ le_int32 CoverageFormat1Table::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
le_uint16 probe = power;
|
||||
le_uint16 index = 0;
|
||||
|
||||
if (count == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (count == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf<TTGlyphID>(base, success, glyphArray, count);
|
||||
if(LE_FAILURE(success)) return -1; // range checks array
|
||||
|
||||
|
||||
if (SWAPW(glyphArray[extra]) <= ttGlyphID) {
|
||||
index = extra;
|
||||
index = extra;
|
||||
}
|
||||
|
||||
while (probe > (1 << 0)) {
|
||||
probe >>= 1;
|
||||
probe >>= 1;
|
||||
|
||||
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
|
||||
index += probe;
|
||||
}
|
||||
if (SWAPW(glyphArray[index + probe]) <= ttGlyphID) {
|
||||
index += probe;
|
||||
}
|
||||
}
|
||||
|
||||
if (SWAPW(glyphArray[index]) == ttGlyphID) {
|
||||
return index;
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
le_int32 CoverageFormat2Table::getGlyphCoverage(LEGlyphID glyphID) const
|
||||
le_int32 CoverageFormat2Table::getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const
|
||||
{
|
||||
if(LE_FAILURE(success)) return -1;
|
||||
|
||||
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
|
||||
le_uint16 count = SWAPW(rangeCount);
|
||||
le_int32 rangeIndex =
|
||||
OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArray, count);
|
||||
|
||||
if (rangeIndex < 0) {
|
||||
LEReferenceToArrayOf<GlyphRangeRecord> rangeRecordArrayRef(base, success, rangeRecordArray, count);
|
||||
le_int32 rangeIndex =
|
||||
OpenTypeUtilities::getGlyphRangeIndex(ttGlyphID, rangeRecordArrayRef, success);
|
||||
|
||||
if (rangeIndex < 0 || LE_FAILURE(success)) { // could fail if array out of bounds
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct CoverageTable
|
||||
{
|
||||
le_uint16 coverageFormat;
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
le_int32 getGlyphCoverage(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
struct CoverageFormat1Table : CoverageTable
|
||||
@ -54,7 +54,7 @@ struct CoverageFormat1Table : CoverageTable
|
||||
le_uint16 glyphCount;
|
||||
TTGlyphID glyphArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat1Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
|
||||
|
||||
@ -64,7 +64,7 @@ struct CoverageFormat2Table : CoverageTable
|
||||
le_uint16 rangeCount;
|
||||
GlyphRangeRecord rangeRecordArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
|
||||
le_int32 getGlyphCoverage(LEReferenceTo<CoverageFormat2Table> &base, LEGlyphID glyphID, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
|
||||
|
||||
|
@ -51,23 +51,27 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachme
|
||||
}
|
||||
|
||||
LEPoint entryAnchor, exitAnchor;
|
||||
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO
|
||||
Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
|
||||
Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
|
||||
|
||||
if (entryOffset != 0) {
|
||||
const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset);
|
||||
LEReferenceTo<AnchorTable> entryAnchorTable(base, success, entryOffset);
|
||||
|
||||
entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
|
||||
glyphIterator->setCursiveEntryPoint(entryAnchor);
|
||||
if( LE_SUCCESS(success) ) {
|
||||
entryAnchorTable->getAnchor(entryAnchorTable, glyphID, fontInstance, entryAnchor, success);
|
||||
glyphIterator->setCursiveEntryPoint(entryAnchor);
|
||||
}
|
||||
} else {
|
||||
//glyphIterator->clearCursiveEntryPoint();
|
||||
}
|
||||
|
||||
if (exitOffset != 0) {
|
||||
const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset);
|
||||
LEReferenceTo<AnchorTable> exitAnchorTable(base, success, exitOffset);
|
||||
|
||||
exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
|
||||
glyphIterator->setCursiveExitPoint(exitAnchor);
|
||||
if( LE_SUCCESS(success) ) {
|
||||
exitAnchorTable->getAnchor(exitAnchorTable, glyphID, fontInstance, exitAnchor, success);
|
||||
glyphIterator->setCursiveExitPoint(exitAnchor);
|
||||
}
|
||||
} else {
|
||||
//glyphIterator->clearCursiveExitPoint();
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ const le_uint16 DeviceTable::fieldBits[] = { 2, 4, 8};
|
||||
|
||||
#define FORMAT_COUNT LE_ARRAY_SIZE(fieldBits)
|
||||
|
||||
le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
|
||||
le_int16 DeviceTable::getAdjustment(const LEReferenceTo<DeviceTable>&base, le_uint16 ppem, LEErrorCode &success) const
|
||||
{
|
||||
le_uint16 start = SWAPW(startSize);
|
||||
le_uint16 format = SWAPW(deltaFormat) - 1;
|
||||
@ -53,6 +53,13 @@ le_int16 DeviceTable::getAdjustment(le_uint16 ppem) const
|
||||
le_uint16 sizeIndex = ppem - start;
|
||||
le_uint16 bits = fieldBits[format];
|
||||
le_uint16 count = 16 / bits;
|
||||
|
||||
LEReferenceToArrayOf<le_uint16> deltaValuesRef(base, success, deltaValues, (sizeIndex / count));
|
||||
|
||||
if(LE_FAILURE(success)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
le_uint16 word = SWAPW(deltaValues[sizeIndex / count]);
|
||||
le_uint16 fieldIndex = sizeIndex % count;
|
||||
le_uint16 shift = 16 - (bits * (fieldIndex + 1));
|
||||
|
@ -50,7 +50,7 @@ struct DeviceTable
|
||||
le_uint16 deltaFormat;
|
||||
le_uint16 deltaValues[ANY_NUMBER];
|
||||
|
||||
le_int16 getAdjustment(le_uint16 ppem) const;
|
||||
le_int16 getAdjustment(const LEReferenceTo<DeviceTable> &base, le_uint16 ppem, LEErrorCode &success) const;
|
||||
|
||||
private:
|
||||
static const le_uint16 fieldMasks[];
|
||||
|
@ -48,7 +48,6 @@ le_uint32 ExtensionSubtable::process(const LEReferenceTo<ExtensionSubtable> &thi
|
||||
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
|
||||
{
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -52,8 +52,7 @@ struct ExtensionSubtable //: GlyphSubstitutionSubtable
|
||||
le_uint16 extensionLookupType;
|
||||
le_uint32 extensionOffset;
|
||||
|
||||
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &extRef,
|
||||
const LookupProcessor *lookupProcessor, le_uint16 lookupType,
|
||||
le_uint32 process(const LEReferenceTo<ExtensionSubtable> &base, const LookupProcessor *lookupProcessor, le_uint16 lookupType,
|
||||
GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
|
||||
};
|
||||
|
||||
|
@ -49,11 +49,11 @@ GDEFMarkFilter::~GDEFMarkFilter()
|
||||
// nothing to do?
|
||||
}
|
||||
|
||||
le_bool GDEFMarkFilter::accept(LEGlyphID glyph) const
|
||||
le_bool GDEFMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
|
||||
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
|
||||
|
||||
return glyphClass == gcdMarkGlyph;
|
||||
return glyphClass == gcdMarkGlyph;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
|
||||
virtual ~GDEFMarkFilter();
|
||||
|
||||
virtual le_bool accept(LEGlyphID glyph) const;
|
||||
virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -41,14 +41,13 @@
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader)
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success)
|
||||
: direction(1), position(-1), nextLimit(-1), prevLimit(-1),
|
||||
glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
|
||||
srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
|
||||
glyphClassDefinitionTable(), markAttachClassDefinitionTable()
|
||||
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR; // TODO
|
||||
le_int32 glyphCount = glyphStorage.getGlyphCount();
|
||||
|
||||
if (theGlyphDefinitionTableHeader.isValid()) {
|
||||
@ -388,7 +387,7 @@ void GlyphIterator::setCursiveGlyph()
|
||||
|
||||
void GlyphIterator::filterResetCache(void) {
|
||||
filterCacheValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
le_bool GlyphIterator::filterGlyph(le_uint32 index)
|
||||
{
|
||||
@ -399,53 +398,53 @@ le_bool GlyphIterator::filterGlyph(le_uint32 index)
|
||||
|
||||
le_bool &filterResult = filterCache.result; // NB: Making this a reference to accept the updated value, in case
|
||||
// we want more fancy cacheing in the future.
|
||||
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
|
||||
if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
|
||||
filterResult = TRUE;
|
||||
} else {
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 glyphClass = gcdNoGlyphClass;
|
||||
if (glyphClassDefinitionTable.isValid()) {
|
||||
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
|
||||
}
|
||||
if (glyphClassDefinitionTable.isValid()) {
|
||||
glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
|
||||
}
|
||||
switch (glyphClass) {
|
||||
case gcdNoGlyphClass:
|
||||
case gcdNoGlyphClass:
|
||||
filterResult = FALSE;
|
||||
break;
|
||||
|
||||
case gcdSimpleGlyph:
|
||||
case gcdSimpleGlyph:
|
||||
filterResult = (lookupFlags & lfIgnoreBaseGlyphs) != 0;
|
||||
break;
|
||||
|
||||
case gcdLigatureGlyph:
|
||||
case gcdLigatureGlyph:
|
||||
filterResult = (lookupFlags & lfIgnoreLigatures) != 0;
|
||||
break;
|
||||
|
||||
case gcdMarkGlyph:
|
||||
if ((lookupFlags & lfIgnoreMarks) != 0) {
|
||||
case gcdMarkGlyph:
|
||||
if ((lookupFlags & lfIgnoreMarks) != 0) {
|
||||
filterResult = TRUE;
|
||||
} else {
|
||||
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
|
||||
le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
|
||||
|
||||
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
|
||||
if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
|
||||
filterResult = (markAttachClassDefinitionTable
|
||||
-> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType);
|
||||
} else {
|
||||
filterResult = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case gcdComponentGlyph:
|
||||
case gcdComponentGlyph:
|
||||
filterResult = ((lookupFlags & lfIgnoreBaseGlyphs) != 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
filterResult = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
filterCacheValid = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return filterCache.result;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class GlyphPositionAdjustments;
|
||||
class GlyphIterator : public UMemory {
|
||||
public:
|
||||
GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader);
|
||||
FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader, LEErrorCode &success);
|
||||
|
||||
GlyphIterator(GlyphIterator &that);
|
||||
|
||||
|
@ -95,6 +95,8 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
|
||||
|
||||
le_uint32 delta = 0;
|
||||
|
||||
//_LETRACE("attempting lookupType #%d", lookupType);
|
||||
|
||||
switch(lookupType)
|
||||
{
|
||||
case 0:
|
||||
@ -152,21 +154,21 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
|
||||
{
|
||||
LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
delta = subtable->process(subtable, this , glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstChainedContext:
|
||||
{
|
||||
LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
|
||||
const LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
case gpstExtension:
|
||||
{
|
||||
LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
|
||||
const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(subtable, this, lookupType, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
@ -176,6 +178,12 @@ le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<Loo
|
||||
break;
|
||||
}
|
||||
|
||||
#if LE_TRACE
|
||||
if(delta != 0) {
|
||||
_LETRACE("GlyphPositioningLookupProcessor applied #%d -> delta %d @ %d", lookupType, delta, glyphIterator->getCurrStreamPosition());
|
||||
}
|
||||
#endif
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
|
||||
{
|
||||
const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<Lo
|
||||
{
|
||||
const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
|
||||
|
||||
delta = subtable->process(this, glyphIterator, fontInstance, success);
|
||||
delta = subtable->process(subtable, this, glyphIterator, fontInstance, success);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include "LEGlyphStorage.h"
|
||||
|
||||
#include "IndicReordering.h"
|
||||
#include <stdio.h>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
|
||||
@ -53,14 +53,14 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
|
||||
le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
|
||||
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
|
||||
{
|
||||
if ( version2 ) {
|
||||
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
|
||||
} else {
|
||||
if ( version2 ) {
|
||||
fFeatureMap = IndicReordering::getv2FeatureMap(fFeatureMapCount);
|
||||
} else {
|
||||
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
|
||||
}
|
||||
fFeatureOrder = TRUE;
|
||||
fVersion2 = version2;
|
||||
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
|
||||
}
|
||||
fFeatureOrder = TRUE;
|
||||
fVersion2 = version2;
|
||||
fFilterZeroWidth = IndicReordering::getFilterZeroWidth(fScriptCode);
|
||||
}
|
||||
|
||||
IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
|
||||
@ -68,7 +68,7 @@ IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontI
|
||||
{
|
||||
fFeatureMap = IndicReordering::getFeatureMap(fFeatureMapCount);
|
||||
fFeatureOrder = TRUE;
|
||||
fVersion2 = FALSE;
|
||||
fVersion2 = FALSE;
|
||||
}
|
||||
|
||||
IndicOpenTypeLayoutEngine::~IndicOpenTypeLayoutEngine()
|
||||
@ -90,6 +90,7 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LETRACE("IOTLE::gp, calling parent");
|
||||
le_int32 retCount = OpenTypeLayoutEngine::glyphProcessing(chars, offset, count, max, rightToLeft, glyphStorage, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
@ -97,11 +98,15 @@ le_int32 IndicOpenTypeLayoutEngine::glyphProcessing(const LEUnicode chars[], le_
|
||||
}
|
||||
|
||||
if (fVersion2) {
|
||||
IndicReordering::finalReordering(glyphStorage,retCount);
|
||||
IndicReordering::applyPresentationForms(glyphStorage,retCount);
|
||||
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
|
||||
_LETRACE("IOTLE::gp, v2 final,");
|
||||
IndicReordering::finalReordering(glyphStorage,retCount);
|
||||
_LETRACE("IOTLE::gp, v2 pres");
|
||||
IndicReordering::applyPresentationForms(glyphStorage,retCount);
|
||||
_LETRACE("IOTLE::gp, parent gsub");
|
||||
OpenTypeLayoutEngine::glyphSubstitution(count,max, rightToLeft, glyphStorage, success);
|
||||
} else {
|
||||
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
|
||||
_LETRACE("IOTLE::gp, adjust mpres");
|
||||
IndicReordering::adjustMPres(fMPreFixups, glyphStorage, success);
|
||||
}
|
||||
return retCount;
|
||||
}
|
||||
@ -116,6 +121,8 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LETRACE("IOTLE: charProc");
|
||||
|
||||
if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
|
||||
success = LE_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
@ -143,8 +150,10 @@ le_int32 IndicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[],
|
||||
|
||||
le_int32 outCharCount;
|
||||
if (fVersion2) {
|
||||
_LETRACE("v2process");
|
||||
outCharCount = IndicReordering::v2process(&chars[offset], count, fScriptCode, outChars, glyphStorage);
|
||||
} else {
|
||||
_LETRACE("reorder");
|
||||
outCharCount = IndicReordering::reorder(&chars[offset], count, fScriptCode, outChars, glyphStorage, &fMPreFixups, success);
|
||||
}
|
||||
|
||||
|
@ -254,8 +254,8 @@ public:
|
||||
return fGlyphStorage.getAuxData(charIndex,success);
|
||||
}
|
||||
|
||||
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
|
||||
le_int32 i;
|
||||
void decomposeReorderMatras ( const IndicClassTable *classTable, le_int32 beginSyllable, le_int32 nextSyllable, le_int32 inv_count ) {
|
||||
le_int32 i;
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
|
||||
for ( i = beginSyllable ; i < nextSyllable ; i++ ) {
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#define DEBUG_KERN_TABLE 0
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
@ -99,14 +99,14 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
|
||||
: pairsSwapped(NULL), fTable(base)
|
||||
{
|
||||
if(LE_FAILURE(success) || (fTable.isEmpty())) {
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "no kern data\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
LEReferenceTo<KernTableHeader> header(fTable, success);
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
// dump first 32 bytes of header
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
|
||||
@ -171,13 +171,13 @@ KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
|
||||
fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
|
||||
fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
|
||||
#endif
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairsSwapped);
|
||||
fprintf(stderr,
|
||||
" searchRange(pairs): %d entrySelector: %d rangeShift(pairs): %d\n",
|
||||
searchRange, entrySelector, rangeShift);
|
||||
|
||||
{
|
||||
if (LE_SUCCESS(success)) {
|
||||
// dump part of the pair list
|
||||
char ids[256];
|
||||
for (int i = 256; --i >= 0;) {
|
||||
@ -242,7 +242,7 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
|
||||
p = tp;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stderr, "binary search for %0.8x\n", key);
|
||||
#endif
|
||||
|
||||
@ -251,13 +251,13 @@ void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
|
||||
probe >>= 1;
|
||||
tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
|
||||
le_uint32 tkey = tp->key;
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stdout, " %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
|
||||
#endif
|
||||
if (tkey <= key) {
|
||||
if (tkey == key) {
|
||||
le_int16 value = SWAPW(tp->value);
|
||||
#if DEBUG
|
||||
#if DEBUG_KERN_TABLE
|
||||
fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n",
|
||||
storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value));
|
||||
fflush(stdout);
|
||||
|
@ -181,6 +181,10 @@ public:
|
||||
*
|
||||
* Subclasses which represent composite fonts should always return <code>NULL</code>.
|
||||
*
|
||||
* Note that implementing this function does not allow for range checking.
|
||||
* Subclasses that desire the safety of range checking must implement the
|
||||
* variation which has a length parameter.
|
||||
*
|
||||
* @param tableTag - the four byte table tag. (e.g. 'cmap')
|
||||
*
|
||||
* @return the address of the table in memory, or <code>NULL</code>
|
||||
@ -200,6 +204,8 @@ public:
|
||||
* Subclasses which represent composite fonts should always return <code>NULL</code>.
|
||||
*
|
||||
* This version sets a length, for range checking.
|
||||
* Note that range checking can only be accomplished if this function is
|
||||
* implemented in subclasses.
|
||||
*
|
||||
* @param tableTag - the four byte table tag. (e.g. 'cmap')
|
||||
* @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
|
||||
@ -572,5 +578,3 @@ inline le_int32 LEFontInstance::floatToFixed(float theFloat)
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@ public:
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
virtual le_bool accept(LEGlyphID glyph) const = 0;
|
||||
virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const = 0;
|
||||
};
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
|
@ -458,7 +458,7 @@ void LEGlyphStorage::setPosition(le_int32 glyphIndex, float x, float y, LEErrorC
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
_LETRACE("set%-4d\t(%.2f, %.2f)", glyphIndex, x, y);
|
||||
fPositions[glyphIndex * 2] = x;
|
||||
fPositions[glyphIndex * 2 + 1] = y;
|
||||
}
|
||||
@ -688,10 +688,9 @@ le_bool LEGlyphStorage::applyInsertion(le_int32 atPosition, le_int32 count, LEGl
|
||||
|
||||
// the source glyph we're pointing at
|
||||
// just got replaced by the insertion
|
||||
fSrcIndex -= 1;
|
||||
fSrcIndex -= 1;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
@ -568,4 +568,3 @@ inline LEGlyphID &LEGlyphStorage::operator[](le_int32 glyphIndex) const
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
* WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
|
||||
* YOU REALLY KNOW WHAT YOU'RE DOING.
|
||||
*
|
||||
* Generated on: 10/26/2010 02:53:33 PM PDT
|
||||
* Generated on: 11/01/2011 04:08:09 PM PDT
|
||||
*/
|
||||
|
||||
#ifndef __LESCRIPTS_H
|
||||
@ -262,7 +262,16 @@ enum ScriptCodes {
|
||||
khojScriptCode = 157,
|
||||
tirhScriptCode = 158,
|
||||
|
||||
scriptCodeCount = 159
|
||||
/**
|
||||
* @stable ICU 52
|
||||
*/
|
||||
aghbScriptCode = 159,
|
||||
mahjScriptCode = 160,
|
||||
|
||||
/**
|
||||
* @stable ICU 2.2
|
||||
*/
|
||||
scriptCodeCount
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -132,6 +132,9 @@ enum LEErrorCode {
|
||||
#define uprv_memcpy memcpy
|
||||
#define uprv_realloc realloc
|
||||
|
||||
#define U_EXPORT2
|
||||
#define U_CAPI extern "C"
|
||||
|
||||
#if !defined(U_IS_BIG_ENDIAN)
|
||||
#ifdef _LITTLE_ENDIAN
|
||||
#define U_IS_BIG_ENDIAN 0
|
||||
|
@ -37,34 +37,47 @@
|
||||
#include "LETypes.h"
|
||||
#include "LEFontInstance.h"
|
||||
|
||||
/**
|
||||
* \def LE_ENABLE_RAW
|
||||
* If this is 1, enables old non-safe raw access
|
||||
*/
|
||||
#ifndef LE_ENABLE_RAW
|
||||
#define LE_ENABLE_RAW 0
|
||||
#endif
|
||||
|
||||
#define kQuestionmarkTableTag 0x3F3F3F3FUL
|
||||
#define kTildeTableTag 0x7e7e7e7eUL
|
||||
#define kQuestionmarkTableTag 0x3F3F3F3FUL /* ???? */
|
||||
#define kStaticTableTag 0x30303030UL /* 0000 */
|
||||
#define kTildeTableTag 0x7e7e7e7eUL /* ~~~~ */
|
||||
#ifdef __cplusplus
|
||||
|
||||
// internal - interface for range checking
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#if LE_ASSERT_BAD_FONT
|
||||
|
||||
#ifndef LE_TRACE_TR
|
||||
#define LE_TRACE_TR 0
|
||||
#endif
|
||||
|
||||
class LETableReference; // fwd
|
||||
/**
|
||||
* defined in OpenTypeUtilities.cpp
|
||||
* @internal
|
||||
*/
|
||||
extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
|
||||
U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
|
||||
|
||||
#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
|
||||
#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
|
||||
#if 0
|
||||
#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
|
||||
#if LE_TRACE_TR
|
||||
#define _TRTRACE(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
|
||||
#else
|
||||
#define LE_TRACE_TR(x)
|
||||
#define _TRTRACE(x)
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define LE_DEBUG_TR(x)
|
||||
#define LE_DEBUG_TR3(x,y,z)
|
||||
#define LE_TRACE_TR(x)
|
||||
#define _TRTRACE(x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -72,6 +85,13 @@ extern void _debug_LETableReference(const char *f, int l, const char *msg, const
|
||||
*/
|
||||
class LETableReference {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Dummy enum asserting that a value is actually static data
|
||||
* and does not need to be range checked
|
||||
*/
|
||||
enum EStaticData { kStaticData = 0 };
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Construct from a specific tag
|
||||
@ -79,28 +99,42 @@ public:
|
||||
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
|
||||
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
|
||||
loadTable(success);
|
||||
LE_TRACE_TR("INFO: new table load")
|
||||
_TRTRACE("INFO: new table load")
|
||||
}
|
||||
|
||||
LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
|
||||
if(LE_FAILURE(success)) {
|
||||
clear();
|
||||
}
|
||||
LE_TRACE_TR("INFO: new clone")
|
||||
_TRTRACE("INFO: new clone")
|
||||
}
|
||||
|
||||
#if LE_ENABLE_RAW
|
||||
/**
|
||||
* Construct without a parent LETR.
|
||||
*/
|
||||
LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
|
||||
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
|
||||
LE_TRACE_TR("INFO: new raw")
|
||||
_TRTRACE("INFO: new raw")
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Construct without a parent LETR.
|
||||
*/
|
||||
LETableReference(EStaticData /* NOTUSED */, const le_uint8* data, size_t length) :
|
||||
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
|
||||
_TRTRACE("INFO: new EStaticData")
|
||||
}
|
||||
|
||||
LETableReference() :
|
||||
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
|
||||
LE_TRACE_TR("INFO: new empty")
|
||||
_TRTRACE("INFO: new empty")
|
||||
}
|
||||
|
||||
~LETableReference() {
|
||||
fTag=kTildeTableTag;
|
||||
LE_TRACE_TR("INFO: new dtor")
|
||||
fTag= (LETag)kTildeTableTag;
|
||||
_TRTRACE("INFO: new dtor")
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +160,7 @@ public:
|
||||
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
|
||||
}
|
||||
if(fLength != LE_UINTPTR_MAX) { // if we have bounds:
|
||||
if(offset+fLength > fParent->fLength) {
|
||||
if((offset+fLength < offset) || (offset+fLength > fParent->fLength)) {
|
||||
LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
|
||||
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
|
||||
clear();
|
||||
@ -136,11 +170,13 @@ public:
|
||||
} else {
|
||||
clear();
|
||||
}
|
||||
LE_TRACE_TR("INFO: new subset")
|
||||
_TRTRACE("INFO: new subset")
|
||||
}
|
||||
|
||||
const void* getAlias() const { return (const void*)fStart; }
|
||||
const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; }
|
||||
#ifndef LE_ENABLE_RAW
|
||||
const void* getAliasRAW() const { LE_DEBUG_TR("getAliasRAW()"); return (const void*)fStart; }
|
||||
#endif
|
||||
le_bool isEmpty() const { return fStart==NULL || fLength==0; }
|
||||
le_bool isValid() const { return !isEmpty(); }
|
||||
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
|
||||
@ -233,7 +269,18 @@ protected:
|
||||
|
||||
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
|
||||
fFont = NULL;
|
||||
fTag = kQuestionmarkTableTag;
|
||||
fTag = (LETag)kQuestionmarkTableTag;
|
||||
fParent = NULL;
|
||||
fStart = (const le_uint8*)data;
|
||||
fLength = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* set this object pointing to static data
|
||||
*/
|
||||
void setTo(EStaticData /*notused*/, const void *data, size_t length) {
|
||||
fFont = NULL;
|
||||
fTag = (LETag)kStaticTableTag;
|
||||
fParent = NULL;
|
||||
fStart = (const le_uint8*)data;
|
||||
fLength = length;
|
||||
@ -276,97 +323,6 @@ size_t LETableVarSizer<T>::getSize() {
|
||||
* Open a new entry based on an existing table
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def LE_UNBOUNDED_ARRAY
|
||||
* define an array with no *known* bound. Will trim to available size.
|
||||
* @internal
|
||||
*/
|
||||
#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
|
||||
|
||||
template<class T>
|
||||
class LEReferenceToArrayOf : public LETableReference {
|
||||
public:
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
|
||||
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
|
||||
LE_TRACE_TR("INFO: new RTAO by offset")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) {
|
||||
fCount=0;
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
|
||||
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
|
||||
LE_TRACE_TR("INFO: new RTAO")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) clear();
|
||||
}
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
|
||||
: LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
|
||||
LE_TRACE_TR("INFO: new RTAO")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(count == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) clear();
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
|
||||
|
||||
le_uint32 getCount() const { return fCount; }
|
||||
|
||||
using LETableReference::getAlias;
|
||||
|
||||
const T *getAlias(le_uint32 i, LEErrorCode &success) const {
|
||||
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
|
||||
}
|
||||
|
||||
const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
|
||||
|
||||
const T& getObject(le_uint32 i, LEErrorCode &success) const {
|
||||
return *getAlias(i,success);
|
||||
}
|
||||
|
||||
const T& operator()(le_uint32 i, LEErrorCode &success) const {
|
||||
return *getAlias(i,success);
|
||||
}
|
||||
|
||||
size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
|
||||
if(LE_SUCCESS(success)&&i<getCount()) {
|
||||
return LETableVarSizer<T>::getSize()*i;
|
||||
} else {
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
|
||||
fParent = &base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
|
||||
LE_TRACE_TR("INFO: null RTAO")
|
||||
}
|
||||
|
||||
private:
|
||||
le_uint32 fCount;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class LEReferenceTo : public LETableReference {
|
||||
public:
|
||||
@ -404,14 +360,26 @@ public:
|
||||
verifyLength(0, LETableVarSizer<T>::getSize(), success);
|
||||
if(LE_FAILURE(success)) clear();
|
||||
}
|
||||
#if LE_ENABLE_RAW
|
||||
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
|
||||
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
|
||||
inline LEReferenceTo() : LETableReference(NULL) {}
|
||||
#endif
|
||||
inline LEReferenceTo(EStaticData staticData, const le_uint8 *data, size_t length) : LETableReference(staticData, data, length) {}
|
||||
inline LEReferenceTo(EStaticData staticData, const T *data, size_t length) : LETableReference(staticData, (const le_uint8*)data, length) {}
|
||||
|
||||
inline LEReferenceTo() : LETableReference() {}
|
||||
|
||||
#if LE_ENABLE_RAW
|
||||
inline LEReferenceTo<T>& operator=(const T* other) {
|
||||
setRaw(other);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
LEReferenceTo<T>& setTo(LETableReference::EStaticData staticData, const T* other, size_t length) {
|
||||
LETableReference::setTo(staticData, other, length);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LEReferenceTo<T> &reparent(const LETableReference &base) {
|
||||
fParent = &base;
|
||||
@ -430,11 +398,135 @@ public:
|
||||
}
|
||||
|
||||
const T *operator->() const { return getAlias(); }
|
||||
const T *operator*() const { return getAlias(); }
|
||||
const T *getAlias() const { return (const T*)fStart; }
|
||||
const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
|
||||
#if LE_ENABLE_RAW
|
||||
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \def LE_UNBOUNDED_ARRAY
|
||||
* define an array with no *known* bound. Will trim to available size.
|
||||
* @internal
|
||||
*/
|
||||
#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
|
||||
|
||||
template<class T>
|
||||
class LEReferenceToArrayOf : public LETableReference {
|
||||
public:
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
|
||||
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
|
||||
_TRTRACE("INFO: new RTAO by offset")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) {
|
||||
fCount=0;
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
|
||||
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
|
||||
_TRTRACE("INFO: new RTAO")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) clear();
|
||||
}
|
||||
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
|
||||
: LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
|
||||
_TRTRACE("INFO: new RTAO")
|
||||
if(LE_SUCCESS(success)) {
|
||||
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
|
||||
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
|
||||
}
|
||||
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*fCount, success);
|
||||
}
|
||||
if(LE_FAILURE(success)) clear();
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
|
||||
|
||||
le_uint32 getCount() const { return fCount; }
|
||||
|
||||
const T *getAlias() const { return (const T*)fStart; }
|
||||
|
||||
const T *getAlias(le_uint32 i, LEErrorCode &success) const {
|
||||
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
|
||||
}
|
||||
|
||||
#ifndef LE_ENABLE_RAW
|
||||
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
|
||||
#endif
|
||||
|
||||
const T& getObject(le_uint32 i, LEErrorCode &success) const {
|
||||
return *getAlias(i,success);
|
||||
}
|
||||
|
||||
/**
|
||||
* by-value array accessor for integral types.
|
||||
*/
|
||||
const T operator[](le_uint32 i) const {
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
const T *ret = getAlias(i, success);
|
||||
if(LE_FAILURE(success) || ret==NULL) {
|
||||
#if LE_ASSERT_BAD_FONT
|
||||
LE_DEBUG_TR3("Range error, out of bounds? (%p) #%d", NULL, i);
|
||||
#endif
|
||||
return T(0); // will not work for all types.
|
||||
}
|
||||
return *ret;
|
||||
}
|
||||
|
||||
const LEReferenceTo<T> getReference(le_uint32 i, LEErrorCode &success) const {
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<T>();
|
||||
return LEReferenceTo<T>(*this, success, getAlias(i,success));
|
||||
}
|
||||
|
||||
const T& operator()(le_uint32 i, LEErrorCode &success) const {
|
||||
return *getAlias(i,success);
|
||||
}
|
||||
|
||||
size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
|
||||
if(LE_SUCCESS(success)&&i<getCount()) {
|
||||
return LETableVarSizer<T>::getSize()*i;
|
||||
} else {
|
||||
LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i);
|
||||
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
|
||||
fParent = &base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
|
||||
_TRTRACE("INFO: null RTAO")
|
||||
}
|
||||
|
||||
private:
|
||||
le_uint32 fCount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _TRTRACE
|
||||
#undef _TRTRACE
|
||||
#endif
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
@ -337,6 +337,20 @@ struct LEPoint
|
||||
typedef struct LEPoint LEPoint;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def LE_TRACE
|
||||
* @internal
|
||||
*/
|
||||
#ifndef LE_TRACE
|
||||
# define LE_TRACE 0
|
||||
#endif
|
||||
|
||||
#if LE_TRACE
|
||||
# include <stdio.h>
|
||||
# define _LETRACE printf("\n%s:%d: LE: ", __FILE__, __LINE__),printf
|
||||
#else
|
||||
# define _LETRACE 0&&
|
||||
#endif
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
|
||||
@ -553,7 +567,7 @@ enum LEFeatureTags {
|
||||
LE_CALT_FEATURE_TAG = 0x63616C74UL, /**< 'calt' */
|
||||
LE_CASE_FEATURE_TAG = 0x63617365UL, /**< 'case' */
|
||||
LE_CCMP_FEATURE_TAG = 0x63636D70UL, /**< 'ccmp' */
|
||||
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
|
||||
LE_CJCT_FEATURE_TAG = 0x636A6374UL, /**< 'cjct' */
|
||||
LE_CLIG_FEATURE_TAG = 0x636C6967UL, /**< 'clig' */
|
||||
LE_CPSP_FEATURE_TAG = 0x63707370UL, /**< 'cpsp' */
|
||||
LE_CSWH_FEATURE_TAG = 0x63737768UL, /**< 'cswh' */
|
||||
@ -701,6 +715,12 @@ enum LEFeatureENUMs {
|
||||
LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Flags for typographic features.
|
||||
* @internal
|
||||
* @{
|
||||
*/
|
||||
#define LE_Kerning_FEATURE_FLAG (1 << LE_Kerning_FEATURE_ENUM)
|
||||
#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
|
||||
#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
|
||||
@ -727,6 +747,9 @@ enum LEFeatureENUMs {
|
||||
#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
|
||||
|
||||
#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */
|
||||
|
||||
@ -768,7 +791,7 @@ typedef enum LEErrorCode LEErrorCode;
|
||||
*
|
||||
* @stable ICU 2.4
|
||||
*/
|
||||
#ifndef LE_FAILURE
|
||||
#ifndef LE_SUCCESS
|
||||
#define LE_SUCCESS(code) (U_SUCCESS((UErrorCode)code))
|
||||
#endif
|
||||
|
||||
@ -781,4 +804,4 @@ typedef enum LEErrorCode LEErrorCode;
|
||||
#define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
|
||||
#endif
|
||||
|
||||
#endif /* __LETYPES_H */
|
||||
#endif
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
|
||||
virtual ~CanonMarkFilter();
|
||||
|
||||
virtual le_bool accept(LEGlyphID glyph) const;
|
||||
virtual le_bool accept(LEGlyphID glyph, LEErrorCode &success) const;
|
||||
};
|
||||
|
||||
CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
|
||||
@ -169,9 +169,8 @@ CanonMarkFilter::~CanonMarkFilter()
|
||||
// nothing to do?
|
||||
}
|
||||
|
||||
le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
|
||||
le_bool CanonMarkFilter::accept(LEGlyphID glyph, LEErrorCode &success) const
|
||||
{
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
|
||||
if(LE_FAILURE(success)) return false;
|
||||
return glyphClass != 0;
|
||||
@ -207,7 +206,7 @@ LayoutEngine::LayoutEngine(const LEFontInstance *fontInstance,
|
||||
fGlyphStorage = new LEGlyphStorage();
|
||||
if (fGlyphStorage == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
le_int32 LayoutEngine::getGlyphCount() const
|
||||
@ -263,7 +262,9 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
|
||||
return count;
|
||||
}
|
||||
|
||||
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
|
||||
LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable(LETableReference::kStaticData,
|
||||
(GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable,
|
||||
CanonShaping::glyphSubstitutionTableLen);
|
||||
LETag scriptTag = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
|
||||
LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
|
||||
le_int32 i, dir = 1, out = 0, outCharCount = count;
|
||||
@ -300,7 +301,7 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
|
||||
|
||||
CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
|
||||
inChars = reordered;
|
||||
}
|
||||
}
|
||||
|
||||
fakeGlyphStorage.allocateAuxData(success);
|
||||
|
||||
@ -323,7 +324,8 @@ le_int32 LayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 off
|
||||
LE_DELETE_ARRAY(reordered);
|
||||
}
|
||||
|
||||
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
|
||||
const LEReferenceTo<GlyphDefinitionTableHeader> noGDEF; // empty gdef header
|
||||
outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, noGDEF, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
delete substitutionFilter;
|
||||
@ -403,10 +405,13 @@ void LayoutEngine::positionGlyphs(LEGlyphStorage &glyphStorage, float x, float y
|
||||
LEPoint advance;
|
||||
|
||||
glyphStorage.setPosition(i, x, y, success);
|
||||
_LETRACE("g#%-4d (%.2f, %.2f)", i, x, y);
|
||||
|
||||
fFontInstance->getGlyphAdvance(glyphStorage[i], advance);
|
||||
x += advance.fX;
|
||||
y += advance.fY;
|
||||
|
||||
|
||||
}
|
||||
|
||||
glyphStorage.setPosition(glyphCount, x, y, success);
|
||||
@ -424,7 +429,7 @@ void LayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset
|
||||
return;
|
||||
}
|
||||
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
|
||||
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(LETableReference::kStaticData, (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
|
||||
CanonShaping::glyphDefinitionTableLen);
|
||||
CanonMarkFilter filter(gdefTable, success);
|
||||
|
||||
@ -464,9 +469,10 @@ void LayoutEngine::adjustMarkGlyphs(LEGlyphStorage &glyphStorage, LEGlyphFilter
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
|
||||
glyphStorage.adjustPosition(p, xAdjust, 0, success);
|
||||
|
||||
if (markFilter->accept(glyphStorage[p])) {
|
||||
if (markFilter->accept(glyphStorage[p], success)) {
|
||||
xAdjust -= xAdvance;
|
||||
}
|
||||
|
||||
@ -506,9 +512,13 @@ void LayoutEngine::adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount,
|
||||
glyphStorage.getGlyphPosition(p + 1, next, ignore, success);
|
||||
|
||||
xAdvance = next - prev;
|
||||
|
||||
_LETRACE("p#%d (%.2f,%.2f)", p, xAdvance, 0);
|
||||
|
||||
|
||||
glyphStorage.adjustPosition(p, xAdjust, 0, success);
|
||||
|
||||
if (markFilter->accept(chars[c])) {
|
||||
if (markFilter->accept(chars[c], success)) {
|
||||
xAdjust -= xAdvance;
|
||||
}
|
||||
|
||||
@ -662,8 +672,10 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
|
||||
if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
|
||||
LEReferenceTo<MorphTableHeader2> morxTable(fontInstance, morxTableTag, success);
|
||||
if (LE_SUCCESS(success) &&
|
||||
morxTable.isValid() &&
|
||||
SWAPL(morxTable->version)==0x00020000) {
|
||||
result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
|
||||
} else {
|
||||
LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
|
||||
@ -686,21 +698,20 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
|
||||
break;
|
||||
}
|
||||
|
||||
case arabScriptCode:
|
||||
//case hebrScriptCode:
|
||||
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case arabScriptCode:
|
||||
result = new UnicodeArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
//case hebrScriptCode:
|
||||
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
|
||||
//case hebrScriptCode:
|
||||
// return new HebrewOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags);
|
||||
|
||||
case thaiScriptCode:
|
||||
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case thaiScriptCode:
|
||||
result = new ThaiLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
case hangScriptCode:
|
||||
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
case hangScriptCode:
|
||||
result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
|
||||
@ -711,9 +722,9 @@ LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstan
|
||||
}
|
||||
|
||||
if (result && LE_FAILURE(success)) {
|
||||
delete result;
|
||||
result = NULL;
|
||||
}
|
||||
delete result;
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
|
@ -156,8 +156,8 @@ protected:
|
||||
* @param fontInstance - the font for the text
|
||||
* @param scriptCode - the script for the text
|
||||
* @param languageCode - the language for the text
|
||||
* @param typoFlags - the typographic control flags for the text. Set bit 1 if kerning
|
||||
* is desired, set bit 2 if ligature formation is desired. Others are reserved.
|
||||
* @param typoFlags - the typographic control flags for the text (a bitfield). Use kTypoFlagKern
|
||||
* if kerning is desired, kTypoFlagLiga if ligature formation is desired. Others are reserved.
|
||||
* @param success - set to an error code if the operation fails
|
||||
*
|
||||
* @see LEFontInstance
|
||||
|
@ -105,7 +105,7 @@ le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyp
|
||||
LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
|
||||
if(LE_FAILURE(success)) {
|
||||
currGlyph+= dir;
|
||||
return nextStateIndex; // get out! bad font
|
||||
return nextStateIndex; // get out! bad font
|
||||
}
|
||||
|
||||
do {
|
||||
|
@ -49,14 +49,20 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
LEReferenceToArrayOf<Offset> ligSetTableOffsetArrayRef(base, success, ligSetTableOffsetArray, SWAPW(ligSetCount));
|
||||
|
||||
if (coverageIndex >= 0 && LE_SUCCESS(success) && (le_uint32)coverageIndex < ligSetTableOffsetArrayRef.getCount()) {
|
||||
Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
|
||||
const LigatureSetTable *ligSetTable = (const LigatureSetTable *) ((char *) this + ligSetTableOffset);
|
||||
LEReferenceTo<LigatureSetTable> ligSetTable(base, success, ligSetTableOffset);
|
||||
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount);
|
||||
|
||||
for (le_uint16 lig = 0; lig < ligCount; lig += 1) {
|
||||
LEReferenceTo<Offset> ligatureTableOffsetArray(base, success, ligSetTable->ligatureTableOffsetArray, ligCount);
|
||||
for (le_uint16 lig = 0; LE_SUCCESS(success) && lig < ligCount; lig += 1) {
|
||||
Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]);
|
||||
const LigatureTable *ligTable = (const LigatureTable *) ((char *)ligSetTable + ligTableOffset);
|
||||
LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset);
|
||||
if(LE_FAILURE(success)) { return 0; }
|
||||
le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
|
||||
le_int32 startPosition = glyphIterator->getCurrStreamPosition();
|
||||
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
|
||||
@ -72,7 +78,7 @@ le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
}
|
||||
}
|
||||
|
||||
if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) {
|
||||
if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph), success))) {
|
||||
GlyphIterator tempIterator(*glyphIterator);
|
||||
TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
|
||||
|
||||
|
@ -60,9 +60,11 @@ le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lo
|
||||
LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
|
||||
|
||||
delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
|
||||
|
||||
if (delta > 0 || LE_FAILURE(success)) {
|
||||
return 1;
|
||||
if (delta > 0 && LE_FAILURE(success)) {
|
||||
#if LE_TRACE
|
||||
_LETRACE("Posn #%d, type %X, applied subtable #%d/%d - %s\n", startPosition, lookupType, subtable, subtableCount, u_errorName((UErrorCode)success));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
glyphIterator->setCurrStreamPosition(startPosition);
|
||||
@ -86,7 +88,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
|
||||
}
|
||||
|
||||
GlyphIterator glyphIterator(glyphStorage, glyphPositionAdjustments,
|
||||
rightToLeft, 0, 0, glyphDefinitionTableHeader);
|
||||
rightToLeft, 0, 0, glyphDefinitionTableHeader, success);
|
||||
le_int32 newGlyphCount = glyphCount;
|
||||
|
||||
for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
|
||||
@ -94,6 +96,7 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
|
||||
FeatureMask selectMask = lookupSelectArray[lookup];
|
||||
|
||||
if (selectMask != 0) {
|
||||
_LETRACE("Processing order#%d/%d", order, lookupOrderCount);
|
||||
const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
|
||||
if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
|
||||
continue;
|
||||
@ -103,8 +106,11 @@ le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdj
|
||||
glyphIterator.reset(lookupFlags, selectMask);
|
||||
|
||||
while (glyphIterator.findFeatureTag()) {
|
||||
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
|
||||
applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
|
||||
if (LE_FAILURE(success)) {
|
||||
#if LE_TRACE
|
||||
_LETRACE("Failure for lookup 0x%x - %s\n", lookup, u_errorName((UErrorCode)success));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -138,7 +144,7 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt
|
||||
le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
|
||||
{
|
||||
le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
|
||||
le_int32 store = order;
|
||||
le_uint32 store = (le_uint32)order;
|
||||
|
||||
LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
|
||||
|
||||
@ -147,6 +153,9 @@ le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featu
|
||||
if (lookupListIndex >= lookupSelectCount) {
|
||||
continue;
|
||||
}
|
||||
if (store >= lookupOrderCount) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lookupSelectArray[lookupListIndex] |= featureMask;
|
||||
lookupOrderArray[store++] = lookupListIndex;
|
||||
@ -246,7 +255,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
|
||||
|
||||
if (requiredFeatureIndex != 0xFFFF) {
|
||||
requiredFeatureTable = featureListTable->getFeatureTable(featureListTable, requiredFeatureIndex, &requiredFeatureTag, success);
|
||||
featureReferences += SWAPW(featureTable->lookupCount);
|
||||
featureReferences += SWAPW(requiredFeatureTable->lookupCount);
|
||||
}
|
||||
|
||||
lookupOrderArray = LE_NEW_ARRAY(le_uint16, featureReferences);
|
||||
@ -254,6 +263,7 @@ LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
|
||||
success = LE_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
lookupOrderCount = featureReferences;
|
||||
|
||||
for (le_int32 f = 0; f < featureMapCount; f += 1) {
|
||||
FeatureMap fm = featureMap[f];
|
||||
|
@ -65,7 +65,7 @@ le_int32 LookupSubtable::getGlyphCoverage(const LEReferenceTo<LookupSubtable> &b
|
||||
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
|
||||
return coverageTable->getGlyphCoverage(glyphID);
|
||||
return coverageTable->getGlyphCoverage(coverageTable, glyphID, success);
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -38,20 +38,28 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
le_int32 MarkArray::getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const
|
||||
le_int32 MarkArray::getMarkClass(const LETableReference &base, LEGlyphID glyphID,
|
||||
le_int32 coverageIndex, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const
|
||||
{
|
||||
le_int32 markClass = -1;
|
||||
|
||||
if (coverageIndex >= 0) {
|
||||
if ( coverageIndex >= 0 && LE_SUCCESS(success) ) {
|
||||
le_uint16 mCount = SWAPW(markCount);
|
||||
|
||||
if (coverageIndex < mCount) {
|
||||
LEReferenceToArrayOf<MarkRecord> markRecordArrayRef(base, success, markRecordArray, mCount);
|
||||
if(LE_FAILURE(success)) {
|
||||
return markClass;
|
||||
}
|
||||
const MarkRecord *markRecord = &markRecordArray[coverageIndex];
|
||||
Offset anchorTableOffset = SWAPW(markRecord->markAnchorTableOffset);
|
||||
const AnchorTable *anchorTable = (AnchorTable *) ((char *) this + anchorTableOffset);
|
||||
LEReferenceTo<AnchorTable> anchorTable(base, success, anchorTableOffset);
|
||||
|
||||
anchorTable->getAnchor(glyphID, fontInstance, anchor);
|
||||
if(LE_FAILURE(success)) {
|
||||
return markClass;
|
||||
}
|
||||
|
||||
anchorTable->getAnchor(anchorTable, glyphID, fontInstance, anchor, success);
|
||||
markClass = SWAPW(markRecord->markClass);
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,9 @@ struct MarkArray
|
||||
le_uint16 markCount;
|
||||
MarkRecord markRecordArray[ANY_NUMBER];
|
||||
|
||||
le_int32 getMarkClass(LEGlyphID glyphID, le_int32 coverageIndex, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor) const;
|
||||
le_int32 getMarkClass(const LETableReference &base, LEGlyphID glyphID,
|
||||
le_int32 coverageIndex, const LEFontInstance *fontInstance,
|
||||
LEPoint &anchor, LEErrorCode &success) const;
|
||||
};
|
||||
LE_VAR_ARRAY(MarkArray, markRecordArray)
|
||||
|
||||
|
@ -66,11 +66,11 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
|
||||
}
|
||||
|
||||
LEPoint markAnchor;
|
||||
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
|
||||
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
|
||||
LEReferenceTo<MarkArray> markArray(base, success, (const MarkArray *) ((char *) this + SWAPW(markArrayOffset)));
|
||||
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
|
||||
le_uint16 mcCount = SWAPW(classCount);
|
||||
|
||||
if (markClass < 0 || markClass >= mcCount) {
|
||||
if (markClass < 0 || markClass >= mcCount || LE_FAILURE(success)) {
|
||||
// markGlyph isn't in the mark array or its
|
||||
// mark class is too big. The table is mal-formed!
|
||||
return 0;
|
||||
@ -80,7 +80,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
|
||||
GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
|
||||
LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
|
||||
le_int32 baseCoverage = getBaseCoverage(base, (LEGlyphID) baseGlyph, success);
|
||||
const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset));
|
||||
LEReferenceTo<BaseArray> baseArray(base, success, (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset)));
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
|
||||
|
||||
if (baseCoverage < 0 || baseCoverage >= baseCount) {
|
||||
@ -89,19 +90,23 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
|
||||
// table is mal-formed...
|
||||
return 0;
|
||||
}
|
||||
LEReferenceTo<BaseRecord> baseRecord(base, success, &baseArray->baseRecordArray[baseCoverage * mcCount]);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
LEReferenceToArrayOf<Offset> baseAnchorTableOffsetArray(base, success, &(baseRecord->baseAnchorTableOffsetArray[0]), markClass+1);
|
||||
|
||||
const BaseRecord *baseRecord = &baseArray->baseRecordArray[baseCoverage * mcCount];
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]);
|
||||
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) baseArray + anchorTableOffset);
|
||||
LEPoint baseAnchor, markAdvance, pixels;
|
||||
|
||||
if (anchorTableOffset == 0) {
|
||||
if (anchorTableOffset <= 0) {
|
||||
// this means the table is mal-formed...
|
||||
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
|
||||
return 0;
|
||||
}
|
||||
|
||||
anchorTable->getAnchor(baseGlyph, fontInstance, baseAnchor);
|
||||
LEReferenceTo<AnchorTable> anchorTable(baseArray, success, anchorTableOffset);
|
||||
LEPoint baseAnchor, markAdvance, pixels;
|
||||
|
||||
|
||||
anchorTable->getAnchor(anchorTable, baseGlyph, fontInstance, baseAnchor, success);
|
||||
|
||||
fontInstance->getGlyphAdvance(markGlyph, pixels);
|
||||
fontInstance->pixelsToUnits(pixels, markAdvance);
|
||||
@ -109,6 +114,8 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
|
||||
float anchorDiffX = baseAnchor.fX - markAnchor.fX;
|
||||
float anchorDiffY = baseAnchor.fY - markAnchor.fY;
|
||||
|
||||
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X", anchorDiffX, anchorDiffY, markGlyph);
|
||||
|
||||
glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
|
||||
|
||||
if (glyphIterator->isRightToLeft()) {
|
||||
@ -132,7 +139,6 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl
|
||||
gi.next();
|
||||
}
|
||||
// end of JK patch
|
||||
|
||||
fontInstance->pixelsToUnits(pixels, baseAdvance);
|
||||
|
||||
glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
|
||||
|
@ -65,8 +65,11 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
|
||||
}
|
||||
|
||||
LEPoint markAnchor;
|
||||
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
|
||||
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
|
||||
LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
|
||||
if( LE_FAILURE(success) ) {
|
||||
return 0;
|
||||
}
|
||||
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
|
||||
le_uint16 mcCount = SWAPW(classCount);
|
||||
|
||||
if (markClass < 0 || markClass >= mcCount) {
|
||||
@ -79,7 +82,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
|
||||
GlyphIterator ligatureIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/));
|
||||
LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
|
||||
le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success);
|
||||
const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset));
|
||||
LEReferenceTo<LigatureArray> ligatureArray(base, success, SWAPW(baseArrayOffset));
|
||||
le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
|
||||
|
||||
if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) {
|
||||
@ -91,7 +94,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
|
||||
|
||||
le_int32 markPosition = glyphIterator->getCurrStreamPosition();
|
||||
Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]);
|
||||
const LigatureAttachTable *ligatureAttachTable = (const LigatureAttachTable *) ((char *) ligatureArray + ligatureAttachOffset);
|
||||
LEReferenceTo<LigatureAttachTable> ligatureAttachTable(ligatureArray, success, ligatureAttachOffset);
|
||||
le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount);
|
||||
le_int32 component = ligatureIterator.getMarkComponent(markPosition);
|
||||
|
||||
@ -100,12 +103,14 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base
|
||||
component = componentCount - 1;
|
||||
}
|
||||
|
||||
const ComponentRecord *componentRecord = &ligatureAttachTable->componentRecordArray[component * mcCount];
|
||||
LEReferenceTo<ComponentRecord> componentRecord(base, success, &ligatureAttachTable->componentRecordArray[component * mcCount]);
|
||||
LEReferenceToArrayOf<Offset> ligatureAnchorTableOffsetArray(base, success, &(componentRecord->ligatureAnchorTableOffsetArray[0]), markClass+1);
|
||||
if( LE_FAILURE(success) ) { return 0; }
|
||||
Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]);
|
||||
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) ligatureAttachTable + anchorTableOffset);
|
||||
LEReferenceTo<AnchorTable> anchorTable(ligatureAttachTable, success, anchorTableOffset);
|
||||
LEPoint ligatureAnchor, markAdvance, pixels;
|
||||
|
||||
anchorTable->getAnchor(ligatureGlyph, fontInstance, ligatureAnchor);
|
||||
anchorTable->getAnchor(anchorTable, ligatureGlyph, fontInstance, ligatureAnchor, success);
|
||||
|
||||
fontInstance->getGlyphAdvance(markGlyph, pixels);
|
||||
fontInstance->pixelsToUnits(pixels, markAdvance);
|
||||
|
@ -66,8 +66,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
|
||||
}
|
||||
|
||||
LEPoint markAnchor;
|
||||
const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
|
||||
le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
|
||||
LEReferenceTo<MarkArray> markArray(base, success, SWAPW(markArrayOffset));
|
||||
if(LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
le_int32 markClass = markArray->getMarkClass(markArray, markGlyph, markCoverage, fontInstance, markAnchor, success);
|
||||
le_uint16 mcCount = SWAPW(classCount);
|
||||
|
||||
if (markClass < 0 || markClass >= mcCount) {
|
||||
@ -79,7 +82,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
|
||||
GlyphIterator mark2Iterator(*glyphIterator);
|
||||
LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
|
||||
le_int32 mark2Coverage = getBaseCoverage(base, (LEGlyphID) mark2Glyph, success);
|
||||
const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
|
||||
LEReferenceTo<Mark2Array> mark2Array(base, success, (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset)));
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
|
||||
|
||||
if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
|
||||
@ -89,9 +93,11 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount];
|
||||
LEReferenceTo<Mark2Record> mark2Record(base, success, &mark2Array->mark2RecordArray[mark2Coverage * mcCount]);
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]);
|
||||
const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset);
|
||||
LEReferenceTo<AnchorTable> anchorTable(mark2Array, success, anchorTableOffset);
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
LEPoint mark2Anchor, markAdvance, pixels;
|
||||
|
||||
if (anchorTableOffset == 0) {
|
||||
@ -99,7 +105,7 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
|
||||
return 0;
|
||||
}
|
||||
|
||||
anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor);
|
||||
anchorTable->getAnchor(anchorTable, mark2Glyph, fontInstance, mark2Anchor, success);
|
||||
|
||||
fontInstance->getGlyphAdvance(markGlyph, pixels);
|
||||
fontInstance->pixelsToUnits(pixels, markAdvance);
|
||||
@ -107,6 +113,8 @@ le_int32 MarkToMarkPositioningSubtable::process(const LETableReference &base, Gl
|
||||
float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
|
||||
float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
|
||||
|
||||
_LETRACE("Offset: (%.2f, %.2f) glyph 0x%X mark2 0x%X", anchorDiffX, anchorDiffY, markGlyph, mark2Glyph);
|
||||
|
||||
glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
|
||||
|
||||
if (glyphIterator->isRightToLeft()) {
|
||||
|
@ -54,9 +54,10 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
// FIXME: is this always the right thing to do?
|
||||
// FIXME: should this only be done for a non-zero
|
||||
// glyphCount?
|
||||
if (filter != NULL && filter->accept(glyph)) {
|
||||
if (filter != NULL && filter->accept(glyph, success)) {
|
||||
return 0;
|
||||
}
|
||||
if(LE_FAILURE(success)) return 0;
|
||||
|
||||
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
|
||||
le_uint16 seqCount = SWAPW(sequenceCount);
|
||||
@ -67,7 +68,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
|
||||
if (coverageIndex >= 0 && coverageIndex < seqCount) {
|
||||
Offset sequenceTableOffset = SWAPW(sequenceTableOffsetArray[coverageIndex]);
|
||||
const SequenceTable *sequenceTable = (const SequenceTable *) ((char *) this + sequenceTableOffset);
|
||||
LEReferenceTo<SequenceTable> sequenceTable(base, success, sequenceTableOffset);
|
||||
le_uint16 glyphCount = SWAPW(sequenceTable->glyphCount);
|
||||
|
||||
if (glyphCount == 0) {
|
||||
@ -76,7 +77,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
} else if (glyphCount == 1) {
|
||||
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[0]);
|
||||
|
||||
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute))) {
|
||||
if (filter != NULL && ! filter->accept(LE_SET_GLYPH(glyph, substitute), success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -89,7 +90,7 @@ le_uint32 MultipleSubstitutionSubtable::process(const LETableReference &base, Gl
|
||||
for (le_int32 i = 0; i < glyphCount; i += 1) {
|
||||
TTGlyphID substitute = SWAPW(sequenceTable->substituteArray[i]);
|
||||
|
||||
if (! filter->accept(substitute)) {
|
||||
if (! filter->accept(substitute, success)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -470,6 +470,7 @@ le_int32 OpenTypeLayoutEngine::computeGlyphs(const LEUnicode chars[], le_int32 o
|
||||
void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
|
||||
LEGlyphStorage &glyphStorage, LEErrorCode &success)
|
||||
{
|
||||
_LETRACE("OTLE::adjustGPOS");
|
||||
if (LE_FAILURE(success)) {
|
||||
return;
|
||||
}
|
||||
@ -510,14 +511,17 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
||||
if (!fGPOSTable.isEmpty()) {
|
||||
if (fScriptTagV2 != nullScriptTag &&
|
||||
fGPOSTable->coversScriptAndLanguage(fGPOSTable, fScriptTagV2,fLangSysTag,success)) {
|
||||
_LETRACE("OTLE::process [0]");
|
||||
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTagV2, fLangSysTag,
|
||||
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
|
||||
|
||||
} else {
|
||||
_LETRACE("OTLE::process [1]");
|
||||
fGPOSTable->process(fGPOSTable, glyphStorage, adjustments, reverse, fScriptTag, fLangSysTag,
|
||||
fGDEFTable, success, fFontInstance, fFeatureMap, fFeatureMapCount, fFeatureOrder);
|
||||
}
|
||||
} else if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
|
||||
_LETRACE("OTLE::kerning");
|
||||
LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
|
||||
KernTable kt(kernTable, success);
|
||||
kt.process(glyphStorage, success);
|
||||
@ -546,6 +550,7 @@ void OpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], le_int3
|
||||
|
||||
xPlacement = fFontInstance->xUnitsToPoints(xPlacement);
|
||||
yPlacement = fFontInstance->yUnitsToPoints(yPlacement);
|
||||
_LETRACE("OTLE GPOS: #%d, (%.2f,%.2f)", i, xPlacement, yPlacement);
|
||||
glyphStorage.adjustPosition(i, xAdjust + xPlacement, -(yAdjust + yPlacement), success);
|
||||
|
||||
xAdjust += fFontInstance->xUnitsToPoints(xAdvance);
|
||||
|
@ -46,15 +46,14 @@ class OpenTypeUtilities /* not : public UObject because all methods are static *
|
||||
public:
|
||||
static le_int8 highBit(le_int32 value);
|
||||
static Offset getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success);
|
||||
/**
|
||||
* @deprecated TODO remove
|
||||
*/
|
||||
#if LE_ENABLE_RAW
|
||||
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount) {
|
||||
LEErrorCode success = LE_NO_ERROR;
|
||||
LETableReference recordRef0((const le_uint8*)records);
|
||||
LEReferenceToArrayOf<GlyphRangeRecord> recordRef(recordRef0, success, (size_t)0, recordCount);
|
||||
return getGlyphRangeIndex(glyphID, recordRef, success);
|
||||
}
|
||||
#endif
|
||||
static le_int32 getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success);
|
||||
static le_int32 search(le_uint16 value, const le_uint16 array[], le_int32 count);
|
||||
static le_int32 search(le_uint32 value, const le_uint32 array[], le_int32 count);
|
||||
|
@ -76,19 +76,17 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
|
||||
{
|
||||
LEGlyphID firstGlyph = glyphIterator->getCurrGlyphID();
|
||||
le_int32 coverageIndex = getGlyphCoverage(base, firstGlyph, success);
|
||||
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
GlyphIterator tempIterator(*glyphIterator);
|
||||
|
||||
if (coverageIndex >= 0 && glyphIterator->next()) {
|
||||
LEReferenceToArrayOf<Offset> pairSetTableOffsetArrayRef(base, success, pairSetTableOffsetArray, SWAPW(pairSetCount));
|
||||
|
||||
if (LE_SUCCESS(success) && coverageIndex >= 0 && glyphIterator->next() && (le_uint32)coverageIndex < pairSetTableOffsetArrayRef.getCount()) {
|
||||
Offset pairSetTableOffset = SWAPW(pairSetTableOffsetArray[coverageIndex]);
|
||||
LEReferenceTo<PairSetTable> pairSetTable(base, success, ((char *) this + pairSetTableOffset));
|
||||
if (LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
LEReferenceTo<PairSetTable> pairSetTable(base, success, pairSetTableOffset);
|
||||
if( LE_FAILURE(success) ) return 0;
|
||||
le_uint16 pairValueCount = SWAPW(pairSetTable->pairValueCount);
|
||||
LEReferenceTo<PairValueRecord> pairValueRecordArray(pairSetTable, success, pairSetTable->pairValueRecordArray);
|
||||
if( LE_FAILURE(success) ) return 0;
|
||||
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
|
||||
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
|
||||
le_int16 recordSize = sizeof(PairValueRecord) - sizeof(ValueRecord) + valueRecord1Size + valueRecord2Size;
|
||||
@ -96,21 +94,22 @@ le_uint32 PairPositioningFormat1Subtable::process(const LEReferenceTo<PairPositi
|
||||
LEReferenceTo<PairValueRecord> pairValueRecord;
|
||||
|
||||
if (pairValueCount != 0) {
|
||||
pairValueRecord = findPairValueRecord(base, (TTGlyphID) LE_GET_GLYPH(secondGlyph), pairSetTable->pairValueRecordArray, pairValueCount, recordSize, success);
|
||||
pairValueRecord = findPairValueRecord((TTGlyphID) LE_GET_GLYPH(secondGlyph), pairValueRecordArray, pairValueCount, recordSize, success);
|
||||
}
|
||||
|
||||
if (pairValueRecord.isEmpty()) {
|
||||
if (pairValueRecord.isEmpty() || LE_FAILURE(success)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (valueFormat1 != 0) {
|
||||
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance);
|
||||
pairValueRecord->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
|
||||
}
|
||||
|
||||
if (valueFormat2 != 0) {
|
||||
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size);
|
||||
|
||||
valueRecord2->adjustPosition(SWAPW(valueFormat2), (char *) this, *glyphIterator, fontInstance);
|
||||
LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &pairValueRecord->valueRecord1 + valueRecord1Size));
|
||||
if(LE_SUCCESS(success)) {
|
||||
valueRecord2->adjustPosition(SWAPW(valueFormat2), base, *glyphIterator, fontInstance, success);
|
||||
}
|
||||
}
|
||||
|
||||
// back up glyphIterator so second glyph can be
|
||||
@ -135,26 +134,28 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
|
||||
|
||||
if (coverageIndex >= 0 && glyphIterator->next()) {
|
||||
LEGlyphID secondGlyph = glyphIterator->getCurrGlyphID();
|
||||
const ClassDefinitionTable *classDef1 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef1Offset));
|
||||
const ClassDefinitionTable *classDef2 = (const ClassDefinitionTable *) ((char *) this + SWAPW(classDef2Offset));
|
||||
le_int32 class1 = classDef1->getGlyphClass(firstGlyph);
|
||||
le_int32 class2 = classDef2->getGlyphClass(secondGlyph);
|
||||
const LEReferenceTo<ClassDefinitionTable> classDef1(base, success, SWAPW(classDef1Offset));
|
||||
const LEReferenceTo<ClassDefinitionTable> classDef2(base, success, SWAPW(classDef2Offset));
|
||||
le_int32 class1 = classDef1->getGlyphClass(classDef1, firstGlyph, success);
|
||||
le_int32 class2 = classDef2->getGlyphClass(classDef2, secondGlyph, success);
|
||||
le_int16 valueRecord1Size = ValueRecord::getSize(SWAPW(valueFormat1));
|
||||
le_int16 valueRecord2Size = ValueRecord::getSize(SWAPW(valueFormat2));
|
||||
le_int16 class2RecordSize = valueRecord1Size + valueRecord2Size;
|
||||
le_int16 class1RecordSize = class2RecordSize * SWAPW(class2Count);
|
||||
const Class1Record *class1Record = (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1));
|
||||
const Class2Record *class2Record = (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2));
|
||||
const LEReferenceTo<Class1Record> class1Record(base, success, (const Class1Record *) ((char *) class1RecordArray + (class1RecordSize * class1)));
|
||||
const LEReferenceTo<Class2Record> class2Record(base, success, (const Class2Record *) ((char *) class1Record->class2RecordArray + (class2RecordSize * class2)));
|
||||
|
||||
|
||||
if (valueFormat1 != 0) {
|
||||
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), (char *) this, tempIterator, fontInstance);
|
||||
}
|
||||
|
||||
if (valueFormat2 != 0) {
|
||||
const ValueRecord *valueRecord2 = (const ValueRecord *) ((char *) &class2Record->valueRecord1 + valueRecord1Size);
|
||||
|
||||
valueRecord2->adjustPosition(SWAPW(valueFormat2), (const char *) this, *glyphIterator, fontInstance);
|
||||
if( LE_SUCCESS(success) ) {
|
||||
if (valueFormat1 != 0) {
|
||||
class2Record->valueRecord1.adjustPosition(SWAPW(valueFormat1), base, tempIterator, fontInstance, success);
|
||||
}
|
||||
if (valueFormat2 != 0) {
|
||||
const LEReferenceTo<ValueRecord> valueRecord2(base, success, ((char *) &class2Record->valueRecord1) + valueRecord1Size);
|
||||
LEReferenceTo<PairPositioningFormat2Subtable> thisRef(base, success, this);
|
||||
if(LE_SUCCESS(success)) {
|
||||
valueRecord2->adjustPosition(SWAPW(valueFormat2), thisRef, *glyphIterator, fontInstance, success);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// back up glyphIterator so second glyph can be
|
||||
@ -166,23 +167,24 @@ le_uint32 PairPositioningFormat2Subtable::process(const LEReferenceTo<PairPositi
|
||||
return 0;
|
||||
}
|
||||
|
||||
LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records, le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const
|
||||
LEReferenceTo<PairValueRecord>
|
||||
PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord>& records,
|
||||
le_uint16 recordCount,
|
||||
le_uint16 recordSize, LEErrorCode &success) const
|
||||
{
|
||||
#if 1
|
||||
// The OpenType spec. says that the ValueRecord table is
|
||||
// sorted by secondGlyph. Unfortunately, there are fonts
|
||||
// around that have an unsorted ValueRecord table.
|
||||
LEReferenceTo<PairValueRecord> record(base, success, records);
|
||||
record.verifyLength(0, recordSize, success);
|
||||
LEReferenceTo<PairValueRecord> record(records);
|
||||
|
||||
for(le_int32 r = 0; r < recordCount; r += 1) {
|
||||
if (LE_FAILURE(success)) return (const PairValueRecord*)NULL;
|
||||
if (SWAPW(record->secondGlyph) == glyphID) {
|
||||
return record;
|
||||
}
|
||||
if(LE_FAILURE(success)) return LEReferenceTo<PairValueRecord>();
|
||||
if (SWAPW(record->secondGlyph) == glyphID) {
|
||||
return record;
|
||||
}
|
||||
|
||||
record = LEReferenceTo<PairValueRecord>(base, success, ((const char*)record.getAlias())+ recordSize);
|
||||
record.verifyLength(0, recordSize, success);
|
||||
record.addOffset(recordSize, success);
|
||||
}
|
||||
#else
|
||||
#error dead code - not updated.
|
||||
@ -211,7 +213,7 @@ LEReferenceTo<PairValueRecord> PairPositioningFormat1Subtable::findPairValueReco
|
||||
}
|
||||
#endif
|
||||
|
||||
return (const PairValueRecord*)NULL;
|
||||
return LEReferenceTo<PairValueRecord>();
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -77,9 +77,8 @@ struct PairPositioningFormat1Subtable : PairPositioningSubtable
|
||||
le_uint32 process(const LEReferenceTo<PairPositioningFormat1Subtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
|
||||
|
||||
private:
|
||||
LEReferenceTo<PairValueRecord> findPairValueRecord(const LETableReference &base, TTGlyphID glyphID, const PairValueRecord *records,
|
||||
LEReferenceTo<PairValueRecord> findPairValueRecord(TTGlyphID glyphID, LEReferenceTo<PairValueRecord> &records,
|
||||
le_uint16 recordCount, le_uint16 recordSize, LEErrorCode &success) const;
|
||||
|
||||
};
|
||||
LE_VAR_ARRAY(PairPositioningFormat1Subtable, pairSetTableOffsetArray)
|
||||
|
||||
|
@ -106,7 +106,8 @@ LEReferenceTo<ScriptTable> ScriptListTable::findScript(const LETableReference &b
|
||||
}
|
||||
} else {
|
||||
LEReferenceToArrayOf<ScriptRecord> scriptRecordArrayRef(base, success, &scriptRecordArray[0], count);
|
||||
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success); // TODO
|
||||
|
||||
scriptTableOffset = OpenTypeUtilities::getTagOffset(scriptTag, scriptRecordArrayRef, success);
|
||||
}
|
||||
|
||||
if (scriptTableOffset != 0) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user