提交 ed853b07 编写于 作者: L lana

Merge

...@@ -98,3 +98,5 @@ ecab7eefb8f2326fd90fb632f47f1b6f81e928f8 jdk7-b119 ...@@ -98,3 +98,5 @@ ecab7eefb8f2326fd90fb632f47f1b6f81e928f8 jdk7-b119
a661d8587b5d8986aacae086f5df66af9e1a96b1 jdk7-b121 a661d8587b5d8986aacae086f5df66af9e1a96b1 jdk7-b121
ac311eb325bfc763698219252bf3cee9e091f3af jdk7-b122 ac311eb325bfc763698219252bf3cee9e091f3af jdk7-b122
869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123 869190935eedee7750d955019ab2a1b80f0a13a8 jdk7-b123
1c72adc9d5f331cb882cf5354ba0dcb118a60b23 jdk7-b124
0a56bdd709d01c1663047e55201d19152ffd3d69 jdk7-b125
...@@ -42,7 +42,15 @@ ifneq ($(PLATFORM), windows) ...@@ -42,7 +42,15 @@ ifneq ($(PLATFORM), windows)
ifndef OPENJDK ifndef OPENJDK
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
ifneq ($(ARCH), amd64) ifneq ($(ARCH), amd64)
DGA_SUBDIR = jdga # Solaris 11 does not have support for new compilation of DGA code.
OS_VERSION = $(shell uname -r)
OS_MAJOR_VERSION := $(call MajorVersion,$(OS_VERSION))
OS_MINOR_VERSION := $(call MinorVersion,$(OS_VERSION))
ifeq ($(shell $(EXPR) $(OS_MAJOR_VERSION) == 5), 1)
ifeq ($(shell $(EXPR) $(OS_MINOR_VERSION) \<= 10), 1)
DGA_SUBDIR = jdga
endif
endif
endif endif
endif endif
endif endif
......
...@@ -175,6 +175,10 @@ endif ...@@ -175,6 +175,10 @@ endif
include $(BUILDDIR)/common/Mapfile-vers.gmk include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk include $(BUILDDIR)/common/Library.gmk
COMPILEFONTCONFIG_FLAGS =
ifdef ALT_COMPILEFONTCONFIG_FLAGS
COMPILEFONTCONFIG_FLAGS += $(ALT_COMPILEFONTCONFIG_FLAGS)
endif
build: fontconfigs build: fontconfigs
...@@ -406,7 +410,7 @@ COMPILEFONTCONFIG_JARFILE = $(BUILDTOOLJARDIR)/compilefontconfig.jar ...@@ -406,7 +410,7 @@ COMPILEFONTCONFIG_JARFILE = $(BUILDTOOLJARDIR)/compilefontconfig.jar
$(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
$(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_JARFILE)
$(prep-target) $(prep-target)
$(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $< $@ $(BOOT_JAVA_CMD) -jar $(COMPILEFONTCONFIG_JARFILE) $(COMPILEFONTCONFIG_FLAGS) $< $@
$(install-module-file) $(install-module-file)
$(call chmod-file, 444) $(call chmod-file, 444)
@$(java-vm-cleanup) @$(java-vm-cleanup)
......
...@@ -224,7 +224,7 @@ $(OBJDIR)/DllUtil.obj:: ../../../src/windows/native/sun/windows/DllUtil.h ...@@ -224,7 +224,7 @@ $(OBJDIR)/DllUtil.obj:: ../../../src/windows/native/sun/windows/DllUtil.h
$(OBJDIR)/DrawLine.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawLine.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/DrawLine.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawLine.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/LoopMacros.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/DrawParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawParallelogram.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/DrawPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/DrawPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
...@@ -232,7 +232,7 @@ $(OBJDIR)/DrawPolygons.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDR ...@@ -232,7 +232,7 @@ $(OBJDIR)/DrawPolygons.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDR
$(OBJDIR)/DrawRect.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawRect.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/DrawRect.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_DrawRect.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/FillParallelogram.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillParallelogram.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/FillPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/FillPath.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_FillPath.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/DrawPath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/LineUtils.h ../../../src/share/native/sun/java2d/loops/ProcessPath.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
...@@ -284,7 +284,7 @@ $(OBJDIR)/IntRgbx.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h ../../../src/sh ...@@ -284,7 +284,7 @@ $(OBJDIR)/IntRgbx.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h ../../../src/sh
$(OBJDIR)/MaskBlit.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskBlit.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/Region.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/awt/utility/rect.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/MaskBlit.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskBlit.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/Region.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/awt/utility/rect.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h $(OBJDIR)/MaskFill.obj:: $(CLASSHDRDIR)/java_awt_AlphaComposite.h $(CLASSHDRDIR)/sun_java2d_loops_MaskFill.h ../../../src/share/javavm/export/jni.h ../../../src/share/native/common/gdefs.h ../../../src/share/native/sun/java2d/loops/AlphaMath.h ../../../src/share/native/sun/java2d/loops/GlyphImageRef.h ../../../src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.h ../../../src/share/native/sun/java2d/loops/ParallelogramUtils.h ../../../src/share/native/sun/java2d/pipe/SpanIterator.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/native/common/gdefs_md.h ../../../src/windows/native/sun/java2d/j2d_md.h
$(OBJDIR)/MouseInfo.obj:: $(CLASSHDRDIR)/java_awt_AWTEvent.h $(CLASSHDRDIR)/java_awt_Component.h $(CLASSHDRDIR)/java_awt_Dimension.h $(CLASSHDRDIR)/java_awt_Event.h $(CLASSHDRDIR)/java_awt_event_FocusEvent.h $(CLASSHDRDIR)/java_awt_event_KeyEvent.h $(CLASSHDRDIR)/java_awt_event_MouseEvent.h $(CLASSHDRDIR)/java_awt_event_WindowEvent.h $(CLASSHDRDIR)/java_awt_Font.h $(CLASSHDRDIR)/sun_awt_FontDescriptor.h $(CLASSHDRDIR)/sun_awt_PlatformFont.h $(CLASSHDRDIR)/sun_awt_windows_WComponentPeer.h $(CLASSHDRDIR)/sun_awt_windows_WFontMetrics.h $(CLASSHDRDIR)/sun_awt_windows_WObjectPeer.h $(CLASSHDRDIR)/sun_awt_windows_WToolkit.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/awt/image/cvutils/img_globals.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h ../../../src/windows/native/sun/windows/alloc.h ../../../src/windows/native/sun/windows/awt.h ../../../src/windows/native/sun/windows/awtmsg.h ../../../src/windows/native/sun/windows/awt_Brush.h ../../../src/windows/native/sun/windows/awt_Component.h ../../../src/windows/native/sun/windows/awt_Debug.h ../../../src/windows/native/sun/windows/awt_Font.h ../../../src/windows/native/sun/windows/awt_GDIObject.h ../../../src/windows/native/sun/windows/awt_Object.h ../../../src/windows/native/sun/windows/awt_Palette.h ../../../src/windows/native/sun/windows/awt_Pen.h ../../../src/windows/native/sun/windows/awt_Toolkit.h ../../../src/windows/native/sun/windows/awt_Win32GraphicsDevice.h ../../../src/windows/native/sun/windows/colordata.h ../../../src/windows/native/sun/windows/Devices.h ../../../src/windows/native/sun/windows/GDIHashtable.h ../../../src/windows/native/sun/windows/Hashtable.h ../../../src/windows/native/sun/windows/ObjectList.h ../../../src/windows/native/sun/windows/stdhdrs.h $(OBJDIR)/MouseInfo.obj:: $(CLASSHDRDIR)/java_awt_AWTEvent.h $(CLASSHDRDIR)/java_awt_Component.h $(CLASSHDRDIR)/java_awt_Dimension.h $(CLASSHDRDIR)/java_awt_Event.h $(CLASSHDRDIR)/java_awt_event_FocusEvent.h $(CLASSHDRDIR)/java_awt_event_KeyEvent.h $(CLASSHDRDIR)/java_awt_event_MouseEvent.h $(CLASSHDRDIR)/java_awt_event_WindowEvent.h $(CLASSHDRDIR)/java_awt_Font.h $(CLASSHDRDIR)/sun_awt_FontDescriptor.h $(CLASSHDRDIR)/sun_awt_PlatformFont.h $(CLASSHDRDIR)/sun_awt_windows_WComponentPeer.h $(CLASSHDRDIR)/sun_awt_windows_WFontMetrics.h $(CLASSHDRDIR)/sun_awt_windows_WObjectPeer.h $(CLASSHDRDIR)/sun_awt_windows_WToolkit.h ../../../src/share/javavm/export/classfile_constants.h ../../../src/share/javavm/export/jni.h ../../../src/share/javavm/export/jvm.h ../../../src/share/native/common/jlong.h ../../../src/share/native/common/jni_util.h ../../../src/share/native/sun/awt/debug/debug_assert.h ../../../src/share/native/sun/awt/debug/debug_mem.h ../../../src/share/native/sun/awt/debug/debug_trace.h ../../../src/share/native/sun/awt/debug/debug_util.h ../../../src/share/native/sun/awt/image/cvutils/img_globals.h ../../../src/share/native/sun/java2d/SurfaceData.h ../../../src/share/native/sun/java2d/Trace.h ../../../src/windows/javavm/export/jni_md.h ../../../src/windows/javavm/export/jvm_md.h ../../../src/windows/native/common/jlong_md.h ../../../src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h ../../../src/windows/native/sun/windows/alloc.h ../../../src/windows/native/sun/windows/awt.h ../../../src/windows/native/sun/windows/awtmsg.h ../../../src/windows/native/sun/windows/awt_Brush.h ../../../src/windows/native/sun/windows/awt_Component.h ../../../src/windows/native/sun/windows/awt_Debug.h ../../../src/windows/native/sun/windows/awt_Font.h ../../../src/windows/native/sun/windows/awt_GDIObject.h ../../../src/windows/native/sun/windows/awt_Object.h ../../../src/windows/native/sun/windows/awt_Palette.h ../../../src/windows/native/sun/windows/awt_Pen.h ../../../src/windows/native/sun/windows/awt_Toolkit.h ../../../src/windows/native/sun/windows/awt_Win32GraphicsDevice.h ../../../src/windows/native/sun/windows/colordata.h ../../../src/windows/native/sun/windows/Devices.h ../../../src/windows/native/sun/windows/GDIHashtable.h ../../../src/windows/native/sun/windows/Hashtable.h ../../../src/windows/native/sun/windows/ObjectList.h ../../../src/windows/native/sun/windows/stdhdrs.h
......
...@@ -118,6 +118,8 @@ SUNWprivate_1.1 { ...@@ -118,6 +118,8 @@ SUNWprivate_1.1 {
Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops; Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
Java_sun_java2d_loops_MaskBlit_MaskBlit; Java_sun_java2d_loops_MaskBlit_MaskBlit;
Java_sun_java2d_loops_MaskFill_MaskFill; Java_sun_java2d_loops_MaskFill_MaskFill;
Java_sun_java2d_loops_MaskFill_FillAAPgram;
Java_sun_java2d_loops_MaskFill_DrawAAPgram;
Java_sun_java2d_loops_TransformHelper_Transform; Java_sun_java2d_loops_TransformHelper_Transform;
Java_sun_java2d_pipe_Region_initIDs; Java_sun_java2d_pipe_Region_initIDs;
Java_sun_java2d_pipe_SpanClipRenderer_initIDs; Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
......
...@@ -115,6 +115,8 @@ SUNWprivate_1.1 { ...@@ -115,6 +115,8 @@ SUNWprivate_1.1 {
Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops; Java_sun_java2d_loops_GraphicsPrimitiveMgr_registerNativeLoops;
Java_sun_java2d_loops_MaskBlit_MaskBlit; Java_sun_java2d_loops_MaskBlit_MaskBlit;
Java_sun_java2d_loops_MaskFill_MaskFill; Java_sun_java2d_loops_MaskFill_MaskFill;
Java_sun_java2d_loops_MaskFill_FillAAPgram;
Java_sun_java2d_loops_MaskFill_DrawAAPgram;
Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans; Java_sun_java2d_pipe_BufferedRenderPipe_fillSpans;
Java_sun_java2d_pipe_SpanClipRenderer_initIDs; Java_sun_java2d_pipe_SpanClipRenderer_initIDs;
sun_awt_image_GifImageDecoder_initIDs; sun_awt_image_GifImageDecoder_initIDs;
......
...@@ -222,6 +222,7 @@ class Zoneinfo { ...@@ -222,6 +222,7 @@ class Zoneinfo {
boolean continued = false; boolean continued = false;
Zone zone = null; Zone zone = null;
String l; String l;
lineNum = 0;
try { try {
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
......
...@@ -33,27 +33,17 @@ import sun.util.logging.PlatformLogger; ...@@ -33,27 +33,17 @@ import sun.util.logging.PlatformLogger;
import sun.awt.image.SunWritableRaster; import sun.awt.image.SunWritableRaster;
/** /**
* The splash screen can be created at application startup, before the * The splash screen can be displayed at application startup, before the
* Java Virtual Machine (JVM) starts. The splash screen is displayed as an * Java Virtual Machine (JVM) starts. The splash screen is displayed as an
* undecorated window containing an image. You can use GIF, JPEG, and PNG files * undecorated window containing an image. You can use GIF, JPEG, or PNG files
* for the image. Animation (for GIF) and transparency (for GIF, PNG) are * for the image. Animation is supported for the GIF format, while transparency
* supported. The window is positioned at the center of the screen (the * is supported both for GIF and PNG. The window is positioned at the center
* position on multi-monitor systems is not specified - it is platform and * of the screen. The position on multi-monitor systems is not specified. It is
* implementation dependent). * platform and implementation dependent. The splash screen window is closed
* The window is closed automatically as soon as the first window is displayed by * automatically as soon as the first window is displayed by Swing/AWT (may be
* Swing/AWT (may be also closed manually using the Java API, see below). * also closed manually using the Java API, see below).
* <P> * <P>
* There are two ways to show the native splash screen: * If your application is packaged in a jar file, you can use the
* <P>
* <UL>
* <LI>If your application is run from the command line or from a shortcut,
* use the "-splash:" Java application launcher option to show a splash screen.
* <BR>
* For example:
* <PRE>
* java -splash:filename.gif Test
* </PRE>
* <LI>If your application is packaged in a jar file, you can use the
* "SplashScreen-Image" option in a manifest file to show a splash screen. * "SplashScreen-Image" option in a manifest file to show a splash screen.
* Place the image in the jar archive and specify the path in the option. * Place the image in the jar archive and specify the path in the option.
* The path should not have a leading slash. * The path should not have a leading slash.
...@@ -64,18 +54,39 @@ import sun.awt.image.SunWritableRaster; ...@@ -64,18 +54,39 @@ import sun.awt.image.SunWritableRaster;
* Main-Class: Test * Main-Class: Test
* SplashScreen-Image: filename.gif * SplashScreen-Image: filename.gif
* </PRE> * </PRE>
* <P>
* If the Java implementation provides the command-line interface and you run
* your application by using the command line or a shortcut, use the Java
* application launcher option to show a splash screen. The Oracle reference
* implementation allows you to specify the splash screen image location with
* the {@code -splash:} option.
* <BR>
* For example:
* <PRE>
* java -splash:filename.gif Test
* </PRE>
* The command line interface has higher precedence over the manifest * The command line interface has higher precedence over the manifest
* setting. * setting.
* </UL> * <p>
* The splash screen will be displayed as faithfully as possible to present the
* whole splash screen image given the limitations of the target platform and
* display.
* <p>
* It is implied that the specified image is presented on the screen "as is",
* i.e. preserving the exact color values as specified in the image file. Under
* certain circumstances, though, the presented image may differ, e.g. when
* applying color dithering to present a 32 bits per pixel (bpp) image on a 16
* or 8 bpp screen. The native platform display configuration may also affect
* the colors of the displayed image (e.g. color profiles, etc.)
* <p> * <p>
* The {@code SplashScreen} class provides the API for controlling the splash * The {@code SplashScreen} class provides the API for controlling the splash
* screen. This class may be used to close the splash screen, change the splash * screen. This class may be used to close the splash screen, change the splash
* screen image, get the image position/size and paint in the splash screen. It * screen image, get the splash screen native window position/size, and paint
* cannot be used to create the splash screen; you should use the command line or manifest * in the splash screen. It cannot be used to create the splash screen. You
* file option for that. * should use the options provided by the Java implementation for that.
* <p> * <p>
* This class cannot be instantiated. Only a single instance of this class * This class cannot be instantiated. Only a single instance of this class
* can exist, and it may be obtained using the {@link #getSplashScreen()} * can exist, and it may be obtained by using the {@link #getSplashScreen()}
* static method. In case the splash screen has not been created at * static method. In case the splash screen has not been created at
* application startup via the command line or manifest file option, * application startup via the command line or manifest file option,
* the <code>getSplashScreen</code> method returns <code>null</code>. * the <code>getSplashScreen</code> method returns <code>null</code>.
...@@ -91,7 +102,7 @@ public final class SplashScreen { ...@@ -91,7 +102,7 @@ public final class SplashScreen {
/** /**
* Returns the {@code SplashScreen} object used for * Returns the {@code SplashScreen} object used for
* Java startup splash screen control. * Java startup splash screen control on systems that support display.
* *
* @throws UnsupportedOperationException if the splash screen feature is not * @throws UnsupportedOperationException if the splash screen feature is not
* supported by the current toolkit * supported by the current toolkit
...@@ -219,6 +230,9 @@ public final class SplashScreen { ...@@ -219,6 +230,9 @@ public final class SplashScreen {
* <p> * <p>
* You cannot control the size or position of the splash screen. * You cannot control the size or position of the splash screen.
* The splash screen size is adjusted automatically when the image changes. * The splash screen size is adjusted automatically when the image changes.
* <p>
* The image may contain transparent areas, and thus the reported bounds may
* be larger than the visible splash screen image on the screen.
* *
* @return a {@code Rectangle} containing the splash screen bounds * @return a {@code Rectangle} containing the splash screen bounds
* @throws IllegalStateException if the splash screen has already been closed * @throws IllegalStateException if the splash screen has already been closed
...@@ -237,6 +251,9 @@ public final class SplashScreen { ...@@ -237,6 +251,9 @@ public final class SplashScreen {
* <p> * <p>
* You cannot control the size or position of the splash screen. * You cannot control the size or position of the splash screen.
* The splash screen size is adjusted automatically when the image changes. * The splash screen size is adjusted automatically when the image changes.
* <p>
* The image may contain transparent areas, and thus the reported size may
* be larger than the visible splash screen image on the screen.
* *
* @return a {@link Dimension} object indicating the splash screen size * @return a {@link Dimension} object indicating the splash screen size
* @throws IllegalStateException if the splash screen has already been closed * @throws IllegalStateException if the splash screen has already been closed
...@@ -254,6 +271,10 @@ public final class SplashScreen { ...@@ -254,6 +271,10 @@ public final class SplashScreen {
* screen window. You should call {@code update()} on the * screen window. You should call {@code update()} on the
* <code>SplashScreen</code> when you want the splash screen to be * <code>SplashScreen</code> when you want the splash screen to be
* updated immediately. * updated immediately.
* <p>
* The pixel (0, 0) in the coordinate space of the graphics context
* corresponds to the origin of the splash screen native window bounds (see
* {@link #getBounds()}).
* *
* @return graphics context for the splash screen overlay surface * @return graphics context for the splash screen overlay surface
* @throws IllegalStateException if the splash screen has already been closed * @throws IllegalStateException if the splash screen has already been closed
...@@ -334,6 +355,11 @@ public final class SplashScreen { ...@@ -334,6 +355,11 @@ public final class SplashScreen {
* Determines whether the splash screen is visible. The splash screen may * Determines whether the splash screen is visible. The splash screen may
* be hidden using {@link #close()}, it is also hidden automatically when * be hidden using {@link #close()}, it is also hidden automatically when
* the first AWT/Swing window is made visible. * the first AWT/Swing window is made visible.
* <p>
* Note that the native platform may delay presenting the splash screen
* native window on the screen. The return value of {@code true} for this
* method only guarantees that the conditions to hide the splash screen
* window have not occurred yet.
* *
* @return true if the splash screen is visible (has not been closed yet), * @return true if the splash screen is visible (has not been closed yet),
* false otherwise * false otherwise
......
...@@ -58,20 +58,20 @@ import java.util.Set; ...@@ -58,20 +58,20 @@ import java.util.Set;
* It is also possible to perform numeric shaping explicitly using instances * It is also possible to perform numeric shaping explicitly using instances
* of <code>NumericShaper</code>, as this code snippet demonstrates:<br> * of <code>NumericShaper</code>, as this code snippet demonstrates:<br>
* <blockquote><pre> * <blockquote><pre>
* char[] text = ...; * char[] text = ...;
* // shape all EUROPEAN digits (except zero) to ARABIC digits * // shape all EUROPEAN digits (except zero) to ARABIC digits
* NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC); * NumericShaper shaper = NumericShaper.getShaper(NumericShaper.ARABIC);
* shaper.shape(text, start, count); * shaper.shape(text, start, count);
* *
* // shape European digits to ARABIC digits if preceding text is Arabic, or * // shape European digits to ARABIC digits if preceding text is Arabic, or
* // shape European digits to TAMIL digits if preceding text is Tamil, or * // shape European digits to TAMIL digits if preceding text is Tamil, or
* // leave European digits alone if there is no preceding text, or * // leave European digits alone if there is no preceding text, or
* // preceding text is neither Arabic nor Tamil * // preceding text is neither Arabic nor Tamil
* NumericShaper shaper = * NumericShaper shaper =
* NumericShaper.getContextualShaper(NumericShaper.ARABIC | * NumericShaper.getContextualShaper(NumericShaper.ARABIC |
* NumericShaper.TAMIL, * NumericShaper.TAMIL,
* NumericShaper.EUROPEAN); * NumericShaper.EUROPEAN);
* shaper.shape(text, start, count); * shaper.shape(text, start, count);
* </pre></blockquote> * </pre></blockquote>
* *
* <p><b>Bit mask- and enum-based Unicode ranges</b></p> * <p><b>Bit mask- and enum-based Unicode ranges</b></p>
...@@ -99,6 +99,37 @@ import java.util.Set; ...@@ -99,6 +99,37 @@ import java.util.Set;
* values are specified, such as {@code NumericShaper.Range.BALINESE}, * values are specified, such as {@code NumericShaper.Range.BALINESE},
* those ranges are ignored. * those ranges are ignored.
* *
* <p><b>Decimal Digits Precedence</b></p>
*
* <p>A Unicode range may have more than one set of decimal digits. If
* multiple decimal digits sets are specified for the same Unicode
* range, one of the sets will take precedence as follows.
*
* <table border=1 cellspacing=3 cellpadding=0 summary="NumericShaper constants precedence.">
* <tr>
* <th class="TableHeadingColor">Unicode Range</th>
* <th class="TableHeadingColor"><code>NumericShaper</code> Constants</th>
* <th class="TableHeadingColor">Precedence</th>
* </tr>
* <tr>
* <td rowspan="2">Arabic</td>
* <td>{@link NumericShaper#ARABIC NumericShaper.ARABIC}<br>
* {@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
* <td>{@link NumericShaper#EASTERN_ARABIC NumericShaper.EASTERN_ARABIC}</td>
* </tr>
* <tr>
* <td>{@link NumericShaper.Range#ARABIC}<br>
* {@link NumericShaper.Range#EASTERN_ARABIC}</td>
* <td>{@link NumericShaper.Range#EASTERN_ARABIC}</td>
* </tr>
* <tr>
* <td>Tai Tham</td>
* <td>{@link NumericShaper.Range#TAI_THAM_HORA}<br>
* {@link NumericShaper.Range#TAI_THAM_THAM}</td>
* <td>{@link NumericShaper.Range#TAI_THAM_THAM}</td>
* </tr>
* </table>
*
* @since 1.4 * @since 1.4
*/ */
......
...@@ -625,7 +625,7 @@ public class IndexColorModel extends ColorModel { ...@@ -625,7 +625,7 @@ public class IndexColorModel extends ColorModel {
} }
nBits[0] = nBits[1] = nBits[2] = 8; nBits[0] = nBits[1] = nBits[2] = 8;
} }
return nBits; return nBits.clone();
} }
/** /**
......
...@@ -121,7 +121,7 @@ public abstract class SampleModel ...@@ -121,7 +121,7 @@ public abstract class SampleModel
*/ */
public SampleModel(int dataType, int w, int h, int numBands) public SampleModel(int dataType, int w, int h, int numBands)
{ {
float size = (float)w*h; long size = (long)w * h;
if (w <= 0 || h <= 0) { if (w <= 0 || h <= 0) {
throw new IllegalArgumentException("Width ("+w+") and height ("+ throw new IllegalArgumentException("Width ("+w+") and height ("+
h+") must be > 0"); h+") must be > 0");
......
...@@ -92,7 +92,8 @@ public class SinglePixelPackedSampleModel extends SampleModel ...@@ -92,7 +92,8 @@ public class SinglePixelPackedSampleModel extends SampleModel
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands. * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
* Each sample is stored in a data array element in the position of * Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and * its corresponding bit mask. Each bit mask must be contiguous and
* masks must not overlap. * masks must not overlap. Bit masks exceeding data type capacity are
* truncated.
* @param dataType The data type for storing samples. * @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of the * @param w The width (in pixels) of the region of the
* image data described. * image data described.
...@@ -120,7 +121,8 @@ public class SinglePixelPackedSampleModel extends SampleModel ...@@ -120,7 +121,8 @@ public class SinglePixelPackedSampleModel extends SampleModel
* and a scanline stride equal to scanlineStride data array elements. * and a scanline stride equal to scanlineStride data array elements.
* Each sample is stored in a data array element in the position of * Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and * its corresponding bit mask. Each bit mask must be contiguous and
* masks must not overlap. * masks must not overlap. Bit masks exceeding data type capacity are
* truncated.
* @param dataType The data type for storing samples. * @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of * @param w The width (in pixels) of the region of
* image data described. * image data described.
...@@ -153,11 +155,13 @@ public class SinglePixelPackedSampleModel extends SampleModel ...@@ -153,11 +155,13 @@ public class SinglePixelPackedSampleModel extends SampleModel
this.bitOffsets = new int[numBands]; this.bitOffsets = new int[numBands];
this.bitSizes = new int[numBands]; this.bitSizes = new int[numBands];
int maxMask = (int)((1L << DataBuffer.getDataTypeSize(dataType)) - 1);
this.maxBitSize = 0; this.maxBitSize = 0;
for (int i=0; i<numBands; i++) { for (int i=0; i<numBands; i++) {
int bitOffset = 0, bitSize = 0, mask; int bitOffset = 0, bitSize = 0, mask;
mask = bitMasks[i]; this.bitMasks[i] &= maxMask;
mask = this.bitMasks[i];
if (mask != 0) { if (mask != 0) {
while ((mask & 1) == 0) { while ((mask & 1) == 0) {
mask = mask >>> 1; mask = mask >>> 1;
...@@ -243,30 +247,12 @@ public class SinglePixelPackedSampleModel extends SampleModel ...@@ -243,30 +247,12 @@ public class SinglePixelPackedSampleModel extends SampleModel
/** Returns the number of bits per sample for all bands. */ /** Returns the number of bits per sample for all bands. */
public int[] getSampleSize() { public int[] getSampleSize() {
int mask; return bitSizes.clone();
int sampleSize[] = new int [numBands];
for (int i=0; i<numBands; i++) {
sampleSize[i] = 0;
mask = bitMasks[i] >>> bitOffsets[i];
while ((mask & 1) != 0) {
sampleSize[i] ++;
mask = mask >>> 1;
}
}
return sampleSize;
} }
/** Returns the number of bits per sample for the specified band. */ /** Returns the number of bits per sample for the specified band. */
public int getSampleSize(int band) { public int getSampleSize(int band) {
int sampleSize = 0; return bitSizes[band];
int mask = bitMasks[band] >>> bitOffsets[band];
while ((mask & 1) != 0) {
sampleSize ++;
mask = mask >>> 1;
}
return sampleSize;
} }
/** Returns the offset (in data array elements) of pixel (x,y). /** Returns the offset (in data array elements) of pixel (x,y).
......
...@@ -93,73 +93,65 @@ import java.util.Locale; ...@@ -93,73 +93,65 @@ import java.util.Locale;
* currency * currency
* percent * percent
* <i>SubformatPattern</i> * <i>SubformatPattern</i>
* </pre></blockquote>
* *
* <i>String:</i> * <p>Within a <i>String</i>, a pair of single quotes can be used to
* <i>StringPart<sub>opt</sub></i> * quote any arbitrary characters except single quotes. For example,
* <i>String</i> <i>StringPart</i> * pattern string <code>"'{0}'"</code> represents string
* <code>"{0}"</code>, not a <i>FormatElement</i>. A single quote itself
* must be represented by doubled single quotes {@code ''} throughout a
* <i>String</i>. For example, pattern string <code>"'{''}'"</code> is
* interpreted as a sequence of <code>'{</code> (start of quoting and a
* left curly brace), <code>''</code> (a single quote), and
* <code>}'</code> (a right curly brace and end of quoting),
* <em>not</em> <code>'{'</code> and <code>'}'</code> (quoted left and
* right curly braces): representing string <code>"{'}"</code>,
* <em>not</em> <code>"{}"</code>.
* *
* <i>StringPart:</i> * <p>A <i>SubformatPattern</i> is interpreted by its corresponding
* '' * subformat, and subformat-dependent pattern rules apply. For example,
* ' <i>QuotedString</i> ' * pattern string <code>"{1,number,<u>$'#',##</u>}"</code>
* <i>UnquotedString</i> * (<i>SubformatPattern</i> with underline) will produce a number format
* with the pound-sign quoted, with a result such as: {@code
* "$#31,45"}. Refer to each {@code Format} subclass documentation for
* details.
* *
* <i>SubformatPattern:</i> * <p>Any unmatched quote is treated as closed at the end of the given
* <i>SubformatPatternPart<sub>opt</sub></i> * pattern. For example, pattern string {@code "'{0}"} is treated as
* <i>SubformatPattern</i> <i>SubformatPatternPart</i> * pattern {@code "'{0}'"}.
* *
* <i>SubFormatPatternPart:</i> * <p>Any curly braces within an unquoted pattern must be balanced. For
* ' <i>QuotedPattern</i> ' * example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code> are
* <i>UnquotedPattern</i> * valid patterns, but <code>"ab {0'}' de"</code>, <code>"ab } de"</code>
* </pre></blockquote> * and <code>"''{''"</code> are not.
* *
* <p> * <p>
* Within a <i>String</i>, <code>"''"</code> represents a single
* quote. A <i>QuotedString</i> can contain arbitrary characters
* except single quotes; the surrounding single quotes are removed.
* An <i>UnquotedString</i> can contain arbitrary characters
* except single quotes and left curly brackets. Thus, a string that
* should result in the formatted message "'{0}'" can be written as
* <code>"'''{'0}''"</code> or <code>"'''{0}'''"</code>.
* <p>
* Within a <i>SubformatPattern</i>, different rules apply.
* A <i>QuotedPattern</i> can contain arbitrary characters
* except single quotes; but the surrounding single quotes are
* <strong>not</strong> removed, so they may be interpreted by the
* subformat. For example, <code>"{1,number,$'#',##}"</code> will
* produce a number format with the pound-sign quoted, with a result
* such as: "$#31,45".
* An <i>UnquotedPattern</i> can contain arbitrary characters
* except single quotes, but curly braces within it must be balanced.
* For example, <code>"ab {0} de"</code> and <code>"ab '}' de"</code>
* are valid subformat patterns, but <code>"ab {0'}' de"</code> and
* <code>"ab } de"</code> are not.
* <p>
* <dl><dt><b>Warning:</b><dd>The rules for using quotes within message * <dl><dt><b>Warning:</b><dd>The rules for using quotes within message
* format patterns unfortunately have shown to be somewhat confusing. * format patterns unfortunately have shown to be somewhat confusing.
* In particular, it isn't always obvious to localizers whether single * In particular, it isn't always obvious to localizers whether single
* quotes need to be doubled or not. Make sure to inform localizers about * quotes need to be doubled or not. Make sure to inform localizers about
* the rules, and tell them (for example, by using comments in resource * the rules, and tell them (for example, by using comments in resource
* bundle source files) which strings will be processed by MessageFormat. * bundle source files) which strings will be processed by {@code MessageFormat}.
* Note that localizers may need to use single quotes in translated * Note that localizers may need to use single quotes in translated
* strings where the original version doesn't have them. * strings where the original version doesn't have them.
* </dl> * </dl>
* <p> * <p>
* The <i>ArgumentIndex</i> value is a non-negative integer written * The <i>ArgumentIndex</i> value is a non-negative integer written
* using the digits '0' through '9', and represents an index into the * using the digits {@code '0'} through {@code '9'}, and represents an index into the
* <code>arguments</code> array passed to the <code>format</code> methods * {@code arguments} array passed to the {@code format} methods
* or the result array returned by the <code>parse</code> methods. * or the result array returned by the {@code parse} methods.
* <p> * <p>
* The <i>FormatType</i> and <i>FormatStyle</i> values are used to create * The <i>FormatType</i> and <i>FormatStyle</i> values are used to create
* a <code>Format</code> instance for the format element. The following * a {@code Format} instance for the format element. The following
* table shows how the values map to Format instances. Combinations not * table shows how the values map to {@code Format} instances. Combinations not
* shown in the table are illegal. A <i>SubformatPattern</i> must * shown in the table are illegal. A <i>SubformatPattern</i> must
* be a valid pattern string for the Format subclass used. * be a valid pattern string for the {@code Format} subclass used.
* <p> * <p>
* <table border=1 summary="Shows how FormatType and FormatStyle values map to Format instances"> * <table border=1 summary="Shows how FormatType and FormatStyle values map to Format instances">
* <tr> * <tr>
* <th id="ft">Format Type * <th id="ft" class="TableHeadingColor">FormatType
* <th id="fs">Format Style * <th id="fs" class="TableHeadingColor">FormatStyle
* <th id="sc">Subformat Created * <th id="sc" class="TableHeadingColor">Subformat Created
* <tr> * <tr>
* <td headers="ft"><i>(none)</i> * <td headers="ft"><i>(none)</i>
* <td headers="fs"><i>(none)</i> * <td headers="fs"><i>(none)</i>
...@@ -167,61 +159,61 @@ import java.util.Locale; ...@@ -167,61 +159,61 @@ import java.util.Locale;
* <tr> * <tr>
* <td headers="ft" rowspan=5><code>number</code> * <td headers="ft" rowspan=5><code>number</code>
* <td headers="fs"><i>(none)</i> * <td headers="fs"><i>(none)</i>
* <td headers="sc"><code>NumberFormat.getInstance(getLocale())</code> * <td headers="sc">{@link NumberFormat#getInstance(Locale) NumberFormat.getInstance}{@code (getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>integer</code> * <td headers="fs"><code>integer</code>
* <td headers="sc"><code>NumberFormat.getIntegerInstance(getLocale())</code> * <td headers="sc">{@link NumberFormat#getIntegerInstance(Locale) NumberFormat.getIntegerInstance}{@code (getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>currency</code> * <td headers="fs"><code>currency</code>
* <td headers="sc"><code>NumberFormat.getCurrencyInstance(getLocale())</code> * <td headers="sc">{@link NumberFormat#getCurrencyInstance(Locale) NumberFormat.getCurrencyInstance}{@code (getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>percent</code> * <td headers="fs"><code>percent</code>
* <td headers="sc"><code>NumberFormat.getPercentInstance(getLocale())</code> * <td headers="sc">{@link NumberFormat#getPercentInstance(Locale) NumberFormat.getPercentInstance}{@code (getLocale())}
* <tr> * <tr>
* <td headers="fs"><i>SubformatPattern</i> * <td headers="fs"><i>SubformatPattern</i>
* <td headers="sc"><code>new DecimalFormat(subformatPattern, DecimalFormatSymbols.getInstance(getLocale()))</code> * <td headers="sc">{@code new} {@link DecimalFormat#DecimalFormat(String,DecimalFormatSymbols) DecimalFormat}{@code (subformatPattern,} {@link DecimalFormatSymbols#getInstance(Locale) DecimalFormatSymbols.getInstance}{@code (getLocale()))}
* <tr> * <tr>
* <td headers="ft" rowspan=6><code>date</code> * <td headers="ft" rowspan=6><code>date</code>
* <td headers="fs"><i>(none)</i> * <td headers="fs"><i>(none)</i>
* <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code> * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>short</code> * <td headers="fs"><code>short</code>
* <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.SHORT, getLocale())</code> * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>medium</code> * <td headers="fs"><code>medium</code>
* <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale())</code> * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>long</code> * <td headers="fs"><code>long</code>
* <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.LONG, getLocale())</code> * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>full</code> * <td headers="fs"><code>full</code>
* <td headers="sc"><code>DateFormat.getDateInstance(DateFormat.FULL, getLocale())</code> * <td headers="sc">{@link DateFormat#getDateInstance(int,Locale) DateFormat.getDateInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><i>SubformatPattern</i> * <td headers="fs"><i>SubformatPattern</i>
* <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code> * <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
* <tr> * <tr>
* <td headers="ft" rowspan=6><code>time</code> * <td headers="ft" rowspan=6><code>time</code>
* <td headers="fs"><i>(none)</i> * <td headers="fs"><i>(none)</i>
* <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code> * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>short</code> * <td headers="fs"><code>short</code>
* <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.SHORT, getLocale())</code> * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#SHORT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>medium</code> * <td headers="fs"><code>medium</code>
* <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale())</code> * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#DEFAULT}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>long</code> * <td headers="fs"><code>long</code>
* <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.LONG, getLocale())</code> * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#LONG}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><code>full</code> * <td headers="fs"><code>full</code>
* <td headers="sc"><code>DateFormat.getTimeInstance(DateFormat.FULL, getLocale())</code> * <td headers="sc">{@link DateFormat#getTimeInstance(int,Locale) DateFormat.getTimeInstance}{@code (}{@link DateFormat#FULL}{@code , getLocale())}
* <tr> * <tr>
* <td headers="fs"><i>SubformatPattern</i> * <td headers="fs"><i>SubformatPattern</i>
* <td headers="sc"><code>new SimpleDateFormat(subformatPattern, getLocale())</code> * <td headers="sc">{@code new} {@link SimpleDateFormat#SimpleDateFormat(String,Locale) SimpleDateFormat}{@code (subformatPattern, getLocale())}
* <tr> * <tr>
* <td headers="ft"><code>choice</code> * <td headers="ft"><code>choice</code>
* <td headers="fs"><i>SubformatPattern</i> * <td headers="fs"><i>SubformatPattern</i>
* <td headers="sc"><code>new ChoiceFormat(subformatPattern)</code> * <td headers="sc">{@code new} {@link ChoiceFormat#ChoiceFormat(String) ChoiceFormat}{@code (subformatPattern)}
* </table> * </table>
* <p> * <p>
* *
...@@ -321,7 +313,7 @@ import java.util.Locale; ...@@ -321,7 +313,7 @@ import java.util.Locale;
* </pre></blockquote> * </pre></blockquote>
* *
* <p> * <p>
* Likewise, parsing with a MessageFormat object using patterns containing * Likewise, parsing with a {@code MessageFormat} object using patterns containing
* multiple occurrences of the same argument would return the last match. For * multiple occurrences of the same argument would return the last match. For
* example, * example,
* <blockquote><pre> * <blockquote><pre>
...@@ -343,7 +335,11 @@ import java.util.Locale; ...@@ -343,7 +335,11 @@ import java.util.Locale;
* @see Format * @see Format
* @see NumberFormat * @see NumberFormat
* @see DecimalFormat * @see DecimalFormat
* @see DecimalFormatSymbols
* @see ChoiceFormat * @see ChoiceFormat
* @see DateFormat
* @see SimpleDateFormat
*
* @author Mark Davis * @author Mark Davis
*/ */
...@@ -427,18 +423,19 @@ public class MessageFormat extends Format { ...@@ -427,18 +423,19 @@ public class MessageFormat extends Format {
* @exception IllegalArgumentException if the pattern is invalid * @exception IllegalArgumentException if the pattern is invalid
*/ */
public void applyPattern(String pattern) { public void applyPattern(String pattern) {
StringBuffer[] segments = new StringBuffer[4]; StringBuilder[] segments = new StringBuilder[4];
for (int i = 0; i < segments.length; ++i) { // Allocate only segments[SEG_RAW] here. The rest are
segments[i] = new StringBuffer(); // allocated on demand.
} segments[SEG_RAW] = new StringBuilder();
int part = 0;
int part = SEG_RAW;
int formatNumber = 0; int formatNumber = 0;
boolean inQuote = false; boolean inQuote = false;
int braceStack = 0; int braceStack = 0;
maxOffset = -1; maxOffset = -1;
for (int i = 0; i < pattern.length(); ++i) { for (int i = 0; i < pattern.length(); ++i) {
char ch = pattern.charAt(i); char ch = pattern.charAt(i);
if (part == 0) { if (part == SEG_RAW) {
if (ch == '\'') { if (ch == '\'') {
if (i + 1 < pattern.length() if (i + 1 < pattern.length()
&& pattern.charAt(i+1) == '\'') { && pattern.charAt(i+1) == '\'') {
...@@ -448,43 +445,61 @@ public class MessageFormat extends Format { ...@@ -448,43 +445,61 @@ public class MessageFormat extends Format {
inQuote = !inQuote; inQuote = !inQuote;
} }
} else if (ch == '{' && !inQuote) { } else if (ch == '{' && !inQuote) {
part = 1; part = SEG_INDEX;
if (segments[SEG_INDEX] == null) {
segments[SEG_INDEX] = new StringBuilder();
}
} else { } else {
segments[part].append(ch); segments[part].append(ch);
} }
} else if (inQuote) { // just copy quotes in parts } else {
segments[part].append(ch); if (inQuote) { // just copy quotes in parts
if (ch == '\'') {
inQuote = false;
}
} else {
switch (ch) {
case ',':
if (part < 3)
part += 1;
else
segments[part].append(ch);
break;
case '{':
++braceStack;
segments[part].append(ch); segments[part].append(ch);
break; if (ch == '\'') {
case '}': inQuote = false;
if (braceStack == 0) { }
part = 0; } else {
makeFormat(i, formatNumber, segments); switch (ch) {
formatNumber++; case ',':
} else { if (part < SEG_MODIFIER) {
--braceStack; if (segments[++part] == null) {
segments[part] = new StringBuilder();
}
} else {
segments[part].append(ch);
}
break;
case '{':
++braceStack;
segments[part].append(ch); segments[part].append(ch);
break;
case '}':
if (braceStack == 0) {
part = SEG_RAW;
makeFormat(i, formatNumber, segments);
formatNumber++;
// throw away other segments
segments[SEG_INDEX] = null;
segments[SEG_TYPE] = null;
segments[SEG_MODIFIER] = null;
} else {
--braceStack;
segments[part].append(ch);
}
break;
case ' ':
// Skip any leading space chars for SEG_TYPE.
if (part != SEG_TYPE || segments[SEG_TYPE].length() > 0) {
segments[part].append(ch);
}
break;
case '\'':
inQuote = true;
// fall through, so we keep quotes in other parts
default:
segments[part].append(ch);
break;
} }
break;
case '\'':
inQuote = true;
// fall through, so we keep quotes in other parts
default:
segments[part].append(ch);
break;
} }
} }
} }
...@@ -506,65 +521,57 @@ public class MessageFormat extends Format { ...@@ -506,65 +521,57 @@ public class MessageFormat extends Format {
public String toPattern() { public String toPattern() {
// later, make this more extensible // later, make this more extensible
int lastOffset = 0; int lastOffset = 0;
StringBuffer result = new StringBuffer(); StringBuilder result = new StringBuilder();
for (int i = 0; i <= maxOffset; ++i) { for (int i = 0; i <= maxOffset; ++i) {
copyAndFixQuotes(pattern, lastOffset, offsets[i],result); copyAndFixQuotes(pattern, lastOffset, offsets[i], result);
lastOffset = offsets[i]; lastOffset = offsets[i];
result.append('{'); result.append('{').append(argumentNumbers[i]);
result.append(argumentNumbers[i]); Format fmt = formats[i];
if (formats[i] == null) { if (fmt == null) {
// do nothing, string format // do nothing, string format
} else if (formats[i] instanceof DecimalFormat) { } else if (fmt instanceof NumberFormat) {
if (formats[i].equals(NumberFormat.getInstance(locale))) { if (fmt.equals(NumberFormat.getInstance(locale))) {
result.append(",number"); result.append(",number");
} else if (formats[i].equals(NumberFormat.getCurrencyInstance(locale))) { } else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
result.append(",number,currency"); result.append(",number,currency");
} else if (formats[i].equals(NumberFormat.getPercentInstance(locale))) { } else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
result.append(",number,percent"); result.append(",number,percent");
} else if (formats[i].equals(NumberFormat.getIntegerInstance(locale))) { } else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
result.append(",number,integer"); result.append(",number,integer");
} else { } else {
result.append(",number," + if (fmt instanceof DecimalFormat) {
((DecimalFormat)formats[i]).toPattern()); result.append(",number,").append(((DecimalFormat)fmt).toPattern());
} else if (fmt instanceof ChoiceFormat) {
result.append(",choice,").append(((ChoiceFormat)fmt).toPattern());
} else {
// UNKNOWN
}
} }
} else if (formats[i] instanceof SimpleDateFormat) { } else if (fmt instanceof DateFormat) {
if (formats[i].equals(DateFormat.getDateInstance( int index;
DateFormat.DEFAULT,locale))) { for (index = MODIFIER_DEFAULT; index < DATE_TIME_MODIFIERS.length; index++) {
result.append(",date"); DateFormat df = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[index],
} else if (formats[i].equals(DateFormat.getDateInstance( locale);
DateFormat.SHORT,locale))) { if (fmt.equals(df)) {
result.append(",date,short"); result.append(",date");
} else if (formats[i].equals(DateFormat.getDateInstance( break;
DateFormat.DEFAULT,locale))) { }
result.append(",date,medium"); df = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[index],
} else if (formats[i].equals(DateFormat.getDateInstance( locale);
DateFormat.LONG,locale))) { if (fmt.equals(df)) {
result.append(",date,long"); result.append(",time");
} else if (formats[i].equals(DateFormat.getDateInstance( break;
DateFormat.FULL,locale))) { }
result.append(",date,full"); }
} else if (formats[i].equals(DateFormat.getTimeInstance( if (index >= DATE_TIME_MODIFIERS.length) {
DateFormat.DEFAULT,locale))) { if (fmt instanceof SimpleDateFormat) {
result.append(",time"); result.append(",date,").append(((SimpleDateFormat)fmt).toPattern());
} else if (formats[i].equals(DateFormat.getTimeInstance( } else {
DateFormat.SHORT,locale))) { // UNKNOWN
result.append(",time,short"); }
} else if (formats[i].equals(DateFormat.getTimeInstance( } else if (index != MODIFIER_DEFAULT) {
DateFormat.DEFAULT,locale))) { result.append(',').append(DATE_TIME_MODIFIER_KEYWORDS[index]);
result.append(",time,medium");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.LONG,locale))) {
result.append(",time,long");
} else if (formats[i].equals(DateFormat.getTimeInstance(
DateFormat.FULL,locale))) {
result.append(",time,full");
} else {
result.append(",date,"
+ ((SimpleDateFormat)formats[i]).toPattern());
} }
} else if (formats[i] instanceof ChoiceFormat) {
result.append(",choice,"
+ ((ChoiceFormat)formats[i]).toPattern());
} else { } else {
//result.append(", unknown"); //result.append(", unknown");
} }
...@@ -678,7 +685,7 @@ public class MessageFormat extends Format { ...@@ -678,7 +685,7 @@ public class MessageFormat extends Format {
* *
* @param formatElementIndex the index of a format element within the pattern * @param formatElementIndex the index of a format element within the pattern
* @param newFormat the format to use for the specified format element * @param newFormat the format to use for the specified format element
* @exception ArrayIndexOutOfBoundsException if formatElementIndex is equal to or * @exception ArrayIndexOutOfBoundsException if {@code formatElementIndex} is equal to or
* larger than the number of format elements in the pattern string * larger than the number of format elements in the pattern string
*/ */
public void setFormat(int formatElementIndex, Format newFormat) { public void setFormat(int formatElementIndex, Format newFormat) {
...@@ -972,7 +979,8 @@ public class MessageFormat extends Format { ...@@ -972,7 +979,8 @@ public class MessageFormat extends Format {
if (patternOffset >= tempLength) { if (patternOffset >= tempLength) {
next = source.length(); next = source.length();
}else{ }else{
next = source.indexOf( pattern.substring(patternOffset,tempLength), sourceOffset); next = source.indexOf(pattern.substring(patternOffset, tempLength),
sourceOffset);
} }
if (next < 0) { if (next < 0) {
...@@ -1226,7 +1234,7 @@ public class MessageFormat extends Format { ...@@ -1226,7 +1234,7 @@ public class MessageFormat extends Format {
lastOffset = offsets[i]; lastOffset = offsets[i];
int argumentNumber = argumentNumbers[i]; int argumentNumber = argumentNumbers[i];
if (arguments == null || argumentNumber >= arguments.length) { if (arguments == null || argumentNumber >= arguments.length) {
result.append("{" + argumentNumber + "}"); result.append('{').append(argumentNumber).append('}');
continue; continue;
} }
// int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3); // int argRecursion = ((recursionProtection >> (argumentNumber*2)) & 0x3);
...@@ -1338,25 +1346,83 @@ public class MessageFormat extends Format { ...@@ -1338,25 +1346,83 @@ public class MessageFormat extends Format {
} }
} }
private static final String[] typeList = // Indices for segments
{"", "", "number", "", "date", "", "time", "", "choice"}; private static final int SEG_RAW = 0;
private static final String[] modifierList = private static final int SEG_INDEX = 1;
{"", "", "currency", "", "percent", "", "integer"}; private static final int SEG_TYPE = 2;
private static final String[] dateModifierList = private static final int SEG_MODIFIER = 3; // modifier or subformat
{"", "", "short", "", "medium", "", "long", "", "full"};
// Indices for type keywords
private static final int TYPE_NULL = 0;
private static final int TYPE_NUMBER = 1;
private static final int TYPE_DATE = 2;
private static final int TYPE_TIME = 3;
private static final int TYPE_CHOICE = 4;
private static final String[] TYPE_KEYWORDS = {
"",
"number",
"date",
"time",
"choice"
};
// Indices for number modifiers
private static final int MODIFIER_DEFAULT = 0; // common in number and date-time
private static final int MODIFIER_CURRENCY = 1;
private static final int MODIFIER_PERCENT = 2;
private static final int MODIFIER_INTEGER = 3;
private static final String[] NUMBER_MODIFIER_KEYWORDS = {
"",
"currency",
"percent",
"integer"
};
// Indices for date-time modifiers
private static final int MODIFIER_SHORT = 1;
private static final int MODIFIER_MEDIUM = 2;
private static final int MODIFIER_LONG = 3;
private static final int MODIFIER_FULL = 4;
private static final String[] DATE_TIME_MODIFIER_KEYWORDS = {
"",
"short",
"medium",
"long",
"full"
};
// Date-time style values corresponding to the date-time modifiers.
private static final int[] DATE_TIME_MODIFIERS = {
DateFormat.DEFAULT,
DateFormat.SHORT,
DateFormat.MEDIUM,
DateFormat.LONG,
DateFormat.FULL,
};
private void makeFormat(int position, int offsetNumber, private void makeFormat(int position, int offsetNumber,
StringBuffer[] segments) StringBuilder[] textSegments)
{ {
String[] segments = new String[textSegments.length];
for (int i = 0; i < textSegments.length; i++) {
StringBuilder oneseg = textSegments[i];
segments[i] = (oneseg != null) ? oneseg.toString() : "";
}
// get the argument number // get the argument number
int argumentNumber; int argumentNumber;
try { try {
argumentNumber = Integer.parseInt(segments[1].toString()); // always unlocalized! argumentNumber = Integer.parseInt(segments[SEG_INDEX]); // always unlocalized!
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new IllegalArgumentException("can't parse argument number: " + segments[1]); throw new IllegalArgumentException("can't parse argument number: "
+ segments[SEG_INDEX], e);
} }
if (argumentNumber < 0) { if (argumentNumber < 0) {
throw new IllegalArgumentException("negative argument number: " + argumentNumber); throw new IllegalArgumentException("negative argument number: "
+ argumentNumber);
} }
// resize format information arrays if necessary // resize format information arrays if necessary
...@@ -1374,120 +1440,129 @@ public class MessageFormat extends Format { ...@@ -1374,120 +1440,129 @@ public class MessageFormat extends Format {
} }
int oldMaxOffset = maxOffset; int oldMaxOffset = maxOffset;
maxOffset = offsetNumber; maxOffset = offsetNumber;
offsets[offsetNumber] = segments[0].length(); offsets[offsetNumber] = segments[SEG_RAW].length();
argumentNumbers[offsetNumber] = argumentNumber; argumentNumbers[offsetNumber] = argumentNumber;
// now get the format // now get the format
Format newFormat = null; Format newFormat = null;
switch (findKeyword(segments[2].toString(), typeList)) { if (segments[SEG_TYPE].length() != 0) {
case 0: int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
break; switch (type) {
case 1: case 2:// number case TYPE_NULL:
switch (findKeyword(segments[3].toString(), modifierList)) { // Type "" is allowed. e.g., "{0,}", "{0,,}", and "{0,,#}"
case 0: // default; // are treated as "{0}".
newFormat = NumberFormat.getInstance(locale);
break;
case 1: case 2:// currency
newFormat = NumberFormat.getCurrencyInstance(locale);
break;
case 3: case 4:// percent
newFormat = NumberFormat.getPercentInstance(locale);
break;
case 5: case 6:// integer
newFormat = NumberFormat.getIntegerInstance(locale);
break;
default: // pattern
newFormat = new DecimalFormat(segments[3].toString(), DecimalFormatSymbols.getInstance(locale));
break; break;
}
break; case TYPE_NUMBER:
case 3: case 4: // date switch (findKeyword(segments[SEG_MODIFIER], NUMBER_MODIFIER_KEYWORDS)) {
switch (findKeyword(segments[3].toString(), dateModifierList)) { case MODIFIER_DEFAULT:
case 0: // default newFormat = NumberFormat.getInstance(locale);
newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); break;
break; case MODIFIER_CURRENCY:
case 1: case 2: // short newFormat = NumberFormat.getCurrencyInstance(locale);
newFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale); break;
break; case MODIFIER_PERCENT:
case 3: case 4: // medium newFormat = NumberFormat.getPercentInstance(locale);
newFormat = DateFormat.getDateInstance(DateFormat.DEFAULT, locale); break;
break; case MODIFIER_INTEGER:
case 5: case 6: // long newFormat = NumberFormat.getIntegerInstance(locale);
newFormat = DateFormat.getDateInstance(DateFormat.LONG, locale); break;
break; default: // DecimalFormat pattern
case 7: case 8: // full try {
newFormat = DateFormat.getDateInstance(DateFormat.FULL, locale); newFormat = new DecimalFormat(segments[SEG_MODIFIER],
break; DecimalFormatSymbols.getInstance(locale));
default: } catch (IllegalArgumentException e) {
newFormat = new SimpleDateFormat(segments[3].toString(), locale); maxOffset = oldMaxOffset;
break; throw e;
} }
break; break;
case 5: case 6:// time }
switch (findKeyword(segments[3].toString(), dateModifierList)) {
case 0: // default
newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
break;
case 1: case 2: // short
newFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
break;
case 3: case 4: // medium
newFormat = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
break; break;
case 5: case 6: // long
newFormat = DateFormat.getTimeInstance(DateFormat.LONG, locale); case TYPE_DATE:
case TYPE_TIME:
int mod = findKeyword(segments[SEG_MODIFIER], DATE_TIME_MODIFIER_KEYWORDS);
if (mod >= 0 && mod < DATE_TIME_MODIFIER_KEYWORDS.length) {
if (type == TYPE_DATE) {
newFormat = DateFormat.getDateInstance(DATE_TIME_MODIFIERS[mod],
locale);
} else {
newFormat = DateFormat.getTimeInstance(DATE_TIME_MODIFIERS[mod],
locale);
}
} else {
// SimpleDateFormat pattern
try {
newFormat = new SimpleDateFormat(segments[SEG_MODIFIER], locale);
} catch (IllegalArgumentException e) {
maxOffset = oldMaxOffset;
throw e;
}
}
break; break;
case 7: case 8: // full
newFormat = DateFormat.getTimeInstance(DateFormat.FULL, locale); case TYPE_CHOICE:
try {
// ChoiceFormat pattern
newFormat = new ChoiceFormat(segments[SEG_MODIFIER]);
} catch (Exception e) {
maxOffset = oldMaxOffset;
throw new IllegalArgumentException("Choice Pattern incorrect: "
+ segments[SEG_MODIFIER], e);
}
break; break;
default: default:
newFormat = new SimpleDateFormat(segments[3].toString(), locale);
break;
}
break;
case 7: case 8:// choice
try {
newFormat = new ChoiceFormat(segments[3].toString());
} catch (Exception e) {
maxOffset = oldMaxOffset; maxOffset = oldMaxOffset;
throw new IllegalArgumentException( throw new IllegalArgumentException("unknown format type: " +
"Choice Pattern incorrect"); segments[SEG_TYPE]);
} }
break;
default:
maxOffset = oldMaxOffset;
throw new IllegalArgumentException("unknown format type: " +
segments[2].toString());
} }
formats[offsetNumber] = newFormat; formats[offsetNumber] = newFormat;
segments[1].setLength(0); // throw away other segments
segments[2].setLength(0);
segments[3].setLength(0);
} }
private static final int findKeyword(String s, String[] list) { private static final int findKeyword(String s, String[] list) {
s = s.trim().toLowerCase();
for (int i = 0; i < list.length; ++i) { for (int i = 0; i < list.length; ++i) {
if (s.equals(list[i])) if (s.equals(list[i]))
return i; return i;
} }
// Try trimmed lowercase.
String ls = s.trim().toLowerCase(Locale.ROOT);
if (ls != s) {
for (int i = 0; i < list.length; ++i) {
if (ls.equals(list[i]))
return i;
}
}
return -1; return -1;
} }
private static final void copyAndFixQuotes( private static final void copyAndFixQuotes(String source, int start, int end,
String source, int start, int end, StringBuffer target) { StringBuilder target) {
boolean quoted = false;
for (int i = start; i < end; ++i) { for (int i = start; i < end; ++i) {
char ch = source.charAt(i); char ch = source.charAt(i);
if (ch == '{') { if (ch == '{') {
target.append("'{'"); if (!quoted) {
} else if (ch == '}') { target.append('\'');
target.append("'}'"); quoted = true;
}
target.append(ch);
} else if (ch == '\'') { } else if (ch == '\'') {
target.append("''"); target.append("''");
} else { } else {
if (quoted) {
target.append('\'');
quoted = false;
}
target.append(ch); target.append(ch);
} }
} }
if (quoted) {
target.append('\'');
}
} }
/** /**
......
...@@ -1662,6 +1662,81 @@ public class SimpleDateFormat extends DateFormat { ...@@ -1662,6 +1662,81 @@ public class SimpleDateFormat extends DateFormat {
return 0; return 0;
} }
/**
* Parses numeric forms of time zone offset, such as "hh:mm", and
* sets calb to the parsed value.
*
* @param text the text to be parsed
* @param start the character position to start parsing
* @param sign 1: positive; -1: negative
* @param count 0: 'Z' or "GMT+hh:mm" parsing; 1 - 3: the number of 'X's
* @param colon true - colon required between hh and mm; false - no colon required
* @param calb a CalendarBuilder in which the parsed value is stored
* @return updated parsed position, or its negative value to indicate a parsing error
*/
private int subParseNumericZone(String text, int start, int sign, int count,
boolean colon, CalendarBuilder calb) {
int index = start;
parse:
try {
char c = text.charAt(index++);
// Parse hh
int hours;
if (!isDigit(c)) {
break parse;
}
hours = c - '0';
c = text.charAt(index++);
if (isDigit(c)) {
hours = hours * 10 + (c - '0');
} else {
// If no colon in RFC 822 or 'X' (ISO), two digits are
// required.
if (count > 0 || !colon) {
break parse;
}
--index;
}
if (hours > 23) {
break parse;
}
int minutes = 0;
if (count != 1) {
// Proceed with parsing mm
c = text.charAt(index++);
if (colon) {
if (c != ':') {
break parse;
}
c = text.charAt(index++);
}
if (!isDigit(c)) {
break parse;
}
minutes = c - '0';
c = text.charAt(index++);
if (!isDigit(c)) {
break parse;
}
minutes = minutes * 10 + (c - '0');
if (minutes > 59) {
break parse;
}
}
minutes += hours * 60;
calb.set(Calendar.ZONE_OFFSET, minutes * MILLIS_PER_MINUTE * sign)
.set(Calendar.DST_OFFSET, 0);
return index;
} catch (IndexOutOfBoundsException e) {
}
return 1 - index; // -(index - 1)
}
private boolean isDigit(char c) {
return c >= '0' && c <= '9';
}
/** /**
* Private member function that converts the parsed date strings into * Private member function that converts the parsed date strings into
* timeFields. Returns -start (for ParsePosition) if failed. * timeFields. Returns -start (for ParsePosition) if failed.
...@@ -1907,248 +1982,95 @@ public class SimpleDateFormat extends DateFormat { ...@@ -1907,248 +1982,95 @@ public class SimpleDateFormat extends DateFormat {
case PATTERN_ZONE_NAME: // 'z' case PATTERN_ZONE_NAME: // 'z'
case PATTERN_ZONE_VALUE: // 'Z' case PATTERN_ZONE_VALUE: // 'Z'
// First try to parse generic forms such as GMT-07:00. Do this first
// in case localized TimeZoneNames contains the string "GMT"
// for a zone; in that case, we don't want to match the first three
// characters of GMT+/-hh:mm etc.
{ {
int sign = 0; int sign = 0;
int offset; try {
char c = text.charAt(pos.index);
// For time zones that have no known names, look for strings if (c == '+') {
// of the form: sign = 1;
// GMT[+-]hours:minutes or } else if (c == '-') {
// GMT. sign = -1;
if ((text.length() - start) >= GMT.length() &&
text.regionMatches(true, start, GMT, 0, GMT.length())) {
int num;
calb.set(Calendar.DST_OFFSET, 0);
pos.index = start + GMT.length();
try { // try-catch for "GMT" only time zone string
char c = text.charAt(pos.index);
if (c == '+') {
sign = 1;
} else if (c == '-') {
sign = -1;
}
}
catch(StringIndexOutOfBoundsException e) {}
if (sign == 0) { /* "GMT" without offset */
calb.set(Calendar.ZONE_OFFSET, 0);
return pos.index;
} }
if (sign == 0) {
// Look for hours. // Try parsing a custom time zone "GMT+hh:mm" or "GMT".
try { if ((c == 'G' || c == 'g')
char c = text.charAt(++pos.index); && (text.length() - start) >= GMT.length()
if (c < '0' || c > '9') { /* must be from '0' to '9'. */ && text.regionMatches(true, start, GMT, 0, GMT.length())) {
break parsing; pos.index = start + GMT.length();
}
num = c - '0'; if ((text.length() - pos.index) > 0) {
c = text.charAt(pos.index);
if (text.charAt(++pos.index) != ':') { if (c == '+') {
c = text.charAt(pos.index); sign = 1;
if (c < '0' || c > '9') { /* must be from '0' to '9'. */ } else if (c == '-') {
break parsing; sign = -1;
}
} }
num *= 10;
num += c - '0';
pos.index++;
}
if (num > 23) {
--pos.index;
break parsing;
}
if (text.charAt(pos.index) != ':') {
break parsing;
}
// Look for minutes. if (sign == 0) { /* "GMT" without offset */
offset = num * 60; calb.set(Calendar.ZONE_OFFSET, 0)
c = text.charAt(++pos.index); .set(Calendar.DST_OFFSET, 0);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */ return pos.index;
break parsing; }
}
num = c - '0';
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
num *= 10;
num += c - '0';
if (num > 59) { // Parse the rest as "hh:mm"
break parsing; int i = subParseNumericZone(text, ++pos.index,
} sign, 0, true, calb);
} catch (StringIndexOutOfBoundsException e) { if (i > 0) {
break parsing; return i;
} }
offset += num; pos.index = -i;
// Fall through for final processing below of 'offset' and 'sign'.
} else {
// If the first character is a sign, look for numeric timezones of
// the form [+-]hhmm as specified by RFC 822. Otherwise, check
// for named time zones by looking through the locale data from
// the TimeZoneNames strings.
try {
char c = text.charAt(pos.index);
if (c == '+') {
sign = 1;
} else if (c == '-') {
sign = -1;
} else { } else {
// Try parsing the text as a time zone name (abbr). // Try parsing the text as a time zone
// name or abbreviation.
int i = subParseZoneString(text, pos.index, calb); int i = subParseZoneString(text, pos.index, calb);
if (i != 0) { if (i > 0) {
return i; return i;
} }
break parsing; pos.index = -i;
}
// Parse the text as an RFC 822 time zone string. This code is
// actually a little more permissive than RFC 822. It will
// try to do its best with numbers that aren't strictly 4
// digits long.
// Look for hh.
int hours = 0;
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
} }
hours = c - '0'; } else {
c = text.charAt(++pos.index); // Parse the rest as "hhmm" (RFC 822)
if (c < '0' || c > '9') { /* must be from '0' to '9'. */ int i = subParseNumericZone(text, ++pos.index,
break parsing; sign, 0, false, calb);
} if (i > 0) {
hours *= 10; return i;
hours += c - '0';
if (hours > 23) {
break parsing;
}
// Look for mm.
int minutes = 0;
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
minutes = c - '0';
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
minutes *= 10;
minutes += c - '0';
if (minutes > 59) {
break parsing;
} }
pos.index = -i;
offset = hours * 60 + minutes;
} catch (StringIndexOutOfBoundsException e) {
break parsing;
} }
} } catch (IndexOutOfBoundsException e) {
// Do the final processing for both of the above cases. We only
// arrive here if the form GMT+/-... or an RFC 822 form was seen.
if (sign != 0) {
offset *= MILLIS_PER_MINUTE * sign;
calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
return ++pos.index;
} }
} }
break parsing; break parsing;
case PATTERN_ISO_ZONE: // 'X' case PATTERN_ISO_ZONE: // 'X'
{ {
int sign = 0; if ((text.length() - pos.index) <= 0) {
int offset = 0; break parsing;
iso8601: {
try {
char c = text.charAt(pos.index);
if (c == 'Z') {
calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
return ++pos.index;
}
// parse text as "+/-hh[[:]mm]" based on count
if (c == '+') {
sign = 1;
} else if (c == '-') {
sign = -1;
}
// Look for hh.
int hours = 0;
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
hours = c - '0';
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
hours *= 10;
hours += c - '0';
if (hours > 23) {
break parsing;
}
if (count == 1) { // "X"
offset = hours * 60;
break iso8601;
}
c = text.charAt(++pos.index);
// Skip ':' if "XXX"
if (c == ':') {
if (count == 2) {
break parsing;
}
c = text.charAt(++pos.index);
} else {
if (count == 3) {
// missing ':'
break parsing;
}
}
// Look for mm.
int minutes = 0;
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
minutes = c - '0';
c = text.charAt(++pos.index);
if (c < '0' || c > '9') { /* must be from '0' to '9'. */
break parsing;
}
minutes *= 10;
minutes += c - '0';
if (minutes > 59) {
break parsing;
}
offset = hours * 60 + minutes;
} catch (StringIndexOutOfBoundsException e) {
break parsing;
}
} }
// Do the final processing for both of the above cases. We only int sign = 0;
// arrive here if the form GMT+/-... or an RFC 822 form was seen. char c = text.charAt(pos.index);
if (sign != 0) { if (c == 'Z') {
offset *= MILLIS_PER_MINUTE * sign; calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
calb.set(Calendar.ZONE_OFFSET, offset).set(Calendar.DST_OFFSET, 0);
return ++pos.index; return ++pos.index;
} }
// parse text as "+/-hh[[:]mm]" based on count
if (c == '+') {
sign = 1;
} else if (c == '-') {
sign = -1;
} else {
++pos.index;
break parsing;
}
int i = subParseNumericZone(text, ++pos.index, sign, count,
count == 3, calb);
if (i > 0) {
return i;
}
pos.index = -i;
} }
break parsing; break parsing;
......
...@@ -1449,10 +1449,15 @@ public final class Locale implements Cloneable, Serializable { ...@@ -1449,10 +1449,15 @@ public final class Locale implements Cloneable, Serializable {
* three-letter language abbreviation is not available for this locale. * three-letter language abbreviation is not available for this locale.
*/ */
public String getISO3Language() throws MissingResourceException { public String getISO3Language() throws MissingResourceException {
String language3 = getISO3Code(_baseLocale.getLanguage(), LocaleISOData.isoLanguageTable); String lang = _baseLocale.getLanguage();
if (lang.length() == 3) {
return lang;
}
String language3 = getISO3Code(lang, LocaleISOData.isoLanguageTable);
if (language3 == null) { if (language3 == null) {
throw new MissingResourceException("Couldn't find 3-letter language code for " throw new MissingResourceException("Couldn't find 3-letter language code for "
+ _baseLocale.getLanguage(), "FormatData_" + toString(), "ShortLanguage"); + lang, "FormatData_" + toString(), "ShortLanguage");
} }
return language3; return language3;
} }
......
...@@ -52,6 +52,8 @@ import javax.print.attribute.PrintRequestAttribute; ...@@ -52,6 +52,8 @@ import javax.print.attribute.PrintRequestAttribute;
public final class DialogTypeSelection extends EnumSyntax public final class DialogTypeSelection extends EnumSyntax
implements PrintRequestAttribute { implements PrintRequestAttribute {
private static final long serialVersionUID = 7518682952133256029L;
/** /**
* *
*/ */
......
...@@ -310,7 +310,7 @@ public class MidiSystem { ...@@ -310,7 +310,7 @@ public class MidiSystem {
} else { } else {
transmitter = device.getTransmitter(); transmitter = device.getTransmitter();
} }
if (!(transmitter instanceof MidiDeviceReceiver)) { if (!(transmitter instanceof MidiDeviceTransmitter)) {
transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter); transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
} }
return transmitter; return transmitter;
......
...@@ -359,7 +359,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -359,7 +359,22 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
f.getWidth()-1, f.getHeight()-1); f.getWidth()-1, f.getHeight()-1);
} }
g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1); g.drawRect( newX, newY, f.getWidth()-1, f.getHeight()-1);
currentLoc = new Point (newX, newY); /* Work around for 6635462: XOR mode may cause a SurfaceLost on first use.
* Swing doesn't expect that its XOR drawRect did
* not complete, so believes that on re-entering at
* the next update location, that there is an XOR rect
* to draw out at "currentLoc". But in fact
* its now got a new clean surface without that rect,
* so drawing it "out" in fact draws it on, leaving garbage.
* So only update/set currentLoc if the draw completed.
*/
sun.java2d.SurfaceData sData =
((sun.java2d.SunGraphics2D)g).getSurfaceData();
if (!sData.isSurfaceLost()) {
currentLoc = new Point (newX, newY);
}
;
g.dispose(); g.dispose();
} }
} else if (dragMode == FASTER_DRAG_MODE) { } else if (dragMode == FASTER_DRAG_MODE) {
...@@ -412,7 +427,14 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab ...@@ -412,7 +427,14 @@ public class DefaultDesktopManager implements DesktopManager, java.io.Serializab
g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1); g.drawRect( currentBounds.x, currentBounds.y, currentBounds.width-1, currentBounds.height-1);
} }
g.drawRect( newX, newY, newWidth-1, newHeight-1); g.drawRect( newX, newY, newWidth-1, newHeight-1);
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
// Work around for 6635462, see comment in dragFrame()
sun.java2d.SurfaceData sData =
((sun.java2d.SunGraphics2D)g).getSurfaceData();
if (!sData.isSurfaceLost()) {
currentBounds = new Rectangle (newX, newY, newWidth, newHeight);
}
g.setPaintMode(); g.setPaintMode();
g.dispose(); g.dispose();
} }
......
...@@ -40,7 +40,8 @@ import java.beans.*; ...@@ -40,7 +40,8 @@ import java.beans.*;
/** /**
* A component that lets the user graphically select a value by sliding * A component that lets the user graphically select a value by sliding
* a knob within a bounded interval. * a knob within a bounded interval. The knob is always positioned
* at the points that match integer values within the specified interval.
* <p> * <p>
* The slider can show both * The slider can show both
* major tick marks, and minor tick marks between the major ones. The number of * major tick marks, and minor tick marks between the major ones. The number of
......
...@@ -908,6 +908,14 @@ public class BasicSpinnerUI extends SpinnerUI ...@@ -908,6 +908,14 @@ public class BasicSpinnerUI extends SpinnerUI
int height = parent.getHeight(); int height = parent.getHeight();
Insets insets = parent.getInsets(); Insets insets = parent.getInsets();
if (nextButton == null && previousButton == null) {
setBounds(editor, insets.left, insets.top, width - insets.left - insets.right,
height - insets.top - insets.bottom);
return;
}
Dimension nextD = preferredSize(nextButton); Dimension nextD = preferredSize(nextButton);
Dimension previousD = preferredSize(previousButton); Dimension previousD = preferredSize(previousButton);
int buttonsWidth = Math.max(nextD.width, previousD.width); int buttonsWidth = Math.max(nextD.width, previousD.width);
......
/* /*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,10 +37,10 @@ import java.nio.charset.Charset; ...@@ -37,10 +37,10 @@ import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetEncoder;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Properties; import java.util.Properties;
...@@ -329,6 +329,8 @@ public abstract class FontConfiguration { ...@@ -329,6 +329,8 @@ public abstract class FontConfiguration {
* tables. * tables.
*/ */
public static void saveBinary(OutputStream out) throws IOException { public static void saveBinary(OutputStream out) throws IOException {
sanityCheck();
DataOutputStream dataOut = new DataOutputStream(out); DataOutputStream dataOut = new DataOutputStream(out);
writeShortTable(dataOut, head); writeShortTable(dataOut, head);
writeShortTable(dataOut, table_scriptIDs); writeShortTable(dataOut, table_scriptIDs);
...@@ -350,7 +352,6 @@ public abstract class FontConfiguration { ...@@ -350,7 +352,6 @@ public abstract class FontConfiguration {
if (verbose) { if (verbose) {
dump(); dump();
} }
sanityCheck();
} }
//private static boolean loadingProperties; //private static boolean loadingProperties;
...@@ -1343,6 +1344,11 @@ public abstract class FontConfiguration { ...@@ -1343,6 +1344,11 @@ public abstract class FontConfiguration {
private static short[] table_stringIDs; private static short[] table_stringIDs;
private static char[] table_stringTable; private static char[] table_stringTable;
/**
* Checks consistencies of complied fontconfig data. This method
* is called only at the build-time from
* build.tools.compilefontconfig.CompileFontConfig.
*/
private static void sanityCheck() { private static void sanityCheck() {
int errors = 0; int errors = 0;
...@@ -1358,12 +1364,20 @@ public abstract class FontConfiguration { ...@@ -1358,12 +1364,20 @@ public abstract class FontConfiguration {
//componentFontNameID starts from "1" //componentFontNameID starts from "1"
for (int ii = 1; ii < table_filenames.length; ii++) { for (int ii = 1; ii < table_filenames.length; ii++) {
if (table_filenames[ii] == -1) { if (table_filenames[ii] == -1) {
System.out.println("\n Warning: " // The corresponding finename entry for a component
+ "<filename." // font name is mandatory on Windows, but it's
+ getString(table_componentFontNameIDs[ii]) // optional on Solaris and Linux.
+ "> entry is missing!!!"); if (osName.contains("Windows")) {
if (!osName.contains("Linux")) { System.err.println("\n Error: <filename."
+ getString(table_componentFontNameIDs[ii])
+ "> entry is missing!!!");
errors++; errors++;
} else {
if (verbose && !isEmpty(table_filenames)) {
System.err.println("\n Note: 'filename' entry is undefined for \""
+ getString(table_componentFontNameIDs[ii])
+ "\"");
}
} }
} }
} }
...@@ -1382,7 +1396,7 @@ public abstract class FontConfiguration { ...@@ -1382,7 +1396,7 @@ public abstract class FontConfiguration {
int jj = iii * NUM_STYLES + iij; int jj = iii * NUM_STYLES + iij;
short ffid = table_scriptFonts[fid + jj]; short ffid = table_scriptFonts[fid + jj];
if (ffid == 0) { if (ffid == 0) {
System.out.println("\n Error: <" System.err.println("\n Error: <"
+ getFontName(iii) + "." + getFontName(iii) + "."
+ getStyleName(iij) + "." + getStyleName(iij) + "."
+ getString(table_scriptIDs[ii]) + getString(table_scriptIDs[ii])
...@@ -1402,7 +1416,7 @@ public abstract class FontConfiguration { ...@@ -1402,7 +1416,7 @@ public abstract class FontConfiguration {
script.contains("symbol")) { script.contains("symbol")) {
continue; continue;
} }
System.out.println("\nError: " System.err.println("\nError: "
+ "<awtfontpath." + "<awtfontpath."
+ script + script
+ "> entry is missing!!!"); + "> entry is missing!!!");
...@@ -1411,11 +1425,19 @@ public abstract class FontConfiguration { ...@@ -1411,11 +1425,19 @@ public abstract class FontConfiguration {
} }
} }
if (errors != 0) { if (errors != 0) {
System.out.println("!!THERE ARE " + errors + " ERROR(S) IN " System.err.println("!!THERE ARE " + errors + " ERROR(S) IN "
+ "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n");
System.exit(1); System.exit(1);
}
}
private static boolean isEmpty(short[] a) {
for (short s : a) {
if (s != -1) {
return false;
}
} }
return true;
} }
//dump the fontconfig data tables //dump the fontconfig data tables
...@@ -1652,20 +1674,16 @@ public abstract class FontConfiguration { ...@@ -1652,20 +1674,16 @@ public abstract class FontConfiguration {
private static void writeShortTable(DataOutputStream out, short[] data) private static void writeShortTable(DataOutputStream out, short[] data)
throws IOException { throws IOException {
for (int i = 0; i < data.length; i++) { for (short val : data) {
out.writeShort(data[i]); out.writeShort(val);
} }
} }
private static short[] toList(HashMap map) { private static short[] toList(HashMap<String, Short> map) {
short[] list = new short[map.size()]; short[] list = new short[map.size()];
for (int i = 0; i < list.length; i++) { Arrays.fill(list, (short) -1);
list[i] = -1; for (Entry<String, Short> entry : map.entrySet()) {
} list[entry.getValue()] = getStringID(entry.getKey());
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Short> entry = (Entry <String, Short>)iterator.next();
list[entry.getValue().shortValue()] = getStringID(entry.getKey());
} }
return list; return list;
} }
...@@ -1763,25 +1781,19 @@ public abstract class FontConfiguration { ...@@ -1763,25 +1781,19 @@ public abstract class FontConfiguration {
int len = table_scriptIDs.length + scriptFonts.size() * 20; int len = table_scriptIDs.length + scriptFonts.size() * 20;
table_scriptFonts = new short[len]; table_scriptFonts = new short[len];
Iterator iterator = scriptAllfonts.entrySet().iterator(); for (Entry<Short, Short> entry : scriptAllfonts.entrySet()) {
while (iterator.hasNext()) { table_scriptFonts[entry.getKey().intValue()] = entry.getValue();
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
table_scriptFonts[entry.getKey().intValue()] = (short)entry.getValue().shortValue();
} }
int off = table_scriptIDs.length; int off = table_scriptIDs.length;
iterator = scriptFonts.entrySet().iterator(); for (Entry<Short, Short[]> entry : scriptFonts.entrySet()) {
while (iterator.hasNext()) {
Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
table_scriptFonts[entry.getKey().intValue()] = (short)-off; table_scriptFonts[entry.getKey().intValue()] = (short)-off;
Short[] v = entry.getValue(); Short[] v = entry.getValue();
int i = 0; for (int i = 0; i < 20; i++) {
while (i < 20) {
if (v[i] != null) { if (v[i] != null) {
table_scriptFonts[off++] = v[i].shortValue(); table_scriptFonts[off++] = v[i];
} else { } else {
table_scriptFonts[off++] = 0; table_scriptFonts[off++] = 0;
} }
i++;
} }
} }
...@@ -1792,9 +1804,7 @@ public abstract class FontConfiguration { ...@@ -1792,9 +1804,7 @@ public abstract class FontConfiguration {
//(3) sequences elcID -> XXXX[1|5] -> scriptID[] //(3) sequences elcID -> XXXX[1|5] -> scriptID[]
head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length); head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length);
table_sequences = new short[elcIDs.size() * NUM_FONTS]; table_sequences = new short[elcIDs.size() * NUM_FONTS];
iterator = sequences.entrySet().iterator(); for (Entry<Short, short[]> entry : sequences.entrySet()) {
while (iterator.hasNext()) {
Entry<Short, short[]> entry = (Entry <Short, short[]>)iterator.next();
//table_sequences[entry.getKey().intValue()] = (short)-off; //table_sequences[entry.getKey().intValue()] = (short)-off;
int k = entry.getKey().intValue(); int k = entry.getKey().intValue();
short[] v = entry.getValue(); short[] v = entry.getValue();
...@@ -1827,31 +1837,24 @@ public abstract class FontConfiguration { ...@@ -1827,31 +1837,24 @@ public abstract class FontConfiguration {
//(6)componentFontNameID -> filenameID //(6)componentFontNameID -> filenameID
head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length); head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length);
table_filenames = new short[table_componentFontNameIDs.length]; table_filenames = new short[table_componentFontNameIDs.length];
for (int i = 0; i < table_filenames.length; i++) { Arrays.fill(table_filenames, (short) -1);
table_filenames[i] = -1;
} for (Entry<Short, Short> entry : filenames.entrySet()) {
iterator = filenames.entrySet().iterator(); table_filenames[entry.getKey()] = entry.getValue();
while (iterator.hasNext()) {
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
table_filenames[entry.getKey().shortValue()] = entry.getValue().shortValue();
} }
//(7)scriptID-> awtfontpath //(7)scriptID-> awtfontpath
//the paths are stored as scriptID -> stringID in awtfontpahts //the paths are stored as scriptID -> stringID in awtfontpahts
head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length); head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length);
table_awtfontpaths = new short[table_scriptIDs.length]; table_awtfontpaths = new short[table_scriptIDs.length];
iterator = awtfontpaths.entrySet().iterator(); for (Entry<Short, Short> entry : awtfontpaths.entrySet()) {
while (iterator.hasNext()) { table_awtfontpaths[entry.getKey()] = entry.getValue();
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
table_awtfontpaths[entry.getKey().shortValue()] = entry.getValue().shortValue();
} }
//(8)exclusions //(8)exclusions
head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length); head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length);
table_exclusions = new short[scriptIDs.size()]; table_exclusions = new short[scriptIDs.size()];
iterator = exclusions.entrySet().iterator(); for (Entry<Short, int[]> entry : exclusions.entrySet()) {
while (iterator.hasNext()) {
Entry<Short, int[]> entry = (Entry <Short, int[]>)iterator.next();
int[] exI = entry.getValue(); int[] exI = entry.getValue();
char[] exC = new char[exI.length * 2]; char[] exC = new char[exI.length * 2];
int j = 0; int j = 0;
...@@ -1859,17 +1862,15 @@ public abstract class FontConfiguration { ...@@ -1859,17 +1862,15 @@ public abstract class FontConfiguration {
exC[j++] = (char) (exI[i] >> 16); exC[j++] = (char) (exI[i] >> 16);
exC[j++] = (char) (exI[i] & 0xffff); exC[j++] = (char) (exI[i] & 0xffff);
} }
table_exclusions[entry.getKey().shortValue()] = getStringID(new String (exC)); table_exclusions[entry.getKey()] = getStringID(new String (exC));
} }
//(9)proportionals //(9)proportionals
head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length); head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length);
table_proportionals = new short[proportionals.size() * 2]; table_proportionals = new short[proportionals.size() * 2];
iterator = proportionals.entrySet().iterator();
int j = 0; int j = 0;
while (iterator.hasNext()) { for (Entry<Short, Short> entry : proportionals.entrySet()) {
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next(); table_proportionals[j++] = entry.getKey();
table_proportionals[j++] = entry.getKey().shortValue(); table_proportionals[j++] = entry.getValue();
table_proportionals[j++] = entry.getValue().shortValue();
} }
//(10) see (1) for info, the only difference is "xxx.motif" //(10) see (1) for info, the only difference is "xxx.motif"
...@@ -1878,22 +1879,18 @@ public abstract class FontConfiguration { ...@@ -1878,22 +1879,18 @@ public abstract class FontConfiguration {
len = table_scriptIDs.length + scriptFontsMotif.size() * 20; len = table_scriptIDs.length + scriptFontsMotif.size() * 20;
table_scriptFontsMotif = new short[len]; table_scriptFontsMotif = new short[len];
iterator = scriptAllfontsMotif.entrySet().iterator(); for (Entry<Short, Short> entry : scriptAllfontsMotif.entrySet()) {
while (iterator.hasNext()) {
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next();
table_scriptFontsMotif[entry.getKey().intValue()] = table_scriptFontsMotif[entry.getKey().intValue()] =
(short)entry.getValue().shortValue(); (short)entry.getValue();
} }
off = table_scriptIDs.length; off = table_scriptIDs.length;
iterator = scriptFontsMotif.entrySet().iterator(); for (Entry<Short, Short[]> entry : scriptFontsMotif.entrySet()) {
while (iterator.hasNext()) {
Entry<Short, Short[]> entry = (Entry <Short, Short[]>)iterator.next();
table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off; table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off;
Short[] v = entry.getValue(); Short[] v = entry.getValue();
int i = 0; int i = 0;
while (i < 20) { while (i < 20) {
if (v[i] != null) { if (v[i] != null) {
table_scriptFontsMotif[off++] = v[i].shortValue(); table_scriptFontsMotif[off++] = v[i];
} else { } else {
table_scriptFontsMotif[off++] = 0; table_scriptFontsMotif[off++] = 0;
} }
...@@ -1907,12 +1904,10 @@ public abstract class FontConfiguration { ...@@ -1907,12 +1904,10 @@ public abstract class FontConfiguration {
//(11)short[] alphabeticSuffix //(11)short[] alphabeticSuffix
head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length); head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length);
table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2]; table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2];
iterator = alphabeticSuffix.entrySet().iterator();
j = 0; j = 0;
while (iterator.hasNext()) { for (Entry<Short, Short> entry : alphabeticSuffix.entrySet()) {
Entry<Short, Short> entry = (Entry <Short, Short>)iterator.next(); table_alphabeticSuffix[j++] = entry.getKey();
table_alphabeticSuffix[j++] = entry.getKey().shortValue(); table_alphabeticSuffix[j++] = entry.getValue();
table_alphabeticSuffix[j++] = entry.getValue().shortValue();
} }
//(15)short[] fallbackScriptIDs; just put the ID in head //(15)short[] fallbackScriptIDs; just put the ID in head
......
...@@ -102,26 +102,6 @@ public abstract class SunToolkit extends Toolkit ...@@ -102,26 +102,6 @@ public abstract class SunToolkit extends Toolkit
public final static int MAX_BUTTONS_SUPPORTED = 20; public final static int MAX_BUTTONS_SUPPORTED = 20;
public SunToolkit() { public SunToolkit() {
/* If awt.threadgroup is set to class name the instance of
* this class is created (should be subclass of ThreadGroup)
* and EventDispatchThread is created inside of it
*
* If loaded class overrides uncaughtException instance
* handles all uncaught exception on EventDispatchThread
*/
ThreadGroup threadGroup = null;
String tgName = System.getProperty("awt.threadgroup", "");
if (tgName.length() != 0) {
try {
Constructor ctor = Class.forName(tgName).
getConstructor(new Class[] {String.class});
threadGroup = (ThreadGroup)ctor.newInstance(new Object[] {"AWT-ThreadGroup"});
} catch (Exception e) {
System.err.println("Failed loading " + tgName + ": " + e);
}
}
Runnable initEQ = new Runnable() { Runnable initEQ = new Runnable() {
public void run () { public void run () {
EventQueue eventQueue; EventQueue eventQueue;
...@@ -144,17 +124,7 @@ public abstract class SunToolkit extends Toolkit ...@@ -144,17 +124,7 @@ public abstract class SunToolkit extends Toolkit
} }
}; };
if (threadGroup != null) { initEQ.run();
Thread eqInitThread = new Thread(threadGroup, initEQ, "EventQueue-Init");
eqInitThread.start();
try {
eqInitThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
initEQ.run();
}
} }
public boolean useBufferPerWindow() { public boolean useBufferPerWindow() {
......
...@@ -635,6 +635,88 @@ public class DuctusRenderingEngine extends RenderingEngine { ...@@ -635,6 +635,88 @@ public class DuctusRenderingEngine extends RenderingEngine {
return r; return r;
} }
/**
* {@inheritDoc}
*/
@Override
public AATileGenerator getAATileGenerator(double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2,
Region clip,
int bbox[])
{
// REMIND: Deal with large coordinates!
double ldx1, ldy1, ldx2, ldy2;
boolean innerpgram = (lw1 > 0 && lw2 > 0);
if (innerpgram) {
ldx1 = dx1 * lw1;
ldy1 = dy1 * lw1;
ldx2 = dx2 * lw2;
ldy2 = dy2 * lw2;
x -= (ldx1 + ldx2) / 2.0;
y -= (ldy1 + ldy2) / 2.0;
dx1 += ldx1;
dy1 += ldy1;
dx2 += ldx2;
dy2 += ldy2;
if (lw1 > 1 && lw2 > 1) {
// Inner parallelogram was entirely consumed by stroke...
innerpgram = false;
}
} else {
ldx1 = ldy1 = ldx2 = ldy2 = 0;
}
Rasterizer r = getRasterizer();
r.setUsage(Rasterizer.EOFILL);
r.beginPath();
r.beginSubpath((float) x, (float) y);
r.appendLine((float) (x+dx1), (float) (y+dy1));
r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
r.appendLine((float) (x+dx2), (float) (y+dy2));
r.closedSubpath();
if (innerpgram) {
x += ldx1 + ldx2;
y += ldy1 + ldy2;
dx1 -= 2.0 * ldx1;
dy1 -= 2.0 * ldy1;
dx2 -= 2.0 * ldx2;
dy2 -= 2.0 * ldy2;
r.beginSubpath((float) x, (float) y);
r.appendLine((float) (x+dx1), (float) (y+dy1));
r.appendLine((float) (x+dx1+dx2), (float) (y+dy1+dy2));
r.appendLine((float) (x+dx2), (float) (y+dy2));
r.closedSubpath();
}
try {
r.endPath();
r.getAlphaBox(bbox);
clip.clipBoxToBounds(bbox);
if (bbox[0] >= bbox[2] || bbox[1] >= bbox[3]) {
dropRasterizer(r);
return null;
}
r.setOutputArea(bbox[0], bbox[1],
bbox[2] - bbox[0],
bbox[3] - bbox[1]);
} catch (PRException e) {
/*
* This exeption is thrown from the native part of the Ductus
* (only in case of a debug build) to indicate that some
* segments of the path have very large coordinates.
* See 4485298 for more info.
*/
System.err.println("DuctusRenderingEngine.getAATileGenerator: "+e);
}
return r;
}
private void feedConsumer(PathConsumer consumer, PathIterator pi) { private void feedConsumer(PathConsumer consumer, PathIterator pi) {
try { try {
consumer.beginPath(); consumer.beginPath();
......
...@@ -58,10 +58,10 @@ public class FileFontStrike extends PhysicalStrike { ...@@ -58,10 +58,10 @@ public class FileFontStrike extends PhysicalStrike {
private static final int SEGINTARRAY = 3; private static final int SEGINTARRAY = 3;
private static final int SEGLONGARRAY = 4; private static final int SEGLONGARRAY = 4;
private int glyphCacheFormat = UNINITIALISED; private volatile int glyphCacheFormat = UNINITIALISED;
/* segmented arrays are blocks of 256 */ /* segmented arrays are blocks of 32 */
private static final int SEGSHIFT = 8; private static final int SEGSHIFT = 5;
private static final int SEGSIZE = 1 << SEGSHIFT; private static final int SEGSIZE = 1 << SEGSHIFT;
private boolean segmentedCache; private boolean segmentedCache;
...@@ -171,7 +171,7 @@ public class FileFontStrike extends PhysicalStrike { ...@@ -171,7 +171,7 @@ public class FileFontStrike extends PhysicalStrike {
mapper = fileFont.getMapper(); mapper = fileFont.getMapper();
int numGlyphs = mapper.getNumGlyphs(); int numGlyphs = mapper.getNumGlyphs();
/* Always segment for fonts with > 2K glyphs, but also for smaller /* Always segment for fonts with > 256 glyphs, but also for smaller
* fonts with non-typical sizes and transforms. * fonts with non-typical sizes and transforms.
* Segmenting for all non-typical pt sizes helps to minimise memory * Segmenting for all non-typical pt sizes helps to minimise memory
* usage when very many distinct strikes are created. * usage when very many distinct strikes are created.
...@@ -522,32 +522,33 @@ public class FileFontStrike extends PhysicalStrike { ...@@ -522,32 +522,33 @@ public class FileFontStrike extends PhysicalStrike {
} }
/* Called only from synchronized code or constructor */ /* Called only from synchronized code or constructor */
private void initGlyphCache() { private synchronized void initGlyphCache() {
int numGlyphs = mapper.getNumGlyphs(); int numGlyphs = mapper.getNumGlyphs();
int tmpFormat = UNINITIALISED;
if (segmentedCache) { if (segmentedCache) {
int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE; int numSegments = (numGlyphs + SEGSIZE-1)/SEGSIZE;
if (longAddresses) { if (longAddresses) {
glyphCacheFormat = SEGLONGARRAY; tmpFormat = SEGLONGARRAY;
segLongGlyphImages = new long[numSegments][]; segLongGlyphImages = new long[numSegments][];
this.disposer.segLongGlyphImages = segLongGlyphImages; this.disposer.segLongGlyphImages = segLongGlyphImages;
} else { } else {
glyphCacheFormat = SEGINTARRAY; tmpFormat = SEGINTARRAY;
segIntGlyphImages = new int[numSegments][]; segIntGlyphImages = new int[numSegments][];
this.disposer.segIntGlyphImages = segIntGlyphImages; this.disposer.segIntGlyphImages = segIntGlyphImages;
} }
} else { } else {
if (longAddresses) { if (longAddresses) {
glyphCacheFormat = LONGARRAY; tmpFormat = LONGARRAY;
longGlyphImages = new long[numGlyphs]; longGlyphImages = new long[numGlyphs];
this.disposer.longGlyphImages = longGlyphImages; this.disposer.longGlyphImages = longGlyphImages;
} else { } else {
glyphCacheFormat = INTARRAY; tmpFormat = INTARRAY;
intGlyphImages = new int[numGlyphs]; intGlyphImages = new int[numGlyphs];
this.disposer.intGlyphImages = intGlyphImages; this.disposer.intGlyphImages = intGlyphImages;
} }
} }
glyphCacheFormat = tmpFormat;
} }
float getGlyphAdvance(int glyphCode) { float getGlyphAdvance(int glyphCode) {
......
...@@ -343,7 +343,21 @@ public abstract class Font2D { ...@@ -343,7 +343,21 @@ public abstract class Font2D {
} }
strike = createStrike(desc); strike = createStrike(desc);
//StrikeCache.addStrike(); //StrikeCache.addStrike();
strikeRef = StrikeCache.getStrikeRef(strike); /* If we are creating many strikes on this font which
* involve non-quadrant rotations, or more general
* transforms which include shears, then force the use
* of weak references rather than soft references.
* This means that it won't live much beyond the next GC,
* which is what we want for what is likely a transient strike.
*/
int txType = desc.glyphTx.getType();
if (txType == AffineTransform.TYPE_GENERAL_TRANSFORM ||
(txType & AffineTransform.TYPE_GENERAL_ROTATION) != 0 &&
strikeCache.size() > 10) {
strikeRef = StrikeCache.getStrikeRef(strike, true);
} else {
strikeRef = StrikeCache.getStrikeRef(strike);
}
strikeCache.put(desc, strikeRef); strikeCache.put(desc, strikeRef);
//strike.lastlookupTime = System.currentTimeMillis(); //strike.lastlookupTime = System.currentTimeMillis();
lastFontStrike = new SoftReference(strike); lastFontStrike = new SoftReference(strike);
......
...@@ -367,16 +367,17 @@ public abstract class SurfaceData ...@@ -367,16 +367,17 @@ public abstract class SurfaceData
public static final TextPipe aaTextRenderer; public static final TextPipe aaTextRenderer;
public static final TextPipe lcdTextRenderer; public static final TextPipe lcdTextRenderer;
protected static final CompositePipe colorPipe; protected static final AlphaColorPipe colorPipe;
protected static final PixelToShapeConverter colorViaShape; protected static final PixelToShapeConverter colorViaShape;
protected static final PixelToParallelogramConverter colorViaPgram; protected static final PixelToParallelogramConverter colorViaPgram;
protected static final TextPipe colorText; protected static final TextPipe colorText;
protected static final CompositePipe clipColorPipe; protected static final CompositePipe clipColorPipe;
protected static final TextPipe clipColorText; protected static final TextPipe clipColorText;
protected static final AAShapePipe AAColorShape; protected static final AAShapePipe AAColorShape;
protected static final PixelToShapeConverter AAColorViaShape; protected static final PixelToParallelogramConverter AAColorViaShape;
protected static final PixelToParallelogramConverter AAColorViaPgram;
protected static final AAShapePipe AAClipColorShape; protected static final AAShapePipe AAClipColorShape;
protected static final PixelToShapeConverter AAClipColorViaShape; protected static final PixelToParallelogramConverter AAClipColorViaShape;
protected static final CompositePipe paintPipe; protected static final CompositePipe paintPipe;
protected static final SpanShapeRenderer paintShape; protected static final SpanShapeRenderer paintShape;
...@@ -385,9 +386,9 @@ public abstract class SurfaceData ...@@ -385,9 +386,9 @@ public abstract class SurfaceData
protected static final CompositePipe clipPaintPipe; protected static final CompositePipe clipPaintPipe;
protected static final TextPipe clipPaintText; protected static final TextPipe clipPaintText;
protected static final AAShapePipe AAPaintShape; protected static final AAShapePipe AAPaintShape;
protected static final PixelToShapeConverter AAPaintViaShape; protected static final PixelToParallelogramConverter AAPaintViaShape;
protected static final AAShapePipe AAClipPaintShape; protected static final AAShapePipe AAClipPaintShape;
protected static final PixelToShapeConverter AAClipPaintViaShape; protected static final PixelToParallelogramConverter AAClipPaintViaShape;
protected static final CompositePipe compPipe; protected static final CompositePipe compPipe;
protected static final SpanShapeRenderer compShape; protected static final SpanShapeRenderer compShape;
...@@ -396,9 +397,9 @@ public abstract class SurfaceData ...@@ -396,9 +397,9 @@ public abstract class SurfaceData
protected static final CompositePipe clipCompPipe; protected static final CompositePipe clipCompPipe;
protected static final TextPipe clipCompText; protected static final TextPipe clipCompText;
protected static final AAShapePipe AACompShape; protected static final AAShapePipe AACompShape;
protected static final PixelToShapeConverter AACompViaShape; protected static final PixelToParallelogramConverter AACompViaShape;
protected static final AAShapePipe AAClipCompShape; protected static final AAShapePipe AAClipCompShape;
protected static final PixelToShapeConverter AAClipCompViaShape; protected static final PixelToParallelogramConverter AAClipCompViaShape;
protected static final DrawImagePipe imagepipe; protected static final DrawImagePipe imagepipe;
...@@ -427,6 +428,22 @@ public abstract class SurfaceData ...@@ -427,6 +428,22 @@ public abstract class SurfaceData
} }
} }
private static PixelToParallelogramConverter
makeConverter(AAShapePipe renderer,
ParallelogramPipe pgrampipe)
{
return new PixelToParallelogramConverter(renderer,
pgrampipe,
1.0/8.0, 0.499,
false);
}
private static PixelToParallelogramConverter
makeConverter(AAShapePipe renderer)
{
return makeConverter(renderer, renderer);
}
static { static {
colorPrimitives = new LoopPipe(); colorPrimitives = new LoopPipe();
...@@ -445,9 +462,10 @@ public abstract class SurfaceData ...@@ -445,9 +462,10 @@ public abstract class SurfaceData
clipColorPipe = new SpanClipRenderer(colorPipe); clipColorPipe = new SpanClipRenderer(colorPipe);
clipColorText = new TextRenderer(clipColorPipe); clipColorText = new TextRenderer(clipColorPipe);
AAColorShape = new AAShapePipe(colorPipe); AAColorShape = new AAShapePipe(colorPipe);
AAColorViaShape = new PixelToShapeConverter(AAColorShape); AAColorViaShape = makeConverter(AAColorShape);
AAColorViaPgram = makeConverter(AAColorShape, colorPipe);
AAClipColorShape = new AAShapePipe(clipColorPipe); AAClipColorShape = new AAShapePipe(clipColorPipe);
AAClipColorViaShape = new PixelToShapeConverter(AAClipColorShape); AAClipColorViaShape = makeConverter(AAClipColorShape);
paintPipe = new AlphaPaintPipe(); paintPipe = new AlphaPaintPipe();
paintShape = new SpanShapeRenderer.Composite(paintPipe); paintShape = new SpanShapeRenderer.Composite(paintPipe);
...@@ -456,9 +474,9 @@ public abstract class SurfaceData ...@@ -456,9 +474,9 @@ public abstract class SurfaceData
clipPaintPipe = new SpanClipRenderer(paintPipe); clipPaintPipe = new SpanClipRenderer(paintPipe);
clipPaintText = new TextRenderer(clipPaintPipe); clipPaintText = new TextRenderer(clipPaintPipe);
AAPaintShape = new AAShapePipe(paintPipe); AAPaintShape = new AAShapePipe(paintPipe);
AAPaintViaShape = new PixelToShapeConverter(AAPaintShape); AAPaintViaShape = makeConverter(AAPaintShape);
AAClipPaintShape = new AAShapePipe(clipPaintPipe); AAClipPaintShape = new AAShapePipe(clipPaintPipe);
AAClipPaintViaShape = new PixelToShapeConverter(AAClipPaintShape); AAClipPaintViaShape = makeConverter(AAClipPaintShape);
compPipe = new GeneralCompositePipe(); compPipe = new GeneralCompositePipe();
compShape = new SpanShapeRenderer.Composite(compPipe); compShape = new SpanShapeRenderer.Composite(compPipe);
...@@ -467,9 +485,9 @@ public abstract class SurfaceData ...@@ -467,9 +485,9 @@ public abstract class SurfaceData
clipCompPipe = new SpanClipRenderer(compPipe); clipCompPipe = new SpanClipRenderer(compPipe);
clipCompText = new TextRenderer(clipCompPipe); clipCompText = new TextRenderer(clipCompPipe);
AACompShape = new AAShapePipe(compPipe); AACompShape = new AAShapePipe(compPipe);
AACompViaShape = new PixelToShapeConverter(AACompShape); AACompViaShape = makeConverter(AACompShape);
AAClipCompShape = new AAShapePipe(clipCompPipe); AAClipCompShape = new AAShapePipe(clipCompPipe);
AAClipCompViaShape = new PixelToShapeConverter(AAClipCompShape); AAClipCompViaShape = makeConverter(AAClipCompShape);
imagepipe = new DrawImage(); imagepipe = new DrawImage();
} }
...@@ -591,12 +609,12 @@ public abstract class SurfaceData ...@@ -591,12 +609,12 @@ public abstract class SurfaceData
if (sg2d.clipState == sg2d.CLIP_SHAPE) { if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipCompViaShape; sg2d.drawpipe = AAClipCompViaShape;
sg2d.fillpipe = AAClipCompViaShape; sg2d.fillpipe = AAClipCompViaShape;
sg2d.shapepipe = AAClipCompShape; sg2d.shapepipe = AAClipCompViaShape;
sg2d.textpipe = clipCompText; sg2d.textpipe = clipCompText;
} else { } else {
sg2d.drawpipe = AACompViaShape; sg2d.drawpipe = AACompViaShape;
sg2d.fillpipe = AACompViaShape; sg2d.fillpipe = AACompViaShape;
sg2d.shapepipe = AACompShape; sg2d.shapepipe = AACompViaShape;
sg2d.textpipe = compText; sg2d.textpipe = compText;
} }
} else { } else {
...@@ -616,13 +634,17 @@ public abstract class SurfaceData ...@@ -616,13 +634,17 @@ public abstract class SurfaceData
if (sg2d.clipState == sg2d.CLIP_SHAPE) { if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipColorViaShape; sg2d.drawpipe = AAClipColorViaShape;
sg2d.fillpipe = AAClipColorViaShape; sg2d.fillpipe = AAClipColorViaShape;
sg2d.shapepipe = AAClipColorShape; sg2d.shapepipe = AAClipColorViaShape;
sg2d.textpipe = clipColorText; sg2d.textpipe = clipColorText;
} else { } else {
sg2d.drawpipe = AAColorViaShape; PixelToParallelogramConverter converter =
sg2d.fillpipe = AAColorViaShape; (sg2d.alphafill.canDoParallelograms()
sg2d.shapepipe = AAColorShape; ? AAColorViaPgram
if (sg2d.paintState > sg2d.PAINT_OPAQUECOLOR || : AAColorViaShape);
sg2d.drawpipe = converter;
sg2d.fillpipe = converter;
sg2d.shapepipe = converter;
if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR ||
sg2d.compositeState > sg2d.COMP_ISCOPY) sg2d.compositeState > sg2d.COMP_ISCOPY)
{ {
sg2d.textpipe = colorText; sg2d.textpipe = colorText;
...@@ -634,12 +656,12 @@ public abstract class SurfaceData ...@@ -634,12 +656,12 @@ public abstract class SurfaceData
if (sg2d.clipState == sg2d.CLIP_SHAPE) { if (sg2d.clipState == sg2d.CLIP_SHAPE) {
sg2d.drawpipe = AAClipPaintViaShape; sg2d.drawpipe = AAClipPaintViaShape;
sg2d.fillpipe = AAClipPaintViaShape; sg2d.fillpipe = AAClipPaintViaShape;
sg2d.shapepipe = AAClipPaintShape; sg2d.shapepipe = AAClipPaintViaShape;
sg2d.textpipe = clipPaintText; sg2d.textpipe = clipPaintText;
} else { } else {
sg2d.drawpipe = AAPaintViaShape; sg2d.drawpipe = AAPaintViaShape;
sg2d.fillpipe = AAPaintViaShape; sg2d.fillpipe = AAPaintViaShape;
sg2d.shapepipe = AAPaintShape; sg2d.shapepipe = AAPaintViaShape;
sg2d.textpipe = paintText; sg2d.textpipe = paintText;
} }
} }
...@@ -793,6 +815,18 @@ public abstract class SurfaceData ...@@ -793,6 +815,18 @@ public abstract class SurfaceData
} }
} }
private static CompositeType getFillCompositeType(SunGraphics2D sg2d) {
CompositeType compType = sg2d.imageComp;
if (sg2d.compositeState == sg2d.COMP_ISCOPY) {
if (compType == CompositeType.SrcOverNoEa) {
compType = CompositeType.OpaqueSrcOverNoEa;
} else {
compType = CompositeType.SrcNoEa;
}
}
return compType;
}
/** /**
* Returns a MaskFill object that can be used on this destination * Returns a MaskFill object that can be used on this destination
* with the source (paint) and composite types determined by the given * with the source (paint) and composite types determined by the given
...@@ -802,9 +836,10 @@ public abstract class SurfaceData ...@@ -802,9 +836,10 @@ public abstract class SurfaceData
* surface) before returning a specific MaskFill object. * surface) before returning a specific MaskFill object.
*/ */
protected MaskFill getMaskFill(SunGraphics2D sg2d) { protected MaskFill getMaskFill(SunGraphics2D sg2d) {
return MaskFill.getFromCache(getPaintSurfaceType(sg2d), SurfaceType src = getPaintSurfaceType(sg2d);
sg2d.imageComp, CompositeType comp = getFillCompositeType(sg2d);
getSurfaceType()); SurfaceType dst = getSurfaceType();
return MaskFill.getFromCache(src, comp, dst);
} }
private static RenderCache loopcache = new RenderCache(30); private static RenderCache loopcache = new RenderCache(30);
...@@ -816,9 +851,7 @@ public abstract class SurfaceData ...@@ -816,9 +851,7 @@ public abstract class SurfaceData
*/ */
public RenderLoops getRenderLoops(SunGraphics2D sg2d) { public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
SurfaceType src = getPaintSurfaceType(sg2d); SurfaceType src = getPaintSurfaceType(sg2d);
CompositeType comp = (sg2d.compositeState == sg2d.COMP_ISCOPY CompositeType comp = getFillCompositeType(sg2d);
? CompositeType.SrcNoEa
: sg2d.imageComp);
SurfaceType dst = sg2d.getSurfaceData().getSurfaceType(); SurfaceType dst = sg2d.getSurfaceData().getSurfaceType();
Object o = loopcache.get(src, comp, dst); Object o = loopcache.get(src, comp, dst);
......
...@@ -27,6 +27,7 @@ package sun.java2d.loops; ...@@ -27,6 +27,7 @@ package sun.java2d.loops;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.util.HashMap;
/** /**
* A CompositeType object provides a chained description of a type of * A CompositeType object provides a chained description of a type of
...@@ -51,6 +52,11 @@ import java.awt.AlphaComposite; ...@@ -51,6 +52,11 @@ import java.awt.AlphaComposite;
* the indicated algorithm if all of the more specific searches fail. * the indicated algorithm if all of the more specific searches fail.
*/ */
public final class CompositeType { public final class CompositeType {
private static int unusedUID = 1;
private static final HashMap<String,Integer> compositeUIDMap =
new HashMap<String,Integer>(100);
/* /*
* CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE COMPOSITING
* ALGORITHMS THEY CAN PERFORM * ALGORITHMS THEY CAN PERFORM
...@@ -152,6 +158,22 @@ public final class CompositeType { ...@@ -152,6 +158,22 @@ public final class CompositeType {
public static final CompositeType public static final CompositeType
SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA); SrcOverNoEa = SrcOver.deriveSubType(DESC_SRC_OVER_NO_EA);
/*
* A special CompositeType for the case where we are filling in
* SrcOverNoEa mode with an opaque color. In that case then the
* best loop for us to use would be a SrcNoEa loop, but what if
* there is no such loop? In that case then we would end up
* backing off to a Src loop (which should still be fine) or an
* AnyAlpha loop which would be slower than a SrcOver loop in
* most cases.
* The fix is to use the following chain which looks for loops
* in the following order:
* SrcNoEa, Src, SrcOverNoEa, SrcOver, AnyAlpha
*/
public static final CompositeType
OpaqueSrcOverNoEa = SrcOverNoEa.deriveSubType(DESC_SRC)
.deriveSubType(DESC_SRC_NO_EA);
/* /*
* END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS * END OF CompositeType OBJECTS FOR THE VARIOUS CONSTANTS
*/ */
...@@ -210,7 +232,6 @@ public final class CompositeType { ...@@ -210,7 +232,6 @@ public final class CompositeType {
} }
} }
private static int unusedUID = 1;
private int uniqueID; private int uniqueID;
private String desc; private String desc;
private CompositeType next; private CompositeType next;
...@@ -218,14 +239,20 @@ public final class CompositeType { ...@@ -218,14 +239,20 @@ public final class CompositeType {
private CompositeType(CompositeType parent, String desc) { private CompositeType(CompositeType parent, String desc) {
next = parent; next = parent;
this.desc = desc; this.desc = desc;
this.uniqueID = makeUniqueID(); this.uniqueID = makeUniqueID(desc);
} }
private synchronized static final int makeUniqueID() { public synchronized static final int makeUniqueID(String desc) {
if (unusedUID > 255) { Integer i = compositeUIDMap.get(desc);
throw new InternalError("composite type id overflow");
if (i == null) {
if (unusedUID > 255) {
throw new InternalError("composite type id overflow");
}
i = unusedUID++;
compositeUIDMap.put(desc, i);
} }
return unusedUID++; return i;
} }
public int getUniqueID() { public int getUniqueID() {
......
...@@ -50,6 +50,10 @@ import sun.java2d.SurfaceData; ...@@ -50,6 +50,10 @@ import sun.java2d.SurfaceData;
public class MaskFill extends GraphicsPrimitive public class MaskFill extends GraphicsPrimitive
{ {
public static final String methodSignature = "MaskFill(...)".toString(); public static final String methodSignature = "MaskFill(...)".toString();
public static final String fillPgramSignature =
"FillAAPgram(...)".toString();
public static final String drawPgramSignature =
"DrawAAPgram(...)".toString();
public static final int primTypeID = makePrimTypeID(); public static final int primTypeID = makePrimTypeID();
...@@ -92,6 +96,14 @@ public class MaskFill extends GraphicsPrimitive ...@@ -92,6 +96,14 @@ public class MaskFill extends GraphicsPrimitive
return fill; return fill;
} }
protected MaskFill(String alternateSignature,
SurfaceType srctype,
CompositeType comptype,
SurfaceType dsttype)
{
super(alternateSignature, primTypeID, srctype, comptype, dsttype);
}
protected MaskFill(SurfaceType srctype, protected MaskFill(SurfaceType srctype,
CompositeType comptype, CompositeType comptype,
SurfaceType dsttype) SurfaceType dsttype)
...@@ -115,6 +127,23 @@ public class MaskFill extends GraphicsPrimitive ...@@ -115,6 +127,23 @@ public class MaskFill extends GraphicsPrimitive
int x, int y, int w, int h, int x, int y, int w, int h,
byte[] mask, int maskoff, int maskscan); byte[] mask, int maskoff, int maskscan);
public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
Composite comp,
double x, double y,
double dx1, double dy1,
double dx2, double dy2);
public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
Composite comp,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2);
public boolean canDoParallelograms() {
return (getNativePrim() != 0);
}
static { static {
GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null)); GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null));
} }
...@@ -182,12 +211,22 @@ public class MaskFill extends GraphicsPrimitive ...@@ -182,12 +211,22 @@ public class MaskFill extends GraphicsPrimitive
private static class TraceMaskFill extends MaskFill { private static class TraceMaskFill extends MaskFill {
MaskFill target; MaskFill target;
MaskFill fillPgramTarget;
MaskFill drawPgramTarget;
public TraceMaskFill(MaskFill target) { public TraceMaskFill(MaskFill target) {
super(target.getSourceType(), super(target.getSourceType(),
target.getCompositeType(), target.getCompositeType(),
target.getDestType()); target.getDestType());
this.target = target; this.target = target;
this.fillPgramTarget = new MaskFill(fillPgramSignature,
target.getSourceType(),
target.getCompositeType(),
target.getDestType());
this.drawPgramTarget = new MaskFill(drawPgramSignature,
target.getSourceType(),
target.getCompositeType(),
target.getDestType());
} }
public GraphicsPrimitive traceWrap() { public GraphicsPrimitive traceWrap() {
...@@ -203,5 +242,32 @@ public class MaskFill extends GraphicsPrimitive ...@@ -203,5 +242,32 @@ public class MaskFill extends GraphicsPrimitive
target.MaskFill(sg2d, sData, comp, x, y, w, h, target.MaskFill(sg2d, sData, comp, x, y, w, h,
mask, maskoff, maskscan); mask, maskoff, maskscan);
} }
public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,
Composite comp,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
tracePrimitive(fillPgramTarget);
target.FillAAPgram(sg2d, sData, comp,
x, y, dx1, dy1, dx2, dy2);
}
public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,
Composite comp,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
tracePrimitive(drawPgramTarget);
target.DrawAAPgram(sg2d, sData, comp,
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
}
public boolean canDoParallelograms() {
return target.canDoParallelograms();
}
} }
} }
...@@ -28,6 +28,7 @@ package sun.java2d.pipe; ...@@ -28,6 +28,7 @@ package sun.java2d.pipe;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.geom.PathIterator; import java.awt.geom.PathIterator;
import sun.awt.SunHints; import sun.awt.SunHints;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
...@@ -39,7 +40,9 @@ import sun.java2d.SunGraphics2D; ...@@ -39,7 +40,9 @@ import sun.java2d.SunGraphics2D;
* This class sets up the Generator and computes the alpha tiles * This class sets up the Generator and computes the alpha tiles
* and then passes them on to a CompositePipe object for painting. * and then passes them on to a CompositePipe object for painting.
*/ */
public class AAShapePipe implements ShapeDrawPipe { public class AAShapePipe
implements ShapeDrawPipe, ParallelogramPipe
{
static RenderingEngine renderengine = RenderingEngine.getInstance(); static RenderingEngine renderengine = RenderingEngine.getInstance();
CompositePipe outpipe; CompositePipe outpipe;
...@@ -65,6 +68,59 @@ public class AAShapePipe implements ShapeDrawPipe { ...@@ -65,6 +68,59 @@ public class AAShapePipe implements ShapeDrawPipe {
renderPath(sg, s, null); renderPath(sg, s, null);
} }
private static Rectangle2D computeBBox(double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
double lox, loy, hix, hiy;
lox = hix = x;
loy = hiy = y;
if (dx1 < 0) { lox += dx1; } else { hix += dx1; }
if (dy1 < 0) { loy += dy1; } else { hiy += dy1; }
if (dx2 < 0) { lox += dx2; } else { hix += dx2; }
if (dy2 < 0) { loy += dy2; } else { hiy += dy2; }
return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy);
}
public void fillParallelogram(SunGraphics2D sg,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
Region clip = sg.getCompClip();
int abox[] = new int[4];
AATileGenerator aatg =
renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
clip, abox);
if (aatg == null) {
// Nothing to render
return;
}
renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
}
public void drawParallelogram(SunGraphics2D sg,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
Region clip = sg.getCompClip();
int abox[] = new int[4];
AATileGenerator aatg =
renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0,
clip, abox);
if (aatg == null) {
// Nothing to render
return;
}
// Note that bbox is of the original shape, not the wide path.
// This is appropriate for handing to Paint methods...
renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
}
private static byte[] theTile; private static byte[] theTile;
public synchronized static byte[] getAlphaTile(int len) { public synchronized static byte[] getAlphaTile(int len) {
...@@ -85,8 +141,6 @@ public class AAShapePipe implements ShapeDrawPipe { ...@@ -85,8 +141,6 @@ public class AAShapePipe implements ShapeDrawPipe {
boolean adjust = (bs != null && boolean adjust = (bs != null &&
sg.strokeHint != SunHints.INTVAL_STROKE_PURE); sg.strokeHint != SunHints.INTVAL_STROKE_PURE);
boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED); boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED);
Object context = null;
byte alpha[] = null;
Region clip = sg.getCompClip(); Region clip = sg.getCompClip();
int abox[] = new int[4]; int abox[] = new int[4];
...@@ -98,6 +152,14 @@ public class AAShapePipe implements ShapeDrawPipe { ...@@ -98,6 +152,14 @@ public class AAShapePipe implements ShapeDrawPipe {
return; return;
} }
renderTiles(sg, s, aatg, abox);
}
public void renderTiles(SunGraphics2D sg, Shape s,
AATileGenerator aatg, int abox[])
{
Object context = null;
byte alpha[] = null;
try { try {
context = outpipe.startSequence(sg, s, context = outpipe.startSequence(sg, s,
new Rectangle(abox[0], abox[1], new Rectangle(abox[0], abox[1],
......
...@@ -34,7 +34,7 @@ import sun.java2d.SunGraphics2D; ...@@ -34,7 +34,7 @@ import sun.java2d.SunGraphics2D;
* into a destination that supports direct alpha compositing of a solid * into a destination that supports direct alpha compositing of a solid
* color, according to one of the rules in the AlphaComposite class. * color, according to one of the rules in the AlphaComposite class.
*/ */
public class AlphaColorPipe implements CompositePipe { public class AlphaColorPipe implements CompositePipe, ParallelogramPipe {
public AlphaColorPipe() { public AlphaColorPipe() {
} }
...@@ -64,4 +64,23 @@ public class AlphaColorPipe implements CompositePipe { ...@@ -64,4 +64,23 @@ public class AlphaColorPipe implements CompositePipe {
public void endSequence(Object context) { public void endSequence(Object context) {
return; return;
} }
public void fillParallelogram(SunGraphics2D sg,
double x, double y,
double dx1, double dy1,
double dx2, double dy2)
{
sg.alphafill.FillAAPgram(sg, sg.getSurfaceData(), sg.composite,
x, y, dx1, dy1, dx2, dy2);
}
public void drawParallelogram(SunGraphics2D sg,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2)
{
sg.alphafill.DrawAAPgram(sg, sg.getSurfaceData(), sg.composite,
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
}
} }
...@@ -280,6 +280,72 @@ public abstract class RenderingEngine { ...@@ -280,6 +280,72 @@ public abstract class RenderingEngine {
boolean normalize, boolean normalize,
int bbox[]); int bbox[]);
/**
* Construct an antialiased tile generator for the given parallelogram
* store the bounds of the tile iteration in the bbox parameter.
* The parallelogram is specified as a starting point and 2 delta
* vectors that indicate the slopes of the 2 pairs of sides of the
* parallelogram.
* The 4 corners of the parallelogram are defined by the 4 points:
* <ul>
* <li> {@code x}, {@code y}
* <li> {@code x+dx1}, {@code y+dy1}
* <li> {@code x+dx1+dx2}, {@code y+dy1+dy2}
* <li> {@code x+dx2}, {@code y+dy2}
* </ul>
* The {@code lw1} and {@code lw2} parameters provide a specification
* for an optionally stroked parallelogram if they are positive numbers.
* The {@code lw1} parameter is the ratio of the length of the {@code dx1},
* {@code dx2} delta vector to half of the line width in that same
* direction.
* The {@code lw2} parameter provides the same ratio for the other delta
* vector.
* If {@code lw1} and {@code lw2} are both greater than zero, then
* the parallelogram figure is doubled by both expanding and contracting
* each delta vector by its corresponding {@code lw} value.
* If either (@code lw1) or {@code lw2} are also greater than 1, then
* the inner (contracted) parallelogram disappears and the figure is
* simply a single expanded parallelogram.
* The {@code clip} parameter specifies the current clip in effect
* in device coordinates and can be used to prune the data for the
* operation, but the renderer is not required to perform any
* clipping.
* <p>
* Upon returning, this method will fill the {@code bbox} parameter
* with 4 values indicating the bounds of the iteration of the
* tile generator.
* The iteration order of the tiles will be as specified by the
* pseudo-code:
* <pre>
* for (y = bbox[1]; y < bbox[3]; y += tileheight) {
* for (x = bbox[0]; x < bbox[2]; x += tilewidth) {
* }
* }
* </pre>
* If there is no output to be rendered, this method may return
* null.
*
* @param x the X coordinate of the first corner of the parallelogram
* @param y the Y coordinate of the first corner of the parallelogram
* @param dx1 the X coordinate delta of the first leg of the parallelogram
* @param dy1 the Y coordinate delta of the first leg of the parallelogram
* @param dx2 the X coordinate delta of the second leg of the parallelogram
* @param dy2 the Y coordinate delta of the second leg of the parallelogram
* @param lw1 the line width ratio for the first leg of the parallelogram
* @param lw2 the line width ratio for the second leg of the parallelogram
* @param clip the current clip in effect in device coordinates
* @param bbox returns the bounds of the iteration
* @return the {@code AATileGenerator} instance to be consulted
* for tile coverages, or null if there is no output to render
* @since 1.7
*/
public abstract AATileGenerator getAATileGenerator(double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2,
Region clip,
int bbox[]);
/** /**
* Returns the minimum pen width that the antialiasing rasterizer * Returns the minimum pen width that the antialiasing rasterizer
* can represent without dropouts occuring. * can represent without dropouts occuring.
...@@ -393,5 +459,24 @@ public abstract class RenderingEngine { ...@@ -393,5 +459,24 @@ public abstract class RenderingEngine {
bs, thin, normalize, bs, thin, normalize,
bbox); bbox);
} }
public AATileGenerator getAATileGenerator(double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2,
Region clip,
int bbox[])
{
System.out.println(name+".getAATileGenerator("+
x+", "+y+", "+
dx1+", "+dy1+", "+
dx2+", "+dy2+", "+
lw1+", "+lw2+", "+
clip+")");
return target.getAATileGenerator(x, y,
dx1, dy1,
dx2, dy2,
lw1, lw2,
clip, bbox);
}
} }
} }
...@@ -557,6 +557,69 @@ public class PiscesRenderingEngine extends RenderingEngine { ...@@ -557,6 +557,69 @@ public class PiscesRenderingEngine extends RenderingEngine {
return ptg; return ptg;
} }
public AATileGenerator getAATileGenerator(double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double lw1, double lw2,
Region clip,
int bbox[])
{
// REMIND: Deal with large coordinates!
double ldx1, ldy1, ldx2, ldy2;
boolean innerpgram = (lw1 > 0 && lw2 > 0);
if (innerpgram) {
ldx1 = dx1 * lw1;
ldy1 = dy1 * lw1;
ldx2 = dx2 * lw2;
ldy2 = dy2 * lw2;
x -= (ldx1 + ldx2) / 2.0;
y -= (ldy1 + ldy2) / 2.0;
dx1 += ldx1;
dy1 += ldy1;
dx2 += ldx2;
dy2 += ldy2;
if (lw1 > 1 && lw2 > 1) {
// Inner parallelogram was entirely consumed by stroke...
innerpgram = false;
}
} else {
ldx1 = ldy1 = ldx2 = ldy2 = 0;
}
Renderer r = new Renderer(3, 3,
clip.getLoX(), clip.getLoY(),
clip.getWidth(), clip.getHeight(),
PathIterator.WIND_EVEN_ODD);
r.moveTo((float) x, (float) y);
r.lineTo((float) (x+dx1), (float) (y+dy1));
r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
r.lineTo((float) (x+dx2), (float) (y+dy2));
r.closePath();
if (innerpgram) {
x += ldx1 + ldx2;
y += ldy1 + ldy2;
dx1 -= 2.0 * ldx1;
dy1 -= 2.0 * ldy1;
dx2 -= 2.0 * ldx2;
dy2 -= 2.0 * ldy2;
r.moveTo((float) x, (float) y);
r.lineTo((float) (x+dx1), (float) (y+dy1));
r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2));
r.lineTo((float) (x+dx2), (float) (y+dy2));
r.closePath();
}
r.pathDone();
r.endRendering();
PiscesTileGenerator ptg = new PiscesTileGenerator(r, r.MAX_AA_ALPHA);
ptg.getBbox(bbox);
return ptg;
}
/** /**
* Returns the minimum pen width that the antialiasing rasterizer * Returns the minimum pen width that the antialiasing rasterizer
* can represent without dropouts occuring. * can represent without dropouts occuring.
......
...@@ -178,7 +178,7 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) { ...@@ -178,7 +178,7 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel, jnbits = (*env)->GetObjectField(env, rasterP->jsampleModel,
g_SPPSMnBitsID); g_SPPSMnBitsID);
if (jmask == NULL || joffs == NULL || jnbits == NULL || if (jmask == NULL || joffs == NULL || jnbits == NULL ||
rasterP->sppsm.maxBitSize < 0 || rasterP->sppsm.maxBitSize > 8) rasterP->sppsm.maxBitSize < 0)
{ {
JNU_ThrowInternalError(env, "Can't grab SPPSM fields"); JNU_ThrowInternalError(env, "Can't grab SPPSM fields");
return -1; return -1;
...@@ -280,6 +280,17 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) { ...@@ -280,6 +280,17 @@ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
rasterP->chanOffsets); rasterP->chanOffsets);
} }
/* additioanl check for sppsm fields validity: make sure that
* size of raster samples doesn't exceed the data type cpacity.
*/
if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
rasterP->sppsm.maxBitSize > (rasterP->dataSize * 8))
{
JNU_ThrowInternalError(env, "Raster samples are too big");
return -1;
}
#if 0 #if 0
fprintf(stderr,"---------------------\n"); fprintf(stderr,"---------------------\n");
fprintf(stderr,"Width : %d\n",rasterP->width); fprintf(stderr,"Width : %d\n",rasterP->width);
......
...@@ -88,27 +88,18 @@ ditherColor(rgbquad_t value, ImageFormat * format, int row, int col) ...@@ -88,27 +88,18 @@ ditherColor(rgbquad_t value, ImageFormat * format, int row, int col)
/* blend (lerp between) two rgb quads /* blend (lerp between) two rgb quads
src and dst alpha is ignored src and dst alpha is ignored
the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately
it's possible to verify that it's almost accurate indeed */ */
INLINE rgbquad_t INLINE rgbquad_t
blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha) blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha)
{ {
const rgbquad_t dstrb = dst & 0xFF00FF; const rgbquad_t a = alpha;
const rgbquad_t dstg = dst & 0xFF00; const rgbquad_t a1 = 0xFF - alpha;
const rgbquad_t srcrb = src & 0xFF00FF;
const rgbquad_t srcg = src & 0xFF00; return MAKE_QUAD(
(rgbquad_t)((QUAD_RED(src) * a + QUAD_RED(dst) * a1) / 0xFF),
rgbquad_t drb = srcrb - dstrb; (rgbquad_t)((QUAD_GREEN(src) * a + QUAD_GREEN(dst) * a1) / 0xFF),
rgbquad_t dg = srcg - dstg; (rgbquad_t)((QUAD_BLUE(src) * a + QUAD_BLUE(dst) * a1) / 0xFF),
0);
alpha += 1;
drb *= alpha;
dg *= alpha;
drb >>= 8;
dg >>= 8;
return ((drb + dstrb) & 0xFF00FF) | ((dg + dstg) & 0xFF00);
} }
/* scales rgb quad by alpha. basically similar to what's above. src alpha is retained. /* scales rgb quad by alpha. basically similar to what's above. src alpha is retained.
......
...@@ -26,14 +26,11 @@ ...@@ -26,14 +26,11 @@
#include "math.h" #include "math.h"
#include "GraphicsPrimitiveMgr.h" #include "GraphicsPrimitiveMgr.h"
#include "LineUtils.h" #include "LineUtils.h"
#include "LoopMacros.h"
#include "Trace.h" #include "Trace.h"
#include "ParallelogramUtils.h"
#include "sun_java2d_loops_FillParallelogram.h"
#include "sun_java2d_loops_DrawParallelogram.h" #include "sun_java2d_loops_DrawParallelogram.h"
DECLARE_SOLID_DRAWLINE(AnyInt);
#define HANDLE_PGRAM_EDGE(X1, Y1, X2, Y2, \ #define HANDLE_PGRAM_EDGE(X1, Y1, X2, Y2, \
pRasInfo, pixel, pPrim, pFunc, pCompInfo) \ pRasInfo, pixel, pPrim, pFunc, pCompInfo) \
do { \ do { \
...@@ -46,28 +43,6 @@ DECLARE_SOLID_DRAWLINE(AnyInt); ...@@ -46,28 +43,6 @@ DECLARE_SOLID_DRAWLINE(AnyInt);
ix1, iy1, ix2, iy2, JNI_TRUE); \ ix1, iy1, ix2, iy2, JNI_TRUE); \
} while (0) } while (0)
#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
do { \
double vmin, vmax; \
if (dv1 < 0) { \
vmin = v0+dv1; \
vmax = v0; \
} else { \
vmin = v0; \
vmax = v0+dv1; \
} \
if (dv2 < 0) { \
vmin -= dv2; \
} else { \
vmax += dv2; \
} \
bmin = (jint) floor(vmin + 0.5); \
bmax = (jint) floor(vmax + 0.5); \
} while(0)
#define PGRAM_INIT_X(starty, x, y, slope) \
(DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
typedef struct { typedef struct {
jdouble x0; jdouble x0;
jdouble y0; jdouble y0;
...@@ -136,20 +111,8 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram ...@@ -136,20 +111,8 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram
* Sort parallelogram by y values, ensure that each delta vector * Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta. * has a non-negative y delta.
*/ */
if (dy1 < 0) { SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
x0 += dx1; y0 += dy1; v = lw1; lw1 = lw2; lw2 = v;);
dx1 = -dx1; dy1 = -dy1;
}
if (dy2 < 0) {
x0 += dx2; y0 += dy2;
dx2 = -dx2; dy2 = -dy2;
}
/* Sort delta vectors so dxy1 is left of dxy2. */
if (dx1 * dy2 > dx2 * dy1) {
double v = dx1; dx1 = dx2; dx2 = v;
v = dy1; dy1 = dy2; dy2 = v;
v = lw1; lw1 = lw2; lw2 = v;
}
// dx,dy for line width in the "1" and "2" directions. // dx,dy for line width in the "1" and "2" directions.
ldx1 = dx1 * lw1; ldx1 = dx1 * lw1;
...@@ -161,7 +124,7 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram ...@@ -161,7 +124,7 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram
ox0 = x0 - (ldx1 + ldx2) / 2.0; ox0 = x0 - (ldx1 + ldx2) / 2.0;
oy0 = y0 - (ldy1 + ldy2) / 2.0; oy0 = y0 - (ldy1 + ldy2) / 2.0;
PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2); PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_FALSE);
iy1 = (jint) floor(oy0 + 0.5); iy1 = (jint) floor(oy0 + 0.5);
iy2 = (jint) floor(oy0 + dy1 + ldy1 + dy2 + ldy2 + 0.5); iy2 = (jint) floor(oy0 + dy1 + ldy1 + dy2 + ldy2 + 0.5);
...@@ -212,7 +175,7 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram ...@@ -212,7 +175,7 @@ Java_sun_java2d_loops_DrawParallelogram_DrawParallelogram
// Only need to generate 4 quads if the interior still // Only need to generate 4 quads if the interior still
// has a hole in it (i.e. if the line width ratios were // has a hole in it (i.e. if the line width ratios were
// both less than 1.0) // both less than 1.0)
if (lw1 < 1.0f && lw2 < 1.0f) { if (lw1 < 1.0 && lw2 < 1.0) {
// If the line widths are both less than a pixel wide // If the line widths are both less than a pixel wide
// then we can use a drawline function instead for even // then we can use a drawline function instead for even
// more performance. // more performance.
......
...@@ -25,31 +25,10 @@ ...@@ -25,31 +25,10 @@
#include "math.h" #include "math.h"
#include "GraphicsPrimitiveMgr.h" #include "GraphicsPrimitiveMgr.h"
#include "ParallelogramUtils.h"
#include "sun_java2d_loops_FillParallelogram.h" #include "sun_java2d_loops_FillParallelogram.h"
#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
do { \
double vmin, vmax; \
if (dv1 < 0) { \
vmin = v0+dv1; \
vmax = v0; \
} else { \
vmin = v0; \
vmax = v0+dv1; \
} \
if (dv2 < 0) { \
vmin -= dv2; \
} else { \
vmax += dv2; \
} \
bmin = (jint) floor(vmin + 0.5); \
bmax = (jint) floor(vmax + 0.5); \
} while(0)
#define PGRAM_INIT_X(starty, x, y, slope) \
(DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
/* /*
* Class: sun_java2d_loops_FillParallelogram * Class: sun_java2d_loops_FillParallelogram
* Method: FillParallelogram * Method: FillParallelogram
...@@ -76,22 +55,11 @@ Java_sun_java2d_loops_FillParallelogram_FillParallelogram ...@@ -76,22 +55,11 @@ Java_sun_java2d_loops_FillParallelogram_FillParallelogram
/* /*
* Sort parallelogram by y values, ensure that each delta vector * Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta, and eliminate degenerate parallelograms. * has a non-negative y delta.
*/ */
if (dy1 < 0) { SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
x0 += dx1; y0 += dy1;
dx1 = -dx1; dy1 = -dy1; PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_FALSE);
}
if (dy2 < 0) {
x0 += dx2; y0 += dy2;
dx2 = -dx2; dy2 = -dy2;
}
/* Sort delta vectors so dxy1 is left of dxy2. */
if (dx1 * dy2 > dx2 * dy1) {
double v = dx1; dx1 = dx2; dx2 = v;
v = dy1; dy1 = dy2; dy2 = v;
}
PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2);
iy1 = (jint) floor(y0 + 0.5); iy1 = (jint) floor(y0 + 0.5);
iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5); iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5);
......
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
* questions. * questions.
*/ */
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "GraphicsPrimitiveMgr.h" #include "GraphicsPrimitiveMgr.h"
#include "ParallelogramUtils.h"
#include "sun_java2d_loops_MaskFill.h" #include "sun_java2d_loops_MaskFill.h"
...@@ -93,6 +97,967 @@ Java_sun_java2d_loops_MaskFill_MaskFill ...@@ -93,6 +97,967 @@ Java_sun_java2d_loops_MaskFill_MaskFill
} }
} }
SurfaceData_InvokeRelease(env, sdOps, &rasInfo); SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
}
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
}
#define MASK_BUF_LEN 1024
#define DblToMask(v) ((unsigned char) ((v)*255.9999))
/* Fills an aligned rectangle with potentially translucent edges. */
static void
fillAARect(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
void *pDst,
jdouble x1, jdouble y1, jdouble x2, jdouble y2)
{
jint cx1 = pRasInfo->bounds.x1;
jint cy1 = pRasInfo->bounds.y1;
jint cx2 = pRasInfo->bounds.x2;
jint cy2 = pRasInfo->bounds.y2;
jint rx1 = (jint) ceil(x1);
jint ry1 = (jint) ceil(y1);
jint rx2 = (jint) floor(x2);
jint ry2 = (jint) floor(y2);
jint width = cx2 - cx1;
jint scan = pRasInfo->scanStride;
/* Convert xy12 into the edge coverage fractions for those edges. */
x1 = rx1-x1;
y1 = ry1-y1;
x2 = x2-rx2;
y2 = y2-ry2;
if (ry2 < ry1) {
/* Accumulate bottom coverage into top coverage. */
y1 = y1 + y2 - 1.0;
/* prevent processing of "bottom fractional row" */
ry2 = cy2;
}
if (rx2 < rx1) {
/* Accumulate right coverage into left coverage. */
x1 = x1 + x2 - 1.0;
/* prevent processing of "right fractional column" */
rx2 = cx2;
}
/* Check for a visible "top fractional row" and process it */
if (cy1 < ry1) {
unsigned char midcov = DblToMask(y1);
jint x;
for (x = 0; x < width; x++) {
pMask[x] = midcov;
}
if (cx1 < rx1) {
pMask[0] = DblToMask(y1 * x1);
}
if (cx2 > rx2) {
pMask[width-1] = DblToMask(y1 * x2);
}
(*pPrim->funcs.maskfill)(pDst,
pMask, 0, 0,
width, 1,
color, pRasInfo,
pPrim, pCompInfo);
pDst = PtrAddBytes(pDst, scan);
cy1++;
}
/* Check for a visible "left fract, solid middle, right fract" section. */
if (cy1 < ry2 && cy1 < cy2) {
jint midh = ((ry2 < cy2) ? ry2 : cy2) - cy1;
jint midx = cx1;
void *pMid = pDst;
/* First process the left "fractional column" if it is visible. */
if (midx < rx1) {
pMask[0] = DblToMask(x1);
/* Note: maskscan == 0 means we reuse this value for every row. */
(*pPrim->funcs.maskfill)(pMid,
pMask, 0, 0,
1, midh,
color, pRasInfo,
pPrim, pCompInfo);
pMid = PtrAddBytes(pMid, pRasInfo->pixelStride);
midx++;
}
/* Process the central solid section if it is visible. */
if (midx < rx2 && midx < cx2) {
jint midw = ((rx2 < cx2) ? rx2 : cx2) - midx;
/* A NULL mask buffer means "all coverages are 0xff" */
(*pPrim->funcs.maskfill)(pMid,
NULL, 0, 0,
midw, midh,
color, pRasInfo,
pPrim, pCompInfo);
pMid = PtrCoord(pMid, midw, pRasInfo->pixelStride, 0, 0);
midx += midw;
}
/* Finally process the right "fractional column" if it is visible. */
if (midx < cx2) {
pMask[0] = DblToMask(x2);
/* Note: maskscan == 0 means we reuse this value for every row. */
(*pPrim->funcs.maskfill)(pMid,
pMask, 0, 0,
1, midh,
color, pRasInfo,
pPrim, pCompInfo);
}
cy1 += midh;
pDst = PtrCoord(pDst, 0, 0, midh, scan);
}
/* Check for a visible "bottom fractional row" and process it */
if (cy1 < cy2) {
unsigned char midcov = DblToMask(y2);
jint x;
for (x = 0; x < width; x++) {
pMask[x] = midcov;
}
if (cx1 < rx1) {
pMask[0] = DblToMask(y2 * x1);
}
if (cx2 > rx2) {
pMask[width-1] = DblToMask(y2 * x2);
}
(*pPrim->funcs.maskfill)(pDst,
pMask, 0, 0,
width, 1,
color, pRasInfo,
pPrim, pCompInfo);
}
}
/*
* Support code for arbitrary tracing and MaskFill filling of
* non-rectilinear (diagonal) parallelograms.
*
* This code is based upon the following model of AA coverage.
*
* Each edge of a parallelogram (for fillPgram) or a double
* parallelogram (inner and outer parallelograms for drawPgram)
* can be rasterized independently because the geometry is well
* defined in such a way that none of the sides will ever cross
* each other and they have a fixed ordering that is fairly
* well predetermined.
*
* So, for each edge we will look at the diagonal line that
* the edge makes as it passes through a row of pixels. Some
* such diagonal lines may pass entirely through the row of
* pixels in a single pixel column. Some may cut across the
* row and pass through several pixel columns before they pass
* on to the next row.
*
* As the edge passes through the row of pixels it will affect
* the coverage of the pixels it passes through as well as all
* of the pixels to the right of the edge. The coverage will
* either be increased (by a left edge of a parallelogram) or
* decreased (by a right edge) for all pixels to the right, until
* another edge passing the opposite direction is encountered.
*
* The coverage added or subtracted by an edge as it crosses a
* given pixel is calculated using a trapezoid formula in the
* following manner:
*
* /
* +-----+---/-+-----+
* | | / | |
* | | / | |
* +-----+/----+-----+
* /
*
* The area to the right of that edge for the pixel where it
* crosses is given as:
*
* trapheight * (topedge + bottomedge)/2
*
* Another thing to note is that the above formula gives the
* contribution of that edge to the given pixel where it crossed,
* but in so crossing the pixel row, it also created 100% coverage
* for all of the pixels to the right.
*
* This example was simplified in that the edge depicted crossed
* the complete pixel row and it did so entirely within the bounds
* of a single pixel column. In practice, many edges may start or
* end in a given row and thus provide only partial row coverage
* (i.e. the total "trapheight" in the formula never reaches 1.0).
* And in other cases, edges may travel sideways through several
* pixel columns on a given pixel row from where they enter it to
* where the leave it (which also mans that the trapheight for a
* given pixel will be less than 1.0, but by the time the edge
* completes its journey through the pixel row the "coverage shadow"
* that it casts on all pixels to the right eventually reaches 100%).
*
* In order to simplify the calculations so that we don't have to
* keep propagating coverages we calculate for one edge "until we
* reach another edge" we will process one edge at a time and
* simply record in a buffer the amount that an edge added to
* or subtracted from the coverage for a given pixel and its
* following right-side neighbors. Thus, the true total coverage
* of a given pixel is only determined by summing the deltas for
* that pixel and all of the pixels to its left. Since we already
* have to scan the buffer to change floating point coverages into
* mask values for a MaskFill loop, it is simple enough to sum the
* values as we perform that scan from left to right.
*
* In the above example, note that 2 deltas need to be recorded even
* though the edge only intersected a single pixel. The delta recorded
* for the pixel where the edge crossed will be approximately 55%
* (guesstimating by examining the poor ascii art) which is fine for
* determining how to render that pixel, but the rest of the pixels
* to its right should have their coverage modified by a full 100%
* and the 55% delta value we recorded for the pixel that the edge
* crossed will not get them there. We adjust for this by adding
* the "remainder" of the coverage implied by the shadow to the
* pixel immediately to the right of where we record a trapezoidal
* contribution. In this case a delta of 45% will be recorded in
* the pixel immediately to the right to raise the total to 100%.
*
* As we sum these delta values as we process the line from left
* to right, these delta values will typically drive the sum from
* 0% up to 100% and back down to 0% over the course of a single
* pixel row. In the case of a drawn (double) parallelogram the
* sum will go to 100% and back to 0% twice on most scanlines.
*
* The fillAAPgram and drawAAPgram functions drive the main flow
* of the algorithm with help from the following structures,
* macros, and functions. It is probably best to start with
* those 2 functions to gain an understanding of the algorithm.
*/
typedef struct {
jdouble x;
jdouble y;
jdouble xbot;
jdouble ybot;
jdouble xnexty;
jdouble ynextx;
jdouble xnextx;
jdouble linedx;
jdouble celldx;
jdouble celldy;
jboolean isTrailing;
} EdgeInfo;
#define MIN_DELTA (1.0/256.0)
/*
* Calculates slopes and deltas for an edge and stores results in an EdgeInfo.
* Returns true if the edge was valid (i.e. not ignored for some reason).
*/
static jboolean
storeEdge(EdgeInfo *pEdge,
jdouble x, jdouble y, jdouble dx, jdouble dy,
jint cx1, jint cy1, jint cx2, jint cy2,
jboolean isTrailing)
{
jdouble xbot = x + dx;
jdouble ybot = y + dy;
jboolean ret;
pEdge->x = x;
pEdge->y = y;
pEdge->xbot = xbot;
pEdge->ybot = ybot;
/* Note that parallelograms are sorted so dy is always non-negative */
if (dy > MIN_DELTA && /* NaN and horizontal protection */
ybot > cy1 && /* NaN and "OUT_ABOVE" protection */
y < cy2 && /* NaN and "OUT_BELOW" protection */
xbot == xbot && /* NaN protection */
(x < cx2 || xbot < cx2)) /* "OUT_RIGHT" protection */
/* Note: "OUT_LEFT" segments may still contribute coverage... */
{
/* no NaNs, dy is not horizontal, and segment contributes to clip */
if (dx < -MIN_DELTA || dx > MIN_DELTA) {
/* dx is not vertical */
jdouble linedx;
jdouble celldy;
jdouble nextx;
linedx = dx / dy;
celldy = dy / dx;
if (y < cy1) {
pEdge->x = x = x + (cy1 - y) * linedx;
pEdge->y = y = cy1;
}
pEdge->linedx = linedx;
if (dx < 0) {
pEdge->celldx = -1.0;
pEdge->celldy = -celldy;
pEdge->xnextx = nextx = ceil(x) - 1.0;
} else {
pEdge->celldx = +1.0;
pEdge->celldy = celldy;
pEdge->xnextx = nextx = floor(x) + 1.0;
}
pEdge->ynextx = y + (nextx - x) * celldy;
pEdge->xnexty = x + ((floor(y) + 1) - y) * linedx;
} else {
/* dx is essentially vertical */
if (y < cy1) {
pEdge->y = y = cy1;
}
pEdge->xbot = x;
pEdge->linedx = 0.0;
pEdge->celldx = 0.0;
pEdge->celldy = 1.0;
pEdge->xnextx = x;
pEdge->xnexty = x;
pEdge->ynextx = ybot;
}
ret = JNI_TRUE;
} else {
/* There is some reason to ignore this segment, "celldy=0" omits it */
pEdge->ybot = y;
pEdge->linedx = dx;
pEdge->celldx = dx;
pEdge->celldy = 0.0;
pEdge->xnextx = xbot;
pEdge->xnexty = xbot;
pEdge->ynextx = y;
ret = JNI_FALSE;
}
pEdge->isTrailing = isTrailing;
return ret;
}
/*
* Calculates and stores slopes and deltas for all edges of a parallelogram.
* Returns true if at least 1 edge was valid (i.e. not ignored for some reason).
*
* The inverted flag is true for an outer parallelogram (left and right
* edges are leading and trailing) and false for an inner parallelogram
* (where the left edge is trailing and the right edge is leading).
*/
static jboolean
storePgram(EdgeInfo *pLeftEdge, EdgeInfo *pRightEdge,
jdouble x, jdouble y,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2,
jint cx1, jint cy1, jint cx2, jint cy2,
jboolean inverted)
{
jboolean ret = JNI_FALSE;
ret = (storeEdge(pLeftEdge + 0,
x , y , dx1, dy1,
cx1, cy1, cx2, cy2, inverted) || ret);
ret = (storeEdge(pLeftEdge + 1,
x+dx1, y+dy1, dx2, dy2,
cx1, cy1, cx2, cy2, inverted) || ret);
ret = (storeEdge(pRightEdge + 0,
x , y , dx2, dy2,
cx1, cy1, cx2, cy2, !inverted) || ret);
ret = (storeEdge(pRightEdge + 1,
x+dx2, y+dy2, dx1, dy1,
cx1, cy1, cx2, cy2, !inverted) || ret);
return ret;
}
/*
* The X0,Y0,X1,Y1 values represent a trapezoidal fragment whose
* coverage must be accounted for in the accum buffer.
*
* All four values are assumed to fall within (or on the edge of)
* a single pixel.
*
* The trapezoid area is accumulated into the proper element of
* the accum buffer and the remainder of the "slice height" is
* accumulated into the element to its right.
*/
#define INSERT_ACCUM(pACCUM, IMIN, IMAX, X0, Y0, X1, Y1, CX1, CX2, MULT) \
do { \
jdouble xmid = ((X0) + (X1)) * 0.5; \
if (xmid <= (CX2)) { \
jdouble sliceh = ((Y1) - (Y0)); \
jdouble slicearea; \
jint i; \
if (xmid < (CX1)) { \
/* Accumulate the entire slice height into accum[0]. */ \
i = 0; \
slicearea = sliceh; \
} else { \
jdouble xpos = floor(xmid); \
i = ((jint) xpos) - (CX1); \
slicearea = (xpos+1-xmid) * sliceh; \
} \
if (IMIN > i) { \
IMIN = i; \
} \
(pACCUM)[i++] += (jfloat) ((MULT) * slicearea); \
(pACCUM)[i++] += (jfloat) ((MULT) * (sliceh - slicearea)); \
if (IMAX < i) { \
IMAX = i; \
} \
} \
} while (0)
/*
* Accumulate the contributions for a given edge crossing a given
* scan line into the corresponding entries of the accum buffer.
* CY1 is the Y coordinate of the top edge of the scanline and CY2
* is equal to (CY1 + 1) and is the Y coordinate of the bottom edge
* of the scanline. CX1 and CX2 are the left and right edges of the
* clip (or area of interest) being rendered.
*
* The edge is processed from the top edge to the bottom edge and
* a single pixel column at a time.
*/
#define ACCUM_EDGE(pEDGE, pACCUM, IMIN, IMAX, CX1, CY1, CX2, CY2) \
do { \
jdouble x, y, xnext, ynext, xlast, ylast, dx, dy, mult; \
y = (pEDGE)->y; \
dy = (pEDGE)->celldy; \
ylast = (pEDGE)->ybot; \
if (ylast <= (CY1) || y >= (CY2) || dy == 0.0) { \
break; \
} \
x = (pEDGE)->x; \
dx = (pEDGE)->celldx; \
if (ylast > (CY2)) { \
ylast = (CY2); \
xlast = (pEDGE)->xnexty; \
} else { \
xlast = (pEDGE)->xbot; \
} \
xnext = (pEDGE)->xnextx; \
ynext = (pEDGE)->ynextx; \
mult = ((pEDGE)->isTrailing) ? -1.0 : 1.0; \
while (ynext <= ylast) { \
INSERT_ACCUM(pACCUM, IMIN, IMAX, \
x, y, xnext, ynext, \
CX1, CX2, mult); \
x = xnext; \
y = ynext; \
xnext += dx; \
ynext += dy; \
} \
(pEDGE)->ynextx = ynext; \
(pEDGE)->xnextx = xnext; \
INSERT_ACCUM(pACCUM, IMIN, IMAX, \
x, y, xlast, ylast, \
CX1, CX2, mult); \
(pEDGE)->x = xlast; \
(pEDGE)->y = ylast; \
(pEDGE)->xnexty = xlast + (pEDGE)->linedx; \
} while(0)
/* Main function to fill a single Parallelogram */
static void
fillAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
void *pDst,
jdouble x1, jdouble y1,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2)
{
jint cx1 = pRasInfo->bounds.x1;
jint cy1 = pRasInfo->bounds.y1;
jint cx2 = pRasInfo->bounds.x2;
jint cy2 = pRasInfo->bounds.y2;
jint width = cx2 - cx1;
EdgeInfo edges[4];
jfloat localaccum[MASK_BUF_LEN + 1];
jfloat *pAccum;
if (!storePgram(edges + 0, edges + 2,
x1, y1, dx1, dy1, dx2, dy2,
cx1, cy1, cx2, cy2,
JNI_FALSE))
{
return;
}
pAccum = ((width > MASK_BUF_LEN)
? malloc((width + 1) * sizeof(jfloat))
: localaccum);
if (pAccum == NULL) {
return;
}
memset(pAccum, 0, (width+1) * sizeof(jfloat));
while (cy1 < cy2) {
jint lmin, lmax, rmin, rmax;
jint moff, x;
jdouble accum;
unsigned char lastcov;
lmin = rmin = width + 2;
lmax = rmax = 0;
ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[2], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[3], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
if (lmax > width) {
lmax = width; /* Extra col has data we do not need. */
}
if (rmax > width) {
rmax = width; /* Extra col has data we do not need. */
}
/* If ranges overlap, handle both in the first pass. */
if (rmin <= lmax) {
lmax = rmax;
}
x = lmin;
accum = 0.0;
moff = 0;
lastcov = 0;
while (x < lmax) {
accum += pAccum[x];
pAccum[x] = 0.0f;
pMask[moff++] = lastcov = DblToMask(accum);
x++;
}
/* Check for a solid center section. */
if (lastcov == 0xFF) {
jint endx;
void *pRow;
/* First process the existing partial coverage data. */
if (moff > 0) {
pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
pMask, 0, 0,
moff, 1,
color, pRasInfo,
pPrim, pCompInfo);
moff = 0;
}
/* Where does the center section end? */
/* If there is no right AA edge in the accum buffer, then */
/* the right edge was beyond the clip, so fill out to width */
endx = (rmin < rmax) ? rmin : width;
if (x < endx) {
pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
NULL, 0, 0,
endx - x, 1,
color, pRasInfo,
pPrim, pCompInfo);
x = endx;
}
} else if (lastcov > 0 && rmin >= rmax) {
/* We are not at 0 coverage, but there is no right edge, */
/* force a right edge so we process pixels out to width. */
rmax = width;
}
/* The following loop will process the right AA edge and/or any */
/* partial coverage center section not processed above. */
while (x < rmax) {
accum += pAccum[x];
pAccum[x] = 0.0f;
pMask[moff++] = DblToMask(accum);
x++;
}
if (moff > 0) {
void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
pMask, 0, 0,
moff, 1,
color, pRasInfo,
pPrim, pCompInfo);
}
pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
cy1++;
}
if (pAccum != localaccum) {
free(pAccum);
}
}
/*
* Class: sun_java2d_loops_MaskFill
* Method: FillAAPgram
* Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDD)V
*/
JNIEXPORT void JNICALL
Java_sun_java2d_loops_MaskFill_FillAAPgram
(JNIEnv *env, jobject self,
jobject sg2d, jobject sData, jobject comp,
jdouble x0, jdouble y0,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2)
{
SurfaceDataOps *sdOps;
SurfaceDataRasInfo rasInfo;
NativePrimitive *pPrim;
CompositeInfo compInfo;
jint ix1, iy1, ix2, iy2;
if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
return;
}
/*
* Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta.
*/
SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, );
PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2, JNI_TRUE);
iy1 = (jint) floor(y0);
iy2 = (jint) ceil(y0 + dy1 + dy2);
pPrim = GetNativePrim(env, self);
if (pPrim == NULL) {
return;
}
if (pPrim->pCompType->getCompInfo != NULL) {
(*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
}
sdOps = SurfaceData_GetOps(env, sData);
if (sdOps == 0) {
return;
}
GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
rasInfo.bounds.x2 <= rasInfo.bounds.x1)
{
return;
}
if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
return;
}
ix1 = rasInfo.bounds.x1;
iy1 = rasInfo.bounds.y1;
ix2 = rasInfo.bounds.x2;
iy2 = rasInfo.bounds.y2;
if (ix2 > ix1 && iy2 > iy1) {
jint width = ix2 - ix1;
jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
unsigned char localmask[MASK_BUF_LEN];
unsigned char *pMask = ((width > MASK_BUF_LEN)
? malloc(width)
: localmask);
sdOps->GetRasInfo(env, sdOps, &rasInfo);
if (rasInfo.rasBase != NULL && pMask != NULL) {
void *pDst = PtrCoord(rasInfo.rasBase,
ix1, rasInfo.pixelStride,
iy1, rasInfo.scanStride);
if (dy1 == 0 && dx2 == 0) {
if (dx1 < 0) {
// We sorted by Y above, but not by X
x0 += dx1;
dx1 = -dx1;
}
fillAARect(pPrim, &rasInfo, &compInfo,
color, pMask, pDst,
x0, y0, x0+dx1, y0+dy2);
} else if (dx1 == 0 && dy2 == 0) {
if (dx2 < 0) {
// We sorted by Y above, but not by X
x0 += dx2;
dx2 = -dx2;
}
fillAARect(pPrim, &rasInfo, &compInfo,
color, pMask, pDst,
x0, y0, x0+dx2, y0+dy1);
} else {
fillAAPgram(pPrim, &rasInfo, &compInfo,
color, pMask, pDst,
x0, y0, dx1, dy1, dx2, dy2);
}
}
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
if (pMask != NULL && pMask != localmask) {
free(pMask);
}
}
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
}
/* Main function to fill a double pair of (inner and outer) parallelograms */
static void
drawAAPgram(NativePrimitive *pPrim, SurfaceDataRasInfo *pRasInfo,
CompositeInfo *pCompInfo, jint color, unsigned char *pMask,
void *pDst,
jdouble ox0, jdouble oy0,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2,
jdouble ldx1, jdouble ldy1,
jdouble ldx2, jdouble ldy2)
{
jint cx1 = pRasInfo->bounds.x1;
jint cy1 = pRasInfo->bounds.y1;
jint cx2 = pRasInfo->bounds.x2;
jint cy2 = pRasInfo->bounds.y2;
jint width = cx2 - cx1;
EdgeInfo edges[8];
jfloat localaccum[MASK_BUF_LEN + 1];
jfloat *pAccum;
if (!storePgram(edges + 0, edges + 6,
ox0, oy0,
dx1 + ldx1, dy1 + ldy1,
dx2 + ldx2, dy2 + ldy2,
cx1, cy1, cx2, cy2,
JNI_FALSE))
{
/* If outer pgram does not contribute, then inner cannot either. */
return;
}
storePgram(edges + 2, edges + 4,
ox0 + ldx1 + ldx2, oy0 + ldy1 + ldy2,
dx1 - ldx1, dy1 - ldy1,
dx2 - ldx2, dy2 - ldy2,
cx1, cy1, cx2, cy2,
JNI_TRUE);
pAccum = ((width > MASK_BUF_LEN)
? malloc((width + 1) * sizeof(jfloat))
: localaccum);
if (pAccum == NULL) {
return;
}
memset(pAccum, 0, (width+1) * sizeof(jfloat));
while (cy1 < cy2) {
jint lmin, lmax, rmin, rmax;
jint moff, x;
jdouble accum;
unsigned char lastcov;
lmin = rmin = width + 2;
lmax = rmax = 0;
ACCUM_EDGE(&edges[0], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[1], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[2], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[3], pAccum, lmin, lmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[4], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[5], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[6], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
ACCUM_EDGE(&edges[7], pAccum, rmin, rmax,
cx1, cy1, cx2, cy1+1);
if (lmax > width) {
lmax = width; /* Extra col has data we do not need. */
}
if (rmax > width) {
rmax = width; /* Extra col has data we do not need. */
}
/* If ranges overlap, handle both in the first pass. */
if (rmin <= lmax) {
lmax = rmax;
}
x = lmin;
accum = 0.0;
moff = 0;
lastcov = 0;
while (x < lmax) {
accum += pAccum[x];
pAccum[x] = 0.0f;
pMask[moff++] = lastcov = DblToMask(accum);
x++;
}
/* Check for an empty or solidcenter section. */
if (lastcov == 0 || lastcov == 0xFF) {
jint endx;
void *pRow;
/* First process the existing partial coverage data. */
if (moff > 0) {
pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
pMask, 0, 0,
moff, 1,
color, pRasInfo,
pPrim, pCompInfo);
moff = 0;
}
/* Where does the center section end? */
/* If there is no right AA edge in the accum buffer, then */
/* the right edge was beyond the clip, so fill out to width */
endx = (rmin < rmax) ? rmin : width;
if (x < endx) {
if (lastcov == 0xFF) {
pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
NULL, 0, 0,
endx - x, 1,
color, pRasInfo,
pPrim, pCompInfo);
}
x = endx;
}
} else if (rmin >= rmax) {
/* We are not at 0 coverage, but there is no right edge, */
/* force a right edge so we process pixels out to width. */
rmax = width;
}
/* The following loop will process the right AA edge and/or any */
/* partial coverage center section not processed above. */
while (x < rmax) {
accum += pAccum[x];
pAccum[x] = 0.0f;
pMask[moff++] = lastcov = DblToMask(accum);
x++;
}
if (moff > 0) {
void *pRow = PtrCoord(pDst, x-moff, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
pMask, 0, 0,
moff, 1,
color, pRasInfo,
pPrim, pCompInfo);
}
if (lastcov == 0xFF && x < width) {
void *pRow = PtrCoord(pDst, x, pRasInfo->pixelStride, 0, 0);
(*pPrim->funcs.maskfill)(pRow,
NULL, 0, 0,
width - x, 1,
color, pRasInfo,
pPrim, pCompInfo);
}
pDst = PtrAddBytes(pDst, pRasInfo->scanStride);
cy1++;
}
if (pAccum != localaccum) {
free(pAccum);
}
}
/*
* Class: sun_java2d_loops_MaskFill
* Method: DrawAAPgram
* Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Ljava/awt/Composite;DDDDDDDD)V
*/
JNIEXPORT void JNICALL
Java_sun_java2d_loops_MaskFill_DrawAAPgram
(JNIEnv *env, jobject self,
jobject sg2d, jobject sData, jobject comp,
jdouble x0, jdouble y0,
jdouble dx1, jdouble dy1,
jdouble dx2, jdouble dy2,
jdouble lw1, jdouble lw2)
{
SurfaceDataOps *sdOps;
SurfaceDataRasInfo rasInfo;
NativePrimitive *pPrim;
CompositeInfo compInfo;
jint ix1, iy1, ix2, iy2;
jdouble ldx1, ldy1, ldx2, ldy2;
jdouble ox0, oy0;
if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
return;
}
/*
* Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta.
*/
SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2,
v = lw1; lw1 = lw2; lw2 = v;);
// dx,dy for line width in the "1" and "2" directions.
ldx1 = dx1 * lw1;
ldy1 = dy1 * lw1;
ldx2 = dx2 * lw2;
ldy2 = dy2 * lw2;
// calculate origin of the outer parallelogram
ox0 = x0 - (ldx1 + ldx2) / 2.0;
oy0 = y0 - (ldy1 + ldy2) / 2.0;
if (lw1 >= 1.0 || lw2 >= 1.0) {
/* Only need to fill an outer pgram if the interior no longer
* has a hole in it (i.e. if either of the line width ratios
* were greater than or equal to 1.0).
*/
Java_sun_java2d_loops_MaskFill_FillAAPgram(env, self,
sg2d, sData, comp,
ox0, oy0,
dx1 + ldx1, dy1 + ldy1,
dx2 + ldx2, dy2 + ldy2);
return;
}
PGRAM_MIN_MAX(ix1, ix2, ox0, dx1+ldx1, dx2+ldx2, JNI_TRUE);
iy1 = (jint) floor(oy0);
iy2 = (jint) ceil(oy0 + dy1 + ldy1 + dy2 + ldy2);
pPrim = GetNativePrim(env, self);
if (pPrim == NULL) {
return;
}
if (pPrim->pCompType->getCompInfo != NULL) {
(*pPrim->pCompType->getCompInfo)(env, &compInfo, comp);
}
sdOps = SurfaceData_GetOps(env, sData);
if (sdOps == 0) {
return;
}
GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
rasInfo.bounds.x2 <= rasInfo.bounds.x1)
{
return;
}
if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
return;
}
ix1 = rasInfo.bounds.x1;
iy1 = rasInfo.bounds.y1;
ix2 = rasInfo.bounds.x2;
iy2 = rasInfo.bounds.y2;
if (ix2 > ix1 && iy2 > iy1) {
jint width = ix2 - ix1;
jint color = GrPrim_Sg2dGetEaRGB(env, sg2d);
unsigned char localmask[MASK_BUF_LEN];
unsigned char *pMask = ((width > MASK_BUF_LEN)
? malloc(width)
: localmask);
sdOps->GetRasInfo(env, sdOps, &rasInfo);
if (rasInfo.rasBase != NULL && pMask != NULL) {
void *pDst = PtrCoord(rasInfo.rasBase,
ix1, rasInfo.pixelStride,
iy1, rasInfo.scanStride);
/*
* NOTE: aligned rects could probably be drawn
* even faster with a little work here.
* if (dy1 == 0 && dx2 == 0) {
* drawAARect(pPrim, &rasInfo, &compInfo,
* color, pMask, pDst,
* ox0, oy0, ox0+dx1+ldx1, oy0+dy2+ldy2, ldx1, ldy2);
* } else if (dx1 == 0 && dy2 == 0) {
* drawAARect(pPrim, &rasInfo, &compInfo,
* color, pMask, pDst,
* ox0, oy0, ox0+dx2+ldx2, oy0+dy1+ldy1, ldx2, ldy1);
* } else {
*/
drawAAPgram(pPrim, &rasInfo, &compInfo,
color, pMask, pDst,
ox0, oy0,
dx1, dy1, dx2, dy2,
ldx1, ldy1, ldx2, ldy2);
/*
* }
*/
}
SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
if (pMask != NULL && pMask != localmask) {
free(pMask);
}
} }
SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
} }
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef ParallelogramUtils_h_Included
#define ParallelogramUtils_h_Included
#ifdef __cplusplus
extern "C" {
#endif
#define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2, AA) \
do { \
double vmin, vmax; \
if (dv1 < 0) { \
vmin = v0+dv1; \
vmax = v0; \
} else { \
vmin = v0; \
vmax = v0+dv1; \
} \
if (dv2 < 0) { \
vmin += dv2; \
} else { \
vmax += dv2; \
} \
if (AA) { \
bmin = (jint) floor(vmin); \
bmax = (jint) ceil(vmax); \
} else { \
bmin = (jint) floor(vmin + 0.5); \
bmax = (jint) floor(vmax + 0.5); \
} \
} while(0)
#define PGRAM_INIT_X(starty, x, y, slope) \
(DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
/*
* Sort parallelogram by y values, ensure that each delta vector
* has a non-negative y delta.
*/
#define SORT_PGRAM(x0, y0, dx1, dy1, dx2, dy2, OTHER_SWAP_CODE) \
do { \
if (dy1 < 0) { \
x0 += dx1; y0 += dy1; \
dx1 = -dx1; dy1 = -dy1; \
} \
if (dy2 < 0) { \
x0 += dx2; y0 += dy2; \
dx2 = -dx2; dy2 = -dy2; \
} \
/* Sort delta vectors so dxy1 is left of dxy2. */ \
if (dx1 * dy2 > dx2 * dy1) { \
double v; \
v = dx1; dx1 = dx2; dx2 = v; \
v = dy1; dy1 = dy2; dy2 = v; \
OTHER_SWAP_CODE \
} \
} while(0)
#endif /* ParallelogramUtils_h_Included */
...@@ -119,7 +119,8 @@ Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile ...@@ -119,7 +119,8 @@ Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile
PtrCoord(srcInfo.rasBase, PtrCoord(srcInfo.rasBase,
srcInfo.bounds.x1, srcInfo.pixelStride, srcInfo.bounds.x1, srcInfo.pixelStride,
srcInfo.bounds.y1, srcInfo.scanStride); srcInfo.bounds.y1, srcInfo.scanStride);
unsigned char *pMask = unsigned char *pMask, *pMaskAlloc;
pMask = pMaskAlloc =
(*env)->GetPrimitiveArrayCritical(env, maskArray, 0); (*env)->GetPrimitiveArrayCritical(env, maskArray, 0);
if (pMask == NULL) { if (pMask == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, J2dRlsTraceLn(J2D_TRACE_ERROR,
...@@ -274,7 +275,7 @@ Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile ...@@ -274,7 +275,7 @@ Java_sun_java2d_pipe_BufferedMaskBlit_enqueueTile
bpos += width * height * sizeof(jint); bpos += width * height * sizeof(jint);
(*env)->ReleasePrimitiveArrayCritical(env, maskArray, (*env)->ReleasePrimitiveArrayCritical(env, maskArray,
pMask, JNI_ABORT); pMaskAlloc, JNI_ABORT);
} }
SurfaceData_InvokeRelease(env, srcOps, &srcInfo); SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
} }
......
...@@ -137,41 +137,43 @@ void getALSAVersion(char* buffer, int len) { ...@@ -137,41 +137,43 @@ void getALSAVersion(char* buffer, int len) {
file = fopen(ALSA_VERSION_PROC_FILE, "r"); file = fopen(ALSA_VERSION_PROC_FILE, "r");
ALSAVersionString[0] = 0; ALSAVersionString[0] = 0;
if (file) { if (file) {
fgets(ALSAVersionString, ALSAVersionString_LENGTH, file); if (NULL != fgets(ALSAVersionString, ALSAVersionString_LENGTH, file)) {
// parse for version number // parse for version number
totalLen = strlen(ALSAVersionString); totalLen = strlen(ALSAVersionString);
inVersionString = FALSE; inVersionString = FALSE;
len = 0; len = 0;
curr = 0; curr = 0;
while (curr < totalLen) { while (curr < totalLen) {
if (!inVersionString) { if (!inVersionString) {
// is this char the beginning of a version string ? // is this char the beginning of a version string ?
if (ALSAVersionString[curr] >= '0' if (ALSAVersionString[curr] >= '0'
&& ALSAVersionString[curr] <= '9') { && ALSAVersionString[curr] <= '9') {
inVersionString = TRUE; inVersionString = TRUE;
}
} }
} if (inVersionString) {
if (inVersionString) { // the version string ends with white space
// the version string ends with white space if (ALSAVersionString[curr] <= 32) {
if (ALSAVersionString[curr] <= 32) { break;
break; }
} if (curr != len) {
if (curr != len) { // copy this char to the beginning of the string
// copy this char to the beginning of the string ALSAVersionString[len] = ALSAVersionString[curr];
ALSAVersionString[len] = ALSAVersionString[curr]; }
len++;
} }
len++; curr++;
} }
curr++; // remove trailing dots
} while ((len > 0) && (ALSAVersionString[len - 1] == '.')) {
// remove trailing dots len--;
while ((len > 0) && (ALSAVersionString[len - 1] == '.')) { }
len--; // null terminate
ALSAVersionString[len] = 0;
} }
// null terminate fclose(file);
ALSAVersionString[len] = 0; hasGottenALSAVersion = TRUE;
} }
hasGottenALSAVersion = TRUE;
} }
strncpy(buffer, ALSAVersionString, len); strncpy(buffer, ALSAVersionString, len);
} }
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include "PlatformMidi.h" #include "PlatformMidi.h"
#include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h" #include "PLATFORM_API_LinuxOS_ALSA_MidiUtils.h"
#if defined(i586)
#include <sys/utsname.h>
#endif
/* /*
* Helper methods * Helper methods
...@@ -73,9 +76,38 @@ char* MIDI_IN_GetErrorStr(INT32 err) { ...@@ -73,9 +76,38 @@ char* MIDI_IN_GetErrorStr(INT32 err) {
return (char*) getErrorStr(err); return (char*) getErrorStr(err);
} }
INT32 MIDI_IN_GetNumDevices() { INT32 MIDI_IN_GetNumDevices() {
/* Workaround for 6842956: 32bit app on 64bit linux
* gets assertion failure trying to open midiIn ports.
* Untill the issue is fixed in ALSA
* (https://bugtrack.alsa-project.org/alsa-bug/view.php?id=4807)
* report no midi in devices in the configuration.
*/
#if defined(i586)
static int jre32onlinux64 = -1;
if (jre32onlinux64 < 0) {
jre32onlinux64 = 0;
/* The workaround may be disabled setting "JAVASOUND_ENABLE_MIDIIN"
* environment variable.
*/
if (getenv("JAVASOUND_ENABLE_MIDIIN") == NULL) {
struct utsname u;
jre32onlinux64 = 0;
if (uname(&u) == 0) {
if (strstr(u.machine, "64") != NULL) {
TRACE0("jre32 on linux64 detected - report no midiIn devices\n");
jre32onlinux64 = 1;
}
}
}
}
if (jre32onlinux64) {
return 0;
}
#endif
TRACE0("MIDI_IN_GetNumDevices()\n"); TRACE0("MIDI_IN_GetNumDevices()\n");
return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT); return getMidiDeviceCount(SND_RAWMIDI_STREAM_INPUT);
} }
......
/* /*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -372,7 +372,7 @@ INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex, ...@@ -372,7 +372,7 @@ INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex,
snd_rawmidi_t* native_handle; snd_rawmidi_t* native_handle;
snd_midi_event_t* event_parser = NULL; snd_midi_event_t* event_parser = NULL;
int err; int err;
UINT32 deviceID; UINT32 deviceID = 0;
char devicename[100]; char devicename[100];
#ifdef ALSA_MIDI_USE_PLUGHW #ifdef ALSA_MIDI_USE_PLUGHW
int usePlugHw = 1; int usePlugHw = 1;
......
/* /*
* Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -127,7 +127,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre ...@@ -127,7 +127,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre
int ret; int ret;
int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc; int sampleSizeInBytes, significantBits, isSigned, isBigEndian, enc;
int origSampleSizeInBytes, origSignificantBits; int origSampleSizeInBytes, origSignificantBits;
int channels, minChannels, maxChannels; unsigned int channels, minChannels, maxChannels;
int rate, bitIndex; int rate, bitIndex;
for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE; for (bitIndex = 0; bitIndex <= MAX_BIT_INDEX; bitIndex++) handledBits[bitIndex] = FALSE;
...@@ -152,7 +152,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre ...@@ -152,7 +152,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre
} }
} }
snd_pcm_hw_params_get_format_mask(hwParams, formatMask); snd_pcm_hw_params_get_format_mask(hwParams, formatMask);
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
if (ret == 0) { if (ret == 0) {
ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels); ret = snd_pcm_hw_params_get_channels_min(hwParams, &minChannels);
if (ret != 0) { if (ret != 0) {
...@@ -165,13 +164,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre ...@@ -165,13 +164,6 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre
ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret); ERROR1("snd_pcm_hw_params_get_channels_max returned error %d\n", ret);
} }
} }
#else
minChannels = snd_pcm_hw_params_get_channels_min(hwParams);
maxChannels = snd_pcm_hw_params_get_channels_max(hwParams);
if (minChannels > maxChannels) {
ERROR2("MinChannels=%d, maxChannels=%d\n", minChannels, maxChannels);
}
#endif
// since we queried the hw: device, for many soundcards, it will only // since we queried the hw: device, for many soundcards, it will only
// report the maximum number of channels (which is the only way to talk // report the maximum number of channels (which is the only way to talk
...@@ -222,7 +214,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre ...@@ -222,7 +214,7 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre
} else { } else {
for (channels = minChannels; channels <= maxChannels; channels++) { for (channels = minChannels; channels <= maxChannels; channels++) {
DAUDIO_AddAudioFormat(creator, significantBits, DAUDIO_AddAudioFormat(creator, significantBits,
(channels < 0)?-1:(sampleSizeInBytes * channels), sampleSizeInBytes * channels,
channels, rate, channels, rate,
enc, isSigned, isBigEndian); enc, isSigned, isBigEndian);
} }
...@@ -254,7 +246,7 @@ typedef struct tag_AlsaPcmInfo { ...@@ -254,7 +246,7 @@ typedef struct tag_AlsaPcmInfo {
snd_pcm_sw_params_t* swParams; snd_pcm_sw_params_t* swParams;
int bufferSizeInBytes; int bufferSizeInBytes;
int frameSize; // storage size in Bytes int frameSize; // storage size in Bytes
int periods; unsigned int periods;
snd_pcm_uframes_t periodSize; snd_pcm_uframes_t periodSize;
#ifdef GET_POSITION_METHOD2 #ifdef GET_POSITION_METHOD2
// to be used exclusively by getBytePosition! // to be used exclusively by getBytePosition!
...@@ -305,8 +297,8 @@ int setHWParams(AlsaPcmInfo* info, ...@@ -305,8 +297,8 @@ int setHWParams(AlsaPcmInfo* info,
int channels, int channels,
int bufferSizeInFrames, int bufferSizeInFrames,
snd_pcm_format_t format) { snd_pcm_format_t format) {
unsigned int rrate; unsigned int rrate, periodTime, periods;
int ret, dir, periods, periodTime; int ret, dir;
snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames; snd_pcm_uframes_t alsaBufferSizeInFrames = (snd_pcm_uframes_t) bufferSizeInFrames;
/* choose all parameters */ /* choose all parameters */
...@@ -335,12 +327,8 @@ int setHWParams(AlsaPcmInfo* info, ...@@ -335,12 +327,8 @@ int setHWParams(AlsaPcmInfo* info,
} }
/* set the stream rate */ /* set the stream rate */
rrate = (int) (sampleRate + 0.5f); rrate = (int) (sampleRate + 0.5f);
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
dir = 0; dir = 0;
ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir); ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, &rrate, &dir);
#else
ret = snd_pcm_hw_params_set_rate_near(info->handle, info->hwParams, rrate, 0);
#endif
if (ret < 0) { if (ret < 0) {
ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret)); ERROR2("Rate %dHz not available for playback: %s\n", (int) (sampleRate+0.5f), snd_strerror(ret));
return FALSE; return FALSE;
...@@ -350,12 +338,7 @@ int setHWParams(AlsaPcmInfo* info, ...@@ -350,12 +338,7 @@ int setHWParams(AlsaPcmInfo* info,
return FALSE; return FALSE;
} }
/* set the buffer time */ /* set the buffer time */
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames); ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, &alsaBufferSizeInFrames);
#else
ret = snd_pcm_hw_params_set_buffer_size_near(info->handle, info->hwParams, alsaBufferSizeInFrames);
#endif
if (ret < 0) { if (ret < 0) {
ERROR2("Unable to set buffer size to %d frames: %s\n", ERROR2("Unable to set buffer size to %d frames: %s\n",
(int) alsaBufferSizeInFrames, snd_strerror(ret)); (int) alsaBufferSizeInFrames, snd_strerror(ret));
...@@ -366,12 +349,7 @@ int setHWParams(AlsaPcmInfo* info, ...@@ -366,12 +349,7 @@ int setHWParams(AlsaPcmInfo* info,
if (bufferSizeInFrames > 1024) { if (bufferSizeInFrames > 1024) {
dir = 0; dir = 0;
periodTime = DEFAULT_PERIOD_TIME; periodTime = DEFAULT_PERIOD_TIME;
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir); ret = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, &periodTime, &dir);
#else
periodTime = snd_pcm_hw_params_set_period_time_near(info->handle, info->hwParams, periodTime, &dir);
ret = periodTime;
#endif
if (ret < 0) { if (ret < 0) {
ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret)); ERROR2("Unable to set period time to %d: %s\n", DEFAULT_PERIOD_TIME, snd_strerror(ret));
return FALSE; return FALSE;
...@@ -380,12 +358,7 @@ int setHWParams(AlsaPcmInfo* info, ...@@ -380,12 +358,7 @@ int setHWParams(AlsaPcmInfo* info,
/* set the period count for very small buffer sizes to 2 */ /* set the period count for very small buffer sizes to 2 */
dir = 0; dir = 0;
periods = 2; periods = 2;
#ifdef ALSA_PCM_NEW_HW_PARAMS_API
ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir); ret = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, &periods, &dir);
#else
periods = snd_pcm_hw_params_set_periods_near(info->handle, info->hwParams, periods, &dir);
ret = periods;
#endif
if (ret < 0) { if (ret < 0) {
ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret)); ERROR2("Unable to set period count to %d: %s\n", /*periods*/ 2, snd_strerror(ret));
return FALSE; return FALSE;
...@@ -421,12 +394,6 @@ int setSWParams(AlsaPcmInfo* info) { ...@@ -421,12 +394,6 @@ int setSWParams(AlsaPcmInfo* info) {
ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret)); ERROR1("Unable to set avail min for playback: %s\n", snd_strerror(ret));
return FALSE; return FALSE;
} }
/* align all transfers to 1 sample */
ret = snd_pcm_sw_params_set_xfer_align(info->handle, info->swParams, 1);
if (ret < 0) {
ERROR1("Unable to set transfer align: %s\n", snd_strerror(ret));
return FALSE;
}
/* write the parameters to the playback device */ /* write the parameters to the playback device */
ret = snd_pcm_sw_params(info->handle, info->swParams); ret = snd_pcm_sw_params(info->handle, info->swParams);
if (ret < 0) { if (ret < 0) {
...@@ -448,7 +415,6 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, ...@@ -448,7 +415,6 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
int ret = 0; int ret = 0;
AlsaPcmInfo* info = NULL; AlsaPcmInfo* info = NULL;
/* snd_pcm_uframes_t is 64 bit on 64-bit systems */ /* snd_pcm_uframes_t is 64 bit on 64-bit systems */
snd_pcm_uframes_t alsaPeriodSize = 0;
snd_pcm_uframes_t alsaBufferSizeInFrames = 0; snd_pcm_uframes_t alsaBufferSizeInFrames = 0;
...@@ -484,21 +450,13 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, ...@@ -484,21 +450,13 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
bufferSizeInBytes / frameSize, bufferSizeInBytes / frameSize,
format)) { format)) {
info->frameSize = frameSize; info->frameSize = frameSize;
#ifdef ALSA_PCM_NEW_HW_PARAMS_API ret = snd_pcm_hw_params_get_period_size(info->hwParams, &info->periodSize, &dir);
ret = snd_pcm_hw_params_get_period_size(info->hwParams, &alsaPeriodSize, &dir);
info->periodSize = (int) alsaPeriodSize;
if (ret < 0) { if (ret < 0) {
ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret)); ERROR1("ERROR: snd_pcm_hw_params_get_period: %s\n", snd_strerror(ret));
} }
snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir); snd_pcm_hw_params_get_periods(info->hwParams, &(info->periods), &dir);
snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames); snd_pcm_hw_params_get_buffer_size(info->hwParams, &alsaBufferSizeInFrames);
info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize; info->bufferSizeInBytes = (int) alsaBufferSizeInFrames * frameSize;
#else
info->periodSize = snd_pcm_hw_params_get_period_size(info->hwParams, &dir);
info->periods = snd_pcm_hw_params_get_periods(info->hwParams, &dir);
info->bufferSizeInBytes = snd_pcm_hw_params_get_buffer_size(info->hwParams) * frameSize;
ret = 0;
#endif
TRACE3(" DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n", TRACE3(" DAUDIO_Open: period size = %d frames, periods = %d. Buffer size: %d bytes.\n",
(int) info->periodSize, info->periods, info->bufferSizeInBytes); (int) info->periodSize, info->periods, info->bufferSizeInBytes);
} }
......
/* /*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
// define this with a later version of ALSA than 0.9.0rc3 // define this with a later version of ALSA than 0.9.0rc3
// (starting from 1.0.0 it became default behaviour)
#define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include "Utilities.h" #include "Utilities.h"
......
/* /*
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -380,7 +380,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) { ...@@ -380,7 +380,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
void* controls[10]; void* controls[10];
int numControls; int numControls;
char* portName; char* portName;
int isPlayback; int isPlayback = 0;
int isMono; int isMono;
int isStereo; int isStereo;
char* type; char* type;
......
...@@ -191,7 +191,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -191,7 +191,7 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
fp_gdk_threads_enter(); fp_gdk_threads_enter();
const char *title = (*env)->GetStringUTFChars(env, jtitle, 0); const char *title = jtitle == NULL? "": (*env)->GetStringUTFChars(env, jtitle, 0);
if (mode == 1) { if (mode == 1) {
/* Save action */ /* Save action */
...@@ -212,7 +212,9 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, ...@@ -212,7 +212,9 @@ Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
} }
} }
(*env)->ReleaseStringUTFChars(env, jtitle, title); if (jtitle != NULL) {
(*env)->ReleaseStringUTFChars(env, jtitle, title);
}
/* Set the directory */ /* Set the directory */
if (jdir != NULL) { if (jdir != NULL) {
......
...@@ -517,13 +517,15 @@ void ADD_SUFF(IntArgbPreSrcMaskFill)(void *rasBase, ...@@ -517,13 +517,15 @@ void ADD_SUFF(IntArgbPreSrcMaskFill)(void *rasBase,
ADD_SUFF(AnyIntSetRect)(pRasInfo, 0, 0, width, height, ADD_SUFF(AnyIntSetRect)(pRasInfo, 0, 0, width, height,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
#else #else
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
if (cnstA != 0xff) { if (cnstA != 0xff) {
fgColor = (cnstA << 24) | (cnstR << 16) | (cnstG << 8) | cnstB; fgColor = (cnstA << 24) | (cnstR << 16) | (cnstG << 8) | cnstB;
} }
ADD_SUFF(AnyIntSetRect)(pRasInfo, ADD_SUFF(AnyIntSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
#endif #endif
return; return;
} }
...@@ -582,11 +584,13 @@ void ADD_SUFF(FourByteAbgrPreSrcMaskFill)(void *rasBase, ...@@ -582,11 +584,13 @@ void ADD_SUFF(FourByteAbgrPreSrcMaskFill)(void *rasBase,
} }
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
fgColor = (cnstR << 24) | (cnstG << 16) | (cnstB << 8) | cnstA; fgColor = (cnstR << 24) | (cnstG << 16) | (cnstB << 8) | cnstA;
ADD_SUFF(Any4ByteSetRect)(pRasInfo, ADD_SUFF(Any4ByteSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
......
...@@ -150,10 +150,12 @@ void ADD_SUFF(IntArgbSrcMaskFill)(void *rasBase, ...@@ -150,10 +150,12 @@ void ADD_SUFF(IntArgbSrcMaskFill)(void *rasBase,
} }
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo, ADD_SUFF(AnyIntSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
...@@ -214,15 +216,17 @@ void ADD_SUFF(FourByteAbgrSrcMaskFill)(void *rasBase, ...@@ -214,15 +216,17 @@ void ADD_SUFF(FourByteAbgrSrcMaskFill)(void *rasBase,
cnstB = (fgColor ) & 0xff; cnstB = (fgColor ) & 0xff;
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
if (cnstA == 0) { if (cnstA == 0) {
fgColor = 0; fgColor = 0;
} else { } else {
fgColor = (fgColor << 8) | cnstA; fgColor = (fgColor << 8) | cnstA;
} }
ADD_SUFF(Any4ByteSetRect)(pRasInfo, ADD_SUFF(Any4ByteSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
...@@ -390,10 +394,12 @@ void ADD_SUFF(IntRgbSrcMaskFill)(void *rasBase, ...@@ -390,10 +394,12 @@ void ADD_SUFF(IntRgbSrcMaskFill)(void *rasBase,
if (cnstA == 0) fgColor = 0; if (cnstA == 0) fgColor = 0;
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo, ADD_SUFF(AnyIntSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
...@@ -458,10 +464,12 @@ void ADD_SUFF(IntBgrSrcMaskFill)(void *rasBase, ...@@ -458,10 +464,12 @@ void ADD_SUFF(IntBgrSrcMaskFill)(void *rasBase,
} }
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
ADD_SUFF(AnyIntSetRect)(pRasInfo, ADD_SUFF(AnyIntSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
...@@ -526,10 +534,12 @@ void ADD_SUFF(ThreeByteBgrSrcMaskFill)(void *rasBase, ...@@ -526,10 +534,12 @@ void ADD_SUFF(ThreeByteBgrSrcMaskFill)(void *rasBase,
} }
if (pMask == NULL) { if (pMask == NULL) {
void *pBase = pRasInfo->rasBase;
pRasInfo->rasBase = rasBase;
ADD_SUFF(Any3ByteSetRect)(pRasInfo, ADD_SUFF(Any3ByteSetRect)(pRasInfo,
pRasInfo->bounds.x1, pRasInfo->bounds.y1, 0, 0, width, height,
pRasInfo->bounds.x2, pRasInfo->bounds.y2,
fgColor, pPrim, pCompInfo); fgColor, pPrim, pCompInfo);
pRasInfo->rasBase = pBase;
return; return;
} }
......
...@@ -187,7 +187,9 @@ Java_java_awt_Component_initIDs ...@@ -187,7 +187,9 @@ Java_java_awt_Component_initIDs
"()Ljava/awt/Point;"); "()Ljava/awt/Point;");
keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent"); keyclass = (*env)->FindClass(env, "java/awt/event/KeyEvent");
DASSERT (keyclass != NULL); if (JNU_IsNull(env, keyclass)) {
return;
}
componentIDs.isProxyActive = componentIDs.isProxyActive =
(*env)->GetFieldID(env, keyclass, "isProxyActive", (*env)->GetFieldID(env, keyclass, "isProxyActive",
...@@ -715,8 +717,10 @@ Window get_xawt_root_shell(JNIEnv *env) { ...@@ -715,8 +717,10 @@ Window get_xawt_root_shell(JNIEnv *env) {
if (xawt_root_shell == None){ if (xawt_root_shell == None){
if (classXRootWindow == NULL){ if (classXRootWindow == NULL){
jclass cls_tmp = (*env)->FindClass(env, "sun/awt/X11/XRootWindow"); jclass cls_tmp = (*env)->FindClass(env, "sun/awt/X11/XRootWindow");
classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp); if (!JNU_IsNull(env, cls_tmp)) {
(*env)->DeleteLocalRef(env, cls_tmp); classXRootWindow = (jclass)(*env)->NewGlobalRef(env, cls_tmp);
(*env)->DeleteLocalRef(env, cls_tmp);
}
} }
if( classXRootWindow != NULL) { if( classXRootWindow != NULL) {
methodGetXRootWindow = (*env)->GetStaticMethodID(env, classXRootWindow, "getXRootWindow", "()J"); methodGetXRootWindow = (*env)->GetStaticMethodID(env, classXRootWindow, "getXRootWindow", "()J");
......
...@@ -999,6 +999,8 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -999,6 +999,8 @@ public abstract class WComponentPeer extends WObjectPeer
public void setBoundsOperation(int operation) { public void setBoundsOperation(int operation) {
} }
private volatile boolean isAccelCapable = true;
/** /**
* Returns whether this component is capable of being hw accelerated. * Returns whether this component is capable of being hw accelerated.
* More specifically, whether rendering to this component or a * More specifically, whether rendering to this component or a
...@@ -1009,11 +1011,22 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -1009,11 +1011,22 @@ public abstract class WComponentPeer extends WObjectPeer
* {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
* PERPIXEL_TRANSLUCENT}. * PERPIXEL_TRANSLUCENT}.
* *
* Another condition is if Xor paint mode was detected when rendering
* to an on-screen accelerated surface associated with this peer.
* in this case both on- and off-screen acceleration for this peer is
* disabled.
*
* @return {@code true} if this component is capable of being hw * @return {@code true} if this component is capable of being hw
* accelerated, {@code false} otherwise * accelerated, {@code false} otherwise
* @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT * @see GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
*/ */
public boolean isAccelCapable() { public boolean isAccelCapable() {
if (!isAccelCapable ||
!isContainingTopLevelAccelCapable((Component)target))
{
return false;
}
boolean isTranslucent = boolean isTranslucent =
SunToolkit.isContainingTopLevelTranslucent((Component)target); SunToolkit.isContainingTopLevelTranslucent((Component)target);
// D3D/OGL and translucent windows interacted poorly in Windows XP; // D3D/OGL and translucent windows interacted poorly in Windows XP;
...@@ -1021,6 +1034,14 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -1021,6 +1034,14 @@ public abstract class WComponentPeer extends WObjectPeer
return !isTranslucent || Win32GraphicsEnvironment.isVistaOS(); return !isTranslucent || Win32GraphicsEnvironment.isVistaOS();
} }
/**
* Disables acceleration for this peer.
*/
public void disableAcceleration() {
isAccelCapable = false;
}
native void setRectangularShape(int lox, int loy, int hix, int hiy, native void setRectangularShape(int lox, int loy, int hix, int hiy,
Region region); Region region);
......
...@@ -437,6 +437,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface { ...@@ -437,6 +437,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
protected int getElem(final int x, final int y, protected int getElem(final int x, final int y,
final SurfaceData sData) final SurfaceData sData)
{ {
if (sData.isSurfaceLost()) {
return 0;
}
int retPixel; int retPixel;
D3DRenderQueue rq = D3DRenderQueue.getInstance(); D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock(); rq.lock();
...@@ -456,6 +460,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface { ...@@ -456,6 +460,10 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
protected void setElem(final int x, final int y, final int pixel, protected void setElem(final int x, final int y, final int pixel,
final SurfaceData sData) final SurfaceData sData)
{ {
if (sData.isSurfaceLost()) {
return;
}
D3DRenderQueue rq = D3DRenderQueue.getInstance(); D3DRenderQueue rq = D3DRenderQueue.getInstance();
rq.lock(); rq.lock();
try { try {
...@@ -512,15 +520,32 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface { ...@@ -512,15 +520,32 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
sg2d.surfaceData.getTransparency() == Transparency.OPAQUE; sg2d.surfaceData.getTransparency() == Transparency.OPAQUE;
} }
/**
* If acceleration should no longer be used for this surface.
* This implementation flags to the manager that it should no
* longer attempt to re-create a D3DSurface.
*/
void disableAccelerationForSurface() {
if (offscreenImage != null) {
SurfaceManager sm = SurfaceManager.getManager(offscreenImage);
if (sm instanceof D3DVolatileSurfaceManager) {
setSurfaceLost(true);
((D3DVolatileSurfaceManager)sm).setAccelerationEnabled(false);
}
}
}
public void validatePipe(SunGraphics2D sg2d) { public void validatePipe(SunGraphics2D sg2d) {
TextPipe textpipe; TextPipe textpipe;
boolean validated = false; boolean validated = false;
// REMIND: the D3D pipeline doesn't support XOR!, more // REMIND: the D3D pipeline doesn't support XOR!, more
// fixes will be needed below // fixes will be needed below. For now we disable D3D rendering
// for the surface which had any XOR rendering done to.
if (sg2d.compositeState >= sg2d.COMP_XOR) { if (sg2d.compositeState >= sg2d.COMP_XOR) {
super.validatePipe(sg2d); super.validatePipe(sg2d);
sg2d.imagepipe = d3dImagePipe; sg2d.imagepipe = d3dImagePipe;
disableAccelerationForSurface();
return; return;
} }
...@@ -894,8 +919,26 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface { ...@@ -894,8 +919,26 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
return peer.getTarget(); return peer.getTarget();
} }
@Override
void disableAccelerationForSurface() {
// for on-screen surfaces we need to make sure a backup GDI surface is
// is used until a new one is set (which may happen during a resize). We
// don't want the screen update maanger to replace the surface right way
// because it causes repainting issues in Swing, so we invalidate it,
// this will prevent SUM from issuing a replaceSurfaceData call.
setSurfaceLost(true);
invalidate();
flush();
peer.disableAcceleration();
ScreenUpdateManager.getInstance().dropScreenSurface(this);
}
@Override @Override
void restoreSurface() { void restoreSurface() {
if (!peer.isAccelCapable()) {
throw new InvalidPipeException("Onscreen acceleration " +
"disabled for this surface");
}
Window fsw = graphicsDevice.getFullScreenWindow(); Window fsw = graphicsDevice.getFullScreenWindow();
if (fsw != null && fsw != peer.getTarget()) { if (fsw != null && fsw != peer.getTarget()) {
throw new InvalidPipeException("Can't restore onscreen surface"+ throw new InvalidPipeException("Can't restore onscreen surface"+
......
...@@ -133,7 +133,9 @@ public class WGLVolatileSurfaceManager ...@@ -133,7 +133,9 @@ public class WGLVolatileSurfaceManager
@Override @Override
protected boolean isConfigValid(GraphicsConfiguration gc) { protected boolean isConfigValid(GraphicsConfiguration gc) {
return ((gc == null) || (gc == vImg.getGraphicsConfig())); return ((gc == null) ||
((gc instanceof WGLGraphicsConfig) &&
(gc == vImg.getGraphicsConfig())));
} }
@Override @Override
......
...@@ -188,5 +188,6 @@ UTC-02:920,920::GMT-0200: ...@@ -188,5 +188,6 @@ UTC-02:920,920::GMT-0200:
UTC-11:921,921::GMT-1100: UTC-11:921,921::GMT-1100:
Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar: Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
Venezuela Standard Time:923,923::America/Caracas: Venezuela Standard Time:923,923::America/Caracas:
Western Brazilian Standard Time:924,924:BR:America/Rio_Branco: Magadan Standard Time:924,924::Asia/Magadan:
Armenian Standard Time:925,925:AM:Asia/Yerevan: Western Brazilian Standard Time:925,925:BR:America/Rio_Branco:
Armenian Standard Time:926,926:AM:Asia/Yerevan:
...@@ -54,7 +54,7 @@ static BOOL UpdateInstance(JNIEnv *env); ...@@ -54,7 +54,7 @@ static BOOL UpdateInstance(JNIEnv *env);
InstanceAccess& operator=(const InstanceAccess&); InstanceAccess& operator=(const InstanceAccess&);
InstanceAccess* operator&(); InstanceAccess* operator&();
}; };
friend InstanceAccess; friend class InstanceAccess;
private: private:
Devices(int numElements); Devices(int numElements);
......
...@@ -173,7 +173,7 @@ extern JavaVM *jvm; ...@@ -173,7 +173,7 @@ extern JavaVM *jvm;
// Platform encoding is Unicode (UTF-16), re-define JNU_ functions // Platform encoding is Unicode (UTF-16), re-define JNU_ functions
// to proper JNI functions. // to proper JNI functions.
#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<jchar*>(x), static_cast<jsize>(_tcslen(x))) #define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<const jchar*>(x), static_cast<jsize>(_tcslen(x)))
#define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y)) #define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y))
#define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y)) #define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y))
......
...@@ -47,12 +47,21 @@ void * operator new(size_t size, const char * filename, int linenumber) { ...@@ -47,12 +47,21 @@ void * operator new(size_t size, const char * filename, int linenumber) {
return ptr; return ptr;
} }
void * operator new[](size_t size, const char * filename, int linenumber) {
void * ptr = DMem_AllocateBlock(size, filename, linenumber);
if (ptr == NULL) {
throw std::bad_alloc();
}
return ptr;
}
#if _MSC_VER >= 1200 #if _MSC_VER >= 1200
void operator delete(void *ptr, const char*, int) { void operator delete(void *ptr, const char*, int) {
DASSERTMSG(FALSE, "This version of 'delete' should never get called!!!"); DASSERTMSG(FALSE, "This version of 'delete' should never get called!!!");
} }
#endif #endif
void operator delete(void *ptr) { void operator delete(void *ptr) throw() {
DMem_FreeBlock(ptr); DMem_FreeBlock(ptr);
} }
......
...@@ -48,11 +48,14 @@ ...@@ -48,11 +48,14 @@
}; };
extern void * operator new(size_t size, const char * filename, int linenumber); extern void * operator new(size_t size, const char * filename, int linenumber);
extern void * operator new[](size_t size, const char * filename, int linenumber);
#if _MSC_VER >= 1200 #if _MSC_VER >= 1200
/* VC 6.0 is more strict about enforcing matching placement new & delete */ /* VC 6.0 is more strict about enforcing matching placement new & delete */
extern void operator delete(void *ptr, const char*, int); extern void operator delete(void *ptr, const char*, int);
#endif #endif
extern void operator delete(void *ptr);
extern void operator delete(void *ptr) throw();
extern void DumpClipRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist); extern void DumpClipRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
extern void DumpUpdateRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist); extern void DumpUpdateRectangle(const char * file, int line, int argc, const char * fmt, va_list arglist);
......
...@@ -650,7 +650,7 @@ UINT AwtDesktopProperties::GetIntegerParameter(UINT spi) { ...@@ -650,7 +650,7 @@ UINT AwtDesktopProperties::GetIntegerParameter(UINT spi) {
} }
void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) { void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setStringPropertyID, AwtDesktopProperties::setStringPropertyID,
key, JNU_NewStringPlatform(GetEnv(), value)); key, JNU_NewStringPlatform(GetEnv(), value));
...@@ -658,7 +658,7 @@ void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) { ...@@ -658,7 +658,7 @@ void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
} }
void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) { void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setIntegerPropertyID, AwtDesktopProperties::setIntegerPropertyID,
key, (jint)value); key, (jint)value);
...@@ -666,7 +666,7 @@ void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) { ...@@ -666,7 +666,7 @@ void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
} }
void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) { void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setBooleanPropertyID, AwtDesktopProperties::setBooleanPropertyID,
key, value ? JNI_TRUE : JNI_FALSE); key, value ? JNI_TRUE : JNI_FALSE);
...@@ -674,7 +674,7 @@ void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) { ...@@ -674,7 +674,7 @@ void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
} }
void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) { void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setColorPropertyID, AwtDesktopProperties::setColorPropertyID,
key, GetRValue(value), GetGValue(value), key, GetRValue(value), GetGValue(value),
...@@ -726,7 +726,7 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, ...@@ -726,7 +726,7 @@ void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
style |= java_awt_Font_ITALIC; style |= java_awt_Font_ITALIC;
} }
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setFontPropertyID, AwtDesktopProperties::setFontPropertyID,
key, fontName, style, pointSize); key, fontName, style, pointSize);
...@@ -744,7 +744,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon ...@@ -744,7 +744,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
jint pointSize; jint pointSize;
jint style; jint style;
fontName = JNU_NewStringPlatform(GetEnv(), const_cast<LPWSTR>(font.lfFaceName)); fontName = JNU_NewStringPlatform(GetEnv(), font.lfFaceName);
#if 0 #if 0
HDC hdc; HDC hdc;
...@@ -767,7 +767,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon ...@@ -767,7 +767,7 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
style |= java_awt_Font_ITALIC; style |= java_awt_Font_ITALIC;
} }
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID, GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID,
key, fontName, style, pointSize); key, fontName, style, pointSize);
...@@ -776,8 +776,8 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon ...@@ -776,8 +776,8 @@ void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & fon
} }
void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) { void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
jstring key = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(propName)); jstring key = JNU_NewStringPlatform(GetEnv(), propName);
jstring event = JNU_NewStringPlatform(GetEnv(), const_cast<LPTSTR>(winEventName)); jstring event = JNU_NewStringPlatform(GetEnv(), winEventName);
GetEnv()->CallVoidMethod(self, GetEnv()->CallVoidMethod(self,
AwtDesktopProperties::setSoundPropertyID, AwtDesktopProperties::setSoundPropertyID,
key, event); key, event);
......
...@@ -230,7 +230,7 @@ LRESULT CALLBACK AwtDialog::ModalFilterProc(int code, ...@@ -230,7 +230,7 @@ LRESULT CALLBACK AwtDialog::ModalFilterProc(int code,
if (::IsIconic(hWnd)) { if (::IsIconic(hWnd)) {
::ShowWindow(hWnd, SW_RESTORE); ::ShowWindow(hWnd, SW_RESTORE);
} }
PopupAllDialogs(blocker, TRUE, ::GetForegroundWindow(), FALSE); PopupBlockers(blocker, TRUE, ::GetForegroundWindow(), FALSE);
// return 1 to prevent the system from allowing the operation // return 1 to prevent the system from allowing the operation
return 1; return 1;
} }
...@@ -256,7 +256,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, ...@@ -256,7 +256,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd)); HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
if (::IsWindow(blocker)) { if (::IsWindow(blocker)) {
BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd); BOOL onTaskbar = !(::WindowFromPoint(mhs->pt) == hWnd);
PopupAllDialogs(hWnd, FALSE, ::GetForegroundWindow(), onTaskbar); PopupBlockers(blocker, FALSE, ::GetForegroundWindow(), onTaskbar);
// return a nonzero value to prevent the system from passing // return a nonzero value to prevent the system from passing
// the message to the target window procedure // the message to the target window procedure
return 1; return 1;
...@@ -268,60 +268,60 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode, ...@@ -268,60 +268,60 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
} }
/* /*
* The function goes through the heirarchy of the blocker dialogs and * The function goes through the hierarchy of the blockers and
* popups all the dialogs. Note that the function starts from the top * popups all the blockers. Note that the function starts from the top
* blocker dialog and goes down to the dialog which is the bottom dialog. * blocker and goes down to the blocker which is the bottom one.
* Using another traversal may cause to the flickering issue as a bottom * Using another traversal algorithm (bottom->top) may cause to flickering
* dialog will cover a top dialog for some period of time. * as the bottom blocker will cover the top blocker for a while.
*/ */
void AwtDialog::PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) void AwtDialog::PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
{ {
HWND blocker = AwtWindow::GetModalBlocker(dialog); HWND nextBlocker = AwtWindow::GetModalBlocker(blocker);
BOOL isBlocked = ::IsWindow(blocker); BOOL nextBlockerExists = ::IsWindow(nextBlocker);
if (isBlocked) { if (nextBlockerExists) {
PopupAllDialogs(blocker, isModalHook, prevFGWindow, onTaskbar); PopupBlockers(nextBlocker, isModalHook, prevFGWindow, onTaskbar);
} }
PopupOneDialog(dialog, blocker, isModalHook, prevFGWindow, onTaskbar); PopupBlocker(blocker, nextBlocker, isModalHook, prevFGWindow, onTaskbar);
} }
/* /*
* The function popups the dialog, it distinguishes non-blocked dialogs * The function popups the blocker, for a non-blocked blocker we need
* and activates the dialogs (sets as foreground window). If the dialog is * to activate the blocker but if a blocker is blocked, then we need
* blocked, then it changes the Z-order of the dialog. * to change z-order of the blocker placing the blocker under the next blocker.
*/ */
void AwtDialog::PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar) void AwtDialog::PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar)
{ {
if (dialog == AwtToolkit::GetInstance().GetHWnd()) { if (blocker == AwtToolkit::GetInstance().GetHWnd()) {
return; return;
} }
// fix for 6494032 // fix for 6494032
if (isModalHook && !::IsWindowVisible(dialog)) { if (isModalHook && !::IsWindowVisible(blocker)) {
::ShowWindow(dialog, SW_SHOWNA); ::ShowWindow(blocker, SW_SHOWNA);
} }
BOOL isBlocked = ::IsWindow(blocker); BOOL nextBlockerExists = ::IsWindow(nextBlocker);
UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
if (isBlocked) { if (nextBlockerExists) {
// Fix for 6829546: if blocker is a top-most window, but window isn't, then // Fix for 6829546: if blocker is a top-most window, but window isn't, then
// calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well // calling ::SetWindowPos(dialog, blocker, ...) makes window top-most as well
BOOL isBlockerTopmost = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; BOOL topmostNextBlocker = (::GetWindowLong(nextBlocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
BOOL isDialogTopmost = (::GetWindowLong(dialog, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0; BOOL topmostBlocker = (::GetWindowLong(blocker, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
if (!isBlockerTopmost || isDialogTopmost) { if (!topmostNextBlocker || topmostBlocker) {
::SetWindowPos(dialog, blocker, 0, 0, 0, 0, flags); ::SetWindowPos(blocker, nextBlocker, 0, 0, 0, 0, flags);
} else { } else {
::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
} }
} else { } else {
::SetWindowPos(dialog, HWND_TOP, 0, 0, 0, 0, flags); ::SetWindowPos(blocker, HWND_TOP, 0, 0, 0, 0, flags);
// no beep/flash if the mouse was clicked in the taskbar menu // no beep/flash if the mouse was clicked in the taskbar menu
// or the dialog is currently inactive // or the dialog is currently inactive
if (!isModalHook && !onTaskbar && (dialog == prevFGWindow)) { if (!isModalHook && !onTaskbar && (blocker == prevFGWindow)) {
AnimateModalBlocker(dialog); AnimateModalBlocker(blocker);
} }
::BringWindowToTop(dialog); ::BringWindowToTop(blocker);
::SetForegroundWindow(dialog); ::SetForegroundWindow(blocker);
} }
} }
......
...@@ -113,8 +113,8 @@ private: ...@@ -113,8 +113,8 @@ private:
*/ */
static void ModalPerformActivation(HWND hWnd); static void ModalPerformActivation(HWND hWnd);
static void PopupAllDialogs(HWND dialog, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar); static void PopupBlockers(HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
static void PopupOneDialog(HWND dialog, HWND blocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar); static void PopupBlocker(HWND blocker, HWND nextBlocker, BOOL isModalHook, HWND prevFGWindow, BOOL onTaskbar);
public: public:
......
...@@ -41,9 +41,6 @@ ...@@ -41,9 +41,6 @@
class AwtTextArea : public AwtTextComponent { class AwtTextArea : public AwtTextComponent {
// inner classes
class OleCallback;
public: public:
/* java.awt.TextArea fields ids */ /* java.awt.TextArea fields ids */
...@@ -89,36 +86,11 @@ public: ...@@ -89,36 +86,11 @@ public:
static void _ReplaceText(void *param); static void _ReplaceText(void *param);
protected: protected:
INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
void EditSetSel(CHARRANGE &cr);
void EditGetSel(CHARRANGE &cr);
LONG EditGetCharFromPos(POINT& pt);
private:
// RichEdit 1.0 control generates EN_CHANGE notifications not only
// on text changes, but also on any character formatting change.
// This flag is true when the latter case is detected.
BOOL m_bIgnoreEnChange;
// RichEdit 1.0 control undoes a character formatting change
// if it is the latest. We don't create our own undo buffer,
// but just prohibit undo in case if the latest operation
// is a formatting change.
BOOL m_bCanUndo;
HWND m_hEditCtrl;
static WNDPROC sm_pDefWindowProc;
LONG m_lHDeltaAccum;
LONG m_lVDeltaAccum;
static OleCallback sm_oleCallback;
/***************************************************************** /*****************************************************************
* Inner class OleCallback declaration. * Inner class OleCallback declaration.
*/ */
class OleCallback : public IRichEditOleCallback {
class AwtTextArea::OleCallback : public IRichEditOleCallback {
public: public:
OleCallback(); OleCallback();
...@@ -143,7 +115,32 @@ protected: ...@@ -143,7 +115,32 @@ protected:
CHARRANGE FAR * pchrg, HMENU FAR * phmenu); CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
private: private:
ULONG m_refs; // Reference count ULONG m_refs; // Reference count
}; };//OleCallback class
INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
void EditSetSel(CHARRANGE &cr);
void EditGetSel(CHARRANGE &cr);
LONG EditGetCharFromPos(POINT& pt);
private:
// RichEdit 1.0 control generates EN_CHANGE notifications not only
// on text changes, but also on any character formatting change.
// This flag is true when the latter case is detected.
BOOL m_bIgnoreEnChange;
// RichEdit 1.0 control undoes a character formatting change
// if it is the latest. We don't create our own undo buffer,
// but just prohibit undo in case if the latest operation
// is a formatting change.
BOOL m_bCanUndo;
HWND m_hEditCtrl;
static WNDPROC sm_pDefWindowProc;
LONG m_lHDeltaAccum;
LONG m_lVDeltaAccum;
static OleCallback sm_oleCallback;
}; };
......
...@@ -110,7 +110,7 @@ class CriticalSection { ...@@ -110,7 +110,7 @@ class CriticalSection {
private: private:
const CriticalSection& critSec; const CriticalSection& critSec;
}; };
friend Lock; friend class Lock;
private: private:
CRITICAL_SECTION rep; CRITICAL_SECTION rep;
......
...@@ -64,6 +64,7 @@ public class WindowOpacity ...@@ -64,6 +64,7 @@ public class WindowOpacity
boolean passed; boolean passed;
Frame f = new Frame("Opacity test"); Frame f = new Frame("Opacity test");
f.setUndecorated(true);
passed = false; passed = false;
try { try {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* @test * @test
* @bug 5010310 6319835 6904882 6968373 * @bug 5010310 6319835 6904882 6968373
* @summary test fonts can be created in the presence of a security manager * @summary test fonts can be created in the presence of a security manager
* @run main/othervm/secure=java.lang.SecurityManager FontPrivilege * @run main FontPrivilege
*/ */
import java.awt.Font; import java.awt.Font;
...@@ -33,6 +33,8 @@ import java.awt.Font; ...@@ -33,6 +33,8 @@ import java.awt.Font;
public class FontPrivilege { public class FontPrivilege {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
System.setSecurityManager(new SecurityManager());
new Font("Helvetica", Font.PLAIN, 12).getFamily(); new Font("Helvetica", Font.PLAIN, 12).getFamily();
new Font("foo bar", Font.PLAIN, 12).getFamily(); new Font("foo bar", Font.PLAIN, 12).getFamily();
} }
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 6996867
* @summary Render as LCD Text in SrcEa composite mode.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class LCDTextSrcEa extends Component {
static int SZ=150;
BufferedImage target =
new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
public static void main(String args[]) {
Frame f = new Frame("LCD Text SrcEa Test");
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
LCDTextSrcEa td = new LCDTextSrcEa();
f.add("Center", td);
f.pack();
f.setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(SZ,SZ);
}
public void paint(Graphics gx) {
Graphics2D g2d = (Graphics2D) target.getGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.01f));
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
g2d.drawString("Some sample text.", 10, 20);
gx.drawImage(target, 0, 0, null);
boolean nongrey = false;
//Test BI: should be some non-greyscale color
for (int px=0;px<SZ;px++) {
for (int py=0;py<SZ;py++) {
int rgb = target.getRGB(px, py);
int r = (rgb & 0xff0000) >> 16;
int g = (rgb & 0x00ff00) >> 8;
int b = (rgb & 0x0000ff);
if (r != g || r !=b || g != b) {
nongrey=true;
break;
}
}
}
if (!nongrey) {
throw new RuntimeException("No LCD text found");
}
}
}
Filled AA Pure Rect(5, 29.4, 10, 10)
Stroked AA Pure Rect(5, 4.4, 10, 10)
Stroked AA Line(20, 20, -10, 20)
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6766342
* @summary Tests clipping invariance for AA rectangle and line primitives
* @run main RenderClipTest -strict -readfile 6766342.tests
* @run main RenderClipTest -rectsuite -count 10
*/
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.event.*;
import java.util.Vector;
import java.io.*;
public class RenderClipTest {
public static double randDblCoord() {
return Math.random()*60 - 10;
}
public static float randFltCoord() {
return (float) randDblCoord();
}
public static int randIntCoord() {
return (int) Math.round(randDblCoord());
}
public static int randInt(int n) {
return ((int) (Math.random() * (n*4))) >> 2;
}
static int numtests;
static int numerrors;
static int numfillfailures;
static int numstrokefailures;
static int maxerr;
static boolean useAA;
static boolean strokePure;
static boolean testFill;
static boolean testDraw;
static boolean silent;
static boolean verbose;
static boolean strict;
static boolean showErrors;
static float lw;
static double rot;
static BufferedImage imgref;
static BufferedImage imgtst;
static Graphics2D grefclear;
static Graphics2D gtstclear;
static Graphics2D grefrender;
static Graphics2D gtstrender;
public static abstract class AnnotatedRenderOp {
public static AnnotatedRenderOp parse(String str) {
AnnotatedRenderOp ar;
if (((ar = Cubic.tryparse(str)) != null) ||
((ar = Quad.tryparse(str)) != null) ||
((ar = Poly.tryparse(str)) != null) ||
((ar = Path.tryparse(str)) != null) ||
((ar = Rect.tryparse(str)) != null) ||
((ar = Line.tryparse(str)) != null) ||
((ar = RectMethod.tryparse(str)) != null) ||
((ar = LineMethod.tryparse(str)) != null))
{
return ar;
}
System.err.println("Unable to parse shape: "+str);
return null;
}
public abstract void randomize();
public abstract void fill(Graphics2D g2d);
public abstract void draw(Graphics2D g2d);
}
public static abstract class AnnotatedShapeOp extends AnnotatedRenderOp {
public abstract Shape getShape();
public void fill(Graphics2D g2d) {
g2d.fill(getShape());
}
public void draw(Graphics2D g2d) {
g2d.draw(getShape());
}
}
public static void usage(String err) {
if (err != null) {
System.err.println(err);
}
System.err.println("usage: java RenderClipTest "+
"[-read[file F]] [-rectsuite] [-fill] [-draw]");
System.err.println(" "+
"[-aa] [-pure] [-lw N] [-rot N]");
System.err.println(" "+
"[-rectmethod] [-linemethod] [-rect] [-line]");
System.err.println(" "+
"[-cubic] [-quad] [-poly] [-path]");
System.err.println(" "+
"[-silent] [-verbose] [-showerr] [-count N]");
System.err.println(" "+
"[-strict] [-usage]");
System.err.println(" -read Read test data from stdin");
System.err.println(" -readfile F Read test data from file F");
System.err.println(" -rectsuite Run a suite of rect/line tests");
System.err.println(" -fill Test g.fill*(...)");
System.err.println(" -draw Test g.draw*(...)");
System.err.println(" -aa Use antialiased rendering");
System.err.println(" -pure Use STROKE_PURE hint");
System.err.println(" -lw N Test line widths of N "+
"(default 1.0)");
System.err.println(" -rot N Test rotation by N degrees "+
"(default 0.0)");
System.err.println(" -rectmethod Test fillRect/drawRect methods");
System.err.println(" -linemethod Test drawLine method");
System.err.println(" -rect Test Rectangle2D shapes");
System.err.println(" -line Test Line2D shapes");
System.err.println(" -cubic Test CubicCurve2D shapes");
System.err.println(" -quad Test QuadCurve2D shapes");
System.err.println(" -poly Test Polygon shapes");
System.err.println(" -path Test GeneralPath shapes");
System.err.println(" -silent Do not print out error curves");
System.err.println(" -verbose Print out progress info");
System.err.println(" -showerr Display errors on screen");
System.err.println(" -count N N tests per shape, then exit "+
"(default 1000)");
System.err.println(" -strict All failures are important");
System.err.println(" -usage Print this help, then exit");
System.exit((err != null) ? -1 : 0);
}
public static void main(String argv[]) {
boolean readTests = false;
String readFile = null;
boolean rectsuite = false;
int count = 1000;
lw = 1.0f;
rot = 0.0;
Vector<AnnotatedRenderOp> testOps = new Vector<AnnotatedRenderOp>();
for (int i = 0; i < argv.length; i++) {
String arg = argv[i].toLowerCase();
if (arg.equals("-aa")) {
useAA = true;
} else if (arg.equals("-pure")) {
strokePure = true;
} else if (arg.equals("-fill")) {
testFill = true;
} else if (arg.equals("-draw")) {
testDraw = true;
} else if (arg.equals("-lw")) {
if (i+1 >= argv.length) {
usage("Missing argument: "+argv[i]);
}
lw = Float.parseFloat(argv[++i]);
} else if (arg.equals("-rot")) {
if (i+1 >= argv.length) {
usage("Missing argument: "+argv[i]);
}
rot = Double.parseDouble(argv[++i]);
} else if (arg.equals("-cubic")) {
testOps.add(new Cubic());
} else if (arg.equals("-quad")) {
testOps.add(new Quad());
} else if (arg.equals("-poly")) {
testOps.add(new Poly());
} else if (arg.equals("-path")) {
testOps.add(new Path());
} else if (arg.equals("-rect")) {
testOps.add(new Rect());
} else if (arg.equals("-line")) {
testOps.add(new Line());
} else if (arg.equals("-rectmethod")) {
testOps.add(new RectMethod());
} else if (arg.equals("-linemethod")) {
testOps.add(new LineMethod());
} else if (arg.equals("-verbose")) {
verbose = true;
} else if (arg.equals("-strict")) {
strict = true;
} else if (arg.equals("-silent")) {
silent = true;
} else if (arg.equals("-showerr")) {
showErrors = true;
} else if (arg.equals("-readfile")) {
if (i+1 >= argv.length) {
usage("Missing argument: "+argv[i]);
}
readTests = true;
readFile = argv[++i];
} else if (arg.equals("-read")) {
readTests = true;
readFile = null;
} else if (arg.equals("-rectsuite")) {
rectsuite = true;
} else if (arg.equals("-count")) {
if (i+1 >= argv.length) {
usage("Missing argument: "+argv[i]);
}
count = Integer.parseInt(argv[++i]);
} else if (arg.equals("-usage")) {
usage(null);
} else {
usage("Unknown argument: "+argv[i]);
}
}
if (readTests) {
if (rectsuite || testDraw || testFill ||
useAA || strokePure ||
lw != 1.0f || rot != 0.0 ||
testOps.size() > 0)
{
usage("Should not specify test types with -read options");
}
} else if (rectsuite) {
if (testDraw || testFill ||
useAA || strokePure ||
lw != 1.0f || rot != 0.0 ||
testOps.size() > 0)
{
usage("Should not specify test types with -rectsuite option");
}
} else {
if (!testDraw && !testFill) {
usage("No work: Must specify one or both of "+
"-fill or -draw");
}
if (testOps.size() == 0) {
usage("No work: Must specify one or more of "+
"-rect[method], -line[method], "+
"-cubic, -quad, -poly, or -path");
}
}
initImages();
if (readTests) {
try {
InputStream is;
if (readFile == null) {
is = System.in;
} else {
File f =
new File(System.getProperty("test.src", "."),
readFile);
is = new FileInputStream(f);
}
parseAndRun(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else if (rectsuite) {
runRectSuite(count);
} else {
initGCs();
for (int k = 0; k < testOps.size(); k++) {
AnnotatedRenderOp ar = testOps.get(k);
runRandomTests(ar, count);
}
disposeGCs();
}
grefclear.dispose();
gtstclear.dispose();
grefclear = gtstclear = null;
reportStatistics();
}
public static int reportStatistics() {
String connector = "";
if (numfillfailures > 0) {
System.out.print(numfillfailures+" fills ");
connector = "and ";
}
if (numstrokefailures > 0) {
System.out.print(connector+numstrokefailures+" strokes ");
}
int totalfailures = numfillfailures + numstrokefailures;
if (totalfailures == 0) {
System.out.print("0 ");
}
System.out.println("out of "+numtests+" tests failed...");
int critical = numerrors;
if (strict) {
critical += totalfailures;
}
if (critical > 0) {
throw new RuntimeException(critical+" tests had critical errors");
}
System.out.println("No tests had critical errors");
return (numerrors+totalfailures);
}
public static void runRectSuite(int count) {
AnnotatedRenderOp ops[] = {
new Rect(),
new RectMethod(),
new Line(),
new LineMethod(),
};
// Sometimes different fill algorithms are chosen for
// thin and wide line modes, make sure we test both...
float filllinewidths[] = { 0.0f, 2.0f };
float drawlinewidths[] = { 0.0f, 0.5f, 1.0f,
2.0f, 2.5f,
5.0f, 5.3f };
double rotations[] = { 0.0, 15.0, 90.0,
135.0, 180.0,
200.0, 270.0,
300.0};
for (AnnotatedRenderOp ar: ops) {
for (double r: rotations) {
rot = r;
for (int i = 0; i < 8; i++) {
float linewidths[];
if ((i & 1) == 0) {
if ((ar instanceof Line) ||
(ar instanceof LineMethod))
{
continue;
}
testFill = true;
testDraw = false;
linewidths = filllinewidths;
} else {
testFill = false;
testDraw = true;
linewidths = drawlinewidths;
}
useAA = ((i & 2) != 0);
strokePure = ((i & 4) != 0);
for (float w : linewidths) {
lw = w;
runSuiteTests(ar, count);
}
}
}
}
}
public static void runSuiteTests(AnnotatedRenderOp ar, int count) {
if (verbose) {
System.out.print("Running ");
System.out.print(testFill ? "Fill " : "Draw ");
System.out.print(BaseName(ar));
if (useAA) {
System.out.print(" AA");
}
if (strokePure) {
System.out.print(" Pure");
}
if (lw != 1.0f) {
System.out.print(" lw="+lw);
}
if (rot != 0.0f) {
System.out.print(" rot="+rot);
}
System.out.println();
}
initGCs();
runRandomTests(ar, count);
disposeGCs();
}
public static String BaseName(AnnotatedRenderOp ar) {
String s = ar.toString();
int leftparen = s.indexOf('(');
if (leftparen >= 0) {
s = s.substring(0, leftparen);
}
return s;
}
public static void runRandomTests(AnnotatedRenderOp ar, int count) {
for (int i = 0; i < count; i++) {
ar.randomize();
if (testDraw) {
test(ar, false);
}
if (testFill) {
test(ar, true);
}
}
}
public static void initImages() {
imgref = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
imgtst = new BufferedImage(40, 40, BufferedImage.TYPE_INT_RGB);
grefclear = imgref.createGraphics();
gtstclear = imgtst.createGraphics();
grefclear.setColor(Color.white);
gtstclear.setColor(Color.white);
}
public static void initGCs() {
grefrender = imgref.createGraphics();
gtstrender = imgtst.createGraphics();
gtstrender.clipRect(10, 10, 20, 20);
grefrender.setColor(Color.blue);
gtstrender.setColor(Color.blue);
if (lw != 1.0f) {
BasicStroke bs = new BasicStroke(lw);
grefrender.setStroke(bs);
gtstrender.setStroke(bs);
}
if (rot != 0.0) {
double rotrad = Math.toRadians(rot);
grefrender.rotate(rotrad, 20, 20);
gtstrender.rotate(rotrad, 20, 20);
}
if (strokePure) {
grefrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
gtstrender.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
}
if (useAA) {
grefrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gtstrender.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
maxerr = 1;
}
}
public static void disposeGCs() {
grefrender.dispose();
gtstrender.dispose();
grefrender = gtstrender = null;
}
public static void parseAndRun(InputStream in) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String str;
while ((str = br.readLine()) != null) {
if (str.startsWith("Stroked ") || str.startsWith("Filled ")) {
parseTest(str);
continue;
}
if (str.startsWith("Running ")) {
continue;
}
if (str.startsWith("Failed: ")) {
continue;
}
if (str.indexOf(" out of ") > 0 &&
str.indexOf(" tests failed...") > 0)
{
continue;
}
if (str.indexOf(" tests had critical errors") > 0) {
continue;
}
System.err.println("Unparseable line: "+str);
}
}
public static void parseTest(String origstr) {
String str = origstr;
boolean isfill = false;
useAA = strokePure = false;
lw = 1.0f;
rot = 0.0;
if (str.startsWith("Stroked ")) {
str = str.substring(8);
isfill = false;
} else if (str.startsWith("Filled ")) {
str = str.substring(7);
isfill = true;
} else {
System.err.println("Unparseable test line: "+origstr);
}
if (str.startsWith("AA ")) {
str = str.substring(3);
useAA = true;
}
if (str.startsWith("Pure ")) {
str = str.substring(5);
strokePure = true;
}
if (str.startsWith("Lw=")) {
int index = str.indexOf(' ', 3);
if (index > 0) {
lw = Float.parseFloat(str.substring(3, index));
str = str.substring(index+1);
}
}
if (str.startsWith("Rot=")) {
int index = str.indexOf(' ', 4);
if (index > 0) {
rot = Double.parseDouble(str.substring(4, index));
str = str.substring(index+1);
}
}
AnnotatedRenderOp ar = AnnotatedRenderOp.parse(str);
if (ar != null) {
initGCs();
test(ar, isfill);
disposeGCs();
} else {
System.err.println("Unparseable test line: "+origstr);
}
}
public static void test(AnnotatedRenderOp ar, boolean isfill) {
grefclear.fillRect(0, 0, 40, 40);
gtstclear.fillRect(0, 0, 40, 40);
if (isfill) {
ar.fill(grefrender);
ar.fill(gtstrender);
} else {
ar.draw(grefrender);
ar.draw(gtstrender);
}
check(imgref, imgtst, ar, isfill);
}
public static int[] getData(BufferedImage img) {
Raster r = img.getRaster();
DataBufferInt dbi = (DataBufferInt) r.getDataBuffer();
return dbi.getData();
}
public static int getScan(BufferedImage img) {
Raster r = img.getRaster();
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel) r.getSampleModel();
return sppsm.getScanlineStride();
}
public static int getOffset(BufferedImage img) {
Raster r = img.getRaster();
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel) r.getSampleModel();
return sppsm.getOffset(-r.getSampleModelTranslateX(),
-r.getSampleModelTranslateY());
}
final static int opaque = 0xff000000;
final static int whitergb = Color.white.getRGB();
public static final int maxdiff(int rgb1, int rgb2) {
int maxd = 0;
for (int i = 0; i < 32; i += 8) {
int c1 = (rgb1 >> i) & 0xff;
int c2 = (rgb2 >> i) & 0xff;
int d = Math.abs(c1-c2);
if (maxd < d) {
maxd = d;
}
}
return maxd;
}
public static void check(BufferedImage imgref, BufferedImage imgtst,
AnnotatedRenderOp ar, boolean wasfill)
{
numtests++;
int dataref[] = getData(imgref);
int datatst[] = getData(imgtst);
int scanref = getScan(imgref);
int scantst = getScan(imgtst);
int offref = getOffset(imgref);
int offtst = getOffset(imgtst);
// We want to check for errors outside the clip at a higher
// priority than errors involving different pixels touched
// inside the clip.
// Check above clip
if (check(ar, wasfill,
null, 0, 0,
datatst, scantst, offtst,
0, 0, 40, 10))
{
return;
}
// Check below clip
if (check(ar, wasfill,
null, 0, 0,
datatst, scantst, offtst,
0, 30, 40, 40))
{
return;
}
// Check left of clip
if (check(ar, wasfill,
null, 0, 0,
datatst, scantst, offtst,
0, 10, 10, 30))
{
return;
}
// Check right of clip
if (check(ar, wasfill,
null, 0, 0,
datatst, scantst, offtst,
30, 10, 40, 30))
{
return;
}
// Check inside clip
check(ar, wasfill,
dataref, scanref, offref,
datatst, scantst, offtst,
10, 10, 30, 30);
}
public static boolean check(AnnotatedRenderOp ar, boolean wasfill,
int dataref[], int scanref, int offref,
int datatst[], int scantst, int offtst,
int x0, int y0, int x1, int y1)
{
offref += scanref * y0;
offtst += scantst * y0;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
boolean failed;
String reason;
int rgbref;
int rgbtst;
rgbtst = datatst[offtst+x] | opaque;
if (dataref == null) {
/* Outside of clip, must be white, no error tolerance */
rgbref = whitergb;
failed = (rgbtst != rgbref);
reason = "stray pixel rendered outside of clip";
} else {
/* Inside of clip, check for maxerr delta in components */
rgbref = dataref[offref+x] | opaque;
failed = (rgbref != rgbtst &&
maxdiff(rgbref, rgbtst) > maxerr);
reason = "different pixel rendered inside clip";
}
if (failed) {
if (dataref == null) {
numerrors++;
}
if (wasfill) {
numfillfailures++;
} else {
numstrokefailures++;
}
if (!silent) {
System.out.println("Failed: "+reason+" at "+x+", "+y+
" ["+Integer.toHexString(rgbref)+
" != "+Integer.toHexString(rgbtst)+
"]");
System.out.print(wasfill ? "Filled " : "Stroked ");
if (useAA) System.out.print("AA ");
if (strokePure) System.out.print("Pure ");
if (lw != 1) System.out.print("Lw="+lw+" ");
if (rot != 0) System.out.print("Rot="+rot+" ");
System.out.println(ar);
}
if (showErrors) {
show(imgref, imgtst);
}
return true;
}
}
offref += scanref;
offtst += scantst;
}
return false;
}
static ErrorWindow errw;
public static void show(BufferedImage imgref, BufferedImage imgtst) {
ErrorWindow errw = new ErrorWindow();
errw.setImages(imgref, imgtst);
errw.setVisible(true);
errw.waitForHide();
errw.dispose();
}
public static class Cubic extends AnnotatedShapeOp {
public static Cubic tryparse(String str) {
str = str.trim();
if (!str.startsWith("Cubic(")) {
return null;
}
str = str.substring(6);
double coords[] = new double[8];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index);
try {
coords[i] = Double.parseDouble(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
Cubic c = new Cubic();
c.cubic.setCurve(coords[0], coords[1],
coords[2], coords[3],
coords[4], coords[5],
coords[6], coords[7]);
return c;
}
private CubicCurve2D cubic = new CubicCurve2D.Double();
public void randomize() {
cubic.setCurve(randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord());
}
public Shape getShape() {
return cubic;
}
public String toString() {
return ("Cubic("+
cubic.getX1()+", "+
cubic.getY1()+", "+
cubic.getCtrlX1()+", "+
cubic.getCtrlY1()+", "+
cubic.getCtrlX2()+", "+
cubic.getCtrlY2()+", "+
cubic.getX2()+", "+
cubic.getY2()
+")");
}
}
public static class Quad extends AnnotatedShapeOp {
public static Quad tryparse(String str) {
str = str.trim();
if (!str.startsWith("Quad(")) {
return null;
}
str = str.substring(5);
double coords[] = new double[6];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index);
try {
coords[i] = Double.parseDouble(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
Quad c = new Quad();
c.quad.setCurve(coords[0], coords[1],
coords[2], coords[3],
coords[4], coords[5]);
return c;
}
private QuadCurve2D quad = new QuadCurve2D.Double();
public void randomize() {
quad.setCurve(randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord());
}
public Shape getShape() {
return quad;
}
public String toString() {
return ("Quad("+
quad.getX1()+", "+
quad.getY1()+", "+
quad.getCtrlX()+", "+
quad.getCtrlY()+", "+
quad.getX2()+", "+
quad.getY2()
+")");
}
}
public static class Poly extends AnnotatedShapeOp {
public static Poly tryparse(String str) {
str = str.trim();
if (!str.startsWith("Poly(")) {
return null;
}
str = str.substring(5);
Polygon p = new Polygon();
while (true) {
int x, y;
str = str.trim();
if (str.startsWith(")")) {
str = str.substring(1);
break;
}
if (p.npoints > 0) {
if (str.startsWith(",")) {
str = str.substring(2).trim();
} else {
return null;
}
}
if (str.startsWith("[")) {
str = str.substring(1);
} else {
return null;
}
int index = str.indexOf(",");
if (index < 0) {
return null;
}
String num = str.substring(0, index);
try {
x = Integer.parseInt(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
index = str.indexOf("]");
if (index < 0) {
return null;
}
num = str.substring(0, index).trim();
try {
y = Integer.parseInt(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
p.addPoint(x, y);
}
if (str.length() > 0) {
return null;
}
if (p.npoints < 3) {
return null;
}
return new Poly(p);
}
private Polygon poly;
public Poly() {
this.poly = new Polygon();
}
private Poly(Polygon p) {
this.poly = p;
}
public void randomize() {
poly.reset();
poly.addPoint(randIntCoord(), randIntCoord());
poly.addPoint(randIntCoord(), randIntCoord());
poly.addPoint(randIntCoord(), randIntCoord());
poly.addPoint(randIntCoord(), randIntCoord());
poly.addPoint(randIntCoord(), randIntCoord());
}
public Shape getShape() {
return poly;
}
public String toString() {
StringBuffer sb = new StringBuffer(100);
sb.append("Poly(");
for (int i = 0; i < poly.npoints; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append("[");
sb.append(poly.xpoints[i]);
sb.append(", ");
sb.append(poly.ypoints[i]);
sb.append("]");
}
sb.append(")");
return sb.toString();
}
}
public static class Path extends AnnotatedShapeOp {
public static Path tryparse(String str) {
str = str.trim();
if (!str.startsWith("Path(")) {
return null;
}
str = str.substring(5);
GeneralPath gp = new GeneralPath();
float coords[] = new float[6];
int numsegs = 0;
while (true) {
int type;
int n;
str = str.trim();
if (str.startsWith(")")) {
str = str.substring(1);
break;
}
if (str.startsWith("M[")) {
type = PathIterator.SEG_MOVETO;
n = 2;
} else if (str.startsWith("L[")) {
type = PathIterator.SEG_LINETO;
n = 2;
} else if (str.startsWith("Q[")) {
type = PathIterator.SEG_QUADTO;
n = 4;
} else if (str.startsWith("C[")) {
type = PathIterator.SEG_CUBICTO;
n = 6;
} else if (str.startsWith("E[")) {
type = PathIterator.SEG_CLOSE;
n = 0;
} else {
return null;
}
str = str.substring(2);
if (n == 0) {
if (str.startsWith("]")) {
str = str.substring(1);
} else {
return null;
}
}
for (int i = 0; i < n; i++) {
int index;
if (i < n-1) {
index = str.indexOf(",");
} else {
index = str.indexOf("]");
}
if (index < 0) {
return null;
}
String num = str.substring(0, index);
try {
coords[i] = Float.parseFloat(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1).trim();
}
switch (type) {
case PathIterator.SEG_MOVETO:
gp.moveTo(coords[0], coords[1]);
break;
case PathIterator.SEG_LINETO:
gp.lineTo(coords[0], coords[1]);
break;
case PathIterator.SEG_QUADTO:
gp.quadTo(coords[0], coords[1],
coords[2], coords[3]);
break;
case PathIterator.SEG_CUBICTO:
gp.curveTo(coords[0], coords[1],
coords[2], coords[3],
coords[4], coords[5]);
break;
case PathIterator.SEG_CLOSE:
gp.closePath();
break;
}
numsegs++;
}
if (str.length() > 0) {
return null;
}
if (numsegs < 2) {
return null;
}
return new Path(gp);
}
private GeneralPath path;
public Path() {
this.path = new GeneralPath();
}
private Path(GeneralPath gp) {
this.path = gp;
}
public void randomize() {
path.reset();
path.moveTo(randFltCoord(), randFltCoord());
for (int i = randInt(5)+3; i > 0; --i) {
switch(randInt(5)) {
case 0:
path.moveTo(randFltCoord(), randFltCoord());
break;
case 1:
path.lineTo(randFltCoord(), randFltCoord());
break;
case 2:
path.quadTo(randFltCoord(), randFltCoord(),
randFltCoord(), randFltCoord());
break;
case 3:
path.curveTo(randFltCoord(), randFltCoord(),
randFltCoord(), randFltCoord(),
randFltCoord(), randFltCoord());
break;
case 4:
path.closePath();
break;
}
}
}
public Shape getShape() {
return path;
}
public String toString() {
StringBuffer sb = new StringBuffer(100);
sb.append("Path(");
PathIterator pi = path.getPathIterator(null);
float coords[] = new float[6];
boolean first = true;
while (!pi.isDone()) {
int n;
char c;
switch(pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
c = 'M';
n = 2;
break;
case PathIterator.SEG_LINETO:
c = 'L';
n = 2;
break;
case PathIterator.SEG_QUADTO:
c = 'Q';
n = 4;
break;
case PathIterator.SEG_CUBICTO:
c = 'C';
n = 6;
break;
case PathIterator.SEG_CLOSE:
c = 'E';
n = 0;
break;
default:
throw new InternalError("Unknown segment!");
}
sb.append(c);
sb.append("[");
for (int i = 0; i < n; i++) {
if (i != 0) {
sb.append(",");
}
sb.append(coords[i]);
}
sb.append("]");
pi.next();
}
sb.append(")");
return sb.toString();
}
}
public static class Rect extends AnnotatedShapeOp {
public static Rect tryparse(String str) {
str = str.trim();
if (!str.startsWith("Rect(")) {
return null;
}
str = str.substring(5);
double coords[] = new double[4];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index);
try {
coords[i] = Double.parseDouble(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
Rect r = new Rect();
r.rect.setRect(coords[0], coords[1],
coords[2], coords[3]);
return r;
}
private Rectangle2D rect = new Rectangle2D.Double();
public void randomize() {
rect.setRect(randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord());
}
public Shape getShape() {
return rect;
}
public String toString() {
return ("Rect("+
rect.getX()+", "+
rect.getY()+", "+
rect.getWidth()+", "+
rect.getHeight()
+")");
}
}
public static class Line extends AnnotatedShapeOp {
public static Line tryparse(String str) {
str = str.trim();
if (!str.startsWith("Line(")) {
return null;
}
str = str.substring(5);
double coords[] = new double[4];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index);
try {
coords[i] = Double.parseDouble(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
Line l = new Line();
l.line.setLine(coords[0], coords[1],
coords[2], coords[3]);
return l;
}
private Line2D line = new Line2D.Double();
public void randomize() {
line.setLine(randDblCoord(), randDblCoord(),
randDblCoord(), randDblCoord());
}
public Shape getShape() {
return line;
}
public String toString() {
return ("Line("+
line.getX1()+", "+
line.getY1()+", "+
line.getX2()+", "+
line.getY2()
+")");
}
}
public static class RectMethod extends AnnotatedRenderOp {
public static RectMethod tryparse(String str) {
str = str.trim();
if (!str.startsWith("RectMethod(")) {
return null;
}
str = str.substring(11);
int coords[] = new int[4];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index).trim();
try {
coords[i] = Integer.parseInt(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
RectMethod rm = new RectMethod();
rm.rect.setBounds(coords[0], coords[1],
coords[2], coords[3]);
return rm;
}
private Rectangle rect = new Rectangle();
public void randomize() {
rect.setBounds(randIntCoord(), randIntCoord(),
randIntCoord(), randIntCoord());
}
public void fill(Graphics2D g2d) {
g2d.fillRect(rect.x, rect.y, rect.width, rect.height);
}
public void draw(Graphics2D g2d) {
g2d.drawRect(rect.x, rect.y, rect.width, rect.height);
}
public String toString() {
return ("RectMethod("+
rect.x+", "+
rect.y+", "+
rect.width+", "+
rect.height
+")");
}
}
public static class LineMethod extends AnnotatedRenderOp {
public static LineMethod tryparse(String str) {
str = str.trim();
if (!str.startsWith("LineMethod(")) {
return null;
}
str = str.substring(11);
int coords[] = new int[4];
boolean foundparen = false;
for (int i = 0; i < coords.length; i++) {
int index = str.indexOf(",");
if (index < 0) {
if (i < coords.length-1) {
return null;
}
index = str.indexOf(")");
if (index < 0) {
return null;
}
foundparen = true;
}
String num = str.substring(0, index).trim();
try {
coords[i] = Integer.parseInt(num);
} catch (NumberFormatException nfe) {
return null;
}
str = str.substring(index+1);
}
if (!foundparen || str.length() > 0) {
return null;
}
LineMethod lm = new LineMethod();
lm.line = coords;
return lm;
}
private int line[] = new int[4];
public void randomize() {
line[0] = randIntCoord();
line[1] = randIntCoord();
line[2] = randIntCoord();
line[3] = randIntCoord();
}
public void fill(Graphics2D g2d) {
}
public void draw(Graphics2D g2d) {
g2d.drawLine(line[0], line[1], line[2], line[3]);
}
public String toString() {
return ("LineMethod("+
line[0]+", "+
line[1]+", "+
line[2]+", "+
line[3]
+")");
}
}
public static class ErrorWindow extends Frame {
ImageCanvas unclipped;
ImageCanvas reference;
ImageCanvas actual;
ImageCanvas diff;
public ErrorWindow() {
super("Error Comparison Window");
unclipped = new ImageCanvas();
reference = new ImageCanvas();
actual = new ImageCanvas();
diff = new ImageCanvas();
setLayout(new SmartGridLayout(0, 2, 5, 5));
addImagePanel(unclipped, "Unclipped rendering");
addImagePanel(reference, "Clipped reference");
addImagePanel(actual, "Actual clipped");
addImagePanel(diff, "Difference");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
setVisible(false);
}
});
}
public void addImagePanel(ImageCanvas ic, String label) {
add(ic);
add(new Label(label));
}
public void setImages(BufferedImage imgref, BufferedImage imgtst) {
unclipped.setImage(imgref);
reference.setReference(imgref);
actual.setImage(imgtst);
diff.setDiff(reference.getImage(), imgtst);
invalidate();
pack();
repaint();
}
public void setVisible(boolean vis) {
super.setVisible(vis);
synchronized (this) {
notifyAll();
}
}
public synchronized void waitForHide() {
while (isShowing()) {
try {
wait();
} catch (InterruptedException e) {
System.exit(2);
}
}
}
}
public static class SmartGridLayout implements LayoutManager {
int rows;
int cols;
int hgap;
int vgap;
public SmartGridLayout(int r, int c, int h, int v) {
this.rows = r;
this.cols = c;
this.hgap = h;
this.vgap = v;
}
public void addLayoutComponent(String name, Component comp) {
}
public void removeLayoutComponent(Component comp) {
}
public int[][] getGridSizes(Container parent, boolean min) {
int ncomponents = parent.getComponentCount();
int nrows = rows;
int ncols = cols;
if (nrows > 0) {
ncols = (ncomponents + nrows - 1) / nrows;
} else {
nrows = (ncomponents + ncols - 1) / ncols;
}
int widths[] = new int[ncols+1];
int heights[] = new int[nrows+1];
int x = 0;
int y = 0;
for (int i = 0 ; i < ncomponents ; i++) {
Component comp = parent.getComponent(i);
Dimension d = (min
? comp.getMinimumSize()
: comp.getPreferredSize());
if (widths[x] < d.width) {
widths[x] = d.width;
}
if (heights[y] < d.height) {
heights[y] = d.height;
}
x++;
if (x >= ncols) {
x = 0;
y++;
}
}
for (int i = 0; i < ncols; i++) {
widths[ncols] += widths[i];
}
for (int i = 0; i < nrows; i++) {
heights[nrows] += heights[i];
}
return new int[][] { widths, heights };
}
public Dimension getSize(Container parent, boolean min) {
int sizes[][] = getGridSizes(parent, min);
int widths[] = sizes[0];
int heights[] = sizes[1];
int nrows = heights.length-1;
int ncols = widths.length-1;
int w = widths[ncols];
int h = heights[nrows];
Insets insets = parent.getInsets();
return new Dimension(insets.left+insets.right + w+(ncols+1)*hgap,
insets.top+insets.bottom + h+(nrows+1)*vgap);
}
public Dimension preferredLayoutSize(Container parent) {
return getSize(parent, false);
}
public Dimension minimumLayoutSize(Container parent) {
return getSize(parent, true);
}
public void layoutContainer(Container parent) {
int pref[][] = getGridSizes(parent, false);
int min[][] = getGridSizes(parent, true);
int minwidths[] = min[0];
int minheights[] = min[1];
int prefwidths[] = pref[0];
int prefheights[] = pref[1];
int nrows = minheights.length - 1;
int ncols = minwidths.length - 1;
Insets insets = parent.getInsets();
int w = parent.getWidth() - insets.left - insets.right;
int h = parent.getHeight() - insets.top - insets.bottom;
w = w - (ncols+1)*hgap;
h = h - (nrows+1)*vgap;
int widths[] = calculateSizes(w, ncols, minwidths, prefwidths);
int heights[] = calculateSizes(h, nrows, minheights, prefheights);
int ncomponents = parent.getComponentCount();
int x = insets.left + hgap;
int y = insets.top + vgap;
int r = 0;
int c = 0;
for (int i = 0; i < ncomponents; i++) {
parent.getComponent(i).setBounds(x, y, widths[c], heights[r]);
x += widths[c++] + hgap;
if (c >= ncols) {
c = 0;
x = insets.left + hgap;
y += heights[r++] + vgap;
if (r >= nrows) {
// just in case
break;
}
}
}
}
public static int[] calculateSizes(int total, int num,
int minsizes[], int prefsizes[])
{
if (total <= minsizes[num]) {
return minsizes;
}
if (total >= prefsizes[num]) {
return prefsizes;
}
int sizes[] = new int[total];
int prevhappy = 0;
int nhappy = 0;
int happysize = 0;
do {
int addsize = (total - happysize) / (num - nhappy);
happysize = 0;
for (int i = 0; i < num; i++) {
if (sizes[i] >= prefsizes[i] ||
minsizes[i] + addsize > prefsizes[i])
{
happysize += (sizes[i] = prefsizes[i]);
nhappy++;
} else {
sizes[i] = minsizes[i] + addsize;
}
}
} while (nhappy < num && nhappy > prevhappy);
return sizes;
}
}
public static class ImageCanvas extends Canvas {
BufferedImage image;
public void setImage(BufferedImage img) {
this.image = img;
}
public BufferedImage getImage() {
return image;
}
public void checkImage(int w, int h) {
if (image == null ||
image.getWidth() < w ||
image.getHeight() < h)
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
}
}
public void setReference(BufferedImage img) {
checkImage(img.getWidth(), img.getHeight());
Graphics g = image.createGraphics();
g.drawImage(img, 0, 0, null);
g.setColor(Color.white);
g.fillRect(0, 0, 30, 10);
g.fillRect(30, 0, 10, 30);
g.fillRect(10, 30, 30, 10);
g.fillRect(0, 10, 10, 30);
g.dispose();
}
public void setDiff(BufferedImage imgref, BufferedImage imgtst) {
int w = Math.max(imgref.getWidth(), imgtst.getWidth());
int h = Math.max(imgref.getHeight(), imgtst.getHeight());
checkImage(w, h);
Graphics g = image.createGraphics();
g.drawImage(imgref, 0, 0, null);
g.setXORMode(Color.white);
g.drawImage(imgtst, 0, 0, null);
g.setPaintMode();
g.setColor(new Color(1f, 1f, 0f, 0.25f));
g.fillRect(10, 10, 20, 20);
g.setColor(new Color(1f, 0f, 0f, 0.25f));
g.fillRect(0, 0, 30, 10);
g.fillRect(30, 0, 10, 30);
g.fillRect(10, 30, 30, 10);
g.fillRect(0, 10, 10, 30);
g.dispose();
}
public Dimension getPreferredSize() {
if (image == null) {
return new Dimension();
} else {
return new Dimension(image.getWidth(), image.getHeight());
}
}
public void paint(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}
}
<html>
<!--
@test
@bug 6391770
@summary Content of the Window should be laid out in the area left after WarningWindow was added.
@author Yuri Nesterenko
@run applet WindowWithWarningTest.html
-->
<head>
<title>WindowWithWarningTest</title>
</head>
<pre>
This test will run automatically.
</pre>
<body>
<applet code="WindowWithWarningTest.class" width=350 height=300></applet>
</body>
</html>
/*
* Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
test
@bug 6391770
@summary Content of the Window should be laid out in the area left after WarningWindow was added.
@author yuri nesterenko: area=
@run applet WindowWithWarningTest.html
*/
// Note there is no @ in front of test above. This is so that the
// harness will not mistake this file as a test file. It should
// only see the html file as a test file. (the harness runs all
// valid test files, so it would run this test twice if this file
// were valid as well as the html file.)
// Also, note the area= after Your Name in the author tag. Here, you
// should put which functional area the test falls in. See the
// AWT-core home page -> test areas and/or -> AWT team for a list of
// areas.
// Note also the 'AutomaticAppletTest.html' in the run tag. This should
// be changed to the name of the test.
/**
* WindowWithWarningTest.java
*
* summary:
*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//Automated tests should run as applet tests if possible because they
// get their environments cleaned up, including AWT threads, any
// test created threads, and any system resources used by the test
// such as file descriptors. (This is normally not a problem as
// main tests usually run in a separate VM, however on some platforms
// such as the Mac, separate VMs are not possible and non-applet
// tests will cause problems). Also, you don't have to worry about
// synchronisation stuff in Applet tests they way you do in main
// tests...
public class WindowWithWarningTest extends Applet
{
//Declare things used in the test, like buttons and labels here
boolean buttonClicked = false;
public static final int MAX_COUNT = 100;
public void init()
{
//Create instructions for the user here, as well as set up
// the environment -- set the layout manager, add buttons,
// etc.
this.setLayout (new BorderLayout ());
String[] instructions =
{
"This is an AUTOMATIC test",
"simply wait until it is done"
};
//Sysout.createDialog( );
//Sysout.printInstructions( instructions );
}//End init()
public void start ()
{
//Get things going. Request focus, set size, et cetera
System.setSecurityManager( new SecurityManager() {
// deny AWTPermission("showWindowWithoutWarningBanner")
public boolean checkTopLevelWindow(Object window) {
return false;
}
});
JFrame frame = new JFrame("Window Test");
frame.setBounds(50, 50, 200, 200);
frame.show();
JWindow window = new JWindow( frame );
JButton jbutton1 = new JButton( "First" );
jbutton1.addMouseListener( new MouseAdapter() {
public void mousePressed( MouseEvent me ) {
buttonClicked = true;
}
});
JButton jbutton2 = new JButton( "Second" );
window.setLocation( 300, 300 );
window.add("North", jbutton1);
window.add("South", jbutton2);
window.pack();
window.show();
//wait for frame to show:
getLocation( frame );
window.toFront();
Dimension size0 = window.getSize();
Dimension size1 = null;
try {
Robot robot = new Robot();
robot.delay(500);
window.pack();
robot.delay(500);
window.pack();
// size1 must be the same as size0
size1 = window.getSize();
robot.delay(500);
Point pt = jbutton1.getLocationOnScreen();
robot.mouseMove((int) jbutton1.getLocationOnScreen().x + jbutton1.getWidth() / 2,
(int) jbutton1.getLocationOnScreen().y + jbutton1.getHeight() / 2);
robot.delay(500);
robot.mousePress(MouseEvent.BUTTON1_MASK);
robot.delay(100);
robot.mouseRelease(MouseEvent.BUTTON1_MASK);
robot.delay(2000);
}catch(Exception e) {
throw new RuntimeException( "Exception "+e );
}
if( !size0.equals(size1) ) {
throw new RuntimeException( "Wrong Window size after multiple pack()s");
}
if( !buttonClicked ) {
throw new RuntimeException( "Button was not clicked");
}
window.dispose();
frame.dispose();
System.out.println("Test Passed.");
}// start()
public static Point getLocation( Component co ) throws RuntimeException {
Point pt = null;
boolean bFound = false;
int count = 0;
while( !bFound ) {
try {
pt = co.getLocationOnScreen();
bFound = true;
}catch( Exception ex ) {
bFound = false;
count++;
}
if( !bFound && count > MAX_COUNT ) {
throw new RuntimeException("don't see a component to get location");
}
}
return pt;
}
}// class AutomaticAppletTest
/****************************************************
Standard Test Machinery
DO NOT modify anything below -- it's a standard
chunk of code whose purpose is to make user
interaction uniform, and thereby make it simpler
to read and understand someone else's test.
****************************************************/
/**
This is part of the standard test machinery.
It creates a dialog (with the instructions), and is the interface
for sending text messages to the user.
To print the instructions, send an array of strings to Sysout.createDialog
WithInstructions method. Put one line of instructions per array entry.
To display a message for the tester to see, simply call Sysout.println
with the string to be displayed.
This mimics System.out.println but works within the test harness as well
as standalone.
*/
class Sysout
{
private static TestDialog dialog;
public static void createDialogWithInstructions( String[] instructions )
{
dialog = new TestDialog( new Frame(), "Instructions" );
dialog.printInstructions( instructions );
dialog.setVisible(true);
println( "Any messages for the tester will display here." );
}
public static void createDialog( )
{
dialog = new TestDialog( new Frame(), "Instructions" );
String[] defInstr = { "Instructions will appear here. ", "" } ;
dialog.printInstructions( defInstr );
dialog.setVisible(true);
println( "Any messages for the tester will display here." );
}
public static void printInstructions( String[] instructions )
{
dialog.printInstructions( instructions );
}
public static void println( String messageIn )
{
dialog.displayMessage( messageIn );
}
}// Sysout class
/**
This is part of the standard test machinery. It provides a place for the
test instructions to be displayed, and a place for interactive messages
to the user to be displayed.
To have the test instructions displayed, see Sysout.
To have a message to the user be displayed, see Sysout.
Do not call anything in this dialog directly.
*/
class TestDialog extends Dialog
{
TextArea instructionsText;
TextArea messageText;
int maxStringLength = 80;
//DO NOT call this directly, go through Sysout
public TestDialog( Frame frame, String name )
{
super( frame, name );
int scrollBoth = TextArea.SCROLLBARS_BOTH;
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
add( "North", instructionsText );
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
add("Center", messageText);
pack();
show();
}// TestDialog()
//DO NOT call this directly, go through Sysout
public void printInstructions( String[] instructions )
{
//Clear out any current instructions
instructionsText.setText( "" );
//Go down array of instruction strings
String printStr, remainingStr;
for( int i=0; i < instructions.length; i++ )
{
//chop up each into pieces maxSringLength long
remainingStr = instructions[ i ];
while( remainingStr.length() > 0 )
{
//if longer than max then chop off first max chars to print
if( remainingStr.length() >= maxStringLength )
{
//Try to chop on a word boundary
int posOfSpace = remainingStr.
lastIndexOf( ' ', maxStringLength - 1 );
if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
printStr = remainingStr.substring( 0, posOfSpace + 1 );
remainingStr = remainingStr.substring( posOfSpace + 1 );
}
//else just print
else
{
printStr = remainingStr;
remainingStr = "";
}
instructionsText.append( printStr + "\n" );
}// while
}// for
}//printInstructions()
//DO NOT call this directly, go through Sysout
public void displayMessage( String messageIn )
{
messageText.append( messageIn + "\n" );
System.out.println(messageIn);
}
}// TestDialog class
...@@ -60,7 +60,6 @@ public class StringWidth extends Frame { ...@@ -60,7 +60,6 @@ public class StringWidth extends Frame {
pg.dispose(); pg.dispose();
pj.end(); pj.end();
setVisible(false); setVisible(false);
System.exit(0);
} }
public static void main(String[] args) { public static void main(String[] args) {
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6782574
* @summary Test verifies that incorrect sample masks are correctly handled
* by the constructor of the SinglePixelPackedSampleModel class
* and do not cause internal error in the medialib glue code.
*
* @run main IncorrectSampleMaskTest
*/
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImageOp;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.DataBufferUShort;
import java.awt.image.Raster;
import java.awt.image.RasterOp;
import java.awt.image.WritableRaster;
import java.awt.image.SinglePixelPackedSampleModel;
public class IncorrectSampleMaskTest {
public static void main(String[] args) {
int[] dataTypes = new int[] {
DataBuffer.TYPE_BYTE,
DataBuffer.TYPE_USHORT,
DataBuffer.TYPE_INT };
for (int type : dataTypes) {
doTest(type);
}
}
private static final int w = 100;
private static final int h = 100;
private static AffineTransform at =
AffineTransform.getScaleInstance(0.5, 0.5);
private static RasterOp op =
new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
private static void doTest(int dataType) {
int maxSize = DataBuffer.getDataTypeSize(dataType);
System.out.println("Type size: " + maxSize);
int theMask = (int)(1L << (maxSize + 2)) - 1;
System.out.printf("theMask=%x\n", theMask);
SinglePixelPackedSampleModel sm =
new SinglePixelPackedSampleModel(dataType, w, h,
new int[] { theMask });
int[] sampleSize = sm.getSampleSize();
for (int s : sampleSize) {
if (s > maxSize) {
throw new RuntimeException("Test failed: sample size is too big:" + s);
}
}
System.out.println("Test medialib...");
DataBuffer buf = createDataBuffer(dataType);
WritableRaster wr = Raster.createWritableRaster(sm, buf, null);
op.filter(wr, null);
System.out.println("Test PASSED.");
}
private static DataBuffer createDataBuffer(int type) {
switch (type) {
case DataBuffer.TYPE_BYTE: {
byte[] buf = new byte[w * h];
return new DataBufferByte(buf, buf.length);
}
case DataBuffer.TYPE_USHORT: {
short[] buf = new short[w * h];
return new DataBufferUShort(buf, buf.length);
}
case DataBuffer.TYPE_INT: {
int[] buf = new int[w * h];
return new DataBufferInt(buf, buf.length);
}
default :
throw new RuntimeException("Unsupported data type.");
}
}
}
...@@ -60,48 +60,51 @@ public class ISO8601ZoneTest { ...@@ -60,48 +60,51 @@ public class ISO8601ZoneTest {
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
}; };
// badData[][0] - format
// badData[][1] - (bad) text to be parsed
// badData[][2] - subtext at the end of which a parse error is detected
static final String[][] badData = { static final String[][] badData = {
{ "X", "1" }, { "X", "1", "1" },
{ "X", "+1" }, { "X", "+1", "+1" },
{ "X", "-2" }, { "X", "-2", "-2" },
{ "X", "-24" }, { "X", "-24", "-2" },
{ "X", "+24" }, { "X", "+24", "+2" },
{ "XX", "9" }, { "XX", "9", "9" },
{ "XX", "23" }, { "XX", "23", "2" },
{ "XX", "234" }, { "XX", "234", "2" },
{ "XX", "3456" }, { "XX", "3456", "3" },
{ "XX", "23456" }, { "XX", "23456", "2" },
{ "XX", "+1" }, { "XX", "+1", "+1" },
{ "XX", "-12" }, { "XX", "-12", "-12" },
{ "XX", "+123" }, { "XX", "+123", "+123" },
{ "XX", "-12:34" }, { "XX", "-12:34", "-12" },
{ "XX", "+12:34" }, { "XX", "+12:34", "+12" },
{ "XX", "-2423" }, { "XX", "-2423", "-2" },
{ "XX", "+2423" }, { "XX", "+2423", "+2" },
{ "XX", "-1260" }, { "XX", "-1260", "-126" },
{ "XX", "+1260" }, { "XX", "+1260", "+126" },
{ "XXX", "9" }, { "XXX", "9", "9" },
{ "XXX", "23" }, { "XXX", "23", "2" },
{ "XXX", "234" }, { "XXX", "234", "2" },
{ "XXX", "3456" }, { "XXX", "3456", "3" },
{ "XXX", "23456" }, { "XXX", "23456", "2" },
{ "XXX", "2:34" }, { "XXX", "2:34", "2" },
{ "XXX", "12:4" }, { "XXX", "12:4", "1" },
{ "XXX", "12:34" }, { "XXX", "12:34", "1" },
{ "XXX", "-1" }, { "XXX", "-1", "-1" },
{ "XXX", "+1" }, { "XXX", "+1", "+1" },
{ "XXX", "-12" }, { "XXX", "-12", "-12" },
{ "XXX", "+12" }, { "XXX", "+12", "+12" },
{ "XXX", "-123" }, { "XXX", "-123", "-12" },
{ "XXX", "+123" }, { "XXX", "+123", "+12" },
{ "XXX", "-1234" }, { "XXX", "-1234", "-12" },
{ "XXX", "+1234" }, { "XXX", "+1234", "+12" },
{ "XXX", "+24:23" }, { "XXX", "+24:23", "+2" },
{ "XXX", "+12:60" }, { "XXX", "+12:60", "+12:6" },
{ "XXX", "+1:23" }, { "XXX", "+1:23", "+1" },
{ "XXX", "+12:3" }, { "XXX", "+12:3", "+12:3" },
}; };
static String[] badFormats = { static String[] badFormats = {
...@@ -110,6 +113,8 @@ public class ISO8601ZoneTest { ...@@ -110,6 +113,8 @@ public class ISO8601ZoneTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
TimeZone tz = TimeZone.getDefault(); TimeZone tz = TimeZone.getDefault();
Locale loc = Locale.getDefault();
Locale.setDefault(Locale.US);
try { try {
for (int i = 0; i < formatData.length; i++) { for (int i = 0; i < formatData.length; i++) {
...@@ -128,7 +133,7 @@ public class ISO8601ZoneTest { ...@@ -128,7 +133,7 @@ public class ISO8601ZoneTest {
} }
for (String[] d : badData) { for (String[] d : badData) {
badDataParsing(d[0], d[1]); badDataParsing(d[0], d[1], d[2].length());
} }
for (String fmt : badFormats) { for (String fmt : badFormats) {
...@@ -136,6 +141,7 @@ public class ISO8601ZoneTest { ...@@ -136,6 +141,7 @@ public class ISO8601ZoneTest {
} }
} finally { } finally {
TimeZone.setDefault(tz); TimeZone.setDefault(tz);
Locale.setDefault(loc);
} }
} }
...@@ -188,15 +194,24 @@ public class ISO8601ZoneTest { ...@@ -188,15 +194,24 @@ public class ISO8601ZoneTest {
} }
static void badDataParsing(String fmt, String text) { static void badDataParsing(String fmt, String text, int expectedErrorIndex) {
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
try { try {
SimpleDateFormat sdf = new SimpleDateFormat(fmt);
sdf.parse(text); sdf.parse(text);
throw new RuntimeException("didn't throw an exception: fmt=" + fmt throw new RuntimeException("didn't throw an exception: fmt=" + fmt
+ ", text=" + text); + ", text=" + text);
} catch (ParseException e) { } catch (ParseException e) {
// OK // OK
} }
ParsePosition pos = new ParsePosition(0);
Date d = sdf.parse(text, pos);
int errorIndex = pos.getErrorIndex();
if (d != null || errorIndex != expectedErrorIndex) {
throw new RuntimeException("Bad error index=" + errorIndex
+ ", expected=" + expectedErrorIndex
+ ", fmt=" + fmt + ", text=" + text);
}
} }
static void badFormat(String fmt) { static void badFormat(String fmt) {
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7003643
* @summary Make sure MessageFormat.toPattern produces correct quoting. (SPI part is tested in PluggableLocale tests.)
*/
import java.text.*;
import java.util.*;
public class Bug7003643 {
private static final int N = 5;
private static final String[] elements = {
"'{'", "'{", "{", "''", "}", "a", "'",
};
public static void main(String[] args) {
Random rand = new Random();
int count = 0;
int max = (int) (Math.pow((double)elements.length, (double)N)/0.52);
while (count < max) {
// Create a random pattern. If the produced pattern is
// valid, then proceed with the round-trip testing.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
sb.append(elements[rand.nextInt(elements.length)]);
}
String pattern = sb.toString();
MessageFormat mf = null;
try {
mf = new MessageFormat(pattern);
} catch (IllegalArgumentException e) {
// bad pattern data
}
if (mf == null) {
continue;
}
count++;
String res1 = MessageFormat.format(pattern, 123);
String toPattern = mf.toPattern();
String res2 = MessageFormat.format(toPattern, 123);
if (!res1.equals(res2)) {
String s = String.format("Failed%n pattern=\"%s\" => result=\"%s\"%n"
+ " toPattern()=\"%s\" => result=\"%s\"%n",
pattern, res1, toPattern, res2);
throw new RuntimeException(s);
}
}
}
}
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
* @test * @test
* @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613 * @bug 4052404 4052440 4084688 4092475 4101316 4105828 4107014 4107953 4110613
* 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951 * 4118587 4118595 4122371 4126371 4126880 4135316 4135752 4139504 4139940 4143951
* 4147315 4147317 4147552 4335196 4778440 5010672 6475525 6544471 6627549 6786276 * 4147315 4147317 4147552 4335196 4778440 4940539 5010672 6475525 6544471 6627549
* 6786276
* @summary test Locales * @summary test Locales
*/ */
/* /*
...@@ -895,17 +896,28 @@ test commented out pending API-change approval ...@@ -895,17 +896,28 @@ test commented out pending API-change approval
} }
/** /**
* @bug 4147317 * @bug 4147317 4940539
* java.util.Locale.getISO3Language() works wrong for non ISO-3166 codes. * java.util.Locale.getISO3Language() works wrong for non ISO-639 codes.
* Should throw an exception for unknown locales * Should throw an exception for unknown locales, except they have three
* letter language codes.
*/ */
public void Test4147317() { public void Test4147317() {
// Try with codes that are the wrong length but happen to match text // Try a three letter language code, and check whether it is
// at a valid offset in the mapping table // returned as is.
Locale locale = new Locale("aaa", "CCC"); Locale locale = new Locale("aaa", "CCC");
String result = locale.getISO3Language();
if (!result.equals("aaa")) {
errln("ERROR: getISO3Language() returns: " + result +
" for locale '" + locale + "' rather than returning it as is" );
}
// Try an invalid two letter language code, and check whether it
// throws a MissingResourceException.
locale = new Locale("zz", "CCC");
try { try {
String result = locale.getISO3Language(); result = locale.getISO3Language();
errln("ERROR: getISO3Language() returns: " + result + errln("ERROR: getISO3Language() returns: " + result +
" for locale '" + locale + "' rather than exception" ); " for locale '" + locale + "' rather than exception" );
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -44,6 +44,7 @@ public class DateFormatProviderTest extends ProviderTest { ...@@ -44,6 +44,7 @@ public class DateFormatProviderTest extends ProviderTest {
availableLocalesTest(); availableLocalesTest();
objectValidityTest(); objectValidityTest();
extendedVariantTest(); extendedVariantTest();
messageFormatTest();
} }
void availableLocalesTest() { void availableLocalesTest() {
...@@ -118,4 +119,48 @@ public class DateFormatProviderTest extends ProviderTest { ...@@ -118,4 +119,48 @@ public class DateFormatProviderTest extends ProviderTest {
} }
} }
} }
private static final String[] TYPES = {
"date",
"time"
};
private static final String[] MODIFIERS = {
"",
"short",
"medium", // Same as DEFAULT
"long",
"full"
};
void messageFormatTest() {
for (Locale target : providerloc) {
for (String type : TYPES) {
for (String modifier : MODIFIERS) {
String pattern, expected;
if (modifier.equals("")) {
pattern = String.format("%s={0,%s}", type, type);
} else {
pattern = String.format("%s={0,%s,%s}", type, type, modifier);
}
if (modifier.equals("medium")) {
// medium is default.
expected = String.format("%s={0,%s}", type, type);
} else {
expected = pattern;
}
MessageFormat mf = new MessageFormat(pattern, target);
Format[] fmts = mf.getFormats();
if (fmts[0] instanceof SimpleDateFormat) {
continue;
}
String toPattern = mf.toPattern();
if (!toPattern.equals(expected)) {
throw new RuntimeException("messageFormatTest: got '" + toPattern
+ "', expected '" + expected + "'");
}
}
}
}
}
} }
# #
# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -23,6 +23,6 @@ ...@@ -23,6 +23,6 @@
#!/bin/sh #!/bin/sh
# #
# @test # @test
# @bug 4052440 # @bug 4052440 7003643
# @summary DateFormatProvider tests # @summary DateFormatProvider tests
# @run shell ExecTest.sh foo DateFormatProviderTest true # @run shell ExecTest.sh foo DateFormatProviderTest true
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,8 @@ import java.util.*; ...@@ -29,6 +29,8 @@ import java.util.*;
import sun.util.*; import sun.util.*;
import sun.util.resources.*; import sun.util.resources.*;
import com.foo.FooNumberFormat;
public class NumberFormatProviderTest extends ProviderTest { public class NumberFormatProviderTest extends ProviderTest {
com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl(); com.foo.NumberFormatProviderImpl nfp = new com.foo.NumberFormatProviderImpl();
...@@ -43,6 +45,7 @@ public class NumberFormatProviderTest extends ProviderTest { ...@@ -43,6 +45,7 @@ public class NumberFormatProviderTest extends ProviderTest {
NumberFormatProviderTest() { NumberFormatProviderTest() {
availableLocalesTest(); availableLocalesTest();
objectValidityTest(); objectValidityTest();
messageFormatTest();
} }
void availableLocalesTest() { void availableLocalesTest() {
...@@ -72,14 +75,10 @@ public class NumberFormatProviderTest extends ProviderTest { ...@@ -72,14 +75,10 @@ public class NumberFormatProviderTest extends ProviderTest {
} }
// result object // result object
String resultCur = String resultCur = getPattern(NumberFormat.getCurrencyInstance(target));
((DecimalFormat)NumberFormat.getCurrencyInstance(target)).toPattern(); String resultInt = getPattern(NumberFormat.getIntegerInstance(target));
String resultInt = String resultNum = getPattern(NumberFormat.getNumberInstance(target));
((DecimalFormat)NumberFormat.getIntegerInstance(target)).toPattern(); String resultPer = getPattern(NumberFormat.getPercentInstance(target));
String resultNum =
((DecimalFormat)NumberFormat.getNumberInstance(target)).toPattern();
String resultPer =
((DecimalFormat)NumberFormat.getPercentInstance(target)).toPattern();
// provider's object (if any) // provider's object (if any)
String providersCur = null; String providersCur = null;
...@@ -87,21 +86,21 @@ public class NumberFormatProviderTest extends ProviderTest { ...@@ -87,21 +86,21 @@ public class NumberFormatProviderTest extends ProviderTest {
String providersNum = null; String providersNum = null;
String providersPer = null; String providersPer = null;
if (providerloc.contains(target)) { if (providerloc.contains(target)) {
DecimalFormat dfCur = (DecimalFormat)nfp.getCurrencyInstance(target); NumberFormat dfCur = nfp.getCurrencyInstance(target);
if (dfCur != null) { if (dfCur != null) {
providersCur = dfCur.toPattern(); providersCur = getPattern(dfCur);
} }
DecimalFormat dfInt = (DecimalFormat)nfp.getIntegerInstance(target); NumberFormat dfInt = nfp.getIntegerInstance(target);
if (dfInt != null) { if (dfInt != null) {
providersInt = dfInt.toPattern(); providersInt = getPattern(dfInt);
} }
DecimalFormat dfNum = (DecimalFormat)nfp.getNumberInstance(target); NumberFormat dfNum = nfp.getNumberInstance(target);
if (dfNum != null) { if (dfNum != null) {
providersNum = dfNum.toPattern(); providersNum = getPattern(dfNum);
} }
DecimalFormat dfPer = (DecimalFormat)nfp.getPercentInstance(target); NumberFormat dfPer = nfp.getPercentInstance(target);
if (dfPer != null) { if (dfPer != null) {
providersPer = dfPer.toPattern(); providersPer = getPattern(dfPer);
} }
} }
...@@ -174,4 +173,35 @@ public class NumberFormatProviderTest extends ProviderTest { ...@@ -174,4 +173,35 @@ public class NumberFormatProviderTest extends ProviderTest {
} }
} }
} }
private static String getPattern(NumberFormat nf) {
if (nf instanceof DecimalFormat) {
return ((DecimalFormat)nf).toPattern();
}
if (nf instanceof FooNumberFormat) {
return ((FooNumberFormat)nf).toPattern();
}
return null;
}
private static final String[] NUMBER_PATTERNS = {
"num={0,number}",
"num={0,number,currency}",
"num={0,number,percent}",
"num={0,number,integer}"
};
void messageFormatTest() {
for (Locale target : providerloc) {
for (String pattern : NUMBER_PATTERNS) {
MessageFormat mf = new MessageFormat(pattern, target);
String toPattern = mf.toPattern();
if (!pattern.equals(toPattern)) {
throw new RuntimeException("MessageFormat.toPattern: got '"
+ toPattern
+ "', expected '" + pattern + "'");
}
}
}
}
} }
# #
# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -23,6 +23,6 @@ ...@@ -23,6 +23,6 @@
#!/bin/sh #!/bin/sh
# #
# @test # @test
# @bug 4052440 # @bug 4052440 7003643
# @summary NumberFormatProvider tests # @summary NumberFormatProvider tests
# @run shell ExecTest.sh foo NumberFormatProviderTest true # @run shell ExecTest.sh foo NumberFormatProviderTest true
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -42,7 +42,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { ...@@ -42,7 +42,7 @@ public class DateFormatProviderImpl extends DateFormatProvider {
static String[] datePattern = { static String[] datePattern = {
"yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern "yyyy'\u5e74'M'\u6708'd'\u65e5'", // full date pattern
"yyyy/MM/dd", // long date pattern "yyyy/MMM/dd", // long date pattern
"yyyy/MM/dd", // medium date pattern "yyyy/MM/dd", // medium date pattern
"yy/MM/dd" // short date pattern "yy/MM/dd" // short date pattern
}; };
...@@ -68,7 +68,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { ...@@ -68,7 +68,7 @@ public class DateFormatProviderImpl extends DateFormatProvider {
public DateFormat getDateInstance(int style, Locale locale) { public DateFormat getDateInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) { for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) { if (Utils.supportsLocale(avail[i], locale)) {
return new SimpleDateFormat(datePattern[style]+dialect[i], locale); return new FooDateFormat(datePattern[style]+dialect[i], locale);
} }
} }
throw new IllegalArgumentException("locale is not supported: "+locale); throw new IllegalArgumentException("locale is not supported: "+locale);
...@@ -77,7 +77,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { ...@@ -77,7 +77,7 @@ public class DateFormatProviderImpl extends DateFormatProvider {
public DateFormat getTimeInstance(int style, Locale locale) { public DateFormat getTimeInstance(int style, Locale locale) {
for (int i = 0; i < avail.length; i ++) { for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) { if (Utils.supportsLocale(avail[i], locale)) {
return new SimpleDateFormat(timePattern[style]+dialect[i], locale); return new FooDateFormat(timePattern[style]+dialect[i], locale);
} }
} }
throw new IllegalArgumentException("locale is not supported: "+locale); throw new IllegalArgumentException("locale is not supported: "+locale);
...@@ -86,7 +86,7 @@ public class DateFormatProviderImpl extends DateFormatProvider { ...@@ -86,7 +86,7 @@ public class DateFormatProviderImpl extends DateFormatProvider {
public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) { public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale) {
for (int i = 0; i < avail.length; i ++) { for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) { if (Utils.supportsLocale(avail[i], locale)) {
return new SimpleDateFormat( return new FooDateFormat(
datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale); datePattern[dateStyle]+" "+timePattern[timeStyle]+dialect[i], locale);
} }
} }
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -21,42 +21,41 @@ ...@@ -21,42 +21,41 @@
* questions. * questions.
*/ */
/* @test package com.foo;
*
* @bug 6480289
* @author Igor Kushnirskiy
* @summary tests if consequent workers are executed on the same thread and that VM can exit.
*/
import java.text.*;
import java.util.*; import java.util.*;
import javax.swing.SwingWorker;
/**
public class bug6480289 { * FooDateFormat provides SimpleDateFormat methods required for the SPI testing.
private static final int ITERATIONS = 5; */
private static final Map<Thread, Integer> threadMap = public class FooDateFormat extends DateFormat {
Collections.synchronizedMap(new HashMap<Thread, Integer>()); private SimpleDateFormat sdf;
public static void main(String[] args) throws Exception {
public FooDateFormat(String pattern, Locale loc) {
for (int i = 0; i < ITERATIONS; i++) { sdf = new SimpleDateFormat(pattern, loc);
if (i != 0) { }
Thread.sleep(1000 * 5);
} @Override
SwingWorker<?,?> worker = public StringBuffer format(Date date,
new SwingWorker<Void, Void>() { StringBuffer toAppendTo,
@Override FieldPosition fieldPosition) {
protected Void doInBackground() { return sdf.format(date, toAppendTo, fieldPosition);
Integer value = threadMap.get(Thread.currentThread()); }
value = Integer.valueOf(
((value == null) ? 0 : value.intValue()) @Override
+ 1); public Date parse(String source, ParsePosition pos) {
threadMap.put(Thread.currentThread(), value); return sdf.parse(source, pos);
return null; }
}
}; @Override
worker.execute(); public boolean equals(Object other) {
} return other instanceof FooDateFormat
if (threadMap.keySet().size() != 1) { && sdf.equals(((FooDateFormat)other).sdf);
throw new RuntimeException("failed. More than one thread."); }
}
@Override
public int hashCode() {
return sdf.hashCode();
} }
} }
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.foo;
import java.text.*;
/**
* FooNumberFormat provides DecimalFormat methods required for the SPI testing.
*/
public class FooNumberFormat extends NumberFormat {
private DecimalFormat df;
public FooNumberFormat(String pattern, DecimalFormatSymbols dfs) {
df = new DecimalFormat(pattern, dfs);
}
@Override
public StringBuffer format(double number,
StringBuffer toAppendTo,
FieldPosition pos) {
return df.format(number, toAppendTo, pos);
}
@Override
public StringBuffer format(long number,
StringBuffer toAppendTo,
FieldPosition pos) {
return df.format(number, toAppendTo, pos);
}
@Override
public Number parse(String source, ParsePosition parsePosition) {
return df.parse(source, parsePosition);
}
@Override
public boolean equals(Object other) {
return other instanceof FooNumberFormat
&& df.equals(((FooNumberFormat)other).df);
}
@Override
public int hashCode() {
return df.hashCode();
}
// DecimalFormat specific methods required for testing
public String toPattern() {
return df.toPattern();
}
public DecimalFormatSymbols getDecimalFormatSymbols() {
return df.getDecimalFormatSymbols();
}
public void setDecimalSeparatorAlwaysShown(boolean newValue) {
df.setDecimalSeparatorAlwaysShown(newValue);
}
}
...@@ -28,6 +28,8 @@ FOOFILES_JAVA = \ ...@@ -28,6 +28,8 @@ FOOFILES_JAVA = \
DateFormatSymbolsProviderImpl.java \ DateFormatSymbolsProviderImpl.java \
DecimalFormatSymbolsProviderImpl.java \ DecimalFormatSymbolsProviderImpl.java \
NumberFormatProviderImpl.java \ NumberFormatProviderImpl.java \
FooDateFormat.java \
FooNumberFormat.java \
Utils.java Utils.java
BARFILES_JAVA = \ BARFILES_JAVA = \
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -49,13 +49,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -49,13 +49,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
static String[] patterns = { static String[] patterns = {
"#,##0.###{0};-#,##0.###{1}", // decimal pattern "#,##0.###{0};-#,##0.###{1}", // decimal pattern
"#{0};(#){1}", // integer pattern
"\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern "\u00A4#,##0{0};-\u00A4#,##0{1}", // currency pattern
"#,##0%{0}" // percent pattern "#,##0%{0}" // percent pattern
}; };
// Constants used by factory methods to specify a style of format. // Constants used by factory methods to specify a style of format.
static final int NUMBERSTYLE = 0; static final int NUMBERSTYLE = 0;
static final int CURRENCYSTYLE = 1; static final int INTEGERSTYLE = 1;
static final int PERCENTSTYLE = 2; static final int CURRENCYSTYLE = 2;
static final int PERCENTSTYLE = 3;
public Locale[] getAvailableLocales() { public Locale[] getAvailableLocales() {
return avail; return avail;
...@@ -68,10 +70,10 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -68,10 +70,10 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
MessageFormat.format(patterns[CURRENCYSTYLE], MessageFormat.format(patterns[CURRENCYSTYLE],
dialect[i], dialect[i],
dialect[i]); dialect[i]);
DecimalFormat df = new DecimalFormat(pattern, FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale)); DecimalFormatSymbols.getInstance(locale));
adjustForCurrencyDefaultFractionDigits(df); adjustForCurrencyDefaultFractionDigits(nf);
return df; return nf;
} }
} }
throw new IllegalArgumentException("locale is not supported: "+locale); throw new IllegalArgumentException("locale is not supported: "+locale);
...@@ -81,15 +83,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -81,15 +83,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
for (int i = 0; i < avail.length; i ++) { for (int i = 0; i < avail.length; i ++) {
if (Utils.supportsLocale(avail[i], locale)) { if (Utils.supportsLocale(avail[i], locale)) {
String pattern = String pattern =
MessageFormat.format(patterns[NUMBERSTYLE], MessageFormat.format(patterns[INTEGERSTYLE],
dialect[i], dialect[i],
dialect[i]); dialect[i]);
DecimalFormat df = new DecimalFormat(pattern, FooNumberFormat nf = new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale)); DecimalFormatSymbols.getInstance(locale));
df.setMaximumFractionDigits(0); nf.setMaximumFractionDigits(0);
df.setDecimalSeparatorAlwaysShown(false); nf.setDecimalSeparatorAlwaysShown(false);
df.setParseIntegerOnly(true); nf.setParseIntegerOnly(true);
return df; return nf;
} }
} }
throw new IllegalArgumentException("locale is not supported: "+locale); throw new IllegalArgumentException("locale is not supported: "+locale);
...@@ -102,7 +104,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -102,7 +104,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
MessageFormat.format(patterns[NUMBERSTYLE], MessageFormat.format(patterns[NUMBERSTYLE],
dialect[i], dialect[i],
dialect[i]); dialect[i]);
return new DecimalFormat(pattern, return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale)); DecimalFormatSymbols.getInstance(locale));
} }
} }
...@@ -115,7 +117,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -115,7 +117,7 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
String pattern = String pattern =
MessageFormat.format(patterns[PERCENTSTYLE], MessageFormat.format(patterns[PERCENTSTYLE],
dialect[i]); dialect[i]);
return new DecimalFormat(pattern, return new FooNumberFormat(pattern,
DecimalFormatSymbols.getInstance(locale)); DecimalFormatSymbols.getInstance(locale));
} }
} }
...@@ -126,8 +128,8 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -126,8 +128,8 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
* Adjusts the minimum and maximum fraction digits to values that * Adjusts the minimum and maximum fraction digits to values that
* are reasonable for the currency's default fraction digits. * are reasonable for the currency's default fraction digits.
*/ */
void adjustForCurrencyDefaultFractionDigits(DecimalFormat df) { void adjustForCurrencyDefaultFractionDigits(FooNumberFormat nf) {
DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); DecimalFormatSymbols dfs = nf.getDecimalFormatSymbols();
Currency currency = dfs.getCurrency(); Currency currency = dfs.getCurrency();
if (currency == null) { if (currency == null) {
try { try {
...@@ -138,15 +140,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider { ...@@ -138,15 +140,15 @@ public class NumberFormatProviderImpl extends NumberFormatProvider {
if (currency != null) { if (currency != null) {
int digits = currency.getDefaultFractionDigits(); int digits = currency.getDefaultFractionDigits();
if (digits != -1) { if (digits != -1) {
int oldMinDigits = df.getMinimumFractionDigits(); int oldMinDigits = nf.getMinimumFractionDigits();
// Common patterns are "#.##", "#.00", "#". // Common patterns are "#.##", "#.00", "#".
// Try to adjust all of them in a reasonable way. // Try to adjust all of them in a reasonable way.
if (oldMinDigits == df.getMaximumFractionDigits()) { if (oldMinDigits == nf.getMaximumFractionDigits()) {
df.setMinimumFractionDigits(digits); nf.setMinimumFractionDigits(digits);
df.setMaximumFractionDigits(digits); nf.setMaximumFractionDigits(digits);
} else { } else {
df.setMinimumFractionDigits(Math.min(digits, oldMinDigits)); nf.setMinimumFractionDigits(Math.min(digits, oldMinDigits));
df.setMaximumFractionDigits(digits); nf.setMaximumFractionDigits(digits);
} }
} }
} }
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4847375
* @summary JFileChooser Create New Folder button is disabled incorrectly
* @author Pavel Porvatov
*/
import sun.awt.OSInfo;
import sun.awt.shell.ShellFolder;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
public class bug4847375 {
private final String newFolderToolTipText;
private final String lookAndFeel;
public static void main(String[] args) throws Exception {
if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
System.out.println("The test is suitable only for Windows OS. Skipped.");
return;
}
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
new bug4847375("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
new bug4847375("javax.swing.plaf.metal.MetalLookAndFeel");
}
});
}
private static Object[][] DIRECTORIES = new Object[][]{
{"getDesktop", Boolean.TRUE},
{"getDrives", Boolean.FALSE}, // My computer
{"getRecent", Boolean.TRUE},
{"getNetwork", Boolean.FALSE},
{"getPersonal", Boolean.TRUE},
};
private bug4847375(String lookAndFeel) {
this.lookAndFeel = lookAndFeel;
try {
UIManager.setLookAndFeel(lookAndFeel);
} catch (Exception e) {
fail("Cannot set LookAndFeel", e);
}
JFileChooser fileChooser = new JFileChooser();
// Find button NewFolder
newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText", fileChooser.getLocale());
if (newFolderToolTipText == null || newFolderToolTipText.length() == 0) {
fail("Cannot find NewFolderButton in FileChooser (tooltip doesn't exist)");
return;
}
JButton newFolderButton = findNewFolderButton(fileChooser);
if (newFolderButton == null) {
fail("Cannot find NewFolderButton in FileChooser");
return;
}
for (Object[] objects : DIRECTORIES) {
String getterName = (String) objects[0];
Boolean enabledNewFolder = (Boolean) objects[1];
fileChooser.setCurrentDirectory(getWin32Folder(getterName));
if (newFolderButton.isEnabled() != enabledNewFolder) {
fail("Enabled state of NewFolderButton should be " + enabledNewFolder +
" for Win32ShellFolderManager2." + getterName + "()");
}
}
}
private JButton findNewFolderButton(Container container) {
JButton result = null;
for (int i = 0; i < container.getComponentCount(); i++) {
Component c = container.getComponent(i);
if (c instanceof JButton && newFolderToolTipText.equals(((JButton) c).getToolTipText())) {
if (result != null) {
fail("Two or more NewFolderButton found in FileChooser");
}
result = (JButton) c;
}
if (c instanceof Container) {
JButton button = findNewFolderButton((Container) c);
if (result == null) {
result = button;
} else {
if (button != null) {
fail("Two or more NewFolderButton found in FileChooser");
}
}
}
}
return result;
}
private ShellFolder getWin32Folder(String getterName) {
try {
Class win32ShellFolderManager2 = Class.forName("sun.awt.shell.Win32ShellFolderManager2");
Method method = win32ShellFolderManager2.getDeclaredMethod(getterName);
method.setAccessible(true);
return (ShellFolder) method.invoke(null);
} catch (Exception e) {
fail("Cannot call '" + getterName + "' in the Win32ShellFolderManager2 class", e);
return null;
}
}
private void fail(String s) {
throw new RuntimeException("Test failed: " + s);
}
private void fail(String s, Throwable e) {
throw new RuntimeException("Test failed for LookAndFeel " + lookAndFeel + ": " + s, e);
}
}
...@@ -40,11 +40,13 @@ public class bug6542335 { ...@@ -40,11 +40,13 @@ public class bug6542335 {
private static MyScrollBarUI ui; private static MyScrollBarUI ui;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Robot robot = new Robot(); final Robot robot = new Robot();
robot.setAutoDelay(10); robot.setAutoDelay(10);
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
final Rectangle[] thumbBounds = new Rectangle[1];
SwingUtilities.invokeAndWait(new Runnable() { SwingUtilities.invokeAndWait(new Runnable() {
public void run() { public void run() {
final JFrame frame = new JFrame("bug6542335"); final JFrame frame = new JFrame("bug6542335");
...@@ -63,25 +65,39 @@ public class bug6542335 { ...@@ -63,25 +65,39 @@ public class bug6542335 {
rangeModel.setValue(50); rangeModel.setValue(50);
sb.setModel(rangeModel); sb.setModel(rangeModel);
frame.add(sb); frame.add(sb, BorderLayout.NORTH);
frame.setSize(200, 100); frame.setSize(200, 100);
frame.setVisible(true); frame.setVisible(true);
thumbBounds[0] = new Rectangle(ui.getThumbBounds());
} }
}); });
Rectangle thumbBounds = new Rectangle(ui.getThumbBounds());
toolkit.realSync(); toolkit.realSync();
Point l = sb.getLocationOnScreen();
robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight()/2); SwingUtilities.invokeAndWait(new Runnable() {
robot.mousePress(InputEvent.BUTTON1_MASK); public void run() {
robot.mouseRelease(InputEvent.BUTTON1_MASK); Point l = sb.getLocationOnScreen();
robot.mouseMove(l.x + (int) (0.75 * sb.getWidth()), l.y + sb.getHeight() / 2);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
}
});
toolkit.realSync(); toolkit.realSync();
if (!thumbBounds.equals(ui.getThumbBounds())) { SwingUtilities.invokeAndWait(new Runnable() {
throw new RuntimeException("Test failed"); public void run() {
} Rectangle newThumbBounds = ui.getThumbBounds();
if (!thumbBounds[0].equals(newThumbBounds)) {
throw new RuntimeException("Test failed.\nOld bounds: " + thumbBounds[0] +
"\nNew bounds: " + newThumbBounds);
}
}
});
} }
static class MyScrollBarUI extends BasicScrollBarUI { static class MyScrollBarUI extends BasicScrollBarUI {
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 6532833
@summary PIT: Metal LAF - The right side border is not shown for the Spinner after the removing the buttons
@author Pavel Porvatov
*/
import javax.swing.*;
import java.awt.*;
public class bug6532833 {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JSpinner[] spinners = new JSpinner[2];
for (int i = 0; i < spinners.length; i++) {
JSpinner spinner = new JSpinner();
spinner.setValue(2010);
Component arrowUp = spinner.getComponent(0);
Component arrowDown = spinner.getComponent(1);
LayoutManager layout = spinner.getLayout();
layout.removeLayoutComponent(arrowUp);
layout.removeLayoutComponent(arrowDown);
if (i == 1) {
spinner.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
spinners[i] = spinner;
}
// Do layout of spinners components
JFrame frame = new JFrame();
for (JSpinner spinner : spinners) {
frame.getContentPane().add(spinner);
}
frame.pack();
for (JSpinner spinner : spinners) {
Insets insets = spinner.getInsets();
if (spinner.getWidth() != insets.left + insets.right + spinner.getEditor().getWidth()) {
throw new RuntimeException("Spinner editor width is invalid");
}
}
frame.dispose();
}
});
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册