diff options
author | Veronika Irvine <veronika> | 2003-03-05 15:00:14 +0000 |
---|---|---|
committer | Veronika Irvine <veronika> | 2003-03-05 15:00:14 +0000 |
commit | 281dc95420976f0ffb0cbab0dc7e5e4a8f3ac547 (patch) | |
tree | 7682936f0fef30a163a6b92d96ef435e09c564c1 /bundles/org.eclipse.swt/Eclipse SWT/common | |
parent | 4d0b24a27232ff40c8169511178d0b60b9efdcc2 (diff) | |
download | eclipse.platform.swt-281dc95420976f0ffb0cbab0dc7e5e4a8f3ac547.tar.gz eclipse.platform.swt-281dc95420976f0ffb0cbab0dc7e5e4a8f3ac547.tar.xz eclipse.platform.swt-281dc95420976f0ffb0cbab0dc7e5e4a8f3ac547.zip |
Converting Binary files to ASCII
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/common')
108 files changed, 19551 insertions, 19551 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/swt.h b/bundles/org.eclipse.swt/Eclipse SWT/common/library/swt.h index 0bdba60b2b..b2af780054 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/library/swt.h +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/swt.h @@ -5,24 +5,24 @@ * http://www.eclipse.org/legal/cpl-v10.html */ -/**
- * swt.h
- *
- * This file contains the global macro declarations for the
- * SWT library.
- *
- */
-
+/** + * swt.h + * + * This file contains the global macro declarations for the + * SWT library. + * + */ + #ifndef INC_swt_H #define INC_swt_H #include "jni.h" -/* For debugging */
+/* For debugging */ #define DEBUG_PRINTF(x) -/*#define DEBUG_PRINTF(x) printf x; */
-
-/* define this to print out debug statements */
+/*#define DEBUG_PRINTF(x) printf x; */ + +/* define this to print out debug statements */ /* #define DEBUG_CALL_PRINTS */ /* #define DEBUG_CHECK_NULL_EXCEPTIONS */ diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java index b605ea0cea..583abe368e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java @@ -1,2381 +1,2381 @@ -package org.eclipse.swt;
-
-/*
+package org.eclipse.swt; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.*;
-
-/**
- * This class provides access to a small number of SWT system-wide
- * methods, and in addition defines the public constants provided
- * by SWT.
- * <p>
- * By defining constants like UP and DOWN in a single class, SWT
- * can share common names and concepts at the same time minimizing
- * the number of classes, names and constants for the application
- * programmer.
- * </p><p>
- * Note that some of the constants provided by this class represent
- * optional, appearance related aspects of widgets which are available
- * either only on some window systems, or for a differing set of
- * widgets on each window system. These constants are marked
- * as <em>HINT</em>s. The set of widgets which support a particular
- * <em>HINT</em> may change from release to release, although we typically
- * will not withdraw support for a <em>HINT</em> once it is made available.
- * </p>
- */
-
-/* NOTE:
- * Good javadoc coding style is to put the values of static final
- * constants in the comments. This reinforces the fact that
- * consumers are allowed to rely on the value (and they must
- * since the values are compiled inline in their code). We
- * can <em>not</em> change the values of these constants between
- * releases.
- */
-public class SWT {
-
- /* Initialize the class */
-// static {
-// /* NOTE: the static initialization is at the end of file */
-// }
-
- /* Widget Event Constants */
-
- /**
- * key down event type (value is 1)
- */
- public static final int KeyDown = 1;
-
- /**
- * key up event type (value is 2)
- */
- public static final int KeyUp = 2;
-
- /**
- * mouse down event type (value is 3)
- */
- public static final int MouseDown = 3;
-
- /**
- * mouse up event type (value is 4)
- */
- public static final int MouseUp = 4;
-
- /**
- * mouse move event type (value is 5)
- */
- public static final int MouseMove = 5;
-
- /**
- * mouse enter event type (value is 6)
- */
- public static final int MouseEnter = 6;
-
- /**
- * Mouse exit event type (value is 7)
- */
- public static final int MouseExit = 7;
-
- /**
- * mouse double click event type (value is 8)
- */
- public static final int MouseDoubleClick = 8;
-
- /**
- * paint event type (value is 9)
- */
- public static final int Paint = 9;
-
- /**
- * move event type (value is 10)
- */
- public static final int Move = 10;
-
- /**
- * resize event type (value is 11)
- */
- public static final int Resize = 11;
-
- /**
- * dispose event type (value is 12)
- */
- public static final int Dispose = 12;
-
- /**
- * selection event type (value is 13)
- */
- public static final int Selection = 13;
-
- /**
- * default selection event type (value is 14)
- */
- public static final int DefaultSelection = 14;
-
- /**
- * focus in event type (value is 15)
- */
- public static final int FocusIn = 15;
-
- /**
- * focus out event type (value is 16)
- */
- public static final int FocusOut = 16;
-
- /**
- * expand event type (value is 17)
- */
- public static final int Expand = 17;
-
- /**
- * collapse event type (value is 18)
- */
- public static final int Collapse = 18;
-
- /**
- * iconify event type (value is 19)
- */
- public static final int Iconify = 19;
-
- /**
- * de-iconify event type (value is 20)
- */
- public static final int Deiconify = 20;
-
- /**
- * close event type (value is 21)
- */
- public static final int Close = 21;
-
- /**
- * show event type (value is 22)
- */
- public static final int Show = 22;
-
- /**
- * hide event type (value is 23)
- */
- public static final int Hide = 23;
-
- /**
- * modify event type (value is 24)
- */
- public static final int Modify = 24;
-
- /**
- * verify event type (value is 25)
- */
- public static final int Verify = 25;
-
- /**
- * activate event type (value is 26)
- */
- public static final int Activate = 26;
-
- /**
- * deactivate event type (value is 27)
- */
- public static final int Deactivate = 27;
-
- /**
- * help event type (value is 28)
- */
- public static final int Help = 28;
-
- /**
- * drag detect event type (value is 29)
- */
- public static final int DragDetect = 29;
-
- /**
- * arm event type (value is 30)
- */
- public static final int Arm = 30;
-
- /**
- * traverse event type (value is 31)
- */
- public static final int Traverse = 31;
-
- /**
- * mouse hover event type (value is 32)
- */
- public static final int MouseHover = 32;
-
- /**
- * hardware key down event type (value is 33)
- */
- public static final int HardKeyDown = 33;
-
- /**
- * hardware key up event type (value is 34)
- */
- public static final int HardKeyUp = 34;
-
- /* Event Details */
-
- /**
- * a constant known to be zero (0), used in operations which
- * take bit flags to indicate that "no bits are set"
- */
- public static final int NONE = 0;
-
- /**
- * indicates that a user-interface component is being dragged,
- * for example dragging the thumb of a scroll bar (value is 1)
- */
- public static final int DRAG = 1;
-
- /**
- * a constant known to be zero (0), used in operations which
- * take pointers to indicate a null argument
- */
- public static final int NULL = 0;
-
- /**
- * indicates that a default should be used (value is -1)
- */
- public static final int DEFAULT = -1;
-
- /**
- * style constant for menu bar behavior (value is 1<<1)
- * <p><b>Used By:</b><ul>
- * <li><code>Menu</code></li>
- * </ul></p>
- */
- public static final int BAR = 1 << 1;
-
- /**
- * style constant for drop down menu/list behavior (value is 1<<2)
- * <p><b>Used By:</b><ul>
- * <li><code>Menu</code></li>
- * <li><code>ToolItem</code></li>
- * <li><code>CoolItem</code></li>
- * <li><code>Combo</code></li>
- * </ul></p>
- */
- public static final int DROP_DOWN = 1 << 2;
-
- /**
- * style constant for pop up menu behavior (value is 1<<3)
- * <p><b>Used By:</b><ul>
- * <li><code>Menu</code></li>
- * </ul></p>
- */
- public static final int POP_UP = 1 << 3;
-
- /**
- * style constant for line separator behavior (value is 1<<1)
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>MenuItem</code></li>
- * <li><code>ToolItem</code></li>
- * </ul></p>
- */
- public static final int SEPARATOR = 1 << 1;
-
- /**
- * style constant for toggle button behavior (value is 1<<1)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * </ul></p>
- */
- public static final int TOGGLE = 1 << 1;
-
- /**
- * style constant for arrow button behavior (value is 1<<2)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * </ul></p>
- */
- public static final int ARROW = 1 << 2;
-
- /**
- * style constant for push button behavior (value is 1<<3)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>MenuItem</code></li>
- * <li><code>ToolItem</code></li>
- * </ul></p>
- */
- public static final int PUSH = 1 << 3;
-
- /**
- * style constant for radio button behavior (value is 1<<4)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>MenuItem</code></li>
- * <li><code>ToolItem</code></li>
- * </ul></p>
- */
- public static final int RADIO = 1 << 4;
-
- /**
- * style constant for check box behavior (value is 1<<5)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>MenuItem</code></li>
- * <li><code>ToolItem</code></li>
- * <li><code>Table</code></li>
- * <li><code>Tree</code></li>
- * </ul></p>
- */
- public static final int CHECK = 1 << 5;
-
- /**
- * style constant for cascade behavior (value is 1<<6)
- * <p><b>Used By:</b><ul>
- * <li><code>MenuItem</code></li>
- * </ul></p>
- */
- public static final int CASCADE = 1 << 6;
-
- /**
- * style constant for multi-selection behavior in lists
- * and multiple line support on text fields (value is 1<<1)
- * <p><b>Used By:</b><ul>
- * <li><code>Text</code></li>
- * <li><code>List</code></li>
- * <li><code>FileDialog</code></li>
- * </ul></p>
- */
- public static final int MULTI = 1 << 1;
-
- /**
- * style constant for single selection behavior in lists
- * and single line support on text fields (value is 1<<2)
- * <p><b>Used By:</b><ul>
- * <li><code>Text</code></li>
- * <li><code>List</code></li>
- * <li><code>Table</code></li>
- * <li><code>Tree</code></li>
- * </ul></p>
- */
- public static final int SINGLE = 1 << 2;
-
- /**
- * style constant for read-only behavior (value is 1<<3)
- * <p><b>Used By:</b><ul>
- * <li><code>Combo</code></li>
- * <li><code>Text</code></li>
- * </ul></p>
- */
- public static final int READ_ONLY = 1 << 3;
-
- /**
- * style constant for automatic line wrap behavior (value is 1<<6)
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>Text</code></li>
- * <li><code>ToolBar</code></li>
- * </ul></p>
- */
- public static final int WRAP = 1 << 6;
-
- /**
- * style constant for simple (not drop down) behavior (value is 1<<6)
- * <p><b>Used By:</b><ul>
- * <li><code>Combo</code></li>
- * </ul></p>
- */
- public static final int SIMPLE = 1 << 6;
-
- /**
- * style constant for shadow in behavior (value is 1<<2)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>Group</code></li>
- * </ul></p>
- */
- public static final int SHADOW_IN = 1 << 2;
-
- /**
- * style constant for shadow out behavior (value is 1<<3)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>Group</code></li>
- * <li><code>ToolBar</code></li>
- * </ul></p>
- */
- public static final int SHADOW_OUT = 1 << 3;
-
- /**
- * style constant for shadow etched in behavior (value is 1<<4)
- * <br>Note that this is a <em>HINT</em>. It is ignored on all platforms except Motif.
- * <p><b>Used By:</b><ul>
- * <li><code>Group</code></li>
- * </ul></p>
- */
- public static final int SHADOW_ETCHED_IN = 1 << 4;
-
- /**
- * style constant for shadow etched out behavior (value is 1<<6)
- * <br>Note that this is a <em>HINT</em>. It is ignored on all platforms except Motif.
- * <p><b>Used By:</b><ul>
- * <li><code>Group</code></li>
- * </ul></p>
- */
- public static final int SHADOW_ETCHED_OUT = 1 << 6;
-
- /**
- * style constant for no shadow behavior (value is 1<<5)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>Group</code></li>
- * </ul></p>
- */
- public static final int SHADOW_NONE = 1 << 5;
-
- /**
- * style constant for progress bar behavior (value is 1<<1)
- * <p><b>Used By:</b><ul>
- * <li><code>ProgressBar</code></li>
- * </ul></p>
- */
- public static final int INDETERMINATE = 1 << 1;
-
- /**
- * style constant for tool window behavior (value is 1<<2)
- * <p>
- * A tool window is a window intended to be used as a floating toolbar.
- * It typically has a title bar that is shorter than a normal title bar,
- * and the window title is typically drawn using a smaller font.
- * <br>Note that this is a <em>HINT</em>.
- * </p><p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int TOOL = 1 << 2;
-
- /**
- * style constant to ensure no trimmings are used (value is 1<<3)
- * <br>Note that this overrides all other trim styles.
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int NO_TRIM = 1 << 3;
-
- /**
- * style constant for resize box trim (value is 1<<4)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * <li><code>Tracker</code></li>
- * </ul></p>
- */
- public static final int RESIZE = 1 << 4;
-
- /**
- * style constant for title area trim (value is 1<<5)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int TITLE = 1 << 5;
-
- /**
- * style constant for close box trim (value is 1<<6,
- * since we do not distinguish between CLOSE style and MENU style)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int CLOSE = 1 << 6;
-
- /**
- * style constant for shell menu trim (value is 1<<6,
- * since we do not distinguish between CLOSE style and MENU style)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int MENU = CLOSE;
-
- /**
- * style constant for minimize box trim (value is 1<<7)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int MIN = 1 << 7;
-
- /**
- * style constant for maximize box trim (value is 1<<10)
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code> and subclasses</li>
- * </ul></p>
- */
- public static final int MAX = 1 << 10;
-
- /**
- * style constant for horizontal scrollbar behavior (value is 1<<8)
- * <p><b>Used By:</b><ul>
- * <li><code>Scrollable</code> and subclasses</li>
- * </ul></p>
- */
- public static final int H_SCROLL = 1 << 8;
-
- /**
- * style constant for vertical scrollbar behavior (value is 1<<9)
- * <p><b>Used By:</b><ul>
- * <li><code>Scrollable</code> and subclasses</li>
- * </ul></p>
- */
- public static final int V_SCROLL = 1 << 9;
-
- /**
- * style constant for bordered behavior (value is 1<<11)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code> and subclasses</li>
- * </ul></p>
- */
- public static final int BORDER = 1 << 11;
-
- /**
- * style constant indicating that the window manager should clip
- * a widget's children with respect to its viewable area. (value is 1<<12)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code> and subclasses</li>
- * </ul></p>
- */
- public static final int CLIP_CHILDREN = 1 << 12;
-
- /**
- * style constant indicating that the window manager should clip
- * a widget's siblings with respect to its viewable area. (value is 1<<13)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code> and subclasses</li>
- * </ul></p>
- */
- public static final int CLIP_SIBLINGS = 1 << 13;
-
- /**
- * style constant for always on top behavior (value is 1<<14)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Decorations</code>and subclasses</li>
- * </ul></p>
- */
- public static final int ON_TOP = 1 << 14;
-
- /**
- * trim style convenience constant for the most common top level shell appearance
- * (value is CLOSE|TITLE|MIN|MAX|RESIZE)
- * <p><b>Used By:</b><ul>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int SHELL_TRIM = CLOSE | TITLE | MIN | MAX | RESIZE;
-
- /**
- * trim style convenience constant for the most common dialog shell appearance
- * (value is CLOSE|TITLE|BORDER)
- * <p><b>Used By:</b><ul>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int DIALOG_TRIM = TITLE | CLOSE | BORDER;
-
- /**
- * style constant for modeless behavior (value is 0)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Dialog</code></li>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int MODELESS = 0;
-
- /**
- * style constant for primary modal behavior (value is 1<<15)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Dialog</code></li>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int PRIMARY_MODAL = 1 << 15;
-
- /**
- * style constant for application modal behavior (value is 1<<16)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Dialog</code></li>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int APPLICATION_MODAL = 1 << 16;
-
- /**
- * style constant for system modal behavior (value is 1<<17)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Dialog</code></li>
- * <li><code>Shell</code></li>
- * </ul></p>
- */
- public static final int SYSTEM_MODAL = 1 << 17;
-
- /**
- * style constant for selection hiding behavior. (value is 1<<15)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Table</code></li>
- * </ul></p>
- */
- public static final int HIDE_SELECTION = 1 << 15;
-
- /**
- * style constant for full row selection behavior. (value is 1<<16)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Table</code></li>
- * </ul></p>
- */
- public static final int FULL_SELECTION = 1 << 16;
-
- /**
- * style constant for flat appearance. (value is 1<<23)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>ToolBar</code></li>
- * </ul></p>
- */
- public static final int FLAT = 1 << 23;
-
- /**
- * style constant for flat appearance. (value is 1<<16)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>ProgressBar</code></li>
- * </ul></p>
- */
- public static final int SMOOTH = 1 << 16;
-
- /**
- * style constant for no background behavior (value is 1<<18)
- * <p>
- * By default, before a widget paints, the client area is filled with the current background color.
- * When this style is specified, the background is not filled, and the application is responsible
- * for filling every pixel of the client area.
- * This style might be used as an alternative to "double-buffering" in order to reduce flicker.
- * This style does not mean "transparent" - widgets that are obscured will not draw through.
- * </p><p><b>Used By:</b><ul>
- * <li><code>Composite</code></li>
- * </ul></p>
- */
- public static final int NO_BACKGROUND = 1 << 18;
-
- /**
- * style constant for does not take focus behavior (value is 1<<19)
- * <br>Note that this is a <em>HINT</em>.
- * <p><b>Used By:</b><ul>
- * <li><code>Composite</code></li>
- * </ul></p>
- */
- public static final int NO_FOCUS = 1 << 19;
-
- /**
- * style constant for no redraw on resize behavior (value is 1<<20)
- * <p>
- * This style stops the entire client area from being invalidated when the size
- * of the Canvas changes. Specifically, when the size of the Canvas gets smaller,
- * the SWT.Paint event is not sent. When it gets bigger, an SWT.Paint event is
- * sent with a GC clipped to only the new areas to be painted. Without this
- * style, the entire client area will be repainted.
- * </p><p><b>Used By:</b><ul>
- * <li><code>Composite</code></li>
- * </ul></p>
- */
- public static final int NO_REDRAW_RESIZE = 1 << 20;
-
- /**
- * style constant for no paint event merging behavior (value is 1<<21)
- * <p><b>Used By:</b><ul>
- * <li><code>Composite</code></li>
- * </ul></p>
- */
- public static final int NO_MERGE_PAINTS = 1 << 21;
-
- /**
- * style constant for preventing child radio group behavior (value is 1<<22)
- * <p><b>Used By:</b><ul>
- * <li><code>Composite</code></li>
- * </ul></p>
- */
- public static final int NO_RADIO_GROUP = 1 << 22;
-
- /**
- * style constant for left to right orientation (value is 1<<25)
- * <p>
- * When orientation is not explicitly specified, orientation is
- * inherited. This means that children will be assigned the
- * orientation of their parent. To override this behavior and
- * force an orientation for a child, explicitly set the orientation
- * of the child when that child is created.
- * </p>
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code></li>
- * <li><code>Menu</code></li>
- * </ul></p>
- *
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
- */
- public static final int LEFT_TO_RIGHT = 1 << 25;
-
- /**
- * style constant for right to left orientation (value is 1<<26)
- * <p>
- * When orientation is not explicitly specified, orientation is
- * inherited. This means that children will be assigned the
- * orientation of their parent. To override this behavior and
- * force an orientation for a child, explicitly set the orientation
- * of the child when that child is created.
- * </p>
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code></li>
- * <li><code>Menu</code></li>
- * </ul></p>
- *
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
- */
- public static final int RIGHT_TO_LEFT = 1 << 26;
-
- /**
- * style constant to indicate coordinate mirroring (value is 1<<27)
- * <p><b>Used By:</b><ul>
- * <li><code>Control</code></li>
- * <li><code>Menu</code></li>
- * </ul></p>
- *
- * <p>
- * <b>NOTE:</b> This API element is part of an interim API that is still under
- * development and is expected to change significantly before reaching stability.
- * It is being made available at this early stage to solicit feedback from
- * pioneering adopters on the understanding that any code that uses this API
- * will almost certainly be broken (repeatedly) as the API evolves.
- * </p>
- *
- * @since 2.1
- */
- public static final int MIRRORED = 1 << 27;
-
- /**
- * style constant for align up behavior (value is 1<<7,
- * since align UP and align TOP are considered the same)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code> with <code>ARROW</code> style</li>
- * <li><code>Tracker</code></li>
- * </ul></p>
- */
- public static final int UP = 1 << 7;
-
- /**
- * style constant for align top behavior (value is 1<<7,
- * since align UP and align TOP are considered the same)
- * <p><b>Used By:</b><ul>
- * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
- * </ul></p>
- */
- public static final int TOP = UP;
-
- /**
- * style constant for align down behavior (value is 1<<10,
- * since align DOWN and align BOTTOM are considered the same)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code> with <code>ARROW</code> style</li>
- * <li><code>Tracker</code></li>
- * </ul></p>
- */
- public static final int DOWN = 1 << 10;
-
- /**
- * style constant for align bottom behavior (value is 1<<10,
- * since align DOWN and align BOTTOM are considered the same)
- * <p><b>Used By:</b><ul>
- * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
- * </ul></p>
- */
- public static final int BOTTOM = DOWN;
-
- /**
- * style constant for align left behavior (value is 1<<14)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>Label</code></li>
- * <li><code>TableColumn</code></li>
- * <li><code>Tracker</code></li>
- * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
- * </ul></p>
- */
- public static final int LEFT = 1 << 14;
-
- /**
- * style constant for align right behavior (value is 1<<17)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>Label</code></li>
- * <li><code>TableColumn</code></li>
- * <li><code>Tracker</code></li>
- * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
- * </ul></p>
- */
- public static final int RIGHT = 1 << 17;
-
- /**
- * style constant for align center behavior (value is 1<<24)
- * <p><b>Used By:</b><ul>
- * <li><code>Button</code></li>
- * <li><code>Label</code></li>
- * <li><code>TableColumn</code></li>
- * <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
- * </ul></p>
- */
- public static final int CENTER = 1 << 24;
-
- /**
- * style constant for horizontal alignment or orientation behavior (value is 1<<8)
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>ProgressBar</code></li>
- * <li><code>Sash</code></li>
- * <li><code>Scale</code></li>
- * <li><code>ScrollBar</code></li>
- * <li><code>Slider</code></li>
- * <li><code>ToolBar</code></li>
- * <li><code>FillLayout</code> type</li>
- * <li><code>RowLayout</code> type</li>
- * </ul></p>
- */
- public static final int HORIZONTAL = 1 << 8;
-
- /**
- * style constant for vertical alignment or orientation behavior (value is 1<<9)
- * <p><b>Used By:</b><ul>
- * <li><code>Label</code></li>
- * <li><code>ProgressBar</code></li>
- * <li><code>Sash</code></li>
- * <li><code>Scale</code></li>
- * <li><code>ScrollBar</code></li>
- * <li><code>Slider</code></li>
- * <li><code>ToolBar</code></li>
- * <li><code>FillLayout</code> type</li>
- * <li><code>RowLayout</code> type</li>
- * </ul></p>
- */
- public static final int VERTICAL = 1 << 9;
-
- /**
- * Input Method Editor style constant for double byte
- * input behavior (value is 1<<1)
- */
- public static final int DBCS = 1 << 1;
-
- /**
- * Input Method Editor style constant for alpha
- * input behavior (value is 1<<2)
- */
- public static final int ALPHA = 1 << 2;
-
- /**
- * Input Method Editor style constant for native
- * input behavior (value is 1<<3)
- */
- public static final int NATIVE = 1 << 3;
-
- /**
- * Input Method Editor style constant for phonetic
- * input behavior (value is 1<<4)
- */
- public static final int PHONETIC = 1 << 4;
-
- /**
- * Input Method Editor style constant for romanicized
- * input behavior (value is 1<<5)
- */
- public static final int ROMAN = 1 << 5;
-
- /**
- * ASCII character convenience constant for the backspace character
- * (value is the <code>char</code> '\b')
- */
- public static final char BS = '\b';
-
- /**
- * ASCII character convenience constant for the carriage return character
- * (value is the <code>char</code> '\r')
- */
- public static final char CR = '\r';
-
- /**
- * ASCII character convenience constant for the delete character
- * (value is the <code>char</code> with value 127)
- */
- public static final char DEL = 0x7F;
-
- /**
- * ASCII character convenience constant for the escape character
- * (value is the <code>char</code> with value 27)
- */
- public static final char ESC = 0x1B;
-
- /**
- * ASCII character convenience constant for the line feed character
- * (value is the <code>char</code> '\n')
- */
- public static final char LF = '\n';
-
- /**
- * ASCII character convenience constant for the tab character
- * (value is the <code>char</code> '\t')
- *
- * @since 2.1
- */
- public static final char TAB = '\t';
-
- /**
- * keyboard and/or mouse event mask indicating that the ALT key
- * was pushed on the keyboard when the event was generated
- * (value is 1<<16)
- */
- public static final int ALT = 1 << 16;
-
- /**
- * keyboard and/or mouse event mask indicating that the SHIFT key
- * was pushed on the keyboard when the event was generated
- * (value is 1<<17)
- */
- public static final int SHIFT = 1 << 17;
-
- /**
- * keyboard and/or mouse event mask indicating that the CTRL key
- * was pushed on the keyboard when the event was generated
- * (value is 1<<18)
- */
- public static final int CTRL = 1 << 18;
-
- /**
- * keyboard and/or mouse event mask indicating that the CTRL key
- * was pushed on the keyboard when the event was generated. This
- * is a synonym for CTRL (value is 1<<18)
- */
- public static final int CONTROL = CTRL;
-
- /**
- * keyboard and/or mouse event mask indicating that the COMMAND key
- * was pushed on the keyboard when the event was generated
- * (value is 1<<22)
- *
- * @since 2.1
- */
- public static final int COMMAND = 1 << 22;
-
- /**
- * keyboard and/or mouse event mask indicating all possible
- * keyboard modifiers. To allow for the future, this mask
- * is intended to be used in place of code that references
- * each individual keyboard mask. For example, the following
- * expression will determine whether any modifer is pressed
- * and will continue to work as new modifier masks are added.
- *
- * <code>(stateMask & SWT.MODIFIER_MASK) != 0</code>.
- *
- * @since 2.1
- */
- public static final int MODIFIER_MASK;
-
- /**
- * keyboard and/or mouse event mask indicating that mouse button one
- * was pushed when the event was generated. (value is 1<<19)
- */
- public static final int BUTTON1 = 1 << 19;
-
- /**
- * keyboard and/or mouse event mask indicating that mouse button two
- * was pushed when the event was generated. (value is 1<<20)
- */
- public static final int BUTTON2 = 1 << 20;
-
- /**
- * keyboard and/or mouse event mask indicating that mouse button three
- * was pushed when the event was generated. (value is 1<<21)
- */
- public static final int BUTTON3 = 1 << 21;
-
- /**
- * keyboard and/or mouse event mask indicating all possible
- * mouse buttons. To allow for the future, this mask
- * is intended to be used in place of code that references
- * each individual button mask. For example, the following
- * expression will determine whether any button is pressed
- * and will continue to work as new button masks are added.
- *
- * <code>(stateMask & SWT.BUTTON_MASK) != 0</code>.
- *
- * @since 2.1
- */
- public static final int BUTTON_MASK;
-
- /**
- * keyboard and/or mouse event mask indicating that the MOD1 key
- * was pushed on the keyboard when the event was generated. This
- * is the primary keyboard modifier for the platform.
- *
- * @since 2.1
- */
- public static final int MOD1;
-
- /**
- * keyboard and/or mouse event mask indicating that the MOD2 key
- * was pushed on the keyboard when the event was generated. This
- * is the secondary keyboard modifier for the platform.
- *
- * @since 2.1
- */
- public static final int MOD2;
-
- /**
- * keyboard and/or mouse event mask indicating that the MOD3 key
- * was pushed on the keyboard when the event was generated.
- *
- * @since 2.1
- */
- public static final int MOD3;
-
- /**
- * keyboard and/or mouse event mask indicating that the MOD4 key
- * was pushed on the keyboard when the event was generated.
- *
- * @since 2.1
- */
- public static final int MOD4;
-
- /**
- * accelerator constant used to differentiate a key code from a
- * unicode character. If this bit is set, then the key stroke
- * portion of an accelerator represents a key code. If this bit
- * is not set, then the key stroke portion of an accelerator is
- * a unicode character.
- *
- * The following expression is false:
- *
- * <code>((SWT.MOD1 | SWT.MOD2 | 'T') & SWT.KEYCODE_BIT) != 0</code>.
- *
- * The following expression is true:
- *
- * <code>((SWT.MOD3 | SWT.F2) & SWT.KEYCODE_BIT) != 0</code>.
- *
- * (value is (1<<24))
- *
- * @since 2.1
- */
- public static final int KEYCODE_BIT = (1 << 24);
-
- /**
- * accelerator constant used to extract the key stroke portion of
- * an accelerator. The key stroke may be a key code or a unicode
- * value. If the key stroke is a key code <code>KEYCODE_BIT</code>
- * will be set.
- *
- * @since 2.1
- */
- public static final int KEY_MASK = KEYCODE_BIT + 0xFFFF;
-
- /**
- * keyboard event constant representing the UP ARROW key
- * (value is (1<<24)+1)
- */
- public static final int ARROW_UP = KEYCODE_BIT + 1;
-
- /**
- * keyboard event constant representing the DOWN ARROW key
- * (value is (1<<24)+2)
- */
- public static final int ARROW_DOWN = KEYCODE_BIT + 2;
-
- /**
- * keyboard event constant representing the LEFT ARROW key
- * (value is (1<<24)+3)
- */
- public static final int ARROW_LEFT = KEYCODE_BIT + 3;
-
- /**
- * keyboard event constant representing the RIGHT ARROW key
- * (value is (1<<24)+4)
- */
- public static final int ARROW_RIGHT = KEYCODE_BIT + 4;
-
- /**
- * keyboard event constant representing the PAGE UP key
- * (value is (1<<24)+5)
- */
- public static final int PAGE_UP = KEYCODE_BIT + 5;
-
- /**
- * keyboard event constant representing the PAGE DOWN key
- * (value is (1<<24)+6)
- */
- public static final int PAGE_DOWN = KEYCODE_BIT + 6;
-
- /**
- * keyboard event constant representing the HOME key
- * (value is (1<<24)+7)
- */
- public static final int HOME = KEYCODE_BIT + 7;
-
- /**
- * keyboard event constant representing the END key
- * (value is (1<<24)+8)
- */
- public static final int END = KEYCODE_BIT + 8;
-
- /**
- * keyboard event constant representing the INSERT key
- * (value is (1<<24)+9)
- */
- public static final int INSERT = KEYCODE_BIT + 9;
-
- /**
- * keyboard event constant representing the F1 key
- * (value is (1<<24)+10)
- */
- public static final int F1 = KEYCODE_BIT + 10;
-
- /**
- * keyboard event constant representing the F2 key
- * (value is (1<<24)+11)
- */
- public static final int F2 = KEYCODE_BIT + 11;
-
- /**
- * keyboard event constant representing the F3 key
- * (value is (1<<24)+12)
- */
- public static final int F3 = KEYCODE_BIT + 12;
-
- /**
- * keyboard event constant representing the F4 key
- * (value is (1<<24)+13)
- */
- public static final int F4 = KEYCODE_BIT + 13;
-
- /**
- * keyboard event constant representing the F5 key
- * (value is (1<<24)+14)
- */
- public static final int F5 = KEYCODE_BIT + 14;
-
- /**
- * keyboard event constant representing the F6 key
- * (value is (1<<24)+15)
- */
- public static final int F6 = KEYCODE_BIT + 15;
-
- /**
- * keyboard event constant representing the F7 key
- * (value is (1<<24)+16)
- */
- public static final int F7 = KEYCODE_BIT + 16;
-
- /**
- * keyboard event constant representing the F8 key
- * (value is (1<<24)+17)
- */
- public static final int F8 = KEYCODE_BIT + 17;
-
- /**
- * keyboard event constant representing the F9 key
- * (value is (1<<24)+18)
- */
- public static final int F9 = KEYCODE_BIT + 18;
-
- /**
- * keyboard event constant representing the F10 key
- * (value is (1<<24)+19)
- */
- public static final int F10 = KEYCODE_BIT + 19;
-
- /**
- * keyboard event constant representing the F11 key
- * (value is (1<<24)+20)
- */
- public static final int F11 = KEYCODE_BIT + 20;
-
- /**
- * keyboard event constant representing the F12 key
- * (value is (1<<24)+21)
- */
- public static final int F12 = KEYCODE_BIT + 21;
-
- /**
- * <code>MessageBox</code> style constant for error icon
- * behavior (value is 1)
- */
- public static final int ICON_ERROR = 1;
-
- /**
- * <code>MessageBox</code> style constant for information icon
- * behavior (value is 1<<1)
- */
- public static final int ICON_INFORMATION = 1 << 1;
-
- /**
- * <code>MessageBox</code> style constant for question icon
- * behavior (value is 1<<2)
- */
- public static final int ICON_QUESTION = 1 << 2;
-
- /**
- * <code>MessageBox</code> style constant for warning icon
- * behavior (value is 1<<3)
- */
- public static final int ICON_WARNING = 1 << 3;
-
- /**
- * <code>MessageBox</code> style constant for "working" icon
- * behavior (value is 1<<4)
- */
- public static final int ICON_WORKING = 1 << 4;
-
- /**
- * <code>MessageBox</code> style constant for an OK button.
- * Valid combinations are OK, OK|CANCEL
- * (value is 1<<5)
- */
- public static final int OK = 1 << 5;
-
- /**
- * <code>MessageBox</code> style constant for YES button.
- * Valid combinations are YES|NO, YES|NO|CANCEL
- * (value is 1<<6)
- */
- public static final int YES = 1 << 6;
-
- /**
- * <code>MessageBox</code> style constant for NO button.
- * Valid combinations are YES|NO, YES|NO|CANCEL
- * (value is 1<<7)
- */
- public static final int NO = 1 << 7;
-
- /**
- * <code>MessageBox</code> style constant for a CANCEL button.
- * Valid combinations are OK|CANCEL, YES|NO|CANCEL, RETRY|CANCEL
- * (value is 1<<8)
- */
- public static final int CANCEL = 1 << 8;
-
- /**
- * <code>MessageBox</code> style constant for an ABORT button.
- * The only valid combination is ABORT|RETRY|IGNORE
- * (value is 1<<9)
- */
- public static final int ABORT = 1 << 9;
-
- /**
- * <code>MessageBox</code> style constant for a RETRY button.
- * Valid combinations are ABORT|RETRY|IGNORE, RETRY|CANCEL
- * (value is 1<<10)
- */
- public static final int RETRY = 1 << 10;
-
- /**
- * <code>MessageBox</code> style constant for an IGNORE button.
- * The only valid combination is ABORT|RETRY|IGNORE
- * (value is 1<<11)
- */
- public static final int IGNORE = 1 << 11;
-
- /**
- * <code>FileDialog</code> style constant for open file dialog behavior
- * (value is 1<<12)
- */
- public static final int OPEN = 1 << 12;
-
- /**
- * <code>FileDialog</code> style constant for save file dialog behavior
- * (value is 1<<13)
- */
- public static final int SAVE = 1 << 13;
-
- /**
- * default color white (value is 1)
- */
- public static final int COLOR_WHITE = 1;
-
- /**
- * default color black (value is 2)
- */
- public static final int COLOR_BLACK = 2;
-
- /**
- * default color red (value is 3)
- */
- public static final int COLOR_RED = 3;
-
- /**
- * default color dark red (value is 4)
- */
- public static final int COLOR_DARK_RED = 4;
-
- /**
- * default color green (value is 5)
- */
- public static final int COLOR_GREEN = 5;
-
- /**
- * default color dark green (value is 6)
- */
- public static final int COLOR_DARK_GREEN = 6;
-
- /**
- * default color yellow (value is 7)
- */
- public static final int COLOR_YELLOW = 7;
-
- /**
- * default color dark yello (value is 8)
- */
- public static final int COLOR_DARK_YELLOW = 8;
-
- /**
- * default color blue (value is 9)
- */
- public static final int COLOR_BLUE = 9;
-
- /**
- * default color dark blue (value is 10)
- */
- public static final int COLOR_DARK_BLUE = 10;
-
- /**
- * default color magenta (value is 11)
- */
- public static final int COLOR_MAGENTA = 11;
-
- /**
- * default color dark magenta (value is 12)
- */
- public static final int COLOR_DARK_MAGENTA = 12;
-
- /**
- * default color cyan (value is 13)
- */
- public static final int COLOR_CYAN = 13;
-
- /**
- * default color dark cyan (value is 14)
- */
- public static final int COLOR_DARK_CYAN = 14;
-
- /**
- * default color gray (value is 15)
- */
- public static final int COLOR_GRAY = 15;
-
- /**
- * default color dark gray (value is 16)
- */
- public static final int COLOR_DARK_GRAY = 16;
-
- /*
- * System Colors
- *
- * Dealing with system colors is an area where there are
- * many platform differences. On some platforms, system
- * colors can change dynamically while the program is
- * running. On other platforms, system colors can be
- * changed for all instances of a particular widget.
- * Therefore, the only truly portable method to obtain
- * a widget color query is to query the color from an
- * instance of the widget.
- *
- * It is expected that the list of supported colors
- * will grow over time.
- */
-
- /**
- * system color used to paint dark shadow areas (value is 17)
- */
- public static final int COLOR_WIDGET_DARK_SHADOW = 17;
-
- /**
- * system color used to paint normal shadow areas (value is 18)
- */
- public static final int COLOR_WIDGET_NORMAL_SHADOW = 18;
-
- /**
- * system color used to paint light shadow areas (value is 19)
- */
- public static final int COLOR_WIDGET_LIGHT_SHADOW = 19;
-
- /**
- * system color used to paint highlight shadow areas (value is 20)
- */
- public static final int COLOR_WIDGET_HIGHLIGHT_SHADOW = 20;
-
- /**
- * system color used to paint foreground areas (value is 21)
- */
- public static final int COLOR_WIDGET_FOREGROUND = 21;
-
- /**
- * system color used to paint background areas (value is 22)
- */
- public static final int COLOR_WIDGET_BACKGROUND = 22;
-
- /**
- * system color used to paint border areas (value is 23)
- */
- public static final int COLOR_WIDGET_BORDER = 23;
-
- /**
- * system color used to paint list foreground areas (value is 24)
- */
- public static final int COLOR_LIST_FOREGROUND = 24;
-
- /**
- * system color used to paint list background areas (value is 25)
- */
- public static final int COLOR_LIST_BACKGROUND = 25;
-
- /**
- * system color used to paint list selection background areas (value is 26)
- */
- public static final int COLOR_LIST_SELECTION = 26;
-
- /**
- * system color used to paint list selected text (value is 27)
- */
- public static final int COLOR_LIST_SELECTION_TEXT = 27;
-
- /**
- * system color used to paint tooltip text (value is 28)
- */
- public static final int COLOR_INFO_FOREGROUND = 28;
-
- /**
- * system color used to paint tooltip background areas (value is 29)
- */
- public static final int COLOR_INFO_BACKGROUND = 29;
-
- /**
- * system color used to paint title text (value is 30)
- */
- public static final int COLOR_TITLE_FOREGROUND = 30;
-
- /**
- * system color used to paint title background areas (value is 31)
- */
- public static final int COLOR_TITLE_BACKGROUND = 31;
-
- /**
- * system color used to paint title background gradient (value is 32)
- */
- public static final int COLOR_TITLE_BACKGROUND_GRADIENT = 32;
-
- /**
- * system color used to paint inactive title text (value is 33)
- */
- public static final int COLOR_TITLE_INACTIVE_FOREGROUND = 33;
-
- /**
- * system color used to paint inactive title background areas (value is 34)
- */
- public static final int COLOR_TITLE_INACTIVE_BACKGROUND = 34;
-
- /**
- * system color used to paint inactive title background gradient (value is 35)
- */
- public static final int COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = 35;
-
- /**
- * draw constant indicating whether the drawing operation
- * should fill the background (value is 1<<0)
- */
- public static final int DRAW_TRANSPARENT = 1 << 0;
-
- /**
- * draw constant indicating whether the string drawing operation
- * should handle line-delimeters (value is 1<<1)
- */
- public static final int DRAW_DELIMITER = 1 << 1;
-
- /**
- * draw constant indicating whether the string drawing operation
- * should expand TAB characters (value is 1<<2)
- */
- public static final int DRAW_TAB = 1 << 2;
-
- /**
- * draw constant indicating whether the string drawing operation
- * should handle mnemonics (value is 1<<3)
- */
- public static final int DRAW_MNEMONIC = 1 << 3;
-
- /**
- * SWT error constant indicating that no error number was specified
- * (value is 1)
- */
- public static final int ERROR_UNSPECIFIED = 1;
-
- /**
- * SWT error constant indicating that no more handles for an
- * operating system resource are available
- * (value is 2)
- */
- public static final int ERROR_NO_HANDLES = 2;
-
- /**
- * SWT error constant indicating that no more callback resources are available
- * (value is 3)
- */
- public static final int ERROR_NO_MORE_CALLBACKS = 3;
-
- /**
- * SWT error constant indicating that a null argument was passed in
- * (value is 4)
- */
- public static final int ERROR_NULL_ARGUMENT = 4;
-
- /**
- * SWT error constant indicating that an invalid argument was passed in
- * (value is 5)
- */
- public static final int ERROR_INVALID_ARGUMENT = 5;
-
- /**
- * SWT error constant indicating that a value was found to be
- * outside the allowable range
- * (value is 6)
- */
- public static final int ERROR_INVALID_RANGE = 6;
-
- /**
- * SWT error constant indicating that a value which can not be
- * zero was found to be
- * (value is 7)
- */
- public static final int ERROR_CANNOT_BE_ZERO = 7;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide the value of an item
- * (value is 8)
- */
- public static final int ERROR_CANNOT_GET_ITEM = 8;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide the selection
- * (value is 9)
- */
- public static final int ERROR_CANNOT_GET_SELECTION = 9;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide the height of an item
- * (value is 11)
- */
- public static final int ERROR_CANNOT_GET_ITEM_HEIGHT = 11;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide the text of a widget
- * (value is 12)
- */
- public static final int ERROR_CANNOT_GET_TEXT = 12;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to set the text of a widget
- * (value is 13)
- */
- public static final int ERROR_CANNOT_SET_TEXT = 13;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to add an item
- * (value is 14)
- */
- public static final int ERROR_ITEM_NOT_ADDED = 14;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to remove an item
- * (value is 15)
- */
- public static final int ERROR_ITEM_NOT_REMOVED = 15;
-
- /**
- * SWT error constant indicating that a particular feature has
- * not been implemented on this platform
- * (value is 20)
- */
- public static final int ERROR_NOT_IMPLEMENTED = 20;
-
- /**
- * SWT error constant indicating that a menu which needed
- * to have the drop down style had some other style instead
- * (value is 21)
- */
- public static final int ERROR_MENU_NOT_DROP_DOWN = 21;
-
- /**
- * SWT error constant indicating that an attempt was made to
- * invoke an SWT operation which can only be executed by the
- * user-interface thread from some other thread
- * (value is 22)
- */
- public static final int ERROR_THREAD_INVALID_ACCESS = 22;
-
- /**
- * SWT error constant indicating that an attempt was made to
- * invoke an SWT operation using a widget which had already
- * been disposed.
- * (value is 24)
- */
- public static final int ERROR_WIDGET_DISPOSED = 24;
-
- /**
- * SWT error constant indicating that a menu item which needed
- * to have the cascade style had some other style instead
- * (value is 27)
- */
- public static final int ERROR_MENUITEM_NOT_CASCADE = 27;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to set the selection of a widget
- * (value is 28)
- */
- public static final int ERROR_CANNOT_SET_SELECTION = 28;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to set the menu
- * (value is 29)
- */
- public static final int ERROR_CANNOT_SET_MENU = 29;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to set the enabled state
- * (value is 30)
- */
- public static final int ERROR_CANNOT_SET_ENABLED = 30;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide enabled/disabled state information
- * (value is 31)
- */
- public static final int ERROR_CANNOT_GET_ENABLED = 31;
-
- /**
- * SWT error constant indicating that a provided widget can
- * not be used as a parent in the current operation
- * (value is 32)
- */
- public static final int ERROR_INVALID_PARENT = 32;
-
- /**
- * SWT error constant indicating that a menu which needed
- * to have the menu bar style had some other style instead
- * (value is 33)
- */
- public static final int ERROR_MENU_NOT_BAR = 33;
-
- /**
- * SWT error constant indicating that the underlying operating
- * system was unable to provide count information
- * (value is 36)
- */
- public static final int ERROR_CANNOT_GET_COUNT = 36;
-
- /**
- * SWT error constant indicating that a menu which needed
- * to have the pop up menu style had some other style instead
- * (value is 37)
- */
- public static final int ERROR_MENU_NOT_POP_UP = 37;
-
- /**
- * SWT error constant indicating that a graphics operation
- * was attempted with an image of an unsupported depth
- * (value is 38)
- */
- public static final int ERROR_UNSUPPORTED_DEPTH = 38;
-
- /**
- * SWT error constant indicating that an input/output operation
- * failed during the execution of an SWT operation
- * (value is 39)
- */
- public static final int ERROR_IO = 39;
-
- /**
- * SWT error constant indicating that a graphics operation
- * was attempted with an image having an invalid format
- * (value is 40)
- */
- public static final int ERROR_INVALID_IMAGE = 40;
-
- /**
- * SWT error constant indicating that a graphics operation
- * was attempted with an image having a valid but unsupported
- * format
- * (value is 42)
- */
- public static final int ERROR_UNSUPPORTED_FORMAT = 42;
-
- /**
- * SWT error constant indicating that an attempt was made
- * to subclass an SWT widget class without implementing the
- * <code>checkSubclass()</code> method. For additional
- * information see the comment in <code>Widget.checkSubclass()</code>
- * (value is 43)
- *
- * @see org.eclipse.swt.widgets.Widget#checkSubclass
- */
- public static final int ERROR_INVALID_SUBCLASS = 43;
-
- /**
- * SWT error constant indicating that an attempt was made to
- * invoke an SWT operation using a graphics object which had
- * already been disposed.
- * (value is 44)
- */
- public static final int ERROR_GRAPHIC_DISPOSED = 44;
-
- /**
- * SWT error constant indicating that an attempt was made to
- * invoke an SWT operation using a device which had already
- * been disposed.
- * (value is 45)
- */
- public static final int ERROR_DEVICE_DISPOSED = 45;
-
- /**
- * SWT error constant indicating that an exception happened
- * when executing a runnable.
- * (value is 46)
- */
- public static final int ERROR_FAILED_EXEC = 46;
-
- /**
- * SWT error constant indicating that an unsatisfied link
- * error occured while attempting to load a library.
- * (value is 47)
- */
- public static final int ERROR_FAILED_LOAD_LIBRARY = 47;
-
- /**
- * traversal event detail field value indicating that no
- * traversal action should be taken.
- * (value is 0)
- */
- public static final int TRAVERSE_NONE = 0;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that a dialog should be cancelled was
- * pressed; typically, this is the ESC key
- * (value is 1<<1)
- */
- public static final int TRAVERSE_ESCAPE = 1 << 1;
-
- /**
- * traversal event detail field value indicating that the
- * key which activates the default button in a dialog was
- * pressed; typically, this is the ENTER key
- * (value is 1<<2)
- */
- public static final int TRAVERSE_RETURN = 1 << 2;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that focus should be given to the
- * previous tab group was pressed; typically, this is the
- * SHIFT-TAB key sequence
- * (value is 1<<3)
- */
- public static final int TRAVERSE_TAB_PREVIOUS = 1 << 3;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that focus should be given to the
- * next tab group was pressed; typically, this is the
- * TAB key
- * (value is 1<<4)
- */
- public static final int TRAVERSE_TAB_NEXT = 1 << 4;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that focus should be given to the
- * previous tab item was pressed; typically, this is either
- * the LEFT-ARROW or UP-ARROW keys
- * (value is 1<<5)
- */
- public static final int TRAVERSE_ARROW_PREVIOUS = 1 << 5;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that focus should be given to the
- * previous tab item was pressed; typically, this is either
- * the RIGHT-ARROW or DOWN-ARROW keys
- * (value is 1<<6)
- */
- public static final int TRAVERSE_ARROW_NEXT = 1 << 6;
-
- /**
- * traversal event detail field value indicating that a
- * mnemonic key sequence was pressed
- * (value is 1<<7)
- */
- public static final int TRAVERSE_MNEMONIC = 1 << 7;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that the previous page of a multi-page
- * window should be shown was pressed; typically, this
- * is the CTRL-PAGEUP key sequence
- * (value is 1<<8)
- */
- public static final int TRAVERSE_PAGE_PREVIOUS = 1 << 8;
-
- /**
- * traversal event detail field value indicating that the
- * key which designates that the next page of a multi-page
- * window should be shown was pressed; typically, this
- * is the CTRL-PAGEDOWN key sequence
- * (value is 1<<9)
- */
- public static final int TRAVERSE_PAGE_NEXT = 1 << 9;
-
- /**
- * constant indicating that an image or operation is of type bitmap (value is 0)
- */
- public static final int BITMAP = 0;
-
- /**
- * constant indicating that an image or operation is of type icon (value is 1)
- */
- public static final int ICON = 1;
-
- /**
- * <code>Image</code> constructor argument indicating that
- * the new image should be a copy of the image provided as
- * an argument (value is 0)
- */
- public static final int IMAGE_COPY = 0;
-
- /**
- * <code>Image</code> constructor argument indicating that
- * the new image should have the appearance of a "disabled"
- * (using the platform's rules for how this should look)
- * copy of the image provided as an argument (value is 1)
- */
- public static final int IMAGE_DISABLE = 1;
-
- /**
- * <code>Image</code> constructor argument indicating that
- * the new image should have the appearance of a "gray scaled"
- * copy of the image provided as an argument (value is 2)
- */
- public static final int IMAGE_GRAY = 2;
-
- /**
- * font style constant indicating a normal weight, non-italic font
- * (value is 0)
- */
- public static final int NORMAL = 0;
-
- /**
- * font style constant indicating a bold weight font
- * (value is 1<<0)
- */
- public static final int BOLD = 1 << 0;
-
- /**
- * font style constant indicating an italic font
- * (value is 1<<1)
- */
- public static final int ITALIC = 1 << 1;
-
- /**
- * system arrow cursor (value is 0)
- */
- public static final int CURSOR_ARROW = 0;
-
- /**
- * system wait cursor (value is 1)
- */
- public static final int CURSOR_WAIT = 1;
-
- /**
- * system cross hair cursor (value is 2)
- */
- public static final int CURSOR_CROSS = 2;
-
- /**
- * system app startup cursor (value is 3)
- */
- public static final int CURSOR_APPSTARTING = 3;
-
- /**
- * system help cursor (value is 4)
- */
- public static final int CURSOR_HELP = 4;
-
- /**
- * system resize all directions cursor (value is 5)
- */
- public static final int CURSOR_SIZEALL = 5;
-
- /**
- * system resize north-east-south-west cursor (value is 6)
- */
- public static final int CURSOR_SIZENESW = 6;
-
- /**
- * system resize north-south cursor (value is 7)
- */
- public static final int CURSOR_SIZENS = 7;
-
- /**
- * system resize north-west-south-east cursor (value is 8)
- */
- public static final int CURSOR_SIZENWSE = 8;
-
- /**
- * system resize west-east cursor (value is 9)
- */
- public static final int CURSOR_SIZEWE = 9;
-
- /**
- * system resize north cursor (value is 10)
- */
- public static final int CURSOR_SIZEN = 10;
-
- /**
- * system resize south cursor (value is 11)
- */
- public static final int CURSOR_SIZES = 11;
-
- /**
- * system resize east cursor (value is 12)
- */
- public static final int CURSOR_SIZEE = 12;
-
- /**
- * system resize west cursor (value is 13)
- */
- public static final int CURSOR_SIZEW = 13;
-
- /**
- * system resize north-east cursor (value is 14)
- */
- public static final int CURSOR_SIZENE = 14;
-
- /**
- * system resize south-east cursor (value is 15)
- */
- public static final int CURSOR_SIZESE = 15;
-
- /**
- * system resize south-west cursor (value is 16)
- */
- public static final int CURSOR_SIZESW = 16;
-
- /**
- * system resize north-west cursor (value is 17)
- */
- public static final int CURSOR_SIZENW = 17;
-
- /**
- * system up arrow cursor (value is 18)
- */
- public static final int CURSOR_UPARROW = 18;
-
- /**
- * system i-beam cursor (value is 19)
- */
- public static final int CURSOR_IBEAM = 19;
-
- /**
- * system "not allowed" cursor (value is 20)
- */
- public static final int CURSOR_NO = 20;
-
- /**
- * system hand cursor (value is 21)
- */
- public static final int CURSOR_HAND = 21;
-
- /**
- * line drawing style for solid lines (value is 1)
- */
- public static final int LINE_SOLID = 1;
-
- /**
- * line drawing style for dashed lines (value is 2)
- */
- public static final int LINE_DASH = 2;
-
- /**
- * line drawing style for dotted lines (value is 3)
- */
- public static final int LINE_DOT = 3;
-
- /**
- * line drawing style for alternating dash-dot lines (value is 4)
- */
- public static final int LINE_DASHDOT = 4;
-
- /**
- * line drawing style for dash-dot-dot lines (value is 5)
- */
- public static final int LINE_DASHDOTDOT = 5;
-
- /**
- * image format constant indicating an unknown image type (value is -1)
- */
- public static final int IMAGE_UNDEFINED = -1;
-
- /**
- * image format constant indicating a Windows BMP format image (value is 0)
- */
- public static final int IMAGE_BMP = 0;
-
- /**
- * image format constant indicating a run-length encoded
- * Windows BMP format image (value is 1)
- */
- public static final int IMAGE_BMP_RLE = 1;
-
- /**
- * image format constant indicating a GIF format image (value is 2)
- */
- public static final int IMAGE_GIF = 2;
-
- /**
- * image format constant indicating a ICO format image (value is 3)
- */
- public static final int IMAGE_ICO = 3;
-
- /**
- * image format constant indicating a JPEG format image (value is 4)
- */
- public static final int IMAGE_JPEG = 4;
-
- /**
- * image format constant indicating a PNG format image (value is 5)
- */
- public static final int IMAGE_PNG = 5;
-
- /**
- * GIF image disposal method constants indicating that the
- * disposal method is unspecified (value is 0)
- */
- public static final int DM_UNSPECIFIED = 0x0;
-
- /**
- * GIF image disposal method constants indicating that the
- * disposal method is to do nothing. That is, to leave the
- * previous image in place (value is 1)
- */
- public static final int DM_FILL_NONE = 0x1;
-
- /**
- * GIF image disposal method constants indicating that the
- * the previous images should be covered with the background
- * color before displaying the next image (value is 2)
- */
- public static final int DM_FILL_BACKGROUND = 0x2;
-
- /**
- * GIF image disposal method constants indicating that the
- * disposal method is to restore the previous picture
- * (value is 3)
- */
- public static final int DM_FILL_PREVIOUS = 0x3;
-
- /**
- * image transparency constant indicating that the image
- * contains no transparency information (value is 0)
- */
- public static final int TRANSPARENCY_NONE = 0x0;
-
- /**
- * image transparency constant indicating that the image
- * contains alpha transparency information (value is 1<<0)
- */
- public static final int TRANSPARENCY_ALPHA = 1 << 0;
-
- /**
- * image transparency constant indicating that the image
- * contains a transparency mask (value is 1<<1)
- */
- public static final int TRANSPARENCY_MASK = 1 << 1;
-
- /**
- * image transparency constant indicating that the image
- * contains a transparent pixel (value is 1<<2)
- */
- public static final int TRANSPARENCY_PIXEL = 1 << 2;
-
-/**
- * Answers a concise, human readable description of the error code.
- *
- * @param code the SWT error code.
- * @return a description of the error code.
- *
- * @see SWT
- */
-static String findErrorText (int code) {
- switch (code) {
- case ERROR_UNSPECIFIED: return "Unspecified error";
- case ERROR_NO_HANDLES: return "No more handles";
- case ERROR_NO_MORE_CALLBACKS: return "No more callbacks";
- case ERROR_NULL_ARGUMENT: return "Argument cannot be null";
- case ERROR_INVALID_ARGUMENT: return "Argument not valid";
- case ERROR_INVALID_RANGE: return "Index out of bounds";
- case ERROR_CANNOT_BE_ZERO: return "Argument cannot be zero";
- case ERROR_CANNOT_GET_ITEM: return "Cannot get item";
- case ERROR_CANNOT_GET_SELECTION: return "Cannot get selection";
- case ERROR_CANNOT_GET_ITEM_HEIGHT: return "Cannot get item height";
- case ERROR_CANNOT_GET_TEXT: return "Cannot get text";
- case ERROR_CANNOT_SET_TEXT: return "Cannot set text";
- case ERROR_ITEM_NOT_ADDED: return "Item not added";
- case ERROR_ITEM_NOT_REMOVED: return "Item not removed";
- case ERROR_NOT_IMPLEMENTED: return "Not implemented";
- case ERROR_MENU_NOT_DROP_DOWN: return "Menu must be a drop down";
- case ERROR_THREAD_INVALID_ACCESS: return "Invalid thread access";
- case ERROR_WIDGET_DISPOSED: return "Widget is disposed";
- case ERROR_MENUITEM_NOT_CASCADE: return "Menu item is not a CASCADE";
- case ERROR_CANNOT_SET_SELECTION: return "Cannot set selection";
- case ERROR_CANNOT_SET_MENU: return "Cannot set menu";
- case ERROR_CANNOT_SET_ENABLED: return "Cannot set the enabled state";
- case ERROR_CANNOT_GET_ENABLED: return "Cannot get the enabled state";
- case ERROR_INVALID_PARENT: return "Widget has the wrong parent";
- case ERROR_MENU_NOT_BAR: return "Menu is not a BAR";
- case ERROR_CANNOT_GET_COUNT: return "Cannot get count";
- case ERROR_MENU_NOT_POP_UP: return "Menu is not a POP_UP";
- case ERROR_UNSUPPORTED_DEPTH: return "Unsupported color depth";
- case ERROR_IO: return "i/o error";
- case ERROR_INVALID_IMAGE: return "Invalid image";
- case ERROR_UNSUPPORTED_FORMAT: return "Unsupported or unrecognized format";
- case ERROR_INVALID_SUBCLASS: return "Subclassing not allowed";
- case ERROR_GRAPHIC_DISPOSED: return "Graphic is disposed";
- case ERROR_DEVICE_DISPOSED: return "Device is disposed";
- case ERROR_FAILED_EXEC: return "Failed to execute runnable";
- case ERROR_FAILED_LOAD_LIBRARY: return "Unable to load library";
- }
- return "Unknown error";
-}
-
-/**
- * Returns the NLS'ed message for the given argument.
- *
- * @param key the key to look up
- * @return the message for the given key
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the key is null</li>
- * </ul>
- */
-public static String getMessage(String key) {
- return Compatibility.getMessage(key);
-}
-
-/**
- * Returns the SWT platform name.
- * Examples: "win32", "motif", "gtk", "photon", "carbon"
- *
- * @return the SWT platform name
- */
-public static String getPlatform () {
- return Callback.getPlatform ();
-}
-
-/**
- * Returns the SWT version number as an integer.
- * Example: "SWT051" == 51
- *
- * @return the SWT version number
- */
-public static int getVersion () {
- return Library.getVersion ();
-}
-
-/**
- * Throws an appropriate exception based on the passed in error code.
- *
- * @param code the SWT error code
- */
-public static void error (int code) {
- error (code, null);
-}
-
-/**
- * Throws an appropriate exception based on the passed in error code.
- * The <code>throwable</code> argument should be either null, or the
- * throwable which caused SWT to throw an exception.
- * <p>
- * In SWT, errors are reported by throwing one of three exceptions:
- * <dl>
- * <dd>java.lang.IllegalArgumentException</dd>
- * <dt>thrown whenever one of the API methods is invoked with an illegal argument</dt>
- * <dd>org.eclipse.swt.SWTException (extends java.lang.RuntimeException)</dd>
- * <dt>thrown whenever a recoverable error happens internally in SWT</dt>
- * <dd>org.eclipse.swt.SWTError (extends java.lang.Error)</dd>
- * <dt>thrown whenever a <b>non-recoverable</b> error happens internally in SWT</dt>
- * </dl>
- * This method provides the logic which maps between error codes
- * and one of the above exceptions.
- * </p>
- *
- * @param code the SWT error code.
- * @param throwable the exception which caused the error to occur.
- *
- * @see SWTError
- * @see SWTException
- * @see IllegalArgumentException
- */
-public static void error (int code, Throwable throwable) {
-
- /*
- * This code prevents the creation of "chains" of SWTErrors and
- * SWTExceptions which in turn contain other SWTErrors and
- * SWTExceptions as their throwable. This can occur when low level
- * code throws an exception past a point where a higher layer is
- * being "safe" and catching all exceptions. (Note that, this is
- * _a_bad_thing_ which we always try to avoid.)
- *
- * On the theory that the low level code is closest to the
- * original problem, we simply re-throw the original exception here.
- */
- if (throwable instanceof SWTError) throw (SWTError) throwable;
- if (throwable instanceof SWTException) throw (SWTException) throwable;
-
- switch (code) {
-
- /* Illegal Arguments (non-fatal) */
- case ERROR_NULL_ARGUMENT:
- case ERROR_CANNOT_BE_ZERO:
- case ERROR_INVALID_ARGUMENT:
- case ERROR_MENU_NOT_BAR:
- case ERROR_MENU_NOT_DROP_DOWN:
- case ERROR_MENU_NOT_POP_UP:
- case ERROR_MENUITEM_NOT_CASCADE:
- case ERROR_INVALID_PARENT:
- case ERROR_INVALID_RANGE: {
- throw new IllegalArgumentException (findErrorText (code));
- }
-
- /* SWT Errors (non-fatal) */
- case ERROR_INVALID_SUBCLASS:
- case ERROR_THREAD_INVALID_ACCESS:
- case ERROR_WIDGET_DISPOSED:
- case ERROR_GRAPHIC_DISPOSED:
- case ERROR_DEVICE_DISPOSED:
- case ERROR_INVALID_IMAGE:
- case ERROR_UNSUPPORTED_DEPTH:
- case ERROR_UNSUPPORTED_FORMAT:
- case ERROR_FAILED_EXEC:
- case ERROR_IO: {
- SWTException exception = new SWTException (code);
- exception.throwable = throwable;
- throw exception;
- }
-
- /* OS Failure/Limit (fatal, may occur only on some platforms) */
- case ERROR_CANNOT_GET_COUNT:
- case ERROR_CANNOT_GET_ENABLED:
- case ERROR_CANNOT_GET_ITEM:
- case ERROR_CANNOT_GET_ITEM_HEIGHT:
- case ERROR_CANNOT_GET_SELECTION:
- case ERROR_CANNOT_GET_TEXT:
- case ERROR_CANNOT_SET_ENABLED:
- case ERROR_CANNOT_SET_MENU:
- case ERROR_CANNOT_SET_SELECTION:
- case ERROR_CANNOT_SET_TEXT:
- case ERROR_ITEM_NOT_ADDED:
- case ERROR_ITEM_NOT_REMOVED:
- case ERROR_NO_HANDLES:
- //FALL THROUGH
-
- /* SWT Failure/Limit (fatal, may occur only on some platforms) */
- case ERROR_FAILED_LOAD_LIBRARY:
- case ERROR_NO_MORE_CALLBACKS:
- case ERROR_NOT_IMPLEMENTED:
- case ERROR_UNSPECIFIED: {
- SWTError error = new SWTError (code);
- error.throwable = throwable;
- throw error;
- }
- }
-
- /* Unknown/Undefined Error */
- SWTError error = new SWTError (code);
- error.throwable = throwable;
- throw error;
-}
-
-static {
- /*
- * These values represent bit masks that may need to
- * expand in the future. Therefore they are not initialized
- * in the declaration to stop the compiler from inlining.
- */
- BUTTON_MASK = BUTTON1 | BUTTON2 | BUTTON3;
- MODIFIER_MASK = ALT | SHIFT | CTRL | COMMAND;
-
- /*
- * These values can be different on different platforms.
- * Therefore they are not initialized in the declaration
- * to stop the compiler from inlining.
- */
- String platform = getPlatform ();
- if ("carbon".equals (platform)) {
- MOD1 = COMMAND;
- MOD2 = SHIFT;
- MOD3 = ALT;
- MOD4 = CONTROL;
- } else {
- MOD1 = CONTROL;
- MOD2 = SHIFT;
- MOD3 = ALT;
- MOD4 = ALT;
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.*; + +/** + * This class provides access to a small number of SWT system-wide + * methods, and in addition defines the public constants provided + * by SWT. + * <p> + * By defining constants like UP and DOWN in a single class, SWT + * can share common names and concepts at the same time minimizing + * the number of classes, names and constants for the application + * programmer. + * </p><p> + * Note that some of the constants provided by this class represent + * optional, appearance related aspects of widgets which are available + * either only on some window systems, or for a differing set of + * widgets on each window system. These constants are marked + * as <em>HINT</em>s. The set of widgets which support a particular + * <em>HINT</em> may change from release to release, although we typically + * will not withdraw support for a <em>HINT</em> once it is made available. + * </p> + */ + +/* NOTE: + * Good javadoc coding style is to put the values of static final + * constants in the comments. This reinforces the fact that + * consumers are allowed to rely on the value (and they must + * since the values are compiled inline in their code). We + * can <em>not</em> change the values of these constants between + * releases. + */ +public class SWT { + + /* Initialize the class */ +// static { +// /* NOTE: the static initialization is at the end of file */ +// } + + /* Widget Event Constants */ + + /** + * key down event type (value is 1) + */ + public static final int KeyDown = 1; + + /** + * key up event type (value is 2) + */ + public static final int KeyUp = 2; + + /** + * mouse down event type (value is 3) + */ + public static final int MouseDown = 3; + + /** + * mouse up event type (value is 4) + */ + public static final int MouseUp = 4; + + /** + * mouse move event type (value is 5) + */ + public static final int MouseMove = 5; + + /** + * mouse enter event type (value is 6) + */ + public static final int MouseEnter = 6; + + /** + * Mouse exit event type (value is 7) + */ + public static final int MouseExit = 7; + + /** + * mouse double click event type (value is 8) + */ + public static final int MouseDoubleClick = 8; + + /** + * paint event type (value is 9) + */ + public static final int Paint = 9; + + /** + * move event type (value is 10) + */ + public static final int Move = 10; + + /** + * resize event type (value is 11) + */ + public static final int Resize = 11; + + /** + * dispose event type (value is 12) + */ + public static final int Dispose = 12; + + /** + * selection event type (value is 13) + */ + public static final int Selection = 13; + + /** + * default selection event type (value is 14) + */ + public static final int DefaultSelection = 14; + + /** + * focus in event type (value is 15) + */ + public static final int FocusIn = 15; + + /** + * focus out event type (value is 16) + */ + public static final int FocusOut = 16; + + /** + * expand event type (value is 17) + */ + public static final int Expand = 17; + + /** + * collapse event type (value is 18) + */ + public static final int Collapse = 18; + + /** + * iconify event type (value is 19) + */ + public static final int Iconify = 19; + + /** + * de-iconify event type (value is 20) + */ + public static final int Deiconify = 20; + + /** + * close event type (value is 21) + */ + public static final int Close = 21; + + /** + * show event type (value is 22) + */ + public static final int Show = 22; + + /** + * hide event type (value is 23) + */ + public static final int Hide = 23; + + /** + * modify event type (value is 24) + */ + public static final int Modify = 24; + + /** + * verify event type (value is 25) + */ + public static final int Verify = 25; + + /** + * activate event type (value is 26) + */ + public static final int Activate = 26; + + /** + * deactivate event type (value is 27) + */ + public static final int Deactivate = 27; + + /** + * help event type (value is 28) + */ + public static final int Help = 28; + + /** + * drag detect event type (value is 29) + */ + public static final int DragDetect = 29; + + /** + * arm event type (value is 30) + */ + public static final int Arm = 30; + + /** + * traverse event type (value is 31) + */ + public static final int Traverse = 31; + + /** + * mouse hover event type (value is 32) + */ + public static final int MouseHover = 32; + + /** + * hardware key down event type (value is 33) + */ + public static final int HardKeyDown = 33; + + /** + * hardware key up event type (value is 34) + */ + public static final int HardKeyUp = 34; + + /* Event Details */ + + /** + * a constant known to be zero (0), used in operations which + * take bit flags to indicate that "no bits are set" + */ + public static final int NONE = 0; + + /** + * indicates that a user-interface component is being dragged, + * for example dragging the thumb of a scroll bar (value is 1) + */ + public static final int DRAG = 1; + + /** + * a constant known to be zero (0), used in operations which + * take pointers to indicate a null argument + */ + public static final int NULL = 0; + + /** + * indicates that a default should be used (value is -1) + */ + public static final int DEFAULT = -1; + + /** + * style constant for menu bar behavior (value is 1<<1) + * <p><b>Used By:</b><ul> + * <li><code>Menu</code></li> + * </ul></p> + */ + public static final int BAR = 1 << 1; + + /** + * style constant for drop down menu/list behavior (value is 1<<2) + * <p><b>Used By:</b><ul> + * <li><code>Menu</code></li> + * <li><code>ToolItem</code></li> + * <li><code>CoolItem</code></li> + * <li><code>Combo</code></li> + * </ul></p> + */ + public static final int DROP_DOWN = 1 << 2; + + /** + * style constant for pop up menu behavior (value is 1<<3) + * <p><b>Used By:</b><ul> + * <li><code>Menu</code></li> + * </ul></p> + */ + public static final int POP_UP = 1 << 3; + + /** + * style constant for line separator behavior (value is 1<<1) + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>MenuItem</code></li> + * <li><code>ToolItem</code></li> + * </ul></p> + */ + public static final int SEPARATOR = 1 << 1; + + /** + * style constant for toggle button behavior (value is 1<<1) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * </ul></p> + */ + public static final int TOGGLE = 1 << 1; + + /** + * style constant for arrow button behavior (value is 1<<2) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * </ul></p> + */ + public static final int ARROW = 1 << 2; + + /** + * style constant for push button behavior (value is 1<<3) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>MenuItem</code></li> + * <li><code>ToolItem</code></li> + * </ul></p> + */ + public static final int PUSH = 1 << 3; + + /** + * style constant for radio button behavior (value is 1<<4) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>MenuItem</code></li> + * <li><code>ToolItem</code></li> + * </ul></p> + */ + public static final int RADIO = 1 << 4; + + /** + * style constant for check box behavior (value is 1<<5) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>MenuItem</code></li> + * <li><code>ToolItem</code></li> + * <li><code>Table</code></li> + * <li><code>Tree</code></li> + * </ul></p> + */ + public static final int CHECK = 1 << 5; + + /** + * style constant for cascade behavior (value is 1<<6) + * <p><b>Used By:</b><ul> + * <li><code>MenuItem</code></li> + * </ul></p> + */ + public static final int CASCADE = 1 << 6; + + /** + * style constant for multi-selection behavior in lists + * and multiple line support on text fields (value is 1<<1) + * <p><b>Used By:</b><ul> + * <li><code>Text</code></li> + * <li><code>List</code></li> + * <li><code>FileDialog</code></li> + * </ul></p> + */ + public static final int MULTI = 1 << 1; + + /** + * style constant for single selection behavior in lists + * and single line support on text fields (value is 1<<2) + * <p><b>Used By:</b><ul> + * <li><code>Text</code></li> + * <li><code>List</code></li> + * <li><code>Table</code></li> + * <li><code>Tree</code></li> + * </ul></p> + */ + public static final int SINGLE = 1 << 2; + + /** + * style constant for read-only behavior (value is 1<<3) + * <p><b>Used By:</b><ul> + * <li><code>Combo</code></li> + * <li><code>Text</code></li> + * </ul></p> + */ + public static final int READ_ONLY = 1 << 3; + + /** + * style constant for automatic line wrap behavior (value is 1<<6) + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>Text</code></li> + * <li><code>ToolBar</code></li> + * </ul></p> + */ + public static final int WRAP = 1 << 6; + + /** + * style constant for simple (not drop down) behavior (value is 1<<6) + * <p><b>Used By:</b><ul> + * <li><code>Combo</code></li> + * </ul></p> + */ + public static final int SIMPLE = 1 << 6; + + /** + * style constant for shadow in behavior (value is 1<<2) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>Group</code></li> + * </ul></p> + */ + public static final int SHADOW_IN = 1 << 2; + + /** + * style constant for shadow out behavior (value is 1<<3) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>Group</code></li> + * <li><code>ToolBar</code></li> + * </ul></p> + */ + public static final int SHADOW_OUT = 1 << 3; + + /** + * style constant for shadow etched in behavior (value is 1<<4) + * <br>Note that this is a <em>HINT</em>. It is ignored on all platforms except Motif. + * <p><b>Used By:</b><ul> + * <li><code>Group</code></li> + * </ul></p> + */ + public static final int SHADOW_ETCHED_IN = 1 << 4; + + /** + * style constant for shadow etched out behavior (value is 1<<6) + * <br>Note that this is a <em>HINT</em>. It is ignored on all platforms except Motif. + * <p><b>Used By:</b><ul> + * <li><code>Group</code></li> + * </ul></p> + */ + public static final int SHADOW_ETCHED_OUT = 1 << 6; + + /** + * style constant for no shadow behavior (value is 1<<5) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>Group</code></li> + * </ul></p> + */ + public static final int SHADOW_NONE = 1 << 5; + + /** + * style constant for progress bar behavior (value is 1<<1) + * <p><b>Used By:</b><ul> + * <li><code>ProgressBar</code></li> + * </ul></p> + */ + public static final int INDETERMINATE = 1 << 1; + + /** + * style constant for tool window behavior (value is 1<<2) + * <p> + * A tool window is a window intended to be used as a floating toolbar. + * It typically has a title bar that is shorter than a normal title bar, + * and the window title is typically drawn using a smaller font. + * <br>Note that this is a <em>HINT</em>. + * </p><p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int TOOL = 1 << 2; + + /** + * style constant to ensure no trimmings are used (value is 1<<3) + * <br>Note that this overrides all other trim styles. + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int NO_TRIM = 1 << 3; + + /** + * style constant for resize box trim (value is 1<<4) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * <li><code>Tracker</code></li> + * </ul></p> + */ + public static final int RESIZE = 1 << 4; + + /** + * style constant for title area trim (value is 1<<5) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int TITLE = 1 << 5; + + /** + * style constant for close box trim (value is 1<<6, + * since we do not distinguish between CLOSE style and MENU style) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int CLOSE = 1 << 6; + + /** + * style constant for shell menu trim (value is 1<<6, + * since we do not distinguish between CLOSE style and MENU style) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int MENU = CLOSE; + + /** + * style constant for minimize box trim (value is 1<<7) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int MIN = 1 << 7; + + /** + * style constant for maximize box trim (value is 1<<10) + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code> and subclasses</li> + * </ul></p> + */ + public static final int MAX = 1 << 10; + + /** + * style constant for horizontal scrollbar behavior (value is 1<<8) + * <p><b>Used By:</b><ul> + * <li><code>Scrollable</code> and subclasses</li> + * </ul></p> + */ + public static final int H_SCROLL = 1 << 8; + + /** + * style constant for vertical scrollbar behavior (value is 1<<9) + * <p><b>Used By:</b><ul> + * <li><code>Scrollable</code> and subclasses</li> + * </ul></p> + */ + public static final int V_SCROLL = 1 << 9; + + /** + * style constant for bordered behavior (value is 1<<11) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Control</code> and subclasses</li> + * </ul></p> + */ + public static final int BORDER = 1 << 11; + + /** + * style constant indicating that the window manager should clip + * a widget's children with respect to its viewable area. (value is 1<<12) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Control</code> and subclasses</li> + * </ul></p> + */ + public static final int CLIP_CHILDREN = 1 << 12; + + /** + * style constant indicating that the window manager should clip + * a widget's siblings with respect to its viewable area. (value is 1<<13) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Control</code> and subclasses</li> + * </ul></p> + */ + public static final int CLIP_SIBLINGS = 1 << 13; + + /** + * style constant for always on top behavior (value is 1<<14) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Decorations</code>and subclasses</li> + * </ul></p> + */ + public static final int ON_TOP = 1 << 14; + + /** + * trim style convenience constant for the most common top level shell appearance + * (value is CLOSE|TITLE|MIN|MAX|RESIZE) + * <p><b>Used By:</b><ul> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int SHELL_TRIM = CLOSE | TITLE | MIN | MAX | RESIZE; + + /** + * trim style convenience constant for the most common dialog shell appearance + * (value is CLOSE|TITLE|BORDER) + * <p><b>Used By:</b><ul> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int DIALOG_TRIM = TITLE | CLOSE | BORDER; + + /** + * style constant for modeless behavior (value is 0) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Dialog</code></li> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int MODELESS = 0; + + /** + * style constant for primary modal behavior (value is 1<<15) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Dialog</code></li> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int PRIMARY_MODAL = 1 << 15; + + /** + * style constant for application modal behavior (value is 1<<16) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Dialog</code></li> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int APPLICATION_MODAL = 1 << 16; + + /** + * style constant for system modal behavior (value is 1<<17) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Dialog</code></li> + * <li><code>Shell</code></li> + * </ul></p> + */ + public static final int SYSTEM_MODAL = 1 << 17; + + /** + * style constant for selection hiding behavior. (value is 1<<15) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Table</code></li> + * </ul></p> + */ + public static final int HIDE_SELECTION = 1 << 15; + + /** + * style constant for full row selection behavior. (value is 1<<16) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Table</code></li> + * </ul></p> + */ + public static final int FULL_SELECTION = 1 << 16; + + /** + * style constant for flat appearance. (value is 1<<23) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>ToolBar</code></li> + * </ul></p> + */ + public static final int FLAT = 1 << 23; + + /** + * style constant for flat appearance. (value is 1<<16) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>ProgressBar</code></li> + * </ul></p> + */ + public static final int SMOOTH = 1 << 16; + + /** + * style constant for no background behavior (value is 1<<18) + * <p> + * By default, before a widget paints, the client area is filled with the current background color. + * When this style is specified, the background is not filled, and the application is responsible + * for filling every pixel of the client area. + * This style might be used as an alternative to "double-buffering" in order to reduce flicker. + * This style does not mean "transparent" - widgets that are obscured will not draw through. + * </p><p><b>Used By:</b><ul> + * <li><code>Composite</code></li> + * </ul></p> + */ + public static final int NO_BACKGROUND = 1 << 18; + + /** + * style constant for does not take focus behavior (value is 1<<19) + * <br>Note that this is a <em>HINT</em>. + * <p><b>Used By:</b><ul> + * <li><code>Composite</code></li> + * </ul></p> + */ + public static final int NO_FOCUS = 1 << 19; + + /** + * style constant for no redraw on resize behavior (value is 1<<20) + * <p> + * This style stops the entire client area from being invalidated when the size + * of the Canvas changes. Specifically, when the size of the Canvas gets smaller, + * the SWT.Paint event is not sent. When it gets bigger, an SWT.Paint event is + * sent with a GC clipped to only the new areas to be painted. Without this + * style, the entire client area will be repainted. + * </p><p><b>Used By:</b><ul> + * <li><code>Composite</code></li> + * </ul></p> + */ + public static final int NO_REDRAW_RESIZE = 1 << 20; + + /** + * style constant for no paint event merging behavior (value is 1<<21) + * <p><b>Used By:</b><ul> + * <li><code>Composite</code></li> + * </ul></p> + */ + public static final int NO_MERGE_PAINTS = 1 << 21; + + /** + * style constant for preventing child radio group behavior (value is 1<<22) + * <p><b>Used By:</b><ul> + * <li><code>Composite</code></li> + * </ul></p> + */ + public static final int NO_RADIO_GROUP = 1 << 22; + + /** + * style constant for left to right orientation (value is 1<<25) + * <p> + * When orientation is not explicitly specified, orientation is + * inherited. This means that children will be assigned the + * orientation of their parent. To override this behavior and + * force an orientation for a child, explicitly set the orientation + * of the child when that child is created. + * </p> + * <p><b>Used By:</b><ul> + * <li><code>Control</code></li> + * <li><code>Menu</code></li> + * </ul></p> + * + * <p> + * <b>NOTE:</b> This API element is part of an interim API that is still under + * development and is expected to change significantly before reaching stability. + * It is being made available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * </p> + * + * @since 2.1 + */ + public static final int LEFT_TO_RIGHT = 1 << 25; + + /** + * style constant for right to left orientation (value is 1<<26) + * <p> + * When orientation is not explicitly specified, orientation is + * inherited. This means that children will be assigned the + * orientation of their parent. To override this behavior and + * force an orientation for a child, explicitly set the orientation + * of the child when that child is created. + * </p> + * <p><b>Used By:</b><ul> + * <li><code>Control</code></li> + * <li><code>Menu</code></li> + * </ul></p> + * + * <p> + * <b>NOTE:</b> This API element is part of an interim API that is still under + * development and is expected to change significantly before reaching stability. + * It is being made available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * </p> + * + * @since 2.1 + */ + public static final int RIGHT_TO_LEFT = 1 << 26; + + /** + * style constant to indicate coordinate mirroring (value is 1<<27) + * <p><b>Used By:</b><ul> + * <li><code>Control</code></li> + * <li><code>Menu</code></li> + * </ul></p> + * + * <p> + * <b>NOTE:</b> This API element is part of an interim API that is still under + * development and is expected to change significantly before reaching stability. + * It is being made available at this early stage to solicit feedback from + * pioneering adopters on the understanding that any code that uses this API + * will almost certainly be broken (repeatedly) as the API evolves. + * </p> + * + * @since 2.1 + */ + public static final int MIRRORED = 1 << 27; + + /** + * style constant for align up behavior (value is 1<<7, + * since align UP and align TOP are considered the same) + * <p><b>Used By:</b><ul> + * <li><code>Button</code> with <code>ARROW</code> style</li> + * <li><code>Tracker</code></li> + * </ul></p> + */ + public static final int UP = 1 << 7; + + /** + * style constant for align top behavior (value is 1<<7, + * since align UP and align TOP are considered the same) + * <p><b>Used By:</b><ul> + * <li><code>FormAttachment</code> in a <code>FormLayout</code></li> + * </ul></p> + */ + public static final int TOP = UP; + + /** + * style constant for align down behavior (value is 1<<10, + * since align DOWN and align BOTTOM are considered the same) + * <p><b>Used By:</b><ul> + * <li><code>Button</code> with <code>ARROW</code> style</li> + * <li><code>Tracker</code></li> + * </ul></p> + */ + public static final int DOWN = 1 << 10; + + /** + * style constant for align bottom behavior (value is 1<<10, + * since align DOWN and align BOTTOM are considered the same) + * <p><b>Used By:</b><ul> + * <li><code>FormAttachment</code> in a <code>FormLayout</code></li> + * </ul></p> + */ + public static final int BOTTOM = DOWN; + + /** + * style constant for align left behavior (value is 1<<14) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>Label</code></li> + * <li><code>TableColumn</code></li> + * <li><code>Tracker</code></li> + * <li><code>FormAttachment</code> in a <code>FormLayout</code></li> + * </ul></p> + */ + public static final int LEFT = 1 << 14; + + /** + * style constant for align right behavior (value is 1<<17) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>Label</code></li> + * <li><code>TableColumn</code></li> + * <li><code>Tracker</code></li> + * <li><code>FormAttachment</code> in a <code>FormLayout</code></li> + * </ul></p> + */ + public static final int RIGHT = 1 << 17; + + /** + * style constant for align center behavior (value is 1<<24) + * <p><b>Used By:</b><ul> + * <li><code>Button</code></li> + * <li><code>Label</code></li> + * <li><code>TableColumn</code></li> + * <li><code>FormAttachment</code> in a <code>FormLayout</code></li> + * </ul></p> + */ + public static final int CENTER = 1 << 24; + + /** + * style constant for horizontal alignment or orientation behavior (value is 1<<8) + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>ProgressBar</code></li> + * <li><code>Sash</code></li> + * <li><code>Scale</code></li> + * <li><code>ScrollBar</code></li> + * <li><code>Slider</code></li> + * <li><code>ToolBar</code></li> + * <li><code>FillLayout</code> type</li> + * <li><code>RowLayout</code> type</li> + * </ul></p> + */ + public static final int HORIZONTAL = 1 << 8; + + /** + * style constant for vertical alignment or orientation behavior (value is 1<<9) + * <p><b>Used By:</b><ul> + * <li><code>Label</code></li> + * <li><code>ProgressBar</code></li> + * <li><code>Sash</code></li> + * <li><code>Scale</code></li> + * <li><code>ScrollBar</code></li> + * <li><code>Slider</code></li> + * <li><code>ToolBar</code></li> + * <li><code>FillLayout</code> type</li> + * <li><code>RowLayout</code> type</li> + * </ul></p> + */ + public static final int VERTICAL = 1 << 9; + + /** + * Input Method Editor style constant for double byte + * input behavior (value is 1<<1) + */ + public static final int DBCS = 1 << 1; + + /** + * Input Method Editor style constant for alpha + * input behavior (value is 1<<2) + */ + public static final int ALPHA = 1 << 2; + + /** + * Input Method Editor style constant for native + * input behavior (value is 1<<3) + */ + public static final int NATIVE = 1 << 3; + + /** + * Input Method Editor style constant for phonetic + * input behavior (value is 1<<4) + */ + public static final int PHONETIC = 1 << 4; + + /** + * Input Method Editor style constant for romanicized + * input behavior (value is 1<<5) + */ + public static final int ROMAN = 1 << 5; + + /** + * ASCII character convenience constant for the backspace character + * (value is the <code>char</code> '\b') + */ + public static final char BS = '\b'; + + /** + * ASCII character convenience constant for the carriage return character + * (value is the <code>char</code> '\r') + */ + public static final char CR = '\r'; + + /** + * ASCII character convenience constant for the delete character + * (value is the <code>char</code> with value 127) + */ + public static final char DEL = 0x7F; + + /** + * ASCII character convenience constant for the escape character + * (value is the <code>char</code> with value 27) + */ + public static final char ESC = 0x1B; + + /** + * ASCII character convenience constant for the line feed character + * (value is the <code>char</code> '\n') + */ + public static final char LF = '\n'; + + /** + * ASCII character convenience constant for the tab character + * (value is the <code>char</code> '\t') + * + * @since 2.1 + */ + public static final char TAB = '\t'; + + /** + * keyboard and/or mouse event mask indicating that the ALT key + * was pushed on the keyboard when the event was generated + * (value is 1<<16) + */ + public static final int ALT = 1 << 16; + + /** + * keyboard and/or mouse event mask indicating that the SHIFT key + * was pushed on the keyboard when the event was generated + * (value is 1<<17) + */ + public static final int SHIFT = 1 << 17; + + /** + * keyboard and/or mouse event mask indicating that the CTRL key + * was pushed on the keyboard when the event was generated + * (value is 1<<18) + */ + public static final int CTRL = 1 << 18; + + /** + * keyboard and/or mouse event mask indicating that the CTRL key + * was pushed on the keyboard when the event was generated. This + * is a synonym for CTRL (value is 1<<18) + */ + public static final int CONTROL = CTRL; + + /** + * keyboard and/or mouse event mask indicating that the COMMAND key + * was pushed on the keyboard when the event was generated + * (value is 1<<22) + * + * @since 2.1 + */ + public static final int COMMAND = 1 << 22; + + /** + * keyboard and/or mouse event mask indicating all possible + * keyboard modifiers. To allow for the future, this mask + * is intended to be used in place of code that references + * each individual keyboard mask. For example, the following + * expression will determine whether any modifer is pressed + * and will continue to work as new modifier masks are added. + * + * <code>(stateMask & SWT.MODIFIER_MASK) != 0</code>. + * + * @since 2.1 + */ + public static final int MODIFIER_MASK; + + /** + * keyboard and/or mouse event mask indicating that mouse button one + * was pushed when the event was generated. (value is 1<<19) + */ + public static final int BUTTON1 = 1 << 19; + + /** + * keyboard and/or mouse event mask indicating that mouse button two + * was pushed when the event was generated. (value is 1<<20) + */ + public static final int BUTTON2 = 1 << 20; + + /** + * keyboard and/or mouse event mask indicating that mouse button three + * was pushed when the event was generated. (value is 1<<21) + */ + public static final int BUTTON3 = 1 << 21; + + /** + * keyboard and/or mouse event mask indicating all possible + * mouse buttons. To allow for the future, this mask + * is intended to be used in place of code that references + * each individual button mask. For example, the following + * expression will determine whether any button is pressed + * and will continue to work as new button masks are added. + * + * <code>(stateMask & SWT.BUTTON_MASK) != 0</code>. + * + * @since 2.1 + */ + public static final int BUTTON_MASK; + + /** + * keyboard and/or mouse event mask indicating that the MOD1 key + * was pushed on the keyboard when the event was generated. This + * is the primary keyboard modifier for the platform. + * + * @since 2.1 + */ + public static final int MOD1; + + /** + * keyboard and/or mouse event mask indicating that the MOD2 key + * was pushed on the keyboard when the event was generated. This + * is the secondary keyboard modifier for the platform. + * + * @since 2.1 + */ + public static final int MOD2; + + /** + * keyboard and/or mouse event mask indicating that the MOD3 key + * was pushed on the keyboard when the event was generated. + * + * @since 2.1 + */ + public static final int MOD3; + + /** + * keyboard and/or mouse event mask indicating that the MOD4 key + * was pushed on the keyboard when the event was generated. + * + * @since 2.1 + */ + public static final int MOD4; + + /** + * accelerator constant used to differentiate a key code from a + * unicode character. If this bit is set, then the key stroke + * portion of an accelerator represents a key code. If this bit + * is not set, then the key stroke portion of an accelerator is + * a unicode character. + * + * The following expression is false: + * + * <code>((SWT.MOD1 | SWT.MOD2 | 'T') & SWT.KEYCODE_BIT) != 0</code>. + * + * The following expression is true: + * + * <code>((SWT.MOD3 | SWT.F2) & SWT.KEYCODE_BIT) != 0</code>. + * + * (value is (1<<24)) + * + * @since 2.1 + */ + public static final int KEYCODE_BIT = (1 << 24); + + /** + * accelerator constant used to extract the key stroke portion of + * an accelerator. The key stroke may be a key code or a unicode + * value. If the key stroke is a key code <code>KEYCODE_BIT</code> + * will be set. + * + * @since 2.1 + */ + public static final int KEY_MASK = KEYCODE_BIT + 0xFFFF; + + /** + * keyboard event constant representing the UP ARROW key + * (value is (1<<24)+1) + */ + public static final int ARROW_UP = KEYCODE_BIT + 1; + + /** + * keyboard event constant representing the DOWN ARROW key + * (value is (1<<24)+2) + */ + public static final int ARROW_DOWN = KEYCODE_BIT + 2; + + /** + * keyboard event constant representing the LEFT ARROW key + * (value is (1<<24)+3) + */ + public static final int ARROW_LEFT = KEYCODE_BIT + 3; + + /** + * keyboard event constant representing the RIGHT ARROW key + * (value is (1<<24)+4) + */ + public static final int ARROW_RIGHT = KEYCODE_BIT + 4; + + /** + * keyboard event constant representing the PAGE UP key + * (value is (1<<24)+5) + */ + public static final int PAGE_UP = KEYCODE_BIT + 5; + + /** + * keyboard event constant representing the PAGE DOWN key + * (value is (1<<24)+6) + */ + public static final int PAGE_DOWN = KEYCODE_BIT + 6; + + /** + * keyboard event constant representing the HOME key + * (value is (1<<24)+7) + */ + public static final int HOME = KEYCODE_BIT + 7; + + /** + * keyboard event constant representing the END key + * (value is (1<<24)+8) + */ + public static final int END = KEYCODE_BIT + 8; + + /** + * keyboard event constant representing the INSERT key + * (value is (1<<24)+9) + */ + public static final int INSERT = KEYCODE_BIT + 9; + + /** + * keyboard event constant representing the F1 key + * (value is (1<<24)+10) + */ + public static final int F1 = KEYCODE_BIT + 10; + + /** + * keyboard event constant representing the F2 key + * (value is (1<<24)+11) + */ + public static final int F2 = KEYCODE_BIT + 11; + + /** + * keyboard event constant representing the F3 key + * (value is (1<<24)+12) + */ + public static final int F3 = KEYCODE_BIT + 12; + + /** + * keyboard event constant representing the F4 key + * (value is (1<<24)+13) + */ + public static final int F4 = KEYCODE_BIT + 13; + + /** + * keyboard event constant representing the F5 key + * (value is (1<<24)+14) + */ + public static final int F5 = KEYCODE_BIT + 14; + + /** + * keyboard event constant representing the F6 key + * (value is (1<<24)+15) + */ + public static final int F6 = KEYCODE_BIT + 15; + + /** + * keyboard event constant representing the F7 key + * (value is (1<<24)+16) + */ + public static final int F7 = KEYCODE_BIT + 16; + + /** + * keyboard event constant representing the F8 key + * (value is (1<<24)+17) + */ + public static final int F8 = KEYCODE_BIT + 17; + + /** + * keyboard event constant representing the F9 key + * (value is (1<<24)+18) + */ + public static final int F9 = KEYCODE_BIT + 18; + + /** + * keyboard event constant representing the F10 key + * (value is (1<<24)+19) + */ + public static final int F10 = KEYCODE_BIT + 19; + + /** + * keyboard event constant representing the F11 key + * (value is (1<<24)+20) + */ + public static final int F11 = KEYCODE_BIT + 20; + + /** + * keyboard event constant representing the F12 key + * (value is (1<<24)+21) + */ + public static final int F12 = KEYCODE_BIT + 21; + + /** + * <code>MessageBox</code> style constant for error icon + * behavior (value is 1) + */ + public static final int ICON_ERROR = 1; + + /** + * <code>MessageBox</code> style constant for information icon + * behavior (value is 1<<1) + */ + public static final int ICON_INFORMATION = 1 << 1; + + /** + * <code>MessageBox</code> style constant for question icon + * behavior (value is 1<<2) + */ + public static final int ICON_QUESTION = 1 << 2; + + /** + * <code>MessageBox</code> style constant for warning icon + * behavior (value is 1<<3) + */ + public static final int ICON_WARNING = 1 << 3; + + /** + * <code>MessageBox</code> style constant for "working" icon + * behavior (value is 1<<4) + */ + public static final int ICON_WORKING = 1 << 4; + + /** + * <code>MessageBox</code> style constant for an OK button. + * Valid combinations are OK, OK|CANCEL + * (value is 1<<5) + */ + public static final int OK = 1 << 5; + + /** + * <code>MessageBox</code> style constant for YES button. + * Valid combinations are YES|NO, YES|NO|CANCEL + * (value is 1<<6) + */ + public static final int YES = 1 << 6; + + /** + * <code>MessageBox</code> style constant for NO button. + * Valid combinations are YES|NO, YES|NO|CANCEL + * (value is 1<<7) + */ + public static final int NO = 1 << 7; + + /** + * <code>MessageBox</code> style constant for a CANCEL button. + * Valid combinations are OK|CANCEL, YES|NO|CANCEL, RETRY|CANCEL + * (value is 1<<8) + */ + public static final int CANCEL = 1 << 8; + + /** + * <code>MessageBox</code> style constant for an ABORT button. + * The only valid combination is ABORT|RETRY|IGNORE + * (value is 1<<9) + */ + public static final int ABORT = 1 << 9; + + /** + * <code>MessageBox</code> style constant for a RETRY button. + * Valid combinations are ABORT|RETRY|IGNORE, RETRY|CANCEL + * (value is 1<<10) + */ + public static final int RETRY = 1 << 10; + + /** + * <code>MessageBox</code> style constant for an IGNORE button. + * The only valid combination is ABORT|RETRY|IGNORE + * (value is 1<<11) + */ + public static final int IGNORE = 1 << 11; + + /** + * <code>FileDialog</code> style constant for open file dialog behavior + * (value is 1<<12) + */ + public static final int OPEN = 1 << 12; + + /** + * <code>FileDialog</code> style constant for save file dialog behavior + * (value is 1<<13) + */ + public static final int SAVE = 1 << 13; + + /** + * default color white (value is 1) + */ + public static final int COLOR_WHITE = 1; + + /** + * default color black (value is 2) + */ + public static final int COLOR_BLACK = 2; + + /** + * default color red (value is 3) + */ + public static final int COLOR_RED = 3; + + /** + * default color dark red (value is 4) + */ + public static final int COLOR_DARK_RED = 4; + + /** + * default color green (value is 5) + */ + public static final int COLOR_GREEN = 5; + + /** + * default color dark green (value is 6) + */ + public static final int COLOR_DARK_GREEN = 6; + + /** + * default color yellow (value is 7) + */ + public static final int COLOR_YELLOW = 7; + + /** + * default color dark yello (value is 8) + */ + public static final int COLOR_DARK_YELLOW = 8; + + /** + * default color blue (value is 9) + */ + public static final int COLOR_BLUE = 9; + + /** + * default color dark blue (value is 10) + */ + public static final int COLOR_DARK_BLUE = 10; + + /** + * default color magenta (value is 11) + */ + public static final int COLOR_MAGENTA = 11; + + /** + * default color dark magenta (value is 12) + */ + public static final int COLOR_DARK_MAGENTA = 12; + + /** + * default color cyan (value is 13) + */ + public static final int COLOR_CYAN = 13; + + /** + * default color dark cyan (value is 14) + */ + public static final int COLOR_DARK_CYAN = 14; + + /** + * default color gray (value is 15) + */ + public static final int COLOR_GRAY = 15; + + /** + * default color dark gray (value is 16) + */ + public static final int COLOR_DARK_GRAY = 16; + + /* + * System Colors + * + * Dealing with system colors is an area where there are + * many platform differences. On some platforms, system + * colors can change dynamically while the program is + * running. On other platforms, system colors can be + * changed for all instances of a particular widget. + * Therefore, the only truly portable method to obtain + * a widget color query is to query the color from an + * instance of the widget. + * + * It is expected that the list of supported colors + * will grow over time. + */ + + /** + * system color used to paint dark shadow areas (value is 17) + */ + public static final int COLOR_WIDGET_DARK_SHADOW = 17; + + /** + * system color used to paint normal shadow areas (value is 18) + */ + public static final int COLOR_WIDGET_NORMAL_SHADOW = 18; + + /** + * system color used to paint light shadow areas (value is 19) + */ + public static final int COLOR_WIDGET_LIGHT_SHADOW = 19; + + /** + * system color used to paint highlight shadow areas (value is 20) + */ + public static final int COLOR_WIDGET_HIGHLIGHT_SHADOW = 20; + + /** + * system color used to paint foreground areas (value is 21) + */ + public static final int COLOR_WIDGET_FOREGROUND = 21; + + /** + * system color used to paint background areas (value is 22) + */ + public static final int COLOR_WIDGET_BACKGROUND = 22; + + /** + * system color used to paint border areas (value is 23) + */ + public static final int COLOR_WIDGET_BORDER = 23; + + /** + * system color used to paint list foreground areas (value is 24) + */ + public static final int COLOR_LIST_FOREGROUND = 24; + + /** + * system color used to paint list background areas (value is 25) + */ + public static final int COLOR_LIST_BACKGROUND = 25; + + /** + * system color used to paint list selection background areas (value is 26) + */ + public static final int COLOR_LIST_SELECTION = 26; + + /** + * system color used to paint list selected text (value is 27) + */ + public static final int COLOR_LIST_SELECTION_TEXT = 27; + + /** + * system color used to paint tooltip text (value is 28) + */ + public static final int COLOR_INFO_FOREGROUND = 28; + + /** + * system color used to paint tooltip background areas (value is 29) + */ + public static final int COLOR_INFO_BACKGROUND = 29; + + /** + * system color used to paint title text (value is 30) + */ + public static final int COLOR_TITLE_FOREGROUND = 30; + + /** + * system color used to paint title background areas (value is 31) + */ + public static final int COLOR_TITLE_BACKGROUND = 31; + + /** + * system color used to paint title background gradient (value is 32) + */ + public static final int COLOR_TITLE_BACKGROUND_GRADIENT = 32; + + /** + * system color used to paint inactive title text (value is 33) + */ + public static final int COLOR_TITLE_INACTIVE_FOREGROUND = 33; + + /** + * system color used to paint inactive title background areas (value is 34) + */ + public static final int COLOR_TITLE_INACTIVE_BACKGROUND = 34; + + /** + * system color used to paint inactive title background gradient (value is 35) + */ + public static final int COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = 35; + + /** + * draw constant indicating whether the drawing operation + * should fill the background (value is 1<<0) + */ + public static final int DRAW_TRANSPARENT = 1 << 0; + + /** + * draw constant indicating whether the string drawing operation + * should handle line-delimeters (value is 1<<1) + */ + public static final int DRAW_DELIMITER = 1 << 1; + + /** + * draw constant indicating whether the string drawing operation + * should expand TAB characters (value is 1<<2) + */ + public static final int DRAW_TAB = 1 << 2; + + /** + * draw constant indicating whether the string drawing operation + * should handle mnemonics (value is 1<<3) + */ + public static final int DRAW_MNEMONIC = 1 << 3; + + /** + * SWT error constant indicating that no error number was specified + * (value is 1) + */ + public static final int ERROR_UNSPECIFIED = 1; + + /** + * SWT error constant indicating that no more handles for an + * operating system resource are available + * (value is 2) + */ + public static final int ERROR_NO_HANDLES = 2; + + /** + * SWT error constant indicating that no more callback resources are available + * (value is 3) + */ + public static final int ERROR_NO_MORE_CALLBACKS = 3; + + /** + * SWT error constant indicating that a null argument was passed in + * (value is 4) + */ + public static final int ERROR_NULL_ARGUMENT = 4; + + /** + * SWT error constant indicating that an invalid argument was passed in + * (value is 5) + */ + public static final int ERROR_INVALID_ARGUMENT = 5; + + /** + * SWT error constant indicating that a value was found to be + * outside the allowable range + * (value is 6) + */ + public static final int ERROR_INVALID_RANGE = 6; + + /** + * SWT error constant indicating that a value which can not be + * zero was found to be + * (value is 7) + */ + public static final int ERROR_CANNOT_BE_ZERO = 7; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide the value of an item + * (value is 8) + */ + public static final int ERROR_CANNOT_GET_ITEM = 8; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide the selection + * (value is 9) + */ + public static final int ERROR_CANNOT_GET_SELECTION = 9; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide the height of an item + * (value is 11) + */ + public static final int ERROR_CANNOT_GET_ITEM_HEIGHT = 11; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide the text of a widget + * (value is 12) + */ + public static final int ERROR_CANNOT_GET_TEXT = 12; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to set the text of a widget + * (value is 13) + */ + public static final int ERROR_CANNOT_SET_TEXT = 13; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to add an item + * (value is 14) + */ + public static final int ERROR_ITEM_NOT_ADDED = 14; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to remove an item + * (value is 15) + */ + public static final int ERROR_ITEM_NOT_REMOVED = 15; + + /** + * SWT error constant indicating that a particular feature has + * not been implemented on this platform + * (value is 20) + */ + public static final int ERROR_NOT_IMPLEMENTED = 20; + + /** + * SWT error constant indicating that a menu which needed + * to have the drop down style had some other style instead + * (value is 21) + */ + public static final int ERROR_MENU_NOT_DROP_DOWN = 21; + + /** + * SWT error constant indicating that an attempt was made to + * invoke an SWT operation which can only be executed by the + * user-interface thread from some other thread + * (value is 22) + */ + public static final int ERROR_THREAD_INVALID_ACCESS = 22; + + /** + * SWT error constant indicating that an attempt was made to + * invoke an SWT operation using a widget which had already + * been disposed. + * (value is 24) + */ + public static final int ERROR_WIDGET_DISPOSED = 24; + + /** + * SWT error constant indicating that a menu item which needed + * to have the cascade style had some other style instead + * (value is 27) + */ + public static final int ERROR_MENUITEM_NOT_CASCADE = 27; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to set the selection of a widget + * (value is 28) + */ + public static final int ERROR_CANNOT_SET_SELECTION = 28; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to set the menu + * (value is 29) + */ + public static final int ERROR_CANNOT_SET_MENU = 29; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to set the enabled state + * (value is 30) + */ + public static final int ERROR_CANNOT_SET_ENABLED = 30; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide enabled/disabled state information + * (value is 31) + */ + public static final int ERROR_CANNOT_GET_ENABLED = 31; + + /** + * SWT error constant indicating that a provided widget can + * not be used as a parent in the current operation + * (value is 32) + */ + public static final int ERROR_INVALID_PARENT = 32; + + /** + * SWT error constant indicating that a menu which needed + * to have the menu bar style had some other style instead + * (value is 33) + */ + public static final int ERROR_MENU_NOT_BAR = 33; + + /** + * SWT error constant indicating that the underlying operating + * system was unable to provide count information + * (value is 36) + */ + public static final int ERROR_CANNOT_GET_COUNT = 36; + + /** + * SWT error constant indicating that a menu which needed + * to have the pop up menu style had some other style instead + * (value is 37) + */ + public static final int ERROR_MENU_NOT_POP_UP = 37; + + /** + * SWT error constant indicating that a graphics operation + * was attempted with an image of an unsupported depth + * (value is 38) + */ + public static final int ERROR_UNSUPPORTED_DEPTH = 38; + + /** + * SWT error constant indicating that an input/output operation + * failed during the execution of an SWT operation + * (value is 39) + */ + public static final int ERROR_IO = 39; + + /** + * SWT error constant indicating that a graphics operation + * was attempted with an image having an invalid format + * (value is 40) + */ + public static final int ERROR_INVALID_IMAGE = 40; + + /** + * SWT error constant indicating that a graphics operation + * was attempted with an image having a valid but unsupported + * format + * (value is 42) + */ + public static final int ERROR_UNSUPPORTED_FORMAT = 42; + + /** + * SWT error constant indicating that an attempt was made + * to subclass an SWT widget class without implementing the + * <code>checkSubclass()</code> method. For additional + * information see the comment in <code>Widget.checkSubclass()</code> + * (value is 43) + * + * @see org.eclipse.swt.widgets.Widget#checkSubclass + */ + public static final int ERROR_INVALID_SUBCLASS = 43; + + /** + * SWT error constant indicating that an attempt was made to + * invoke an SWT operation using a graphics object which had + * already been disposed. + * (value is 44) + */ + public static final int ERROR_GRAPHIC_DISPOSED = 44; + + /** + * SWT error constant indicating that an attempt was made to + * invoke an SWT operation using a device which had already + * been disposed. + * (value is 45) + */ + public static final int ERROR_DEVICE_DISPOSED = 45; + + /** + * SWT error constant indicating that an exception happened + * when executing a runnable. + * (value is 46) + */ + public static final int ERROR_FAILED_EXEC = 46; + + /** + * SWT error constant indicating that an unsatisfied link + * error occured while attempting to load a library. + * (value is 47) + */ + public static final int ERROR_FAILED_LOAD_LIBRARY = 47; + + /** + * traversal event detail field value indicating that no + * traversal action should be taken. + * (value is 0) + */ + public static final int TRAVERSE_NONE = 0; + + /** + * traversal event detail field value indicating that the + * key which designates that a dialog should be cancelled was + * pressed; typically, this is the ESC key + * (value is 1<<1) + */ + public static final int TRAVERSE_ESCAPE = 1 << 1; + + /** + * traversal event detail field value indicating that the + * key which activates the default button in a dialog was + * pressed; typically, this is the ENTER key + * (value is 1<<2) + */ + public static final int TRAVERSE_RETURN = 1 << 2; + + /** + * traversal event detail field value indicating that the + * key which designates that focus should be given to the + * previous tab group was pressed; typically, this is the + * SHIFT-TAB key sequence + * (value is 1<<3) + */ + public static final int TRAVERSE_TAB_PREVIOUS = 1 << 3; + + /** + * traversal event detail field value indicating that the + * key which designates that focus should be given to the + * next tab group was pressed; typically, this is the + * TAB key + * (value is 1<<4) + */ + public static final int TRAVERSE_TAB_NEXT = 1 << 4; + + /** + * traversal event detail field value indicating that the + * key which designates that focus should be given to the + * previous tab item was pressed; typically, this is either + * the LEFT-ARROW or UP-ARROW keys + * (value is 1<<5) + */ + public static final int TRAVERSE_ARROW_PREVIOUS = 1 << 5; + + /** + * traversal event detail field value indicating that the + * key which designates that focus should be given to the + * previous tab item was pressed; typically, this is either + * the RIGHT-ARROW or DOWN-ARROW keys + * (value is 1<<6) + */ + public static final int TRAVERSE_ARROW_NEXT = 1 << 6; + + /** + * traversal event detail field value indicating that a + * mnemonic key sequence was pressed + * (value is 1<<7) + */ + public static final int TRAVERSE_MNEMONIC = 1 << 7; + + /** + * traversal event detail field value indicating that the + * key which designates that the previous page of a multi-page + * window should be shown was pressed; typically, this + * is the CTRL-PAGEUP key sequence + * (value is 1<<8) + */ + public static final int TRAVERSE_PAGE_PREVIOUS = 1 << 8; + + /** + * traversal event detail field value indicating that the + * key which designates that the next page of a multi-page + * window should be shown was pressed; typically, this + * is the CTRL-PAGEDOWN key sequence + * (value is 1<<9) + */ + public static final int TRAVERSE_PAGE_NEXT = 1 << 9; + + /** + * constant indicating that an image or operation is of type bitmap (value is 0) + */ + public static final int BITMAP = 0; + + /** + * constant indicating that an image or operation is of type icon (value is 1) + */ + public static final int ICON = 1; + + /** + * <code>Image</code> constructor argument indicating that + * the new image should be a copy of the image provided as + * an argument (value is 0) + */ + public static final int IMAGE_COPY = 0; + + /** + * <code>Image</code> constructor argument indicating that + * the new image should have the appearance of a "disabled" + * (using the platform's rules for how this should look) + * copy of the image provided as an argument (value is 1) + */ + public static final int IMAGE_DISABLE = 1; + + /** + * <code>Image</code> constructor argument indicating that + * the new image should have the appearance of a "gray scaled" + * copy of the image provided as an argument (value is 2) + */ + public static final int IMAGE_GRAY = 2; + + /** + * font style constant indicating a normal weight, non-italic font + * (value is 0) + */ + public static final int NORMAL = 0; + + /** + * font style constant indicating a bold weight font + * (value is 1<<0) + */ + public static final int BOLD = 1 << 0; + + /** + * font style constant indicating an italic font + * (value is 1<<1) + */ + public static final int ITALIC = 1 << 1; + + /** + * system arrow cursor (value is 0) + */ + public static final int CURSOR_ARROW = 0; + + /** + * system wait cursor (value is 1) + */ + public static final int CURSOR_WAIT = 1; + + /** + * system cross hair cursor (value is 2) + */ + public static final int CURSOR_CROSS = 2; + + /** + * system app startup cursor (value is 3) + */ + public static final int CURSOR_APPSTARTING = 3; + + /** + * system help cursor (value is 4) + */ + public static final int CURSOR_HELP = 4; + + /** + * system resize all directions cursor (value is 5) + */ + public static final int CURSOR_SIZEALL = 5; + + /** + * system resize north-east-south-west cursor (value is 6) + */ + public static final int CURSOR_SIZENESW = 6; + + /** + * system resize north-south cursor (value is 7) + */ + public static final int CURSOR_SIZENS = 7; + + /** + * system resize north-west-south-east cursor (value is 8) + */ + public static final int CURSOR_SIZENWSE = 8; + + /** + * system resize west-east cursor (value is 9) + */ + public static final int CURSOR_SIZEWE = 9; + + /** + * system resize north cursor (value is 10) + */ + public static final int CURSOR_SIZEN = 10; + + /** + * system resize south cursor (value is 11) + */ + public static final int CURSOR_SIZES = 11; + + /** + * system resize east cursor (value is 12) + */ + public static final int CURSOR_SIZEE = 12; + + /** + * system resize west cursor (value is 13) + */ + public static final int CURSOR_SIZEW = 13; + + /** + * system resize north-east cursor (value is 14) + */ + public static final int CURSOR_SIZENE = 14; + + /** + * system resize south-east cursor (value is 15) + */ + public static final int CURSOR_SIZESE = 15; + + /** + * system resize south-west cursor (value is 16) + */ + public static final int CURSOR_SIZESW = 16; + + /** + * system resize north-west cursor (value is 17) + */ + public static final int CURSOR_SIZENW = 17; + + /** + * system up arrow cursor (value is 18) + */ + public static final int CURSOR_UPARROW = 18; + + /** + * system i-beam cursor (value is 19) + */ + public static final int CURSOR_IBEAM = 19; + + /** + * system "not allowed" cursor (value is 20) + */ + public static final int CURSOR_NO = 20; + + /** + * system hand cursor (value is 21) + */ + public static final int CURSOR_HAND = 21; + + /** + * line drawing style for solid lines (value is 1) + */ + public static final int LINE_SOLID = 1; + + /** + * line drawing style for dashed lines (value is 2) + */ + public static final int LINE_DASH = 2; + + /** + * line drawing style for dotted lines (value is 3) + */ + public static final int LINE_DOT = 3; + + /** + * line drawing style for alternating dash-dot lines (value is 4) + */ + public static final int LINE_DASHDOT = 4; + + /** + * line drawing style for dash-dot-dot lines (value is 5) + */ + public static final int LINE_DASHDOTDOT = 5; + + /** + * image format constant indicating an unknown image type (value is -1) + */ + public static final int IMAGE_UNDEFINED = -1; + + /** + * image format constant indicating a Windows BMP format image (value is 0) + */ + public static final int IMAGE_BMP = 0; + + /** + * image format constant indicating a run-length encoded + * Windows BMP format image (value is 1) + */ + public static final int IMAGE_BMP_RLE = 1; + + /** + * image format constant indicating a GIF format image (value is 2) + */ + public static final int IMAGE_GIF = 2; + + /** + * image format constant indicating a ICO format image (value is 3) + */ + public static final int IMAGE_ICO = 3; + + /** + * image format constant indicating a JPEG format image (value is 4) + */ + public static final int IMAGE_JPEG = 4; + + /** + * image format constant indicating a PNG format image (value is 5) + */ + public static final int IMAGE_PNG = 5; + + /** + * GIF image disposal method constants indicating that the + * disposal method is unspecified (value is 0) + */ + public static final int DM_UNSPECIFIED = 0x0; + + /** + * GIF image disposal method constants indicating that the + * disposal method is to do nothing. That is, to leave the + * previous image in place (value is 1) + */ + public static final int DM_FILL_NONE = 0x1; + + /** + * GIF image disposal method constants indicating that the + * the previous images should be covered with the background + * color before displaying the next image (value is 2) + */ + public static final int DM_FILL_BACKGROUND = 0x2; + + /** + * GIF image disposal method constants indicating that the + * disposal method is to restore the previous picture + * (value is 3) + */ + public static final int DM_FILL_PREVIOUS = 0x3; + + /** + * image transparency constant indicating that the image + * contains no transparency information (value is 0) + */ + public static final int TRANSPARENCY_NONE = 0x0; + + /** + * image transparency constant indicating that the image + * contains alpha transparency information (value is 1<<0) + */ + public static final int TRANSPARENCY_ALPHA = 1 << 0; + + /** + * image transparency constant indicating that the image + * contains a transparency mask (value is 1<<1) + */ + public static final int TRANSPARENCY_MASK = 1 << 1; + + /** + * image transparency constant indicating that the image + * contains a transparent pixel (value is 1<<2) + */ + public static final int TRANSPARENCY_PIXEL = 1 << 2; + +/** + * Answers a concise, human readable description of the error code. + * + * @param code the SWT error code. + * @return a description of the error code. + * + * @see SWT + */ +static String findErrorText (int code) { + switch (code) { + case ERROR_UNSPECIFIED: return "Unspecified error"; + case ERROR_NO_HANDLES: return "No more handles"; + case ERROR_NO_MORE_CALLBACKS: return "No more callbacks"; + case ERROR_NULL_ARGUMENT: return "Argument cannot be null"; + case ERROR_INVALID_ARGUMENT: return "Argument not valid"; + case ERROR_INVALID_RANGE: return "Index out of bounds"; + case ERROR_CANNOT_BE_ZERO: return "Argument cannot be zero"; + case ERROR_CANNOT_GET_ITEM: return "Cannot get item"; + case ERROR_CANNOT_GET_SELECTION: return "Cannot get selection"; + case ERROR_CANNOT_GET_ITEM_HEIGHT: return "Cannot get item height"; + case ERROR_CANNOT_GET_TEXT: return "Cannot get text"; + case ERROR_CANNOT_SET_TEXT: return "Cannot set text"; + case ERROR_ITEM_NOT_ADDED: return "Item not added"; + case ERROR_ITEM_NOT_REMOVED: return "Item not removed"; + case ERROR_NOT_IMPLEMENTED: return "Not implemented"; + case ERROR_MENU_NOT_DROP_DOWN: return "Menu must be a drop down"; + case ERROR_THREAD_INVALID_ACCESS: return "Invalid thread access"; + case ERROR_WIDGET_DISPOSED: return "Widget is disposed"; + case ERROR_MENUITEM_NOT_CASCADE: return "Menu item is not a CASCADE"; + case ERROR_CANNOT_SET_SELECTION: return "Cannot set selection"; + case ERROR_CANNOT_SET_MENU: return "Cannot set menu"; + case ERROR_CANNOT_SET_ENABLED: return "Cannot set the enabled state"; + case ERROR_CANNOT_GET_ENABLED: return "Cannot get the enabled state"; + case ERROR_INVALID_PARENT: return "Widget has the wrong parent"; + case ERROR_MENU_NOT_BAR: return "Menu is not a BAR"; + case ERROR_CANNOT_GET_COUNT: return "Cannot get count"; + case ERROR_MENU_NOT_POP_UP: return "Menu is not a POP_UP"; + case ERROR_UNSUPPORTED_DEPTH: return "Unsupported color depth"; + case ERROR_IO: return "i/o error"; + case ERROR_INVALID_IMAGE: return "Invalid image"; + case ERROR_UNSUPPORTED_FORMAT: return "Unsupported or unrecognized format"; + case ERROR_INVALID_SUBCLASS: return "Subclassing not allowed"; + case ERROR_GRAPHIC_DISPOSED: return "Graphic is disposed"; + case ERROR_DEVICE_DISPOSED: return "Device is disposed"; + case ERROR_FAILED_EXEC: return "Failed to execute runnable"; + case ERROR_FAILED_LOAD_LIBRARY: return "Unable to load library"; + } + return "Unknown error"; +} + +/** + * Returns the NLS'ed message for the given argument. + * + * @param key the key to look up + * @return the message for the given key + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the key is null</li> + * </ul> + */ +public static String getMessage(String key) { + return Compatibility.getMessage(key); +} + +/** + * Returns the SWT platform name. + * Examples: "win32", "motif", "gtk", "photon", "carbon" + * + * @return the SWT platform name + */ +public static String getPlatform () { + return Callback.getPlatform (); +} + +/** + * Returns the SWT version number as an integer. + * Example: "SWT051" == 51 + * + * @return the SWT version number + */ +public static int getVersion () { + return Library.getVersion (); +} + +/** + * Throws an appropriate exception based on the passed in error code. + * + * @param code the SWT error code + */ +public static void error (int code) { + error (code, null); +} + +/** + * Throws an appropriate exception based on the passed in error code. + * The <code>throwable</code> argument should be either null, or the + * throwable which caused SWT to throw an exception. + * <p> + * In SWT, errors are reported by throwing one of three exceptions: + * <dl> + * <dd>java.lang.IllegalArgumentException</dd> + * <dt>thrown whenever one of the API methods is invoked with an illegal argument</dt> + * <dd>org.eclipse.swt.SWTException (extends java.lang.RuntimeException)</dd> + * <dt>thrown whenever a recoverable error happens internally in SWT</dt> + * <dd>org.eclipse.swt.SWTError (extends java.lang.Error)</dd> + * <dt>thrown whenever a <b>non-recoverable</b> error happens internally in SWT</dt> + * </dl> + * This method provides the logic which maps between error codes + * and one of the above exceptions. + * </p> + * + * @param code the SWT error code. + * @param throwable the exception which caused the error to occur. + * + * @see SWTError + * @see SWTException + * @see IllegalArgumentException + */ +public static void error (int code, Throwable throwable) { + + /* + * This code prevents the creation of "chains" of SWTErrors and + * SWTExceptions which in turn contain other SWTErrors and + * SWTExceptions as their throwable. This can occur when low level + * code throws an exception past a point where a higher layer is + * being "safe" and catching all exceptions. (Note that, this is + * _a_bad_thing_ which we always try to avoid.) + * + * On the theory that the low level code is closest to the + * original problem, we simply re-throw the original exception here. + */ + if (throwable instanceof SWTError) throw (SWTError) throwable; + if (throwable instanceof SWTException) throw (SWTException) throwable; + + switch (code) { + + /* Illegal Arguments (non-fatal) */ + case ERROR_NULL_ARGUMENT: + case ERROR_CANNOT_BE_ZERO: + case ERROR_INVALID_ARGUMENT: + case ERROR_MENU_NOT_BAR: + case ERROR_MENU_NOT_DROP_DOWN: + case ERROR_MENU_NOT_POP_UP: + case ERROR_MENUITEM_NOT_CASCADE: + case ERROR_INVALID_PARENT: + case ERROR_INVALID_RANGE: { + throw new IllegalArgumentException (findErrorText (code)); + } + + /* SWT Errors (non-fatal) */ + case ERROR_INVALID_SUBCLASS: + case ERROR_THREAD_INVALID_ACCESS: + case ERROR_WIDGET_DISPOSED: + case ERROR_GRAPHIC_DISPOSED: + case ERROR_DEVICE_DISPOSED: + case ERROR_INVALID_IMAGE: + case ERROR_UNSUPPORTED_DEPTH: + case ERROR_UNSUPPORTED_FORMAT: + case ERROR_FAILED_EXEC: + case ERROR_IO: { + SWTException exception = new SWTException (code); + exception.throwable = throwable; + throw exception; + } + + /* OS Failure/Limit (fatal, may occur only on some platforms) */ + case ERROR_CANNOT_GET_COUNT: + case ERROR_CANNOT_GET_ENABLED: + case ERROR_CANNOT_GET_ITEM: + case ERROR_CANNOT_GET_ITEM_HEIGHT: + case ERROR_CANNOT_GET_SELECTION: + case ERROR_CANNOT_GET_TEXT: + case ERROR_CANNOT_SET_ENABLED: + case ERROR_CANNOT_SET_MENU: + case ERROR_CANNOT_SET_SELECTION: + case ERROR_CANNOT_SET_TEXT: + case ERROR_ITEM_NOT_ADDED: + case ERROR_ITEM_NOT_REMOVED: + case ERROR_NO_HANDLES: + //FALL THROUGH + + /* SWT Failure/Limit (fatal, may occur only on some platforms) */ + case ERROR_FAILED_LOAD_LIBRARY: + case ERROR_NO_MORE_CALLBACKS: + case ERROR_NOT_IMPLEMENTED: + case ERROR_UNSPECIFIED: { + SWTError error = new SWTError (code); + error.throwable = throwable; + throw error; + } + } + + /* Unknown/Undefined Error */ + SWTError error = new SWTError (code); + error.throwable = throwable; + throw error; +} + +static { + /* + * These values represent bit masks that may need to + * expand in the future. Therefore they are not initialized + * in the declaration to stop the compiler from inlining. + */ + BUTTON_MASK = BUTTON1 | BUTTON2 | BUTTON3; + MODIFIER_MASK = ALT | SHIFT | CTRL | COMMAND; + + /* + * These values can be different on different platforms. + * Therefore they are not initialized in the declaration + * to stop the compiler from inlining. + */ + String platform = getPlatform (); + if ("carbon".equals (platform)) { + MOD1 = COMMAND; + MOD2 = SHIFT; + MOD3 = ALT; + MOD4 = CONTROL; + } else { + MOD1 = CONTROL; + MOD2 = SHIFT; + MOD3 = ALT; + MOD4 = ALT; + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTError.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTError.java index 1aa1b3b730..8e9566168a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTError.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTError.java @@ -1,113 +1,113 @@ -package org.eclipse.swt;
-
-/*
+package org.eclipse.swt; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This error is thrown whenever an unrecoverable error
- * occurs internally in SWT. The message text and error code
- * provide a further description of the problem. The exception
- * has a <code>throwable</code> field which holds the underlying
- * throwable that caused the problem (if this information is
- * available (i.e. it may be null)).
- * <p>
- * SWTErrors are thrown when something fails internally which
- * either leaves SWT in an unknown state (eg. the o/s call to
- * remove an item from a list returns an error code) or when SWT
- * is left in a known-to-be-unrecoverable state (eg. it runs out
- * of callback resources). SWTErrors should not occur in typical
- * programs, although "high reliability" applications should
- * still catch them.
- * </p><p>
- * This class also provides support methods used by SWT to match
- * error codes to the appropriate exception class (SWTError,
- * SWTException, or IllegalArgumentException) and to provide
- * human readable strings for SWT error codes.
- * </p>
- *
- * @see SWTException
- * @see SWT#error
- */
-
-public class SWTError extends Error {
- public int code;
- public Throwable throwable;
-
-/**
- * Constructs a new instance of this class with its
- * walkback filled in. The error code is set to an
- * unspecified value.
- */
-public SWTError () {
- this (SWT.ERROR_UNSPECIFIED);
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback and message filled in. The error code is
- * set to an unspecified value.
- *
- * @param message the detail message for the exception
- */
-public SWTError (String message) {
- this (SWT.ERROR_UNSPECIFIED, message);
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback and error code filled in.
- *
- * @param code the SWT error code
- */
-public SWTError (int code) {
- this (code, SWT.findErrorText (code));
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback, error code and message filled in.
- *
- * @param code the SWT error code
- * @param message the detail message for the exception
- */
-public SWTError (int code, String message) {
- super (message);
- this.code = code;
-}
-
-/**
- * Returns the string describing this SWTError object.
- * <p>
- * It is combined with the message string of the Throwable
- * which caused this SWTError (if this information is available).
- * </p>
- * @return the error message string of this SWTError object
- */
-public String getMessage() {
- if (throwable == null)
- return super.getMessage();
- else
- return super.getMessage() + " (" + throwable.toString() + ")";
-}
-
-/**
- * Outputs a printable representation of this error's
- * walkback on the standard error stream.
- * <p>
- * Note: printStackTrace(PrintStream) and printStackTrace(PrintWriter)
- * are not provided in order to maintain compatibility with CLDC.
- * </p>
- */
-public synchronized void printStackTrace() {
- super.printStackTrace();
- if (throwable != null) {
- System.err.println("*** Stack trace of contained error ***");
- throwable.printStackTrace();
- }
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This error is thrown whenever an unrecoverable error + * occurs internally in SWT. The message text and error code + * provide a further description of the problem. The exception + * has a <code>throwable</code> field which holds the underlying + * throwable that caused the problem (if this information is + * available (i.e. it may be null)). + * <p> + * SWTErrors are thrown when something fails internally which + * either leaves SWT in an unknown state (eg. the o/s call to + * remove an item from a list returns an error code) or when SWT + * is left in a known-to-be-unrecoverable state (eg. it runs out + * of callback resources). SWTErrors should not occur in typical + * programs, although "high reliability" applications should + * still catch them. + * </p><p> + * This class also provides support methods used by SWT to match + * error codes to the appropriate exception class (SWTError, + * SWTException, or IllegalArgumentException) and to provide + * human readable strings for SWT error codes. + * </p> + * + * @see SWTException + * @see SWT#error + */ + +public class SWTError extends Error { + public int code; + public Throwable throwable; + +/** + * Constructs a new instance of this class with its + * walkback filled in. The error code is set to an + * unspecified value. + */ +public SWTError () { + this (SWT.ERROR_UNSPECIFIED); +} + +/** + * Constructs a new instance of this class with its + * walkback and message filled in. The error code is + * set to an unspecified value. + * + * @param message the detail message for the exception + */ +public SWTError (String message) { + this (SWT.ERROR_UNSPECIFIED, message); +} + +/** + * Constructs a new instance of this class with its + * walkback and error code filled in. + * + * @param code the SWT error code + */ +public SWTError (int code) { + this (code, SWT.findErrorText (code)); +} + +/** + * Constructs a new instance of this class with its + * walkback, error code and message filled in. + * + * @param code the SWT error code + * @param message the detail message for the exception + */ +public SWTError (int code, String message) { + super (message); + this.code = code; +} + +/** + * Returns the string describing this SWTError object. + * <p> + * It is combined with the message string of the Throwable + * which caused this SWTError (if this information is available). + * </p> + * @return the error message string of this SWTError object + */ +public String getMessage() { + if (throwable == null) + return super.getMessage(); + else + return super.getMessage() + " (" + throwable.toString() + ")"; +} + +/** + * Outputs a printable representation of this error's + * walkback on the standard error stream. + * <p> + * Note: printStackTrace(PrintStream) and printStackTrace(PrintWriter) + * are not provided in order to maintain compatibility with CLDC. + * </p> + */ +public synchronized void printStackTrace() { + super.printStackTrace(); + if (throwable != null) { + System.err.println("*** Stack trace of contained error ***"); + throwable.printStackTrace(); + } +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTException.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTException.java index 74c76f6d41..674a6dd40a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTException.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWTException.java @@ -1,106 +1,106 @@ -package org.eclipse.swt;
-
-/*
+package org.eclipse.swt; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This runtime exception is thrown whenever a recoverable error
- * occurs internally in SWT. The message text and error code
- * provide a further description of the problem. The exception
- * has a <code>throwable</code> field which holds the underlying
- * exception that caused the problem (if this information is
- * available (i.e. it may be null)).
- * <p>
- * SWTExceptions are thrown when something fails internally,
- * but SWT is left in a known stable state (eg. a widget call
- * was made from a non-u/i thread, or there is failure while
- * reading an Image because the source file was corrupt).
- * </p>
- *
- * @see SWTError
- */
-
-public class SWTException extends RuntimeException {
- public int code;
- public Throwable throwable;
-
-/**
- * Constructs a new instance of this class with its
- * walkback filled in. The error code is set to an
- * unspecified value.
- */
-public SWTException () {
- this (SWT.ERROR_UNSPECIFIED);
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback and message filled in. The error code is
- * set to an unspecified value.
- *
- * @param message the detail message for the exception
- */
-public SWTException (String message) {
- this (SWT.ERROR_UNSPECIFIED, message);
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback and error code filled in.
- *
- * @param code the SWT error code
- */
-public SWTException (int code) {
- this (code, SWT.findErrorText (code));
-}
-
-/**
- * Constructs a new instance of this class with its
- * walkback, error code and message filled in.
- *
- * @param code the SWT error code
- * @param message the detail message for the exception
- */
-public SWTException (int code, String message) {
- super (message);
- this.code = code;
-}
-
-/**
- * Returns the string describing this SWTException object.
- * <p>
- * It is combined with the message string of the Throwable
- * which caused this SWTException (if this information is available).
- * </p>
- * @return the error message string of this SWTException object
- */
-public String getMessage() {
- if (throwable == null)
- return super.getMessage();
- else
- return super.getMessage() + " (" + throwable.toString() + ")";
-}
-
-/**
- * Outputs a printable representation of this exception's
- * walkback on the standard error stream.
- * <p>
- * Note: printStackTrace(PrintStream) and printStackTrace(PrintWriter)
- * are not provided in order to maintain compatibility with CLDC.
- * </p>
- */
-public void printStackTrace() {
- super.printStackTrace();
- if (throwable != null) {
- System.err.println("*** Stack trace of contained exception ***");
- throwable.printStackTrace();
- }
-}
-
-}
-
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This runtime exception is thrown whenever a recoverable error + * occurs internally in SWT. The message text and error code + * provide a further description of the problem. The exception + * has a <code>throwable</code> field which holds the underlying + * exception that caused the problem (if this information is + * available (i.e. it may be null)). + * <p> + * SWTExceptions are thrown when something fails internally, + * but SWT is left in a known stable state (eg. a widget call + * was made from a non-u/i thread, or there is failure while + * reading an Image because the source file was corrupt). + * </p> + * + * @see SWTError + */ + +public class SWTException extends RuntimeException { + public int code; + public Throwable throwable; + +/** + * Constructs a new instance of this class with its + * walkback filled in. The error code is set to an + * unspecified value. + */ +public SWTException () { + this (SWT.ERROR_UNSPECIFIED); +} + +/** + * Constructs a new instance of this class with its + * walkback and message filled in. The error code is + * set to an unspecified value. + * + * @param message the detail message for the exception + */ +public SWTException (String message) { + this (SWT.ERROR_UNSPECIFIED, message); +} + +/** + * Constructs a new instance of this class with its + * walkback and error code filled in. + * + * @param code the SWT error code + */ +public SWTException (int code) { + this (code, SWT.findErrorText (code)); +} + +/** + * Constructs a new instance of this class with its + * walkback, error code and message filled in. + * + * @param code the SWT error code + * @param message the detail message for the exception + */ +public SWTException (int code, String message) { + super (message); + this.code = code; +} + +/** + * Returns the string describing this SWTException object. + * <p> + * It is combined with the message string of the Throwable + * which caused this SWTException (if this information is available). + * </p> + * @return the error message string of this SWTException object + */ +public String getMessage() { + if (throwable == null) + return super.getMessage(); + else + return super.getMessage() + " (" + throwable.toString() + ")"; +} + +/** + * Outputs a printable representation of this exception's + * walkback on the standard error stream. + * <p> + * Note: printStackTrace(PrintStream) and printStackTrace(PrintWriter) + * are not provided in order to maintain compatibility with CLDC. + * </p> + */ +public void printStackTrace() { + super.printStackTrace(); + if (throwable != null) { + System.err.println("*** Stack trace of contained exception ***"); + throwable.printStackTrace(); + } +} + +} + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmEvent.java index df645735e1..f16bf68834 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmEvent.java @@ -1,31 +1,31 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * a widget such as a menu item being armed.
- *
- * @see ArmListener
- */
-
-public final class ArmEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public ArmEvent(Event e) {
- super(e);
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * a widget such as a menu item being armed. + * + * @see ArmListener + */ + +public final class ArmEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public ArmEvent(Event e) { + super(e); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmListener.java index 8df5ab46cc..73b6df6b58 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ArmListener.java @@ -1,34 +1,34 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the event that is generated when a widget,
- * such as a menu item, is armed.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a widget using the
- * <code>addArmListener</code> method and removed using
- * the <code>removeArmListener</code> method. When the
- * widget is armed, the widgetArmed method will be invoked.
- * </p>
- *
- * @see ArmEvent
- */
-public interface ArmListener extends SWTEventListener {
-
-/**
- * Sent when a widget is armed, or 'about to be selected'.
- *
- * @param e an event containing information about the arm
- */
-public void widgetArmed(ArmEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the event that is generated when a widget, + * such as a menu item, is armed. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a widget using the + * <code>addArmListener</code> method and removed using + * the <code>removeArmListener</code> method. When the + * widget is armed, the widgetArmed method will be invoked. + * </p> + * + * @see ArmEvent + */ +public interface ArmListener extends SWTEventListener { + +/** + * Sent when a widget is armed, or 'about to be selected'. + * + * @param e an event containing information about the arm + */ +public void widgetArmed(ArmEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlAdapter.java index 2edaedd813..502a130841 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlAdapter.java @@ -1,42 +1,42 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>ControlListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>ControlEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see ControlListener
- * @see ControlEvent
- */
-public abstract class ControlAdapter implements ControlListener {
-
-/**
- * Sent when the location (x, y) of a control changes relative
- * to its parent (or relative to the display, for <code>Shell</code>s).
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the move
- */
-public void controlMoved(ControlEvent e) {
-}
-
-/**
- * Sent when the size (width, height) of a control changes.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the resize
- */
-public void controlResized(ControlEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>ControlListener</code> interface. + * <p> + * Classes that wish to deal with <code>ControlEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see ControlListener + * @see ControlEvent + */ +public abstract class ControlAdapter implements ControlListener { + +/** + * Sent when the location (x, y) of a control changes relative + * to its parent (or relative to the display, for <code>Shell</code>s). + * The default behavior is to do nothing. + * + * @param e an event containing information about the move + */ +public void controlMoved(ControlEvent e) { +} + +/** + * Sent when the size (width, height) of a control changes. + * The default behavior is to do nothing. + * + * @param e an event containing information about the resize + */ +public void controlResized(ControlEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlEvent.java index 6dde2b2614..84934d83a7 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlEvent.java @@ -1,33 +1,33 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * controls being moved or resized.
- *
- * @see ControlListener
- */
-
-public final class ControlEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public ControlEvent(Event e) {
- super(e);
-}
-
-}
-
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * controls being moved or resized. + * + * @see ControlListener + */ + +public final class ControlEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public ControlEvent(Event e) { + super(e); +} + +} + + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlListener.java index fc44d77263..46679df5d8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ControlListener.java @@ -1,44 +1,44 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated by moving
- * and resizing controls.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addControlListener</code> method and removed using
- * the <code>removeControlListener</code> method. When a
- * control is moved or resized, the appropriate method will
- * be invoked.
- * </p>
- *
- * @see ControlAdapter
- * @see ControlEvent
- */
-public interface ControlListener extends SWTEventListener {
-
-/**
- * Sent when the location (x, y) of a control changes relative
- * to its parent (or relative to the display, for <code>Shell</code>s).
- *
- * @param e an event containing information about the move
- */
-public void controlMoved(ControlEvent e);
-
-/**
- * Sent when the size (width, height) of a control changes.
- *
- * @param e an event containing information about the resize
- */
-public void controlResized(ControlEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated by moving + * and resizing controls. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addControlListener</code> method and removed using + * the <code>removeControlListener</code> method. When a + * control is moved or resized, the appropriate method will + * be invoked. + * </p> + * + * @see ControlAdapter + * @see ControlEvent + */ +public interface ControlListener extends SWTEventListener { + +/** + * Sent when the location (x, y) of a control changes relative + * to its parent (or relative to the display, for <code>Shell</code>s). + * + * @param e an event containing information about the move + */ +public void controlMoved(ControlEvent e); + +/** + * Sent when the size (width, height) of a control changes. + * + * @param e an event containing information about the resize + */ +public void controlResized(ControlEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeEvent.java index 28db666b51..9fcf3dfb02 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * widgets being disposed.
- *
- * @see DisposeListener
- */
-
-public final class DisposeEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public DisposeEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * widgets being disposed. + * + * @see DisposeListener + */ + +public final class DisposeEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public DisposeEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeListener.java index 1cc032f89b..cb381854e6 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/DisposeListener.java @@ -1,35 +1,35 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the event that is generated when a widget
- * is disposed.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a widget using the
- * <code>addDisposeListener</code> method and removed using
- * the <code>removeDisposeListener</code> method. When a
- * widget is disposed, the widgetDisposed method will
- * be invoked.
- * </p>
- *
- * @see DisposeEvent
- */
-public interface DisposeListener extends SWTEventListener {
-
-/**
- * Sent when the widget is disposed.
- *
- * @param e an event containing information about the dispose
- */
-public void widgetDisposed(DisposeEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the event that is generated when a widget + * is disposed. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a widget using the + * <code>addDisposeListener</code> method and removed using + * the <code>removeDisposeListener</code> method. When a + * widget is disposed, the widgetDisposed method will + * be invoked. + * </p> + * + * @see DisposeEvent + */ +public interface DisposeListener extends SWTEventListener { + +/** + * Sent when the widget is disposed. + * + * @param e an event containing information about the dispose + */ +public void widgetDisposed(DisposeEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusAdapter.java index 309480e9da..520689571e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusAdapter.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>FocusListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>FocusEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see FocusListener
- * @see FocusEvent
- */
-public abstract class FocusAdapter implements FocusListener {
-
-/**
- * Sent when a control gets focus.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the focus change
- */
-public void focusGained(FocusEvent e) {
-}
-
-/**
- * Sent when a control loses focus.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the focus change
- */
-public void focusLost(FocusEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>FocusListener</code> interface. + * <p> + * Classes that wish to deal with <code>FocusEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see FocusListener + * @see FocusEvent + */ +public abstract class FocusAdapter implements FocusListener { + +/** + * Sent when a control gets focus. + * The default behavior is to do nothing. + * + * @param e an event containing information about the focus change + */ +public void focusGained(FocusEvent e) { +} + +/** + * Sent when a control loses focus. + * The default behavior is to do nothing. + * + * @param e an event containing information about the focus change + */ +public void focusLost(FocusEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusEvent.java index 5dc9227e09..66fba93a51 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * widgets gaining and losing focus.
- *
- * @see FocusListener
- */
-
-public final class FocusEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public FocusEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * widgets gaining and losing focus. + * + * @see FocusListener + */ + +public final class FocusEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public FocusEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusListener.java index 75bb0c3692..74250720a6 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/FocusListener.java @@ -1,44 +1,44 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated as controls
- * gain and lose focus.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addFocusListener</code> method and removed using
- * the <code>removeFocusListener</code> method. When a
- * control gains or loses focus, the appropriate method
- * will be invoked.
- * </p>
- *
- * @see FocusAdapter
- * @see FocusEvent
- */
-public interface FocusListener extends SWTEventListener {
-
-/**
- * Sent when a control gets focus.
- *
- * @param e an event containing information about the focus change
- */
-public void focusGained(FocusEvent e);
-
-/**
- * Sent when a control loses focus.
- *
- * @param e an event containing information about the focus change
- */
-public void focusLost(FocusEvent e);
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated as controls + * gain and lose focus. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addFocusListener</code> method and removed using + * the <code>removeFocusListener</code> method. When a + * control gains or loses focus, the appropriate method + * will be invoked. + * </p> + * + * @see FocusAdapter + * @see FocusEvent + */ +public interface FocusListener extends SWTEventListener { + +/** + * Sent when a control gets focus. + * + * @param e an event containing information about the focus change + */ +public void focusGained(FocusEvent e); + +/** + * Sent when a control loses focus. + * + * @param e an event containing information about the focus change + */ +public void focusLost(FocusEvent e); +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpEvent.java index bbce9429f3..3fbb3e793a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * help being requested for a widget.
- *
- * @see HelpListener
- */
-
-public final class HelpEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public HelpEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * help being requested for a widget. + * + * @see HelpListener + */ + +public final class HelpEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public HelpEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpListener.java index b1c6c6f8d1..0a301522c4 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/HelpListener.java @@ -1,36 +1,36 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the event that is generated when help is
- * requested for a control, typically when the user presses F1.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addHelpListener</code> method and removed using
- * the <code>removeHelpListener</code> method. When help
- * is requested for a control, the helpRequested method
- * will be invoked.
- * </p>
- *
- * @see HelpEvent
- */
-public interface HelpListener extends SWTEventListener {
-
-/**
- * Sent when help is requested for a control, typically
- * when the user presses F1.
- *
- * @param e an event containing information about the help
- */
-public void helpRequested(HelpEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the event that is generated when help is + * requested for a control, typically when the user presses F1. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addHelpListener</code> method and removed using + * the <code>removeHelpListener</code> method. When help + * is requested for a control, the helpRequested method + * will be invoked. + * </p> + * + * @see HelpEvent + */ +public interface HelpListener extends SWTEventListener { + +/** + * Sent when help is requested for a control, typically + * when the user presses F1. + * + * @param e an event containing information about the help + */ +public void helpRequested(HelpEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyAdapter.java index daeba33f89..2cbc44a3a0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyAdapter.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>KeyListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>KeyEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see KeyListener
- * @see KeyEvent
- */
-public abstract class KeyAdapter implements KeyListener {
-
-/**
- * Sent when a key is pressed on the system keyboard.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the key press
- */
-public void keyPressed(KeyEvent e) {
-}
-
-/**
- * Sent when a key is released on the system keyboard.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the key release
- */
-public void keyReleased(KeyEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>KeyListener</code> interface. + * <p> + * Classes that wish to deal with <code>KeyEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see KeyListener + * @see KeyEvent + */ +public abstract class KeyAdapter implements KeyListener { + +/** + * Sent when a key is pressed on the system keyboard. + * The default behavior is to do nothing. + * + * @param e an event containing information about the key press + */ +public void keyPressed(KeyEvent e) { +} + +/** + * Sent when a key is released on the system keyboard. + * The default behavior is to do nothing. + * + * @param e an event containing information about the key release + */ +public void keyReleased(KeyEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyEvent.java index 8142831776..8415afffed 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyEvent.java @@ -1,62 +1,62 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * keys being pressed and released on the keyboard
- *
- * @see KeyListener
- */
-
-public class KeyEvent extends TypedEvent {
-
- /**
- * the character represented by the key that was typed.
- * This is the final character that results after all modifiers have been
- * applied. For example, when the user types Ctrl+A, the character value
- * is 0x01 (NUL). It is important that applications do not attempt to modify
- * the character value based on a stateMask (such as SWT.CTRL) or the resulting
- * character will not be correct.
- */
- public char character;
-
- /**
- * the key code of the key that was typed,
- * as defined by the key code constants in class <code>SWT</code>.
- * When the character field of the event is ambiguous, this field
- * contains the unicode value of the original character. For example,
- * typing Ctrl+M or Return both result in the character '\r' but the
- * keyCode field will also contain '\r' when Return was typed.
- *
- * @see SWT
- */
- public int keyCode;
-
- /**
- * the state of the keyboard modifier keys at the time
- * the event was generated
- */
- public int stateMask;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public KeyEvent(Event e) {
- super(e);
- this.character = e.character;
- this.keyCode = e.keyCode;
- this.stateMask = e.stateMask;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * keys being pressed and released on the keyboard + * + * @see KeyListener + */ + +public class KeyEvent extends TypedEvent { + + /** + * the character represented by the key that was typed. + * This is the final character that results after all modifiers have been + * applied. For example, when the user types Ctrl+A, the character value + * is 0x01 (NUL). It is important that applications do not attempt to modify + * the character value based on a stateMask (such as SWT.CTRL) or the resulting + * character will not be correct. + */ + public char character; + + /** + * the key code of the key that was typed, + * as defined by the key code constants in class <code>SWT</code>. + * When the character field of the event is ambiguous, this field + * contains the unicode value of the original character. For example, + * typing Ctrl+M or Return both result in the character '\r' but the + * keyCode field will also contain '\r' when Return was typed. + * + * @see SWT + */ + public int keyCode; + + /** + * the state of the keyboard modifier keys at the time + * the event was generated + */ + public int stateMask; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public KeyEvent(Event e) { + super(e); + this.character = e.character; + this.keyCode = e.keyCode; + this.stateMask = e.stateMask; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyListener.java index 4e8270a9b5..61315d5536 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/KeyListener.java @@ -1,43 +1,43 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated as keys
- * are pressed on the system keyboard.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addKeyListener</code> method and removed using
- * the <code>removeKeyListener</code> method. When a
- * key is pressed or released, the appropriate method will
- * be invoked.
- * </p>
- *
- * @see KeyAdapter
- * @see KeyEvent
- */
-public interface KeyListener extends SWTEventListener {
-
-/**
- * Sent when a key is pressed on the system keyboard.
- *
- * @param e an event containing information about the key press
- */
-public void keyPressed(KeyEvent e);
-
-/**
- * Sent when a key is released on the system keyboard.
- *
- * @param e an event containing information about the key release
- */
-public void keyReleased(KeyEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated as keys + * are pressed on the system keyboard. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addKeyListener</code> method and removed using + * the <code>removeKeyListener</code> method. When a + * key is pressed or released, the appropriate method will + * be invoked. + * </p> + * + * @see KeyAdapter + * @see KeyEvent + */ +public interface KeyListener extends SWTEventListener { + +/** + * Sent when a key is pressed on the system keyboard. + * + * @param e an event containing information about the key press + */ +public void keyPressed(KeyEvent e); + +/** + * Sent when a key is released on the system keyboard. + * + * @param e an event containing information about the key release + */ +public void keyReleased(KeyEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuAdapter.java index 209a35353b..e089640377 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuAdapter.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>MenuListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>MenuEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see MenuListener
- * @see MenuEvent
- */
-public abstract class MenuAdapter implements MenuListener {
-
-/**
- * Sent when a menu is hidden.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the menu operation
- */
-public void menuHidden(MenuEvent e) {
-}
-
-/**
- * Sent when a menu is shown.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the menu operation
- */
-public void menuShown(MenuEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>MenuListener</code> interface. + * <p> + * Classes that wish to deal with <code>MenuEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see MenuListener + * @see MenuEvent + */ +public abstract class MenuAdapter implements MenuListener { + +/** + * Sent when a menu is hidden. + * The default behavior is to do nothing. + * + * @param e an event containing information about the menu operation + */ +public void menuHidden(MenuEvent e) { +} + +/** + * Sent when a menu is shown. + * The default behavior is to do nothing. + * + * @param e an event containing information about the menu operation + */ +public void menuShown(MenuEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuEvent.java index 4f4878e5cd..1a836492ed 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * menus being shown and hidden.
- *
- * @see MenuListener
- */
-
-public final class MenuEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public MenuEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * menus being shown and hidden. + * + * @see MenuListener + */ + +public final class MenuEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public MenuEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuListener.java index 6dab527839..ae53b2ce09 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MenuListener.java @@ -1,42 +1,42 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the hiding and showing of menus.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addMenuListener</code> method and removed using
- * the <code>removeMenuListener</code> method. When a
- * menu is hidden or shown, the appropriate method will
- * be invoked.
- * </p>
- *
- * @see MenuAdapter
- * @see MenuEvent
- */
-public interface MenuListener extends SWTEventListener {
-
-/**
- * Sent when a menu is hidden.
- *
- * @param e an event containing information about the menu operation
- */
-public void menuHidden(MenuEvent e);
-
-/**
- * Sent when a menu is shown.
- *
- * @param e an event containing information about the menu operation
- */
-public void menuShown(MenuEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the hiding and showing of menus. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addMenuListener</code> method and removed using + * the <code>removeMenuListener</code> method. When a + * menu is hidden or shown, the appropriate method will + * be invoked. + * </p> + * + * @see MenuAdapter + * @see MenuEvent + */ +public interface MenuListener extends SWTEventListener { + +/** + * Sent when a menu is hidden. + * + * @param e an event containing information about the menu operation + */ +public void menuHidden(MenuEvent e); + +/** + * Sent when a menu is shown. + * + * @param e an event containing information about the menu operation + */ +public void menuShown(MenuEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyEvent.java index 35c2637318..11f3575ed4 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * text being modified.
- *
- * @see ModifyListener
- */
-
-public final class ModifyEvent extends TypedEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public ModifyEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * text being modified. + * + * @see ModifyListener + */ + +public final class ModifyEvent extends TypedEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public ModifyEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyListener.java index a32f26e7c0..440b19e99b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ModifyListener.java @@ -1,34 +1,34 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the events that are generated when text
- * is modified.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a text widget using the
- * <code>addModifyListener</code> method and removed using
- * the <code>removeModifyListener</code> method. When the
- * text is modified, the modifyText method will be invoked.
- * </p>
- *
- * @see ModifyEvent
- */
-public interface ModifyListener extends SWTEventListener {
-
-/**
- * Sent when the text is modified.
- *
- * @param e an event containing information about the modify
- */
-public void modifyText(ModifyEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the events that are generated when text + * is modified. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a text widget using the + * <code>addModifyListener</code> method and removed using + * the <code>removeModifyListener</code> method. When the + * text is modified, the modifyText method will be invoked. + * </p> + * + * @see ModifyEvent + */ +public interface ModifyListener extends SWTEventListener { + +/** + * Sent when the text is modified. + * + * @param e an event containing information about the modify + */ +public void modifyText(ModifyEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseAdapter.java index 9ba388ea78..7f6bea71db 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseAdapter.java @@ -1,54 +1,54 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>MouseListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>MouseEvent</code>s
- * which occur as mouse buttons are pressed and released can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see MouseListener
- * @see MouseEvent
- */
-public abstract class MouseAdapter implements MouseListener {
-
-/**
- * Sent when a mouse button is pressed twice within the
- * (operating system specified) double click period.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the mouse double click
- *
- * @see org.eclipse.swt.widgets.Display#getDoubleClickTime
- */
-public void mouseDoubleClick(MouseEvent e) {
-}
-
-/**
- * Sent when a mouse button is pressed.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the mouse button press
- */
-public void mouseDown(MouseEvent e) {
-}
-
-/**
- * Sent when a mouse button is released.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the mouse button release
- */
-public void mouseUp(MouseEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>MouseListener</code> interface. + * <p> + * Classes that wish to deal with <code>MouseEvent</code>s + * which occur as mouse buttons are pressed and released can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see MouseListener + * @see MouseEvent + */ +public abstract class MouseAdapter implements MouseListener { + +/** + * Sent when a mouse button is pressed twice within the + * (operating system specified) double click period. + * The default behavior is to do nothing. + * + * @param e an event containing information about the mouse double click + * + * @see org.eclipse.swt.widgets.Display#getDoubleClickTime + */ +public void mouseDoubleClick(MouseEvent e) { +} + +/** + * Sent when a mouse button is pressed. + * The default behavior is to do nothing. + * + * @param e an event containing information about the mouse button press + */ +public void mouseDown(MouseEvent e) { +} + +/** + * Sent when a mouse button is released. + * The default behavior is to do nothing. + * + * @param e an event containing information about the mouse button release + */ +public void mouseUp(MouseEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseEvent.java index a4b6c71ba1..b03ef7a048 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseEvent.java @@ -1,70 +1,70 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent whenever mouse
- * related actions occur. This includes mouse buttons
- * being pressed and released, the mouse pointer being
- * moved and the mouse pointer crossing widget boundaries.
- * <p>
- * Note: The <code>button</code> field is an integer that
- * represents the mouse button number. This is not the same
- * as the <code>SWT</code> mask constants <code>BUTTONx</code>.
- * </p>
- *
- * @see MouseListener
- * @see MouseMoveListener
- * @see MouseTrackListener
- */
-
-public final class MouseEvent extends TypedEvent {
-
- /**
- * the button that was pressed or released; 1 for the
- * first button, 2 for the second button, and 3 for the
- * third button, etc.
- */
- public int button;
-
- /**
- * the state of the keyboard modifier keys at the time
- * the event was generated
- */
- public int stateMask;
-
- /**
- * the widget-relative, x coordinate of the pointer
- * at the time the mouse button was pressed or released
- */
- public int x;
-
- /**
- * the widget-relative, y coordinate of the pointer
- * at the time the mouse button was pressed or released
- */
- public int y;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public MouseEvent(Event e) {
- super(e);
- this.x = e.x;
- this.y = e.y;
- this.button = e.button;
- this.stateMask = e.stateMask;
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent whenever mouse + * related actions occur. This includes mouse buttons + * being pressed and released, the mouse pointer being + * moved and the mouse pointer crossing widget boundaries. + * <p> + * Note: The <code>button</code> field is an integer that + * represents the mouse button number. This is not the same + * as the <code>SWT</code> mask constants <code>BUTTONx</code>. + * </p> + * + * @see MouseListener + * @see MouseMoveListener + * @see MouseTrackListener + */ + +public final class MouseEvent extends TypedEvent { + + /** + * the button that was pressed or released; 1 for the + * first button, 2 for the second button, and 3 for the + * third button, etc. + */ + public int button; + + /** + * the state of the keyboard modifier keys at the time + * the event was generated + */ + public int stateMask; + + /** + * the widget-relative, x coordinate of the pointer + * at the time the mouse button was pressed or released + */ + public int x; + + /** + * the widget-relative, y coordinate of the pointer + * at the time the mouse button was pressed or released + */ + public int y; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public MouseEvent(Event e) { + super(e); + this.x = e.x; + this.y = e.y; + this.button = e.button; + this.stateMask = e.stateMask; +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseListener.java index 704d58e1ff..35170ccd2e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseListener.java @@ -1,53 +1,53 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated as mouse buttons
- * are pressed.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addMouseListener</code> method and removed using
- * the <code>removeMouseListener</code> method. When a
- * mouse button is pressed or released, the appropriate method
- * will be invoked.
- * </p>
- *
- * @see MouseAdapter
- * @see MouseEvent
- */
-public interface MouseListener extends SWTEventListener {
-
-/**
- * Sent when a mouse button is pressed twice within the
- * (operating system specified) double click period.
- *
- * @param e an event containing information about the mouse double click
- *
- * @see org.eclipse.swt.widgets.Display#getDoubleClickTime
- */
-public void mouseDoubleClick(MouseEvent e);
-
-/**
- * Sent when a mouse button is pressed.
- *
- * @param e an event containing information about the mouse button press
- */
-public void mouseDown(MouseEvent e);
-
-/**
- * Sent when a mouse button is released.
- *
- * @param e an event containing information about the mouse button release
- */
-public void mouseUp(MouseEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated as mouse buttons + * are pressed. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addMouseListener</code> method and removed using + * the <code>removeMouseListener</code> method. When a + * mouse button is pressed or released, the appropriate method + * will be invoked. + * </p> + * + * @see MouseAdapter + * @see MouseEvent + */ +public interface MouseListener extends SWTEventListener { + +/** + * Sent when a mouse button is pressed twice within the + * (operating system specified) double click period. + * + * @param e an event containing information about the mouse double click + * + * @see org.eclipse.swt.widgets.Display#getDoubleClickTime + */ +public void mouseDoubleClick(MouseEvent e); + +/** + * Sent when a mouse button is pressed. + * + * @param e an event containing information about the mouse button press + */ +public void mouseDown(MouseEvent e); + +/** + * Sent when a mouse button is released. + * + * @param e an event containing information about the mouse button release + */ +public void mouseUp(MouseEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseMoveListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseMoveListener.java index a1338afa50..838057ceb4 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseMoveListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseMoveListener.java @@ -1,34 +1,34 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the events that are generated as the mouse
- * pointer moves.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addMouseMoveListener</code> method and removed using
- * the <code>removeMouseMoveListener</code> method. As the
- * mouse moves, the mouseMove method will be invoked.
- * </p>
- *
- * @see MouseEvent
- */
-public interface MouseMoveListener extends SWTEventListener {
-
-/**
- * Sent when the mouse moves.
- *
- * @param e an event containing information about the mouse move
- */
-public void mouseMove(MouseEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the events that are generated as the mouse + * pointer moves. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addMouseMoveListener</code> method and removed using + * the <code>removeMouseMoveListener</code> method. As the + * mouse moves, the mouseMove method will be invoked. + * </p> + * + * @see MouseEvent + */ +public interface MouseMoveListener extends SWTEventListener { + +/** + * Sent when the mouse moves. + * + * @param e an event containing information about the mouse move + */ +public void mouseMove(MouseEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackAdapter.java index 172ff0f66c..1b5cbae896 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackAdapter.java @@ -1,55 +1,55 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>MouseTrackListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>MouseEvent</code>s which
- * occur as the mouse pointer passes (or hovers) over controls can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see MouseTrackListener
- * @see MouseEvent
- */
-public class MouseTrackAdapter implements MouseTrackListener {
-
-/**
- * Sent when the mouse pointer passes into the area of
- * the screen covered by a control.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the mouse enter
- */
-public void mouseEnter(MouseEvent e) {
-}
-
-/**
- * Sent when the mouse pointer passes out of the area of
- * the screen covered by a control.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the mouse exit
- */
-public void mouseExit(MouseEvent e) {
-}
-
-/**
- * Sent when the mouse pointer hovers (that is, stops moving
- * for an (operating system specified) period of time) over
- * a control.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the hover
- */
-public void mouseHover(MouseEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>MouseTrackListener</code> interface. + * <p> + * Classes that wish to deal with <code>MouseEvent</code>s which + * occur as the mouse pointer passes (or hovers) over controls can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see MouseTrackListener + * @see MouseEvent + */ +public class MouseTrackAdapter implements MouseTrackListener { + +/** + * Sent when the mouse pointer passes into the area of + * the screen covered by a control. + * The default behavior is to do nothing. + * + * @param e an event containing information about the mouse enter + */ +public void mouseEnter(MouseEvent e) { +} + +/** + * Sent when the mouse pointer passes out of the area of + * the screen covered by a control. + * The default behavior is to do nothing. + * + * @param e an event containing information about the mouse exit + */ +public void mouseExit(MouseEvent e) { +} + +/** + * Sent when the mouse pointer hovers (that is, stops moving + * for an (operating system specified) period of time) over + * a control. + * The default behavior is to do nothing. + * + * @param e an event containing information about the hover + */ +public void mouseHover(MouseEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackListener.java index b82e5eae9d..e6ba65f6fa 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/MouseTrackListener.java @@ -1,55 +1,55 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated as the mouse
- * pointer passes (or hovers) over controls.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addMouseTrackListener</code> method and removed using
- * the <code>removeMouseTrackListener</code> method. When the
- * mouse pointer passes into or out of the area of the screen
- * covered by a control or pauses while over a control, the
- * appropriate method will be invoked.
- * </p>
- *
- * @see MouseTrackAdapter
- * @see MouseEvent
- */
-public interface MouseTrackListener extends SWTEventListener {
-
-/**
- * Sent when the mouse pointer passes into the area of
- * the screen covered by a control.
- *
- * @param e an event containing information about the mouse enter
- */
-public void mouseEnter(MouseEvent e);
-
-/**
- * Sent when the mouse pointer passes out of the area of
- * the screen covered by a control.
- *
- * @param e an event containing information about the mouse exit
- */
-public void mouseExit(MouseEvent e);
-
-/**
- * Sent when the mouse pointer hovers (that is, stops moving
- * for an (operating system specified) period of time) over
- * a control.
- *
- * @param e an event containing information about the hover
- */
-public void mouseHover(MouseEvent e);
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated as the mouse + * pointer passes (or hovers) over controls. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addMouseTrackListener</code> method and removed using + * the <code>removeMouseTrackListener</code> method. When the + * mouse pointer passes into or out of the area of the screen + * covered by a control or pauses while over a control, the + * appropriate method will be invoked. + * </p> + * + * @see MouseTrackAdapter + * @see MouseEvent + */ +public interface MouseTrackListener extends SWTEventListener { + +/** + * Sent when the mouse pointer passes into the area of + * the screen covered by a control. + * + * @param e an event containing information about the mouse enter + */ +public void mouseEnter(MouseEvent e); + +/** + * Sent when the mouse pointer passes out of the area of + * the screen covered by a control. + * + * @param e an event containing information about the mouse exit + */ +public void mouseExit(MouseEvent e); + +/** + * Sent when the mouse pointer hovers (that is, stops moving + * for an (operating system specified) period of time) over + * a control. + * + * @param e an event containing information about the hover + */ +public void mouseHover(MouseEvent e); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintEvent.java index 3231819e8d..16b0ca2e5c 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintEvent.java @@ -1,78 +1,78 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.graphics.GC;
-
-/**
- * Instances of this class are sent as a result of
- * visible areas of controls requiring re-painting.
- *
- * @see PaintListener
- */
-
-public final class PaintEvent extends TypedEvent {
-
- /**
- * the graphics context to use when painting
- * that is configured to use the colors, font and
- * damaged region of the control. It is valid
- * only during the paint and must not be disposed
- */
- public GC gc;
-
- /**
- * the x offset of the bounding rectangle of the
- * region that requires painting
- */
- public int x;
-
- /**
- * the y offset of the bounding rectangle of the
- * region that requires painting
- */
- public int y;
-
- /**
- * the width of the bounding rectangle of the
- * region that requires painting
- */
- public int width;
-
- /**
- * the height of the bounding rectangle of the
- * region that requires painting
- */
- public int height;
-
- /**
- * the number of following paint events which
- * are pending which may always be zero on
- * some platforms
- */
- public int count;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public PaintEvent(Event e) {
- super(e);
- this.gc = e.gc;
- this.x = e.x;
- this.y = e.y;
- this.width = e.width;
- this.height = e.height;
- this.count = e.count;
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.graphics.GC; + +/** + * Instances of this class are sent as a result of + * visible areas of controls requiring re-painting. + * + * @see PaintListener + */ + +public final class PaintEvent extends TypedEvent { + + /** + * the graphics context to use when painting + * that is configured to use the colors, font and + * damaged region of the control. It is valid + * only during the paint and must not be disposed + */ + public GC gc; + + /** + * the x offset of the bounding rectangle of the + * region that requires painting + */ + public int x; + + /** + * the y offset of the bounding rectangle of the + * region that requires painting + */ + public int y; + + /** + * the width of the bounding rectangle of the + * region that requires painting + */ + public int width; + + /** + * the height of the bounding rectangle of the + * region that requires painting + */ + public int height; + + /** + * the number of following paint events which + * are pending which may always be zero on + * some platforms + */ + public int count; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public PaintEvent(Event e) { + super(e); + this.gc = e.gc; + this.x = e.x; + this.y = e.y; + this.width = e.width; + this.height = e.height; + this.count = e.count; +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintListener.java index f8ae91bc58..8e15870f60 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/PaintListener.java @@ -1,35 +1,35 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated when the
- * control needs to be painted.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addPaintListener</code> method and removed using
- * the <code>removePaintListener</code> method. When a
- * paint event occurs, the paintControl method will be
- * invoked.
- * </p>
- *
- * @see PaintEvent
- */
-public interface PaintListener extends SWTEventListener {
-
-/**
- * Sent when a paint event occurs for the control.
- *
- * @param e an event containing information about the paint
- */
-public void paintControl(PaintEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated when the + * control needs to be painted. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addPaintListener</code> method and removed using + * the <code>removePaintListener</code> method. When a + * paint event occurs, the paintControl method will be + * invoked. + * </p> + * + * @see PaintEvent + */ +public interface PaintListener extends SWTEventListener { + +/** + * Sent when a paint event occurs for the control. + * + * @param e an event containing information about the paint + */ +public void paintControl(PaintEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionAdapter.java index c4773a5f39..b5ffd2538d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionAdapter.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>SelectionListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>SelectionEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see SelectionListener
- * @see SelectionEvent
- */
-public abstract class SelectionAdapter implements SelectionListener {
-
-/**
- * Sent when selection occurs in the control.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the selection
- */
-public void widgetSelected(SelectionEvent e) {
-}
-
-/**
- * Sent when default selection occurs in the control.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the default selection
- */
-public void widgetDefaultSelected(SelectionEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>SelectionListener</code> interface. + * <p> + * Classes that wish to deal with <code>SelectionEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see SelectionListener + * @see SelectionEvent + */ +public abstract class SelectionAdapter implements SelectionListener { + +/** + * Sent when selection occurs in the control. + * The default behavior is to do nothing. + * + * @param e an event containing information about the selection + */ +public void widgetSelected(SelectionEvent e) { +} + +/** + * Sent when default selection occurs in the control. + * The default behavior is to do nothing. + * + * @param e an event containing information about the default selection + */ +public void widgetDefaultSelected(SelectionEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionEvent.java index 6567ebb84c..9973a17bdf 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionEvent.java @@ -1,99 +1,99 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.*;
-
-/**
- * Instances of this class are sent as a result of
- * widgets being selected.
- * <p>
- * Note: The fields that are filled in depend on the widget.
- * </p>
- *
- * @see SelectionListener
- */
-
-public class SelectionEvent extends TypedEvent {
-
- /**
- * the item that was selected
- */
- public Widget item;
-
- /**
- * extra detail information about the selection, depending on the widget
- * <p><b>Sash</b><ul>
- * <li>{@link SWT#DRAG}</li>
- * </ul></p><p><b>ScrollBar and Slider</b><ul>
- * <li>{@link SWT#DRAG}</li>
- * <li>{@link SWT#HOME}</li>
- * <li>{@link SWT#END}</li>
- * <li>{@link SWT#ARROW_DOWN}</li>
- * <li>{@link SWT#ARROW_UP}</li>
- * <li>{@link SWT#PAGE_DOWN}</li>
- * <li>{@link SWT#PAGE_UP}</li>
- * </ul></p><p><b>Table, Tree and TableTree</b><ul>
- * <li>{@link SWT#CHECK}</li>
- * </ul></p><p><b>CoolItem and ToolItem</b><ul>
- * <li>{@link SWT#ARROW}</li>
- * </ul></p>
- */
- public int detail;
-
- /**
- * the x location of the selected area
- */
- public int x;
-
- /**
- * the y location of selected area
- */
- public int y;
-
- /**
- * the width of selected area
- */
- public int width;
-
- /**
- * the height of selected area
- */
- public int height;
-
- /**
- * the state of the keyboard modifier keys at the time
- * the event was generated.
- */
- public int stateMask;
-
- /**
- * a flag indicating whether the operation should be allowed
- */
- public boolean doit;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public SelectionEvent(Event e) {
- super(e);
- this.item = e.item;
- this.x = e.x;
- this.y = e.y;
- this.width = e.width;
- this.height = e.height;
- this.detail = e.detail;
- this.stateMask = e.stateMask;
- this.doit = e.doit;
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.*; + +/** + * Instances of this class are sent as a result of + * widgets being selected. + * <p> + * Note: The fields that are filled in depend on the widget. + * </p> + * + * @see SelectionListener + */ + +public class SelectionEvent extends TypedEvent { + + /** + * the item that was selected + */ + public Widget item; + + /** + * extra detail information about the selection, depending on the widget + * <p><b>Sash</b><ul> + * <li>{@link SWT#DRAG}</li> + * </ul></p><p><b>ScrollBar and Slider</b><ul> + * <li>{@link SWT#DRAG}</li> + * <li>{@link SWT#HOME}</li> + * <li>{@link SWT#END}</li> + * <li>{@link SWT#ARROW_DOWN}</li> + * <li>{@link SWT#ARROW_UP}</li> + * <li>{@link SWT#PAGE_DOWN}</li> + * <li>{@link SWT#PAGE_UP}</li> + * </ul></p><p><b>Table, Tree and TableTree</b><ul> + * <li>{@link SWT#CHECK}</li> + * </ul></p><p><b>CoolItem and ToolItem</b><ul> + * <li>{@link SWT#ARROW}</li> + * </ul></p> + */ + public int detail; + + /** + * the x location of the selected area + */ + public int x; + + /** + * the y location of selected area + */ + public int y; + + /** + * the width of selected area + */ + public int width; + + /** + * the height of selected area + */ + public int height; + + /** + * the state of the keyboard modifier keys at the time + * the event was generated. + */ + public int stateMask; + + /** + * a flag indicating whether the operation should be allowed + */ + public boolean doit; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public SelectionEvent(Event e) { + super(e); + this.item = e.item; + this.x = e.x; + this.y = e.y; + this.width = e.width; + this.height = e.height; + this.detail = e.detail; + this.stateMask = e.stateMask; + this.doit = e.doit; +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionListener.java index a782fa697c..522abb37f3 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/SelectionListener.java @@ -1,52 +1,52 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the events that are generated when selection
- * occurs in a control.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addSelectionListener</code> method and removed using
- * the <code>removeSelectionListener</code> method. When
- * selection occurs in a control the appropriate method
- * will be invoked.
- * </p>
- *
- * @see SelectionAdapter
- * @see SelectionEvent
- */
-public interface SelectionListener extends SWTEventListener {
-
-/**
- * Sent when selection occurs in the control.
- * <p>
- * For example, on some platforms selection occurs in
- * a List when the user selects an item or items.
- * </p>
- *
- * @param e an event containing information about the selection
- */
-public void widgetSelected(SelectionEvent e);
-
-/**
- * Sent when default selection occurs in the control.
- * <p>
- * For example, on some platforms default selection occurs
- * in a List when the user double-clicks an item or types
- * return in a Text.
- * </p>
- *
- * @param e an event containing information about the default selection
- */
-public void widgetDefaultSelected(SelectionEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the events that are generated when selection + * occurs in a control. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addSelectionListener</code> method and removed using + * the <code>removeSelectionListener</code> method. When + * selection occurs in a control the appropriate method + * will be invoked. + * </p> + * + * @see SelectionAdapter + * @see SelectionEvent + */ +public interface SelectionListener extends SWTEventListener { + +/** + * Sent when selection occurs in the control. + * <p> + * For example, on some platforms selection occurs in + * a List when the user selects an item or items. + * </p> + * + * @param e an event containing information about the selection + */ +public void widgetSelected(SelectionEvent e); + +/** + * Sent when default selection occurs in the control. + * <p> + * For example, on some platforms default selection occurs + * in a List when the user double-clicks an item or types + * return in a Text. + * </p> + * + * @param e an event containing information about the default selection + */ +public void widgetDefaultSelected(SelectionEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellAdapter.java index 99af81306d..edbbdaef53 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellAdapter.java @@ -1,68 +1,68 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>ShellListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>ShellEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see ShellListener
- * @see ShellEvent
- */
-public abstract class ShellAdapter implements ShellListener {
-
-/**
- * Sent when a shell becomes the active window.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the activation
- */
-public void shellActivated(ShellEvent e) {
-}
-
-/**
- * Sent when a shell is closed.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the close
- */
-public void shellClosed(ShellEvent e) {
-}
-
-/**
- * Sent when a shell stops being the active window.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the deactivation
- */
-public void shellDeactivated(ShellEvent e) {
-}
-
-/**
- * Sent when a shell is un-minimized.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the un-minimization
- */
-public void shellDeiconified(ShellEvent e) {
-}
-
-/**
- * Sent when a shell is minimized.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the minimization
- */
-public void shellIconified(ShellEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>ShellListener</code> interface. + * <p> + * Classes that wish to deal with <code>ShellEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see ShellListener + * @see ShellEvent + */ +public abstract class ShellAdapter implements ShellListener { + +/** + * Sent when a shell becomes the active window. + * The default behavior is to do nothing. + * + * @param e an event containing information about the activation + */ +public void shellActivated(ShellEvent e) { +} + +/** + * Sent when a shell is closed. + * The default behavior is to do nothing. + * + * @param e an event containing information about the close + */ +public void shellClosed(ShellEvent e) { +} + +/** + * Sent when a shell stops being the active window. + * The default behavior is to do nothing. + * + * @param e an event containing information about the deactivation + */ +public void shellDeactivated(ShellEvent e) { +} + +/** + * Sent when a shell is un-minimized. + * The default behavior is to do nothing. + * + * @param e an event containing information about the un-minimization + */ +public void shellDeiconified(ShellEvent e) { +} + +/** + * Sent when a shell is minimized. + * The default behavior is to do nothing. + * + * @param e an event containing information about the minimization + */ +public void shellIconified(ShellEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellEvent.java index 7bd0a87eed..5156f48443 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * operations being performed on shells.
- *
- * @see ShellListener
- */
-
-public final class ShellEvent extends TypedEvent {
-
- /**
- * a flag indicating whether the operation should be allowed
- */
- public boolean doit;
-
-public ShellEvent(Event e) {
- super(e);
- this.doit = e.doit;
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * operations being performed on shells. + * + * @see ShellListener + */ + +public final class ShellEvent extends TypedEvent { + + /** + * a flag indicating whether the operation should be allowed + */ + public boolean doit; + +public ShellEvent(Event e) { + super(e); + this.doit = e.doit; +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellListener.java index d118fde7be..85ffb47973 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/ShellListener.java @@ -1,63 +1,63 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with changes in state of <code>Shell</code>s.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addShellListener</code> method and removed using
- * the <code>removeShellListener</code> method. When the
- * state of a shell changes, the appropriate method will
- * be invoked.
- * </p>
- *
- * @see ShellAdapter
- * @see ShellEvent
- */
-public interface ShellListener extends SWTEventListener {
-
-/**
- * Sent when a shell becomes the active window.
- *
- * @param e an event containing information about the activation
- */
-public void shellActivated(ShellEvent e);
-
-/**
- * Sent when a shell is closed.
- *
- * @param e an event containing information about the close
- */
-public void shellClosed(ShellEvent e);
-
-/**
- * Sent when a shell stops being the active window.
- *
- * @param e an event containing information about the deactivation
- */
-public void shellDeactivated(ShellEvent e);
-
-/**
- * Sent when a shell is un-minimized.
- *
- * @param e an event containing information about the un-minimization
- */
-public void shellDeiconified(ShellEvent e);
-
-/**
- * Sent when a shell is minimized.
- *
- * @param e an event containing information about the minimization
- */
-public void shellIconified(ShellEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with changes in state of <code>Shell</code>s. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addShellListener</code> method and removed using + * the <code>removeShellListener</code> method. When the + * state of a shell changes, the appropriate method will + * be invoked. + * </p> + * + * @see ShellAdapter + * @see ShellEvent + */ +public interface ShellListener extends SWTEventListener { + +/** + * Sent when a shell becomes the active window. + * + * @param e an event containing information about the activation + */ +public void shellActivated(ShellEvent e); + +/** + * Sent when a shell is closed. + * + * @param e an event containing information about the close + */ +public void shellClosed(ShellEvent e); + +/** + * Sent when a shell stops being the active window. + * + * @param e an event containing information about the deactivation + */ +public void shellDeactivated(ShellEvent e); + +/** + * Sent when a shell is un-minimized. + * + * @param e an event containing information about the un-minimization + */ +public void shellDeiconified(ShellEvent e); + +/** + * Sent when a shell is minimized. + * + * @param e an event containing information about the minimization + */ +public void shellIconified(ShellEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseEvent.java index 90181c3ec1..18faee5489 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseEvent.java @@ -1,123 +1,123 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.*;
-
-/**
- * Instances of this class are sent as a result of
- * widget traversal actions.
- * <p>
- * The traversal event allows fine control over keyboard traversal
- * in a control both to implement traversal and override the default
- * traversal behavior defined by the system. This is achieved using
- * two fields, <code>detail</code> and <code>doit</code>.
- * </p><p>
- * When a control is traversed, a traverse event is sent. The detail
- * describes the type of traversal and the doit indicates the default
- * behavior of the system. For example, when a right arrow key is pressed
- * in a text control, the detail field is <code>TRAVERSE_ARROW_NEXT</code>
- * and the doit field is <code>false</code>, indicating that the system
- * will not traverse to the next tab item and the arrow key will be
- * delivered to the text control. If the same key is pressed in a radio
- * button, the doit field will be <code>true</code>, indicating that
- * traversal is to proceed to the next tab item, possibly another
- * radio button in the group and that the arrow key is not be delivered
- * to the radio button.
- * </p><p>
- * How can the traversal event be used to implement traversal?
- * When a tab key is pressed in a canvas, the detail field will be
- * <code>TRAVERSE_TAB_NEXT</code> and the doit field will be
- * <code>false</code>. The default behavior of the system is to
- * provide no traversal for canvas controls. This means that by
- * default in a canvas, a key listener will see every key that
- * user types, including traversal keys. To understand why this
- * is so, it is important to understand that only the widget implementor
- * can decide which traversal is appropriate for the widget. Returning
- * to the <code>TRAVERSE_TAB_NEXT</code> example, a text widget implemented
- * by a canvas, would typically want to use the tab key to insert a
- * tab character into the widget. A list widget implementation, on the
- * other hand, would like the system default traversal behavior. Using
- * only the doit flag, both implementations are possible. The text widget
- * implementor sets doit to <code>false</false>, ensuring that the system
- * will not traverse and that the tab key will be delivered to key listeners.
- * The list widget implementor sets doit to <code>true</code>, indicating
- * that the system should perform tab traversal and that the key should not
- * be delivered to the list widget.
- * </p><p>
- * How can the traversal event be used to override system traversal?
- * When the return key is pressed in a single line text control, the
- * detail field is be <code>TRAVERSE_RETURN</code> and the doit field
- * is <code>true</code>. This means that the return key will processed
- * by the default button, not the text widget. If the text widget has
- * a default selection listener, it will not run because the return key
- * will be processed by the default button. Imagine that the text control
- * is being used as an in-place editor and return is used to dispose the
- * widget. Setting doit to <code>false</code> will stop the system from
- * activating the default button but the key will be delivered to the text
- * control, running the key and selection listeners for the text. How
- * can <code>TRAVERSE_RETURN be implemented so that the default button
- * will not be activated and the text widget will not see the return key?
- * This is achieved by setting doit to <code>true</code>, and the detail
- * to <code>TRAVERSE_NONE</code>.
- * </p><p>
- * Note: A widget implementor will typically implement traversal using
- * only the doit flag to either enable or disable system traversal.
- * </p>
- *
- * @see TraverseListener
- */
-
-public class TraverseEvent extends KeyEvent {
-
- /**
- * the type of traversal
- * <p><ul>
- * <li>{@link SWT#TRAVERSE_NONE}</li>
- * <li>{@link SWT#TRAVERSE_ESCAPE}</li>
- * <li>{@link SWT#TRAVERSE_RETURN}</li>
- * <li>{@link SWT#TRAVERSE_TAB_NEXT}</li>
- * <li>{@link SWT#TRAVERSE_TAB_PREVIOUS}</li>
- * <li>{@link SWT#TRAVERSE_ARROW_NEXT}</li>
- * <li>{@link SWT#TRAVERSE_ARROW_PREVIOUS}</li>
- * <li>{@link SWT#TRAVERSE_MNEMONIC}</li>
- * <li>{@link SWT#TRAVERSE_PAGE_NEXT}</li>
- * <li>{@link SWT#TRAVERSE_PAGE_PREVIOUS}</li>
- * </ul></p>
- *
- * Setting this field will change the type of traversal.
- * For example, setting the detail to <code>TRAVERSE_NONE</code>
- * causes no traversal action to be taked. The traversal detail,
- * in conjuction with the <code>doit</code> field can be useful
- * when overriding the default traversal mechanism for a control.
- *
- */
- public int detail;
-
- /**
- * a flag indicating whether the operation should be allowed.
- * Setting this field to <code>false</code> will cancel the operation
- * and allow the traversal key stroke to be delivered to the control.
- * A value of true indicates that the traversal, described by the
- * traversal <code>detail</code> is to be performed.
- */
- public boolean doit;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public TraverseEvent(Event e) {
- super(e);
- this.doit = e.doit;
- this.detail = e.detail;
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.*; + +/** + * Instances of this class are sent as a result of + * widget traversal actions. + * <p> + * The traversal event allows fine control over keyboard traversal + * in a control both to implement traversal and override the default + * traversal behavior defined by the system. This is achieved using + * two fields, <code>detail</code> and <code>doit</code>. + * </p><p> + * When a control is traversed, a traverse event is sent. The detail + * describes the type of traversal and the doit indicates the default + * behavior of the system. For example, when a right arrow key is pressed + * in a text control, the detail field is <code>TRAVERSE_ARROW_NEXT</code> + * and the doit field is <code>false</code>, indicating that the system + * will not traverse to the next tab item and the arrow key will be + * delivered to the text control. If the same key is pressed in a radio + * button, the doit field will be <code>true</code>, indicating that + * traversal is to proceed to the next tab item, possibly another + * radio button in the group and that the arrow key is not be delivered + * to the radio button. + * </p><p> + * How can the traversal event be used to implement traversal? + * When a tab key is pressed in a canvas, the detail field will be + * <code>TRAVERSE_TAB_NEXT</code> and the doit field will be + * <code>false</code>. The default behavior of the system is to + * provide no traversal for canvas controls. This means that by + * default in a canvas, a key listener will see every key that + * user types, including traversal keys. To understand why this + * is so, it is important to understand that only the widget implementor + * can decide which traversal is appropriate for the widget. Returning + * to the <code>TRAVERSE_TAB_NEXT</code> example, a text widget implemented + * by a canvas, would typically want to use the tab key to insert a + * tab character into the widget. A list widget implementation, on the + * other hand, would like the system default traversal behavior. Using + * only the doit flag, both implementations are possible. The text widget + * implementor sets doit to <code>false</false>, ensuring that the system + * will not traverse and that the tab key will be delivered to key listeners. + * The list widget implementor sets doit to <code>true</code>, indicating + * that the system should perform tab traversal and that the key should not + * be delivered to the list widget. + * </p><p> + * How can the traversal event be used to override system traversal? + * When the return key is pressed in a single line text control, the + * detail field is be <code>TRAVERSE_RETURN</code> and the doit field + * is <code>true</code>. This means that the return key will processed + * by the default button, not the text widget. If the text widget has + * a default selection listener, it will not run because the return key + * will be processed by the default button. Imagine that the text control + * is being used as an in-place editor and return is used to dispose the + * widget. Setting doit to <code>false</code> will stop the system from + * activating the default button but the key will be delivered to the text + * control, running the key and selection listeners for the text. How + * can <code>TRAVERSE_RETURN be implemented so that the default button + * will not be activated and the text widget will not see the return key? + * This is achieved by setting doit to <code>true</code>, and the detail + * to <code>TRAVERSE_NONE</code>. + * </p><p> + * Note: A widget implementor will typically implement traversal using + * only the doit flag to either enable or disable system traversal. + * </p> + * + * @see TraverseListener + */ + +public class TraverseEvent extends KeyEvent { + + /** + * the type of traversal + * <p><ul> + * <li>{@link SWT#TRAVERSE_NONE}</li> + * <li>{@link SWT#TRAVERSE_ESCAPE}</li> + * <li>{@link SWT#TRAVERSE_RETURN}</li> + * <li>{@link SWT#TRAVERSE_TAB_NEXT}</li> + * <li>{@link SWT#TRAVERSE_TAB_PREVIOUS}</li> + * <li>{@link SWT#TRAVERSE_ARROW_NEXT}</li> + * <li>{@link SWT#TRAVERSE_ARROW_PREVIOUS}</li> + * <li>{@link SWT#TRAVERSE_MNEMONIC}</li> + * <li>{@link SWT#TRAVERSE_PAGE_NEXT}</li> + * <li>{@link SWT#TRAVERSE_PAGE_PREVIOUS}</li> + * </ul></p> + * + * Setting this field will change the type of traversal. + * For example, setting the detail to <code>TRAVERSE_NONE</code> + * causes no traversal action to be taked. The traversal detail, + * in conjuction with the <code>doit</code> field can be useful + * when overriding the default traversal mechanism for a control. + * + */ + public int detail; + + /** + * a flag indicating whether the operation should be allowed. + * Setting this field to <code>false</code> will cancel the operation + * and allow the traversal key stroke to be delivered to the control. + * A value of true indicates that the traversal, described by the + * traversal <code>detail</code> is to be performed. + */ + public boolean doit; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public TraverseEvent(Event e) { + super(e); + this.doit = e.doit; + this.detail = e.detail; +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseListener.java index 95d4d94714..a8c6bd3a95 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TraverseListener.java @@ -1,42 +1,42 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the events that are generated when a
- * traverse event occurs in a control.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addTraverseListener</code> method and removed using
- * the <code>removeTraverseListener</code> method. When a
- * traverse event occurs in a control, the keyTraversed method
- * will be invoked.
- * </p>
- *
- * @see TraverseEvent
- */
-public interface TraverseListener extends SWTEventListener {
-
-/**
- * Sent when a traverse event occurs in a control.
- * <p>
- * A traverse event occurs when the user presses a traversal
- * key. Traversal keys are typically tab and arrow keys, along
- * with certain other keys on some platforms. Traversal key
- * constants beginning with <code>TRAVERSE_</code> are defined
- * in the <code>SWT</code> class.
- * </p>
- *
- * @param e an event containing information about the traverse
- */
-public void keyTraversed(TraverseEvent e);
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the events that are generated when a + * traverse event occurs in a control. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addTraverseListener</code> method and removed using + * the <code>removeTraverseListener</code> method. When a + * traverse event occurs in a control, the keyTraversed method + * will be invoked. + * </p> + * + * @see TraverseEvent + */ +public interface TraverseListener extends SWTEventListener { + +/** + * Sent when a traverse event occurs in a control. + * <p> + * A traverse event occurs when the user presses a traversal + * key. Traversal keys are typically tab and arrow keys, along + * with certain other keys on some platforms. Traversal key + * constants beginning with <code>TRAVERSE_</code> are defined + * in the <code>SWT</code> class. + * </p> + * + * @param e an event containing information about the traverse + */ +public void keyTraversed(TraverseEvent e); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeAdapter.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeAdapter.java index f1da6f472c..cfa2817bfb 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeAdapter.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeAdapter.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * This adapter class provides default implementations for the
- * methods described by the <code>TreeListener</code> interface.
- * <p>
- * Classes that wish to deal with <code>TreeEvent</code>s can
- * extend this class and override only the methods which they are
- * interested in.
- * </p>
- *
- * @see TreeListener
- * @see TreeEvent
- */
-public abstract class TreeAdapter implements TreeListener {
-
-/**
- * Sent when a tree branch is collapsed.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the tree operation
- */
-public void treeCollapsed(TreeEvent e) {
-}
-
-/**
- * Sent when a tree branch is expanded.
- * The default behavior is to do nothing.
- *
- * @param e an event containing information about the tree operation
- */
-public void treeExpanded(TreeEvent e) {
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * This adapter class provides default implementations for the + * methods described by the <code>TreeListener</code> interface. + * <p> + * Classes that wish to deal with <code>TreeEvent</code>s can + * extend this class and override only the methods which they are + * interested in. + * </p> + * + * @see TreeListener + * @see TreeEvent + */ +public abstract class TreeAdapter implements TreeListener { + +/** + * Sent when a tree branch is collapsed. + * The default behavior is to do nothing. + * + * @param e an event containing information about the tree operation + */ +public void treeCollapsed(TreeEvent e) { +} + +/** + * Sent when a tree branch is expanded. + * The default behavior is to do nothing. + * + * @param e an event containing information about the tree operation + */ +public void treeExpanded(TreeEvent e) { +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeEvent.java index 0776d19dae..23634de5a0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeEvent.java @@ -1,32 +1,32 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * trees being expanded and collapsed.
- *
- * @see TreeListener
- */
-
-public final class TreeEvent extends SelectionEvent {
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public TreeEvent(Event e) {
- super(e);
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * trees being expanded and collapsed. + * + * @see TreeListener + */ + +public final class TreeEvent extends SelectionEvent { + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public TreeEvent(Event e) { + super(e); +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeListener.java index 82039e035a..b910e12ea4 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TreeListener.java @@ -1,43 +1,43 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the expanding and collapsing of tree
- * branches.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a control using the
- * <code>addTreeListener</code> method and removed using
- * the <code>removeTreeListener</code> method. When a branch
- * of a tree is expanded or collapsed, the appropriate method
- * will be invoked.
- * </p>
- *
- * @see TreeAdapter
- * @see TreeEvent
- */
-public interface TreeListener extends SWTEventListener {
-
-/**
- * Sent when a tree branch is collapsed.
- *
- * @param e an event containing information about the tree operation
- */
-public void treeCollapsed(TreeEvent e);
-
-/**
- * Sent when a tree branch is expanded.
- *
- * @param e an event containing information about the tree operation
- */
-public void treeExpanded(TreeEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the expanding and collapsing of tree + * branches. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a control using the + * <code>addTreeListener</code> method and removed using + * the <code>removeTreeListener</code> method. When a branch + * of a tree is expanded or collapsed, the appropriate method + * will be invoked. + * </p> + * + * @see TreeAdapter + * @see TreeEvent + */ +public interface TreeListener extends SWTEventListener { + +/** + * Sent when a tree branch is collapsed. + * + * @param e an event containing information about the tree operation + */ +public void treeCollapsed(TreeEvent e); + +/** + * Sent when a tree branch is expanded. + * + * @param e an event containing information about the tree operation + */ +public void treeExpanded(TreeEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TypedEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TypedEvent.java index bea11e8879..7d90cf6ad0 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TypedEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/TypedEvent.java @@ -1,71 +1,71 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.internal.SWTEventObject;
-
-/**
- * This is the super class for all typed event classes provided
- * by SWT. Typed events contain particular information which is
- * applicable to the event occurance.
- *
- * @see org.eclipse.swt.widgets.Event
- */
-public class TypedEvent extends SWTEventObject {
-
- /**
- * the display where the event occurred
- *
- * @since 2.0
- */
- public Display display;
-
- /**
- * the widget that issued the event
- */
- public Widget widget;
-
- /**
- * the time that the event occurred.
- *
- * NOTE: This field is an unsigned integer and should
- * be AND'ed with 0xFFFFFFFFL so that it can be treated
- * as a signed long.
- */
- public int time;
-
- /**
- * a field for application use
- */
- public Object data;
-
-/**
- * Constructs a new instance of this class.
- *
- * @param source the object that fired the event
- */
-public TypedEvent(Object object) {
- super(object);
-}
-
-/**
- * Constructs a new instance of this class based on the
- * information in the argument.
- *
- * @param e the low level event to initialize the receiver with
- */
-public TypedEvent(Event e) {
- super(e.widget);
- this.display = e.display;
- this.widget = e.widget;
- this.time = e.time;
- this.data = e.data;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.*; +import org.eclipse.swt.internal.SWTEventObject; + +/** + * This is the super class for all typed event classes provided + * by SWT. Typed events contain particular information which is + * applicable to the event occurance. + * + * @see org.eclipse.swt.widgets.Event + */ +public class TypedEvent extends SWTEventObject { + + /** + * the display where the event occurred + * + * @since 2.0 + */ + public Display display; + + /** + * the widget that issued the event + */ + public Widget widget; + + /** + * the time that the event occurred. + * + * NOTE: This field is an unsigned integer and should + * be AND'ed with 0xFFFFFFFFL so that it can be treated + * as a signed long. + */ + public int time; + + /** + * a field for application use + */ + public Object data; + +/** + * Constructs a new instance of this class. + * + * @param source the object that fired the event + */ +public TypedEvent(Object object) { + super(object); +} + +/** + * Constructs a new instance of this class based on the + * information in the argument. + * + * @param e the low level event to initialize the receiver with + */ +public TypedEvent(Event e) { + super(e.widget); + this.display = e.display; + this.widget = e.widget; + this.time = e.time; + this.data = e.data; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyEvent.java index b5a0e1bfca..6281209110 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyEvent.java @@ -1,57 +1,57 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.widgets.Event;
-
-/**
- * Instances of this class are sent as a result of
- * widgets handling keyboard events
- *
- * @see VerifyListener
- */
-
-public final class VerifyEvent extends KeyEvent {
-
- /**
- * the range of text being modified.
- * Setting these fields has no effect.
- */
- public int start, end;
-
- /**
- * the new text that will be inserted.
- * Setting this field will change the text that is about to
- * be inserted or deleted.
- */
- public String text;
-
- /**
- * a flag indicating whether the operation should be allowed.
- * Setting this field to false will cancel the operation.
- */
- public boolean doit;
-
-/**
- * Constructs a new instance of this class based on the
- * information in the given untyped event.
- *
- * @param e the untyped event containing the information
- */
-public VerifyEvent(Event e) {
- super(e);
- this.character = e.character;
- this.keyCode = e.keyCode;
- this.stateMask = e.stateMask;
- this.start = e.start;
- this.end = e.end;
- this.text = e.text;
- this.doit = e.doit;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.widgets.Event; + +/** + * Instances of this class are sent as a result of + * widgets handling keyboard events + * + * @see VerifyListener + */ + +public final class VerifyEvent extends KeyEvent { + + /** + * the range of text being modified. + * Setting these fields has no effect. + */ + public int start, end; + + /** + * the new text that will be inserted. + * Setting this field will change the text that is about to + * be inserted or deleted. + */ + public String text; + + /** + * a flag indicating whether the operation should be allowed. + * Setting this field to false will cancel the operation. + */ + public boolean doit; + +/** + * Constructs a new instance of this class based on the + * information in the given untyped event. + * + * @param e the untyped event containing the information + */ +public VerifyEvent(Event e) { + super(e); + this.character = e.character; + this.keyCode = e.keyCode; + this.stateMask = e.stateMask; + this.start = e.start; + this.end = e.end; + this.text = e.text; + this.doit = e.doit; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyListener.java index cbffca9bad..2a2fb493ea 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/events/VerifyListener.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.events;
-
-/*
+package org.eclipse.swt.events; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide a method
- * that deals with the events that are generated when text
- * is about to be modified.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to a text widget using the
- * <code>addVerifyListener</code> method and removed using
- * the <code>removeVerifyListener</code> method. When the
- * text is about to be modified, the verifyText method
- * will be invoked.
- * </p>
- *
- * @see VerifyEvent
- */
-public interface VerifyListener extends SWTEventListener {
-
-/**
- * Sent when the text is about to be modified.
- * <p>
- * A verify event occurs after the user has done something
- * to modify the text (typically typed a key), but before
- * the text is modified. The doit field in the verify event
- * indicates whether or not to modify the text.
- * </p>
- *
- * @param e an event containing information about the verify
- */
-public void verifyText(VerifyEvent e);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide a method + * that deals with the events that are generated when text + * is about to be modified. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to a text widget using the + * <code>addVerifyListener</code> method and removed using + * the <code>removeVerifyListener</code> method. When the + * text is about to be modified, the verifyText method + * will be invoked. + * </p> + * + * @see VerifyEvent + */ +public interface VerifyListener extends SWTEventListener { + +/** + * Sent when the text is about to be modified. + * <p> + * A verify event occurs after the user has done something + * to modify the text (typically typed a key), but before + * the text is modified. The doit field in the verify event + * indicates whether or not to modify the text. + * </p> + * + * @param e an event containing information about the verify + */ +public void verifyText(VerifyEvent e); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Drawable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Drawable.java index 903e9df135..cb647efdba 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Drawable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Drawable.java @@ -1,47 +1,47 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-public interface Drawable {
-
-/**
- * Invokes platform specific functionality to allocate a new GC handle.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
- * API for <code>Drawable</code>. It is marked public only so that it
- * can be shared within the packages provided by SWT. It is not
- * available on all platforms, and should never be called from
- * application code.
- * </p>
- *
- * @param data the platform specific GC data
- * @return the platform specific GC handle
- *
- * @private
- */
-
-public int internal_new_GC (GCData data);
-
-/**
- * Invokes platform specific functionality to dispose a GC handle.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
- * API for <code>Drawable</code>. It is marked public only so that it
- * can be shared within the packages provided by SWT. It is not
- * available on all platforms, and should never be called from
- * application code.
- * </p>
- *
- * @param handle the platform specific GC handle
- * @param data the platform specific GC data
- *
- * @private
- */
-public void internal_dispose_GC (int handle, GCData data);
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +public interface Drawable { + +/** + * Invokes platform specific functionality to allocate a new GC handle. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the public + * API for <code>Drawable</code>. It is marked public only so that it + * can be shared within the packages provided by SWT. It is not + * available on all platforms, and should never be called from + * application code. + * </p> + * + * @param data the platform specific GC data + * @return the platform specific GC handle + * + * @private + */ + +public int internal_new_GC (GCData data); + +/** + * Invokes platform specific functionality to dispose a GC handle. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the public + * API for <code>Drawable</code>. It is marked public only so that it + * can be shared within the packages provided by SWT. It is not + * available on all platforms, and should never be called from + * application code. + * </p> + * + * @param handle the platform specific GC handle + * @param data the platform specific GC data + * + * @private + */ +public void internal_dispose_GC (int handle, GCData data); + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageData.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageData.java index e7587a4fe7..6d663d23b9 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageData.java @@ -1,3551 +1,3551 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-import org.eclipse.swt.*;
-import org.eclipse.swt.internal.CloneableCompatibility;
-
-/**
- * Instances of this class are device-independent descriptions
- * of images. They are typically used as an intermediate format
- * between loading from or writing to streams and creating an
- * <code>Image</code>.
- * <p>
- * Note that the public fields <code>x</code>, <code>y</code>,
- * <code>disposalMethod</code> and <code>delayTime</code> are
- * typically only used when the image is in a set of images used
- * for animation.
- * </p>
- *
- * @see Image
- * @see ImageLoader
- */
-
-public final class ImageData implements CloneableCompatibility {
-
- /**
- * the width of the image, in pixels
- */
- public int width;
-
- /**
- * the height of the image, in pixels
- */
- public int height;
-
- /**
- * the color depth of the image, in bits per pixel
- * <p>
- * Note that a depth of 8 or less does not necessary
- * mean that the image is palette indexed, or
- * conversely that a depth greater than 8 means that
- * the image is direct color. Check the associated
- * PaletteData's isDirect field for such determinations.
- */
- public int depth;
-
- /**
- * the scanline padding
- * <p>
- * If one scanline of the image is not a multiple of
- * this number, it will be padded with zeros until it is.
- * </p>
- */
- public int scanlinePad;
-
- /**
- * the number of bytes per scanline
- * <p>
- * This is a multiple of the scanline padding.
- * </p>
- */
- public int bytesPerLine;
-
- /**
- * the pixel data of the image
- * <p>
- * Note that for 16 bit depth images the pixel data is stored
- * in least significant byte order; however, for 24bit and
- * 32bit depth images the pixel data is stored in most
- * significant byte order.
- * </p>
- */
- public byte[] data;
-
- /**
- * the color table for the image
- */
- public PaletteData palette;
-
- /**
- * the transparent pixel
- * <p>
- * Pixels with this value are transparent.
- * </p><p>
- * The default is -1 which means 'no transparent pixel'.
- * </p>
- */
- public int transparentPixel;
-
- /**
- * icon-specific field containing the data from the icon mask
- * <p>
- * This is a 1 bit bitmap stored with the most significant
- * bit first. The number of bytes per scanline is
- * '((width + 7) / 8 + (maskPad - 1)) / maskPad * maskPad'.
- * </p><p>
- * The default is null which means 'no transparency mask'.
- * </p>
- */
- public byte[] maskData;
-
- /**
- * icon-specific field containing the scanline pad of the mask
- * <p>
- * If one scanline of the transparency mask is not a
- * multiple of this number, it will be padded with zeros until
- * it is.
- * </p>
- */
- public int maskPad;
-
- /**
- * the alpha data of the image
- * <p>
- * Every pixel can have an <em>alpha blending</em> value that
- * varies from 0, meaning fully transparent, to 255 meaning
- * fully opaque. The number of bytes per scanline is
- * 'width'.
- * </p>
- */
- public byte[] alphaData;
-
- /**
- * the global alpha value to be used for every pixel
- * <p>
- * If this value is set, the <code>alphaData</code> field
- * is ignored and when the image is rendered each pixel
- * will be blended with the background an amount
- * proportional to this value.
- * </p><p>
- * The default is -1 which means 'no global alpha value'
- * </p>
- */
- public int alpha;
-
- /**
- * the type of file that the image was read in from,
- * expressed as one of the following values:
- * <dl>
- * <dt><code>IMAGE_BMP</code></dt>
- * <dd>Windows BMP file format, no compression</dd>
- * <dt><code>IMAGE_BMP_RLE</code></dt>
- * <dd>Windows BMP file format, RLE compression if appropriate</dd>
- * <dt><code>IMAGE_GIF</code></dt>
- * <dd>GIF file format</dd>
- * <dt><code>IMAGE_ICO</code></dt>
- * <dd>Windows ICO file format</dd>
- * <dt><code>IMAGE_JPEG</code></dt>
- * <dd>JPEG file format</dd>
- * <dt><code>IMAGE_PNG</code></dt>
- * <dd>PNG file format</dd>
- * </dl>
- */
- public int type;
-
- /**
- * the x coordinate of the top left corner of the image
- * within the logical screen (this field corresponds to
- * the GIF89a Image Left Position value)
- */
- public int x;
-
- /**
- * The y coordinate of the top left corner of the image
- * within the logical screen (this field corresponds to
- * the GIF89a Image Top Position value)
- */
- public int y;
-
- /**
- * a description of how to dispose of the current image
- * before displaying the next, expressed as one of the
- * following values:
- * <dl>
- * <dt><code>DM_UNSPECIFIED</code></dt>
- * <dd>disposal method not specified</dd>
- * <dt><code>DM_FILL_NONE</code></dt>
- * <dd>do nothing - leave the image in place</dd>
- * <dt><code>DM_FILL_BACKGROUND</code></dt>
- * <dd>fill with the background color</dd>
- * <dt><code>DM_FILL_PREVIOUS</code></dt>
- * <dd>restore the previous picture</dd>
- * </dl>
- * (this field corresponds to the GIF89a Disposal Method value)
- */
- public int disposalMethod;
-
- /**
- * the time to delay before displaying the next image
- * in an animation (this field corresponds to the GIF89a
- * Delay Time value)
- */
- public int delayTime;
-
- /**
- * Arbitrary channel width data to 8-bit conversion table
- */
- static final byte[][] ANY_TO_EIGHT = new byte[9][];
- static {
- for (int b = 0; b < 9; ++b) {
- byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b];
- if (b == 0) continue;
- int inc = 0;
- for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit;
- for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8);
- }
- }
- static final byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8];
-
- /**
- * Scaled 8x8 Bayer dither matrix
- */
- static final int[][] DITHER_MATRIX = {
- { 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 },
- { 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 },
- { 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 },
- { 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 },
- { 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 },
- { 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 },
- { 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 },
- { 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 }
- };
-
-/**
- * Constructs a new, empty ImageData with the given width, height,
- * depth and palette. The data will be initialized to an (all zero)
- * array of the appropriate size.
- *
- * @param width the width of the image
- * @param height the height of the image
- * @param depth the depth of the image
- * @param palette the palette of the image (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the width or height is negative</li>
- * <li>ERROR_NULL_ARGUMENT - if the palette is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth argument is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public ImageData(int width, int height, int depth, PaletteData palette) {
- this(width, height, depth, palette,
- 4, null, 0, null,
- null, -1, -1, SWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
-}
-
-/**
- * Constructs a new, empty ImageData with the given width, height,
- * depth, palette, scanlinePad and data.
- *
- * @param width the width of the image
- * @param height the height of the image
- * @param depth the depth of the image
- * @param palette the palette of the image
- * @param scanlinePad the padding of each line, in bytes
- * @param data the data of the image
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the width or height is negative</li>
- * <li>ERROR_NULL_ARGUMENT - if the palette or data is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth argument is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public ImageData(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) {
- this(width, height, depth, palette,
- scanlinePad, checkData(data), 0, null,
- null, -1, -1, SWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
-}
-
-/**
- * Constructs an <code>ImageData</code> loaded from the specified
- * input stream. Throws an error if an error occurs while loading
- * the image, or if the image has an unsupported type.
- * <p>
- * This constructor is provided for convenience when loading a single
- * image only. If the stream contains multiple images, only the first
- * one will be loaded. To load multiple images, use
- * <code>ImageLoader.load()</code>.
- * </p>
- *
- * @param stream the input stream to load the image from (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
- * <li>ERROR_IO - if an IO error occurs while reading data</li>
- * </ul>
- *
- * @see ImageLoader#load
- */
-public ImageData(InputStream stream) {
- ImageData[] data = new ImageLoader().load(stream);
- if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE);
- ImageData i = data[0];
- setAllFields(
- i.width,
- i.height,
- i.depth,
- i.scanlinePad,
- i.bytesPerLine,
- i.data,
- i.palette,
- i.transparentPixel,
- i.maskData,
- i.maskPad,
- i.alphaData,
- i.alpha,
- i.type,
- i.x,
- i.y,
- i.disposalMethod,
- i.delayTime);
-}
-
-/**
- * Constructs an <code>ImageData</code> loaded from a file with the
- * specified name. Throws an error if an error occurs loading the
- * image, or if the image has an unsupported type.
- * <p>
- * This constructor is provided for convenience when loading a single
- * image only. If the file contains multiple images, only the first
- * one will be loaded. To load multiple images, use
- * <code>ImageLoader.load()</code>.
- * </p>
- *
- * @param filename the name of the file to load the image from (must not be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
- * <li>ERROR_IO if an IO error occurs while reading data</li>
- * </ul>
- */
-public ImageData(String filename) {
- ImageData[] data = new ImageLoader().load(filename);
- if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE);
- ImageData i = data[0];
- setAllFields(
- i.width,
- i.height,
- i.depth,
- i.scanlinePad,
- i.bytesPerLine,
- i.data,
- i.palette,
- i.transparentPixel,
- i.maskData,
- i.maskPad,
- i.alphaData,
- i.alpha,
- i.type,
- i.x,
- i.y,
- i.disposalMethod,
- i.delayTime);
-}
-
-/**
- * Prevents uninitialized instances from being created outside the package.
- */
-ImageData() {
-}
-
-/**
- * Constructs an image data by giving values for all non-computable fields.
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- */
-ImageData(
- int width, int height, int depth, PaletteData palette,
- int scanlinePad, byte[] data, int maskPad, byte[] maskData,
- byte[] alphaData, int alpha, int transparentPixel, int type,
- int x, int y, int disposalMethod, int delayTime)
-{
-
- if (palette == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (!(depth == 1 || depth == 2 || depth == 4 || depth == 8
- || depth == 16 || depth == 24 || depth == 32)) {
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
- if (width <= 0 || height <= 0) {
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
- int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1))
- / scanlinePad * scanlinePad;
- setAllFields(
- width,
- height,
- depth,
- scanlinePad,
- bytesPerLine,
- data != null ? data : new byte[bytesPerLine * height],
- palette,
- transparentPixel,
- maskData,
- maskPad,
- alphaData,
- alpha,
- type,
- x,
- y,
- disposalMethod,
- delayTime);
-}
-
-/**
- * Initializes all fields in the receiver. This method must be called
- * by all public constructors to ensure that all fields are initialized
- * for a new ImageData object. If a new field is added to the class,
- * then it must be added to this method.
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- */
-void setAllFields(int width, int height, int depth, int scanlinePad,
- int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel,
- byte[] maskData, int maskPad, byte[] alphaData, int alpha,
- int type, int x, int y, int disposalMethod, int delayTime) {
-
- this.width = width;
- this.height = height;
- this.depth = depth;
- this.scanlinePad = scanlinePad;
- this.bytesPerLine = bytesPerLine;
- this.data = data;
- this.palette = palette;
- this.transparentPixel = transparentPixel;
- this.maskData = maskData;
- this.maskPad = maskPad;
- this.alphaData = alphaData;
- this.alpha = alpha;
- this.type = type;
- this.x = x;
- this.y = y;
- this.disposalMethod = disposalMethod;
- this.delayTime = delayTime;
-}
-
-/**
- * Invokes internal SWT functionality to create a new instance of
- * this class.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
- * API for <code>ImageData</code>. It is marked public only so that it
- * can be shared within the packages provided by SWT. It is subject
- * to change without notice, and should never be called from
- * application code.
- * </p>
- * <p>
- * This method is for internal use, and is not described further.
- * </p>
- *
- * @private
- */
-public static ImageData internal_new(
- int width, int height, int depth, PaletteData palette,
- int scanlinePad, byte[] data, int maskPad, byte[] maskData,
- byte[] alphaData, int alpha, int transparentPixel, int type,
- int x, int y, int disposalMethod, int delayTime)
-{
- return new ImageData(
- width, height, depth, palette, scanlinePad, data, maskPad, maskData,
- alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime);
-}
-
-ImageData colorMaskImage(int pixel) {
- ImageData mask = new ImageData(width, height, 1, bwPalette(),
- Image.DEFAULT_SCANLINE_PAD, null, 0, null,
- null, -1, -1, SWT.IMAGE_UNDEFINED,
- 0, 0, 0, 0);
- int[] row = new int[width];
- for (int y = 0; y < height; y++) {
- getPixels(0, y, width, row, 0);
- for (int i = 0; i < width; i++) {
- if (pixel != -1 && row[i] == pixel) {
- row[i] = 0;
- } else {
- row[i] = 1;
- }
- }
- mask.setPixels(0, y, width, row, 0);
- }
- return mask;
-}
-
-static byte[] checkData(byte [] data) {
- if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- return data;
-}
-
-/**
- * Returns a new instance of the same class as the receiver,
- * whose slots have been filled in with <em>copies</em> of
- * the values in the slots of the receiver. That is, the
- * returned object is a <em>deep copy</em> of the receiver.
- *
- * @return a copy of the receiver.
- */
-public Object clone() {
- byte[] cloneData = new byte[data.length];
- System.arraycopy(data, 0, cloneData, 0, data.length);
- byte[] cloneMaskData = null;
- if (maskData != null) {
- cloneMaskData = new byte[maskData.length];
- System.arraycopy(maskData, 0, cloneMaskData, 0, maskData.length);
- }
- byte[] cloneAlphaData = null;
- if (alphaData != null) {
- cloneAlphaData = new byte[alphaData.length];
- System.arraycopy(alphaData, 0, cloneAlphaData, 0, alphaData.length);
- }
- return new ImageData(
- width,
- height,
- depth,
- palette,
- scanlinePad,
- cloneData,
- maskPad,
- cloneMaskData,
- cloneAlphaData,
- alpha,
- transparentPixel,
- type,
- x,
- y,
- disposalMethod,
- delayTime);
-}
-
-/**
- * Returns the alpha value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data.
- *
- * @param x the x coodinate of the pixel to get the alpha value of
- * @param y the y coordinate of the pixel to get the alpha value of
- * @return the alpha value at the given coordinates
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if either argument is out of range</li>
- * </ul>
- */
-public int getAlpha(int x, int y) {
- if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-
- if (alphaData == null) return 255;
- return alphaData[y * width + x] & 0xFF;
-}
-
-/**
- * Returns <code>getWidth</code> alpha values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's alpha
- * data starting at <code>startIndex</code>.
- *
- * @param x the x position of the pixel to begin getting alpha values
- * @param y the y position of the pixel to begin getting alpha values
- * @param getWidth the width of the data to get
- * @param alphas the buffer in which to put the alpha values
- * @param startIndex the offset into the image to begin getting alpha values
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- */
-public void getAlphas(int x, int y, int getWidth, byte[] alphas, int startIndex) {
- if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (getWidth == 0) return;
-
- if (alphaData == null) {
- int endIndex = startIndex + getWidth;
- for (int i = startIndex; i < endIndex; i++) {
- alphas[i] = (byte)255;
- }
- return;
- }
- // may throw an IndexOutOfBoundsException
- System.arraycopy(alphaData, y * width + x, alphas, startIndex, getWidth);
-}
-
-/**
- * Returns the pixel value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data.
- *
- * @param x the x position of the pixel to get
- * @param y the y position of the pixel to get
- * @return the pixel at the given coordinates
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if either argument is out of bounds</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public int getPixel(int x, int y) {
- if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- int index;
- int theByte;
- int mask;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- mask = 1 << (7 - (x & 0x7));
- if ((theByte & mask) == 0) {
- return 0;
- } else {
- return 1;
- }
- }
- if (depth == 2) {
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset = 3 - (x % 4);
- mask = 3 << (offset * 2);
- return (theByte & mask) >> (offset * 2);
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- theByte = data[index] & 0xFF;
- if ((x & 0x1) == 0) {
- return theByte >> 4;
- } else {
- return theByte & 0x0F;
- }
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x ;
- return data[index] & 0xFF;
- }
- if (depth == 16) {
- index = (y * bytesPerLine) + (x * 2);
- return ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
- }
- if (depth == 24) {
- index = (y * bytesPerLine) + (x * 3);
- return ((data[index] & 0xFF) << 16) + ((data[index+1] & 0xFF) << 8) +
- (data[index+2] & 0xFF);
- }
- if (depth == 32) {
- index = (y * bytesPerLine) + (x * 4);
- return ((data[index] & 0xFF) << 24) + ((data[index+1] & 0xFF) << 16) +
- ((data[index+2] & 0xFF) << 8) + (data[index+3] & 0xFF);
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
- return 0;
-}
-
-/**
- * Returns <code>getWidth</code> pixel values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's
- * data starting at <code>startIndex</code>.
- *
- * @param x the x position of the first pixel to get
- * @param y the y position of the first pixel to get
- * @param getWidth the width of the data to get
- * @param pixels the buffer in which to put the pixels
- * @param startIndex the offset into the byte array to begin storing pixels
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4 or 8
- * (For higher depths, use the int[] version of this method.)</li>
- * </ul>
- */
-public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) {
- if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (getWidth == 0) return;
- int index;
- int theByte;
- int mask = 0;
- int n = getWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- while (n > 1) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((theByte & mask) == 0) {
- pixels[i] = 0;
- } else {
- pixels[i] = 1;
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (mask == 1) {
- index++;
- if (n > 0) theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- }
- if (depth == 2) {
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset;
- while (n > 0) {
- offset = 3 - (srcX % 4);
- mask = 3 << (offset * 2);
- pixels[i] = (byte)((theByte & mask) >> (offset * 2));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (offset == 0) {
- index++;
- theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) == 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = (byte)(theByte & 0x0F);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- while (n > 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = (byte)(theByte >> 4);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- pixels[i] = (byte)(theByte & 0x0F);
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- }
- if (n > 0) {
- theByte = data[index] & 0xFF;
- pixels[i] = (byte)(theByte >> 4);
- }
- return;
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = data[index];
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
-}
-
-/**
- * Returns <code>getWidth</code> pixel values starting at offset
- * <code>x</code> in scanline <code>y</code> in the receiver's
- * data starting at <code>startIndex</code>.
- *
- * @param x the x position of the first pixel to get
- * @param y the y position of the first pixel to get
- * @param getWidth the width of the data to get
- * @param pixels the buffer in which to put the pixels
- * @param startIndex the offset into the buffer to begin storing pixels
- *
- * @exception IndexOutOfBoundsException if getWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) {
- if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (getWidth == 0) return;
- int index;
- int theByte;
- int mask;
- int n = getWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index] & 0xFF;
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((theByte & mask) == 0) {
- pixels[i] = 0;
- } else {
- pixels[i] = 1;
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (mask == 1) {
- index++;
- if (n > 0) theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- }
- if (depth == 2) {
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index] & 0xFF;
- int offset;
- while (n > 0) {
- offset = 3 - (srcX % 4);
- mask = 3 << (offset * 2);
- pixels[i] = (byte)((theByte & mask) >> (offset * 2));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- if (n > 0) theByte = data[index] & 0xFF;
- srcX = 0;
- } else {
- if (offset == 0) {
- index++;
- theByte = data[index] & 0xFF;
- }
- }
- }
- return;
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) == 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte & 0x0F;
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- while (n > 1) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte >> 4;
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- pixels[i] = theByte & 0x0F;
- i++;
- n--;
- srcX++;;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- }
- if (n > 0) {
- theByte = data[index] & 0xFF;
- pixels[i] = theByte >> 4;
- }
- return;
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = data[index] & 0xFF;
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- }
- if (depth == 16) {
- index = (y * bytesPerLine) + (x * 2);
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 2;
- }
- }
- return;
- }
- if (depth == 24) {
- index = (y * bytesPerLine) + (x * 3);
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8)
- | (data[index+2] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 3;
- }
- }
- return;
- }
- if (depth == 32) {
- index = (y * bytesPerLine) + (x * 4);
- i = startIndex;
- for (int j = 0; j < getWidth; j++) {
- pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16)
- | ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 4;
- }
- }
- return;
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
-}
-
-/**
- * Returns an array of <code>RGB</code>s which comprise the
- * indexed color table of the receiver, or null if the receiver
- * has a direct color model.
- *
- * @return the RGB values for the image or null if direct color
- *
- * @see PaletteData#getRGBs
- */
-public RGB[] getRGBs() {
- return palette.getRGBs();
-}
-
-/**
- * Returns an <code>ImageData</code> which specifies the
- * transparency mask information for the receiver, or null if the
- * receiver has no transparency and is not an icon.
- *
- * @return the transparency mask or null if none exists
- */
-public ImageData getTransparencyMask() {
- if (getTransparencyType() == SWT.TRANSPARENCY_MASK) {
- return new ImageData(width, height, 1, bwPalette(), maskPad, maskData);
- } else {
- return colorMaskImage(transparentPixel);
- }
-}
-
-/**
- * Returns the image transparency type.
- *
- * @return the receiver's transparency type
- */
-public int getTransparencyType() {
- if (maskData != null) return SWT.TRANSPARENCY_MASK;
- if (transparentPixel != -1) return SWT.TRANSPARENCY_PIXEL;
- if (alphaData != null) return SWT.TRANSPARENCY_ALPHA;
- return SWT.TRANSPARENCY_NONE;
-}
-
-/**
- * Returns the byte order of the receiver.
- *
- * @return MSB_FIRST or LSB_FIRST
- */
-int getByteOrder() {
- return depth != 16 ? MSB_FIRST : LSB_FIRST;
-}
-
-/**
- * Returns a copy of the receiver which has been stretched or
- * shrunk to the specified size. If either the width or height
- * is negative, the resulting image will be inverted in the
- * associated axis.
- *
- * @param width the width of the new ImageData
- * @param height the height of the new ImageData
- * @return a scaled copy of the image
- */
-public ImageData scaledTo(int width, int height) {
- /* Create a destination image with no data */
- final boolean flipX = (width < 0);
- if (flipX) width = - width;
- final boolean flipY = (height < 0);
- if (flipY) height = - height;
-
- ImageData dest = new ImageData(
- width, height, depth, palette,
- scanlinePad, null, 0, null,
- null, -1, transparentPixel, type,
- x, y, disposalMethod, delayTime);
-
- /* Scale the image contents */
- if (palette.isDirect) blit(BLIT_SRC,
- this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, 0, 0, 0,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, 0, 0, 0,
- flipX, flipY);
- else blit(BLIT_SRC,
- this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
-
- /* Scale the image mask or alpha */
- if (maskData != null) {
- dest.maskPad = this.maskPad;
- int destBpl = (dest.width + 7) / 8;
- destBpl = (destBpl + (dest.maskPad - 1)) / dest.maskPad * dest.maskPad;
- dest.maskData = new byte[destBpl * dest.height];
- int srcBpl = (this.width + 7) / 8;
- srcBpl = (srcBpl + (this.maskPad - 1)) / this.maskPad * this.maskPad;
- blit(BLIT_SRC,
- this.maskData, 1, srcBpl, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.maskData, 1, destBpl, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
- } else if (alpha != -1) {
- dest.alpha = this.alpha;
- } else if (alphaData != null) {
- dest.alphaData = new byte[dest.width * dest.height];
- blit(BLIT_SRC,
- this.alphaData, 8, this.width, MSB_FIRST, 0, 0, this.width, this.height, null, null, null,
- ALPHA_OPAQUE, null, 0, 0, 0,
- dest.alphaData, 8, dest.width, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null,
- flipX, flipY);
- }
- return dest;
-}
-
-/**
- * Sets the alpha value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data.
- *
- * @param x the x coordinate of the alpha value to set
- * @param y the y coordinate of the alpha value to set
- * @param alpha the value to set the alpha to
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * </ul>
- */
-public void setAlpha(int x, int y, int alpha) {
- if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255)
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-
- if (alphaData == null) alphaData = new byte[width * height];
- alphaData[y * width + x] = (byte)alpha;
-}
-
-/**
- * Sets the alpha values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's alpha data to the
- * values from the array <code>alphas</code> starting at
- * <code>startIndex</code>.
- *
- * @param x the x coordinate of the pixel to being setting the alpha values
- * @param y the y coordinate of the pixel to being setting the alpha values
- * @param putWidth the width of the alpha values to set
- * @param alphas the alpha values to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- */
-public void setAlphas(int x, int y, int putWidth, byte[] alphas, int startIndex) {
- if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (putWidth == 0) return;
-
- if (alphaData == null) alphaData = new byte[width * height];
- // may throw an IndexOutOfBoundsException
- System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth);
-}
-
-/**
- * Sets the pixel value at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data.
- *
- * @param x the x coordinate of the pixel to set
- * @param y the y coordinate of the pixel to set
- * @param pixelValue the value to set the pixel to
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public void setPixel(int x, int y, int pixelValue) {
- if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- int index;
- byte theByte;
- int mask;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- theByte = data[index];
- mask = 1 << (7 - (x & 0x7));
- if ((pixelValue & 0x1) == 1) {
- data[index] = (byte)(theByte | mask);
- } else {
- data[index] = (byte)(theByte & (mask ^ -1));
- }
- return;
- }
- if (depth == 2) {
- index = (y * bytesPerLine) + (x >> 2);
- theByte = data[index];
- int offset = 3 - (x % 4);
- mask = 0xFF ^ (3 << (offset * 2));
- data[index] = (byte)((data[index] & mask) | (pixelValue << (offset * 2)));
- return;
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- if ((x & 0x1) == 0) {
- data[index] = (byte)((data[index] & 0x0F) | ((pixelValue & 0x0F) << 4));
- } else {
- data[index] = (byte)((data[index] & 0xF0) | (pixelValue & 0x0F));
- }
- return;
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x ;
- data[index] = (byte)(pixelValue & 0xFF);
- return;
- }
- if (depth == 16) {
- index = (y * bytesPerLine) + (x * 2);
- data[index + 1] = (byte)((pixelValue >> 8) & 0xFF);
- data[index] = (byte)(pixelValue & 0xFF);
- return;
- }
- if (depth == 24) {
- index = (y * bytesPerLine) + (x * 3);
- data[index] = (byte)((pixelValue >> 16) & 0xFF);
- data[index + 1] = (byte)((pixelValue >> 8) & 0xFF);
- data[index + 2] = (byte)(pixelValue & 0xFF);
- return;
- }
- if (depth == 32) {
- index = (y * bytesPerLine) + (x * 4);
- data[index] = (byte)((pixelValue >> 24) & 0xFF);
- data[index + 1] = (byte)((pixelValue >> 16) & 0xFF);
- data[index + 2] = (byte)((pixelValue >> 8) & 0xFF);
- data[index + 3] = (byte)(pixelValue & 0xFF);
- return;
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
-}
-
-/**
- * Sets the pixel values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data to the
- * values from the array <code>pixels</code> starting at
- * <code>startIndex</code>.
- *
- * @param x the x position of the pixel to set
- * @param y the y position of the pixel to set
- * @param putWidth the width of the pixels to set
- * @param pixels the pixels to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8
- * (For higher depths, use the int[] version of this method.)</li>
- * </ul>
- */
-public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) {
- if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (putWidth == 0) return;
- int index;
- int theByte;
- int mask;
- int n = putWidth;
- int i = startIndex;
- int srcX = x, srcY = y;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((pixels[i] & 0x1) == 1) {
- data[index] = (byte)((data[index] & 0xFF) | mask);
- } else {
- data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- if (mask == 1) {
- index++;
- }
- }
- }
- return;
- }
- if (depth == 2) {
- byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
- index = (y * bytesPerLine) + (x >> 2);
- int offset = 3 - (x % 4);
- while (n > 0) {
- theByte = pixels[i] & 0x3;
- data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- offset = 0;
- srcX = 0;
- } else {
- if (offset == 0) {
- index++;
- offset = 3;
- } else {
- offset--;
- }
- }
- }
- return;
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- boolean high = (x & 0x1) == 0;
- while (n > 0) {
- theByte = pixels[i] & 0x0F;
- if (high) {
- data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
- } else {
- data[index] = (byte)((data[index] & 0xF0) | theByte);
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- high = true;
- srcX = 0;
- } else {
- if (!high) index++;
- high = !high;
- }
- }
- return;
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < putWidth; j++) {
- data[index] = (byte)(pixels[i] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
-}
-
-/**
- * Sets the pixel values starting at offset <code>x</code> in
- * scanline <code>y</code> in the receiver's data to the
- * values from the array <code>pixels</code> starting at
- * <code>startIndex</code>.
- *
- * @param x the x position of the pixel to set
- * @param y the y position of the pixel to set
- * @param putWidth the width of the pixels to set
- * @param pixels the pixels to set
- * @param startIndex the index at which to begin setting
- *
- * @exception IndexOutOfBoundsException if putWidth is too large
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if pixels is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li>
- * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li>
- * </ul>
- */
-public void setPixels(int x, int y, int putWidth, int[] pixels, int startIndex) {
- if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (putWidth == 0) return;
- int index;
- int theByte;
- int mask;
- int n = putWidth;
- int i = startIndex;
- int pixel;
- int srcX = x, srcY = y;
- if (depth == 1) {
- index = (y * bytesPerLine) + (x >> 3);
- while (n > 0) {
- mask = 1 << (7 - (srcX & 0x7));
- if ((pixels[i] & 0x1) == 1) {
- data[index] = (byte)((data[index] & 0xFF) | mask);
- } else {
- data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1));
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- if (mask == 1) {
- index++;
- }
- }
- }
- return;
- }
- if (depth == 2) {
- byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F };
- index = (y * bytesPerLine) + (x >> 2);
- int offset = 3 - (x % 4);
- while (n > 0) {
- theByte = pixels[i] & 0x3;
- data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2)));
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- offset = 3;
- srcX = 0;
- } else {
- if (offset == 0) {
- index++;
- offset = 3;
- } else {
- offset--;
- }
- }
- }
- return;
- }
- if (depth == 4) {
- index = (y * bytesPerLine) + (x >> 1);
- boolean high = (x & 0x1) == 0;
- while (n > 0) {
- theByte = pixels[i] & 0x0F;
- if (high) {
- data[index] = (byte)((data[index] & 0x0F) | (theByte << 4));
- } else {
- data[index] = (byte)((data[index] & 0xF0) | theByte);
- }
- i++;
- n--;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- high = true;
- srcX = 0;
- } else {
- if (!high) index++;
- high = !high;
- }
- }
- return;
- }
- if (depth == 8) {
- index = (y * bytesPerLine) + x;
- for (int j = 0; j < putWidth; j++) {
- data[index] = (byte)(pixels[i] & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index++;
- }
- }
- return;
-
- }
- if (depth == 16) {
- index = (y * bytesPerLine) + (x * 2);
- for (int j = 0; j < putWidth; j++) {
- pixel = pixels[i];
- data[index] = (byte)(pixel & 0xFF);
- data[index + 1] = (byte)((pixel >> 8) & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 2;
- }
- }
- return;
- }
- if (depth == 24) {
- index = (y * bytesPerLine) + (x * 3);
- for (int j = 0; j < putWidth; j++) {
- pixel = pixels[i];
- data[index] = (byte)((pixel >> 16) & 0xFF);
- data[index + 1] = (byte)((pixel >> 8) & 0xFF);
- data[index + 2] = (byte)(pixel & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 3;
- }
- }
- return;
- }
- if (depth == 32) {
- index = (y * bytesPerLine) + (x * 4);
- for (int j = 0; j < putWidth; j++) {
- pixel = pixels[i];
- data[index] = (byte)((pixel >> 24) & 0xFF);
- data[index + 1] = (byte)((pixel >> 16) & 0xFF);
- data[index + 2] = (byte)((pixel >> 8) & 0xFF);
- data[index + 3] = (byte)(pixel & 0xFF);
- i++;
- srcX++;
- if (srcX >= width) {
- srcY++;
- index = srcY * bytesPerLine;
- srcX = 0;
- } else {
- index += 4;
- }
- }
- return;
- }
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
-}
-
-/**
- * Returns a palette with 2 colors: black & white.
- */
-static PaletteData bwPalette() {
- return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)});
-}
-
-/**
- * Gets the offset of the most significant bit for
- * the given mask.
- */
-static int getMSBOffset(int mask) {
- for (int i = 31; i >= 0; i--) {
- if (((mask >> i) & 0x1) != 0) return i + 1;
- }
- return 0;
-}
-
-/**
- * Finds the closest match.
- */
-static int closestMatch(int depth, byte red, byte green, byte blue, int redMask, int greenMask, int blueMask, byte[] reds, byte[] greens, byte[] blues) {
- if (depth > 8) {
- int rshift = 32 - getMSBOffset(redMask);
- int gshift = 32 - getMSBOffset(greenMask);
- int bshift = 32 - getMSBOffset(blueMask);
- return (((red << 24) >>> rshift) & redMask) |
- (((green << 24) >>> gshift) & greenMask) |
- (((blue << 24) >>> bshift) & blueMask);
- }
- int r, g, b;
- int minDistance = 0x7fffffff;
- int nearestPixel = 0;
- int n = reds.length;
- for (int j = 0; j < n; j++) {
- r = (reds[j] & 0xFF) - (red & 0xFF);
- g = (greens[j] & 0xFF) - (green & 0xFF);
- b = (blues[j] & 0xFF) - (blue & 0xFF);
- int distance = r*r + g*g + b*b;
- if (distance < minDistance) {
- nearestPixel = j;
- if (distance == 0) break;
- minDistance = distance;
- }
- }
- return nearestPixel;
-}
-
-/**
- * Blit operation bits to be OR'ed together to specify the desired operation.
- */
-static final int
- BLIT_SRC = 1, // copy source directly, else applies logic operations
- BLIT_ALPHA = 2, // enable alpha blending
- BLIT_DITHER = 4; // enable dithering in low color modes
-
-/**
- * Alpha mode, values 0 - 255 specify global alpha level
- */
-static final int
- ALPHA_OPAQUE = 255, // Fully opaque (ignores any alpha data)
- ALPHA_TRANSPARENT = 0, // Fully transparent (ignores any alpha data)
- ALPHA_CHANNEL_SEPARATE = -1, // Use alpha channel from separate alphaData
- ALPHA_CHANNEL_SOURCE = -2, // Use alpha channel embedded in sourceData
- ALPHA_MASK_UNPACKED = -3, // Use transparency mask formed by bytes in alphaData (non-zero is opaque)
- ALPHA_MASK_PACKED = -4, // Use transparency mask formed by packed bits in alphaData
- ALPHA_MASK_INDEX = -5, // Consider source palette indices transparent if in alphaData array
- ALPHA_MASK_RGB = -6; // Consider source RGBs transparent if in RGB888 format alphaData array
-
-/**
- * Byte and bit order constants.
- */
-static final int LSB_FIRST = 0;
-static final int MSB_FIRST = 1;
-
-/**
- * Data types (internal)
- */
-private static final int
- // direct / true color formats with arbitrary masks & shifts
- TYPE_GENERIC_8 = 0,
- TYPE_GENERIC_16_MSB = 1,
- TYPE_GENERIC_16_LSB = 2,
- TYPE_GENERIC_24 = 3,
- TYPE_GENERIC_32_MSB = 4,
- TYPE_GENERIC_32_LSB = 5,
- // palette indexed color formats
- TYPE_INDEX_8 = 6,
- TYPE_INDEX_4 = 7,
- TYPE_INDEX_2 = 8,
- TYPE_INDEX_1_MSB = 9,
- TYPE_INDEX_1_LSB = 10;
-
-/**
- * Blits a direct palette image into a direct palette image.
- * <p>
- * Note: When the source and destination depth, order and masks
- * are pairwise equal and the blitter operation is BLIT_SRC,
- * the masks are ignored. Hence when not changing the image
- * data format, 0 may be specified for the masks.
- * </p>
- *
- * @param op the blitter operation: a combination of BLIT_xxx flags
- * (see BLIT_xxx constants)
- * @param srcData the source byte array containing image data
- * @param srcDepth the source depth: one of 8, 16, 24, 32
- * @param srcStride the source number of bytes per line
- * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if srcDepth is not 16 or 32
- * @param srcX the top-left x-coord of the source blit region
- * @param srcY the top-left y-coord of the source blit region
- * @param srcWidth the width of the source blit region
- * @param srcHeight the height of the source blit region
- * @param srcRedMask the source red channel mask
- * @param srcGreenMask the source green channel mask
- * @param srcBlueMask the source blue channel mask
- * @param alphaMode the alpha blending or mask mode, may be
- * an integer 0-255 for global alpha; ignored if BLIT_ALPHA
- * not specified in the blitter operations
- * (see ALPHA_MODE_xxx constants)
- * @param alphaData the alpha blending or mask data, varies depending
- * on the value of alphaMode and sometimes ignored
- * @param alphaStride the alpha data number of bytes per line
- * @param alphaX the top-left x-coord of the alpha blit region
- * @param alphaY the top-left y-coord of the alpha blit region
- * @param destData the destination byte array containing image data
- * @param destDepth the destination depth: one of 8, 16, 24, 32
- * @param destStride the destination number of bytes per line
- * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if destDepth is not 16 or 32
- * @param destX the top-left x-coord of the destination blit region
- * @param destY the top-left y-coord of the destination blit region
- * @param destWidth the width of the destination blit region
- * @param destHeight the height of the destination blit region
- * @param destRedMask the destination red channel mask
- * @param destGreenMask the destination green channel mask
- * @param destBlueMask the destination blue channel mask
- * @param flipX if true the resulting image is flipped along the vertical axis
- * @param flipY if true the resulting image is flipped along the horizontal axis
- */
-static void blit(int op,
- byte[] srcData, int srcDepth, int srcStride, int srcOrder,
- int srcX, int srcY, int srcWidth, int srcHeight,
- int srcRedMask, int srcGreenMask, int srcBlueMask,
- int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
- byte[] destData, int destDepth, int destStride, int destOrder,
- int destX, int destY, int destWidth, int destHeight,
- int destRedMask, int destGreenMask, int destBlueMask,
- boolean flipX, boolean flipY) {
- if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;
-
- // these should be supplied as params later
- final int srcAlphaMask = 0, destAlphaMask = 0;
-
- /*** Prepare scaling data ***/
- final int dwm1 = destWidth - 1;
- final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
- final int dhm1 = destHeight - 1;
- final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;
-
- /*** Prepare source-related data ***/
- final int sbpp, stype;
- switch (srcDepth) {
- case 8:
- sbpp = 1;
- stype = TYPE_GENERIC_8;
- break;
- case 16:
- sbpp = 2;
- stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
- break;
- case 24:
- sbpp = 3;
- stype = TYPE_GENERIC_24;
- break;
- case 32:
- sbpp = 4;
- stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int spr = srcY * srcStride + srcX * sbpp;
-
- /*** Prepare destination-related data ***/
- final int dbpp, dtype;
- switch (destDepth) {
- case 8:
- dbpp = 1;
- dtype = TYPE_GENERIC_8;
- break;
- case 16:
- dbpp = 2;
- dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
- break;
- case 24:
- dbpp = 3;
- dtype = TYPE_GENERIC_24;
- break;
- case 32:
- dbpp = 4;
- dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid destination type");
- return;
- }
- int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp;
- final int dprxi = (flipX) ? -dbpp : dbpp;
- final int dpryi = (flipY) ? -destStride : destStride;
-
- /*** Prepare special processing data ***/
- int apr;
- if ((op & BLIT_ALPHA) != 0) {
- switch (alphaMode) {
- case ALPHA_MASK_UNPACKED:
- case ALPHA_CHANNEL_SEPARATE:
- if (alphaData == null) alphaMode = 0x10000;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_PACKED:
- if (alphaData == null) alphaMode = 0x10000;
- alphaStride <<= 3;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_INDEX:
- //throw new IllegalArgumentException("Invalid alpha type");
- return;
- case ALPHA_MASK_RGB:
- if (alphaData == null) alphaMode = 0x10000;
- apr = 0;
- break;
- default:
- alphaMode = (alphaMode << 16) / 255; // prescale
- case ALPHA_CHANNEL_SOURCE:
- apr = 0;
- break;
- }
- } else {
- alphaMode = 0x10000;
- apr = 0;
- }
-
- /*** Blit ***/
- int dp = dpr;
- int sp = spr;
- if ((alphaMode == 0x10000) && (stype == dtype) &&
- (srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) &&
- (srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) {
- /*** Fast blit (straight copy) ***/
- switch (sbpp) {
- case 1:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- destData[dp] = srcData[sp];
- sp += (sfx >>> 16);
- }
- }
- break;
- case 2:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- destData[dp] = srcData[sp];
- destData[dp + 1] = srcData[sp + 1];
- sp += (sfx >>> 16) * 2;
- }
- }
- break;
- case 3:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- destData[dp] = srcData[sp];
- destData[dp + 1] = srcData[sp + 1];
- destData[dp + 2] = srcData[sp + 2];
- sp += (sfx >>> 16) * 3;
- }
- }
- break;
- case 4:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- destData[dp] = srcData[sp];
- destData[dp + 1] = srcData[sp + 1];
- destData[dp + 2] = srcData[sp + 2];
- destData[dp + 3] = srcData[sp + 3];
- sp += (sfx >>> 16) * 4;
- }
- }
- break;
- }
- return;
- }
- /*** Comprehensive blit (apply transformations) ***/
- final int srcRedShift = getChannelShift(srcRedMask);
- final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)];
- final int srcGreenShift = getChannelShift(srcGreenMask);
- final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)];
- final int srcBlueShift = getChannelShift(srcBlueMask);
- final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)];
- final int srcAlphaShift = getChannelShift(srcAlphaMask);
- final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)];
-
- final int destRedShift = getChannelShift(destRedMask);
- final int destRedWidth = getChannelWidth(destRedMask, destRedShift);
- final byte[] destReds = ANY_TO_EIGHT[destRedWidth];
- final int destRedPreShift = 8 - destRedWidth;
- final int destGreenShift = getChannelShift(destGreenMask);
- final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
- final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
- final int destGreenPreShift = 8 - destGreenWidth;
- final int destBlueShift = getChannelShift(destBlueMask);
- final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
- final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
- final int destBluePreShift = 8 - destBlueWidth;
- final int destAlphaShift = getChannelShift(destAlphaMask);
- final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift);
- final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
- final int destAlphaPreShift = 8 - destAlphaWidth;
-
- int ap = apr, alpha = alphaMode;
- int r = 0, g = 0, b = 0, a = 0;
- int rq = 0, gq = 0, bq = 0, aq = 0;
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
- sp = spr += (sfy >>> 16) * srcStride,
- ap = apr += (sfy >>> 16) * alphaStride,
- sfy = (sfy & 0xffff) + sfyi,
- dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
- dp += dprxi,
- sfx = (sfx & 0xffff) + sfxi) {
- /*** READ NEXT PIXEL ***/
- switch (stype) {
- case TYPE_GENERIC_8: {
- final int data = srcData[sp] & 0xff;
- sp += (sfx >>> 16);
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_MSB: {
- final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff);
- sp += (sfx >>> 16) * 2;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_LSB: {
- final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff);
- sp += (sfx >>> 16) * 2;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_24: {
- final int data = (( ((srcData[sp] & 0xff) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp + 2] & 0xff);
- sp += (sfx >>> 16) * 3;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_MSB: {
- final int data = (( (( ((srcData[sp] & 0xff) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp + 2] & 0xff)) << 8) |
- (srcData[sp + 3] & 0xff);
- sp += (sfx >>> 16) * 4;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_LSB: {
- final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) |
- (srcData[sp + 2] & 0xff)) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp] & 0xff);
- sp += (sfx >>> 16) * 4;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- }
-
- /*** DO SPECIAL PROCESSING IF REQUIRED ***/
- switch (alphaMode) {
- case ALPHA_CHANNEL_SEPARATE:
- alpha = ((alphaData[ap] & 0xff) << 16) / 255;
- ap += (sfx >> 16);
- break;
- case ALPHA_CHANNEL_SOURCE:
- alpha = (a << 16) / 255;
- break;
- case ALPHA_MASK_UNPACKED:
- alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_PACKED:
- alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_RGB:
- alpha = 0x10000;
- for (int i = 0; i < alphaData.length; i += 3) {
- if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) {
- alpha = 0x0000;
- break;
- }
- }
- break;
- }
- if (alpha != 0x10000) {
- if (alpha == 0x0000) continue;
- switch (dtype) {
- case TYPE_GENERIC_8: {
- final int data = destData[dp] & 0xff;
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_MSB: {
- final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_LSB: {
- final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_24: {
- final int data = (( ((destData[dp] & 0xff) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp + 2] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_MSB: {
- final int data = (( (( ((destData[dp] & 0xff) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp + 2] & 0xff)) << 8) |
- (destData[dp + 3] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_LSB: {
- final int data = (( (( ((destData[dp + 3] & 0xff) << 8) |
- (destData[dp + 2] & 0xff)) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- }
- // Perform alpha blending
- a = aq + ((a - aq) * alpha >> 16);
- r = rq + ((r - rq) * alpha >> 16);
- g = gq + ((g - gq) * alpha >> 16);
- b = bq + ((b - bq) * alpha >> 16);
- }
-
- /*** WRITE NEXT PIXEL ***/
- final int data =
- (r >>> destRedPreShift << destRedShift) |
- (g >>> destGreenPreShift << destGreenShift) |
- (b >>> destBluePreShift << destBlueShift) |
- (a >>> destAlphaPreShift << destAlphaShift);
- switch (dtype) {
- case TYPE_GENERIC_8: {
- destData[dp] = (byte) data;
- } break;
- case TYPE_GENERIC_16_MSB: {
- destData[dp] = (byte) (data >>> 8);
- destData[dp + 1] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_16_LSB: {
- destData[dp] = (byte) (data & 0xff);
- destData[dp + 1] = (byte) (data >>> 8);
- } break;
- case TYPE_GENERIC_24: {
- destData[dp] = (byte) (data >>> 16);
- destData[dp + 1] = (byte) (data >>> 8);
- destData[dp + 2] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_32_MSB: {
- destData[dp] = (byte) (data >>> 24);
- destData[dp + 1] = (byte) (data >>> 16);
- destData[dp + 2] = (byte) (data >>> 8);
- destData[dp + 3] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_32_LSB: {
- destData[dp] = (byte) (data & 0xff);
- destData[dp + 1] = (byte) (data >>> 8);
- destData[dp + 2] = (byte) (data >>> 16);
- destData[dp + 3] = (byte) (data >>> 24);
- } break;
- }
- }
- }
-}
-
-/**
- * Blits an index palette image into an index palette image.
- * <p>
- * Note: The source and destination red, green, and blue
- * arrays may be null if no alpha blending or dither is to be
- * performed.
- * </p>
- *
- * @param op the blitter operation: a combination of BLIT_xxx flags
- * (see BLIT_xxx constants)
- * @param srcData the source byte array containing image data
- * @param srcDepth the source depth: one of 1, 2, 4, 8
- * @param srcStride the source number of bytes per line
- * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if srcDepth is not 1
- * @param srcX the top-left x-coord of the source blit region
- * @param srcY the top-left y-coord of the source blit region
- * @param srcWidth the width of the source blit region
- * @param srcHeight the height of the source blit region
- * @param srcReds the source palette red component intensities
- * @param srcGreens the source palette green component intensities
- * @param srcBlues the source palette blue component intensities
- * @param alphaMode the alpha blending or mask mode, may be
- * an integer 0-255 for global alpha; ignored if BLIT_ALPHA
- * not specified in the blitter operations
- * (see ALPHA_MODE_xxx constants)
- * @param alphaData the alpha blending or mask data, varies depending
- * on the value of alphaMode and sometimes ignored
- * @param alphaStride the alpha data number of bytes per line
- * @param alphaX the top-left x-coord of the alpha blit region
- * @param alphaY the top-left y-coord of the alpha blit region
- * @param destData the destination byte array containing image data
- * @param destDepth the destination depth: one of 1, 2, 4, 8
- * @param destStride the destination number of bytes per line
- * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if destDepth is not 1
- * @param destX the top-left x-coord of the destination blit region
- * @param destY the top-left y-coord of the destination blit region
- * @param destWidth the width of the destination blit region
- * @param destHeight the height of the destination blit region
- * @param destReds the destination palette red component intensities
- * @param destGreens the destination palette green component intensities
- * @param destBlues the destination palette blue component intensities
- * @param flipX if true the resulting image is flipped along the vertical axis
- * @param flipY if true the resulting image is flipped along the horizontal axis
- */
-static void blit(int op,
- byte[] srcData, int srcDepth, int srcStride, int srcOrder,
- int srcX, int srcY, int srcWidth, int srcHeight,
- byte[] srcReds, byte[] srcGreens, byte[] srcBlues,
- int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
- byte[] destData, int destDepth, int destStride, int destOrder,
- int destX, int destY, int destWidth, int destHeight,
- byte[] destReds, byte[] destGreens, byte[] destBlues,
- boolean flipX, boolean flipY) {
- if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;
-
- /*** Prepare scaling data ***/
- final int dwm1 = destWidth - 1;
- final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
- final int dhm1 = destHeight - 1;
- final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;
-
- /*** Prepare source-related data ***/
- final int stype;
- switch (srcDepth) {
- case 8:
- stype = TYPE_INDEX_8;
- break;
- case 4:
- srcStride <<= 1;
- stype = TYPE_INDEX_4;
- break;
- case 2:
- srcStride <<= 2;
- stype = TYPE_INDEX_2;
- break;
- case 1:
- srcStride <<= 3;
- stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int spr = srcY * srcStride + srcX;
-
- /*** Prepare destination-related data ***/
- final int dtype;
- switch (destDepth) {
- case 8:
- dtype = TYPE_INDEX_8;
- break;
- case 4:
- destStride <<= 1;
- dtype = TYPE_INDEX_4;
- break;
- case 2:
- destStride <<= 2;
- dtype = TYPE_INDEX_2;
- break;
- case 1:
- destStride <<= 3;
- dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX);
- final int dprxi = (flipX) ? -1 : 1;
- final int dpryi = (flipY) ? -destStride : destStride;
-
- /*** Prepare special processing data ***/
- int apr;
- if ((op & BLIT_ALPHA) != 0) {
- switch (alphaMode) {
- case ALPHA_MASK_UNPACKED:
- case ALPHA_CHANNEL_SEPARATE:
- if (alphaData == null) alphaMode = 0x10000;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_PACKED:
- if (alphaData == null) alphaMode = 0x10000;
- alphaStride <<= 3;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_INDEX:
- case ALPHA_MASK_RGB:
- if (alphaData == null) alphaMode = 0x10000;
- apr = 0;
- break;
- default:
- alphaMode = (alphaMode << 16) / 255; // prescale
- case ALPHA_CHANNEL_SOURCE:
- apr = 0;
- break;
- }
- } else {
- alphaMode = 0x10000;
- apr = 0;
- }
- final boolean ditherEnabled = (op & BLIT_DITHER) != 0;
-
- /*** Blit ***/
- int dp = dpr;
- int sp = spr;
- int ap = apr;
- int destPaletteSize = 1 << destDepth;
- if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length;
- byte[] paletteMapping = null;
- boolean isExactPaletteMapping = true;
- switch (alphaMode) {
- case 0x10000:
- /*** If the palettes and formats are equivalent use a one-to-one mapping ***/
- if ((stype == dtype) &&
- (srcReds == destReds) && (srcGreens == destGreens) && (srcBlues == destBlues)) {
- paletteMapping = ONE_TO_ONE_MAPPING;
- break;
- /*** If palettes have not been supplied, supply a suitable mapping ***/
- } else if ((srcReds == null) || (destReds == null)) {
- if (srcDepth <= destDepth) {
- paletteMapping = ONE_TO_ONE_MAPPING;
- } else {
- paletteMapping = new byte[1 << srcDepth];
- int mask = (0xff << destDepth) >>> 8;
- for (int i = 0; i < paletteMapping.length; ++i) paletteMapping[i] = (byte)(i & mask);
- }
- break;
- }
- case ALPHA_MASK_UNPACKED:
- case ALPHA_MASK_PACKED:
- case ALPHA_MASK_INDEX:
- case ALPHA_MASK_RGB:
- /*** Generate a palette mapping ***/
- int srcPaletteSize = 1 << srcDepth;
- paletteMapping = new byte[srcPaletteSize];
- if ((srcReds != null) && (srcReds.length < srcPaletteSize)) srcPaletteSize = srcReds.length;
- for (int i = 0, r, g, b, index; i < srcPaletteSize; ++i) {
- r = srcReds[i] & 0xff;
- g = srcGreens[i] & 0xff;
- b = srcBlues[i] & 0xff;
- index = 0;
- int minDistance = 0x7fffffff;
- for (int j = 0, dr, dg, db, distance; j < destPaletteSize; ++j) {
- dr = (destReds[j] & 0xff) - r;
- dg = (destGreens[j] & 0xff) - g;
- db = (destBlues[j] & 0xff) - b;
- distance = dr * dr + dg * dg + db * db;
- if (distance < minDistance) {
- index = j;
- if (distance == 0) break;
- minDistance = distance;
- }
- }
- paletteMapping[i] = (byte)index;
- if (minDistance != 0) isExactPaletteMapping = false;
- }
- break;
- }
- if ((paletteMapping != null) && (isExactPaletteMapping || ! ditherEnabled)) {
- if ((stype == dtype) && (alphaMode == 0x10000)) {
- /*** Fast blit (copy w/ mapping) ***/
- switch (stype) {
- case TYPE_INDEX_8:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- destData[dp] = paletteMapping[srcData[sp] & 0xff];
- sp += (sfx >>> 16);
- }
- }
- break;
- case TYPE_INDEX_4:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- final int v;
- if ((sp & 1) != 0) v = paletteMapping[srcData[sp >> 1] & 0x0f];
- else v = (srcData[sp >> 1] >>> 4) & 0x0f;
- sp += (sfx >>> 16);
- if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | v);
- else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (v << 4));
- }
- }
- break;
- case TYPE_INDEX_2:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- final int index = paletteMapping[(srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03];
- sp += (sfx >>> 16);
- final int shift = 6 - (dp & 3) * 2;
- destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift));
- }
- }
- break;
- case TYPE_INDEX_1_MSB:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- final int index = paletteMapping[(srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01];
- sp += (sfx >>> 16);
- final int shift = 7 - (dp & 7);
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
- }
- }
- break;
- case TYPE_INDEX_1_LSB:
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) {
- final int index = paletteMapping[(srcData[sp >> 3] >>> (sp & 7)) & 0x01];
- sp += (sfx >>> 16);
- final int shift = dp & 7;
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
- }
- }
- break;
- }
- } else {
- /*** Convert between indexed modes using mapping and mask ***/
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
- sp = spr += (sfy >>> 16) * srcStride,
- sfy = (sfy & 0xffff) + sfyi,
- dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
- dp += dprxi,
- sfx = (sfx & 0xffff) + sfxi) {
- int index;
- /*** READ NEXT PIXEL ***/
- switch (stype) {
- case TYPE_INDEX_8:
- index = srcData[sp] & 0xff;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_4:
- if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
- else index = (srcData[sp >> 1] >>> 4) & 0x0f;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_2:
- index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_MSB:
- index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_LSB:
- index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01;
- sp += (sfx >>> 16);
- break;
- default:
- return;
- }
- /*** APPLY MASK ***/
- switch (alphaMode) {
- case ALPHA_MASK_UNPACKED: {
- final byte mask = alphaData[ap];
- ap += (sfx >> 16);
- if (mask == 0) continue;
- } break;
- case ALPHA_MASK_PACKED: {
- final int mask = alphaData[ap >> 3] & (1 << (ap & 7));
- ap += (sfx >> 16);
- if (mask == 0) continue;
- } break;
- case ALPHA_MASK_INDEX: {
- int i = 0;
- while (i < alphaData.length) {
- if (index == (alphaData[i] & 0xff)) break;
- }
- if (i < alphaData.length) continue;
- } break;
- case ALPHA_MASK_RGB: {
- final byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index];
- int i = 0;
- while (i < alphaData.length) {
- if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) break;
- i += 3;
- }
- if (i < alphaData.length) continue;
- } break;
- }
- index = paletteMapping[index] & 0xff;
-
- /*** WRITE NEXT PIXEL ***/
- switch (dtype) {
- case TYPE_INDEX_8:
- destData[dp] = (byte) index;
- break;
- case TYPE_INDEX_4:
- if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | index);
- else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (index << 4));
- break;
- case TYPE_INDEX_2: {
- final int shift = 6 - (dp & 3) * 2;
- destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift));
- } break;
- case TYPE_INDEX_1_MSB: {
- final int shift = 7 - (dp & 7);
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
- } break;
- case TYPE_INDEX_1_LSB: {
- final int shift = dp & 7;
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift));
- } break;
- }
- }
- }
- }
- return;
- }
-
- /*** Comprehensive blit (apply transformations) ***/
- int alpha = alphaMode;
- int index = 0;
- int indexq = 0;
- int lastindex = 0, lastr = -1, lastg = -1, lastb = -1;
- final int[] rerr, gerr, berr;
- if (ditherEnabled) {
- rerr = new int[destWidth + 2];
- gerr = new int[destWidth + 2];
- berr = new int[destWidth + 2];
- } else {
- rerr = null; gerr = null; berr = null;
- }
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
- sp = spr += (sfy >>> 16) * srcStride,
- ap = apr += (sfy >>> 16) * alphaStride,
- sfy = (sfy & 0xffff) + sfyi,
- dp = dpr += dpryi) {
- int lrerr = 0, lgerr = 0, lberr = 0;
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
- dp += dprxi,
- sfx = (sfx & 0xffff) + sfxi) {
- /*** READ NEXT PIXEL ***/
- switch (stype) {
- case TYPE_INDEX_8:
- index = srcData[sp] & 0xff;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_4:
- if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
- else index = (srcData[sp >> 1] >>> 4) & 0x0f;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_2:
- index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_MSB:
- index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_LSB:
- index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01;
- sp += (sfx >>> 16);
- break;
- }
-
- /*** DO SPECIAL PROCESSING IF REQUIRED ***/
- int r = srcReds[index] & 0xff, g = srcGreens[index] & 0xff, b = srcBlues[index] & 0xff;
- switch (alphaMode) {
- case ALPHA_CHANNEL_SEPARATE:
- alpha = ((alphaData[ap] & 0xff) << 16) / 255;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_UNPACKED:
- alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_PACKED:
- alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices
- int i = 0;
- while (i < alphaData.length) {
- if (index == (alphaData[i] & 0xff)) break;
- }
- if (i < alphaData.length) continue;
- } break;
- case ALPHA_MASK_RGB: {
- int i = 0;
- while (i < alphaData.length) {
- if ((r == (alphaData[i] & 0xff)) &&
- (g == (alphaData[i + 1] & 0xff)) &&
- (b == (alphaData[i + 2] & 0xff))) break;
- i += 3;
- }
- if (i < alphaData.length) continue;
- } break;
- }
- if (alpha != 0x10000) {
- if (alpha == 0x0000) continue;
- switch (dtype) {
- case TYPE_INDEX_8:
- indexq = destData[dp] & 0xff;
- break;
- case TYPE_INDEX_4:
- if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f;
- else indexq = (destData[dp >> 1] >>> 4) & 0x0f;
- break;
- case TYPE_INDEX_2:
- indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03;
- break;
- case TYPE_INDEX_1_MSB:
- indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01;
- break;
- case TYPE_INDEX_1_LSB:
- indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01;
- break;
- }
- // Perform alpha blending
- final int rq = destReds[indexq] & 0xff;
- final int gq = destGreens[indexq] & 0xff;
- final int bq = destBlues[indexq] & 0xff;
- r = rq + ((r - rq) * alpha >> 16);
- g = gq + ((g - gq) * alpha >> 16);
- b = bq + ((b - bq) * alpha >> 16);
- }
-
- /*** MAP COLOR TO THE PALETTE ***/
- if (ditherEnabled) {
- // Floyd-Steinberg error diffusion
- r += rerr[dx] >> 4;
- if (r < 0) r = 0; else if (r > 255) r = 255;
- g += gerr[dx] >> 4;
- if (g < 0) g = 0; else if (g > 255) g = 255;
- b += berr[dx] >> 4;
- if (b < 0) b = 0; else if (b > 255) b = 255;
- rerr[dx] = lrerr;
- gerr[dx] = lgerr;
- berr[dx] = lberr;
- }
- if (r != lastr || g != lastg || b != lastb) {
- // moving the variable declarations out seems to make the JDK JIT happier...
- for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) {
- dr = (destReds[j] & 0xff) - r;
- dg = (destGreens[j] & 0xff) - g;
- db = (destBlues[j] & 0xff) - b;
- distance = dr * dr + dg * dg + db * db;
- if (distance < minDistance) {
- lastindex = j;
- if (distance == 0) break;
- minDistance = distance;
- }
- }
- lastr = r; lastg = g; lastb = b;
- }
- if (ditherEnabled) {
- // Floyd-Steinberg error diffusion, cont'd...
- final int dxm1 = dx - 1, dxp1 = dx + 1;
- int acc;
- rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr;
- rerr[dx] += acc += lrerr + lrerr;
- rerr[dxm1] += acc + lrerr + lrerr;
- gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr;
- gerr[dx] += acc += lgerr + lgerr;
- gerr[dxm1] += acc + lgerr + lgerr;
- berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr;
- berr[dx] += acc += lberr + lberr;
- berr[dxm1] += acc + lberr + lberr;
- }
-
- /*** WRITE NEXT PIXEL ***/
- switch (dtype) {
- case TYPE_INDEX_8:
- destData[dp] = (byte) lastindex;
- break;
- case TYPE_INDEX_4:
- if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex);
- else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4));
- break;
- case TYPE_INDEX_2: {
- final int shift = 6 - (dp & 3) * 2;
- destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift));
- } break;
- case TYPE_INDEX_1_MSB: {
- final int shift = 7 - (dp & 7);
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
- } break;
- case TYPE_INDEX_1_LSB: {
- final int shift = dp & 7;
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
- } break;
- }
- }
- }
-}
-
-/**
- * Blits an index palette image into a direct palette image.
- * <p>
- * Note: The source and destination masks and palettes must
- * always be fully specified.
- * </p>
- *
- * @param op the blitter operation: a combination of BLIT_xxx flags
- * (see BLIT_xxx constants)
- * @param srcData the source byte array containing image data
- * @param srcDepth the source depth: one of 1, 2, 4, 8
- * @param srcStride the source number of bytes per line
- * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if srcDepth is not 1
- * @param srcX the top-left x-coord of the source blit region
- * @param srcY the top-left y-coord of the source blit region
- * @param srcWidth the width of the source blit region
- * @param srcHeight the height of the source blit region
- * @param srcReds the source palette red component intensities
- * @param srcGreens the source palette green component intensities
- * @param srcBlues the source palette blue component intensities
- * @param alphaMode the alpha blending or mask mode, may be
- * an integer 0-255 for global alpha; ignored if BLIT_ALPHA
- * not specified in the blitter operations
- * (see ALPHA_MODE_xxx constants)
- * @param alphaData the alpha blending or mask data, varies depending
- * on the value of alphaMode and sometimes ignored
- * @param alphaStride the alpha data number of bytes per line
- * @param alphaX the top-left x-coord of the alpha blit region
- * @param alphaY the top-left y-coord of the alpha blit region
- * @param destData the destination byte array containing image data
- * @param destDepth the destination depth: one of 8, 16, 24, 32
- * @param destStride the destination number of bytes per line
- * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if destDepth is not 16 or 32
- * @param destX the top-left x-coord of the destination blit region
- * @param destY the top-left y-coord of the destination blit region
- * @param destWidth the width of the destination blit region
- * @param destHeight the height of the destination blit region
- * @param destRedMask the destination red channel mask
- * @param destGreenMask the destination green channel mask
- * @param destBlueMask the destination blue channel mask
- * @param flipX if true the resulting image is flipped along the vertical axis
- * @param flipY if true the resulting image is flipped along the horizontal axis
- */
-static void blit(int op,
- byte[] srcData, int srcDepth, int srcStride, int srcOrder,
- int srcX, int srcY, int srcWidth, int srcHeight,
- byte[] srcReds, byte[] srcGreens, byte[] srcBlues,
- int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
- byte[] destData, int destDepth, int destStride, int destOrder,
- int destX, int destY, int destWidth, int destHeight,
- int destRedMask, int destGreenMask, int destBlueMask,
- boolean flipX, boolean flipY) {
- if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;
-
- // these should be supplied as params later
- final int destAlphaMask = 0;
-
- /*** Prepare scaling data ***/
- final int dwm1 = destWidth - 1;
- final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
- final int dhm1 = destHeight - 1;
- final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;
-
- /*** Prepare source-related data ***/
- final int stype;
- switch (srcDepth) {
- case 8:
- stype = TYPE_INDEX_8;
- break;
- case 4:
- srcStride <<= 1;
- stype = TYPE_INDEX_4;
- break;
- case 2:
- srcStride <<= 2;
- stype = TYPE_INDEX_2;
- break;
- case 1:
- srcStride <<= 3;
- stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int spr = srcY * srcStride + srcX;
-
- /*** Prepare destination-related data ***/
- final int dbpp, dtype;
- switch (destDepth) {
- case 8:
- dbpp = 1;
- dtype = TYPE_GENERIC_8;
- break;
- case 16:
- dbpp = 2;
- dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
- break;
- case 24:
- dbpp = 3;
- dtype = TYPE_GENERIC_24;
- break;
- case 32:
- dbpp = 4;
- dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid destination type");
- return;
- }
- int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp;
- final int dprxi = (flipX) ? -dbpp : dbpp;
- final int dpryi = (flipY) ? -destStride : destStride;
-
- /*** Prepare special processing data ***/
- int apr;
- if ((op & BLIT_ALPHA) != 0) {
- switch (alphaMode) {
- case ALPHA_MASK_UNPACKED:
- case ALPHA_CHANNEL_SEPARATE:
- if (alphaData == null) alphaMode = 0x10000;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_PACKED:
- if (alphaData == null) alphaMode = 0x10000;
- alphaStride <<= 3;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_INDEX:
- case ALPHA_MASK_RGB:
- if (alphaData == null) alphaMode = 0x10000;
- apr = 0;
- break;
- default:
- alphaMode = (alphaMode << 16) / 255; // prescale
- case ALPHA_CHANNEL_SOURCE:
- apr = 0;
- break;
- }
- } else {
- alphaMode = 0x10000;
- apr = 0;
- }
-
- /*** Comprehensive blit (apply transformations) ***/
- final int destRedShift = getChannelShift(destRedMask);
- final int destRedWidth = getChannelWidth(destRedMask, destRedShift);
- final byte[] destReds = ANY_TO_EIGHT[destRedWidth];
- final int destRedPreShift = 8 - destRedWidth;
- final int destGreenShift = getChannelShift(destGreenMask);
- final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift);
- final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth];
- final int destGreenPreShift = 8 - destGreenWidth;
- final int destBlueShift = getChannelShift(destBlueMask);
- final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift);
- final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth];
- final int destBluePreShift = 8 - destBlueWidth;
- final int destAlphaShift = getChannelShift(destAlphaMask);
- final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift);
- final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth];
- final int destAlphaPreShift = 8 - destAlphaWidth;
-
- int dp = dpr;
- int sp = spr;
- int ap = apr, alpha = alphaMode;
- int r = 0, g = 0, b = 0, a = 0, index = 0;
- int rq = 0, gq = 0, bq = 0, aq = 0;
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
- sp = spr += (sfy >>> 16) * srcStride,
- ap = apr += (sfy >>> 16) * alphaStride,
- sfy = (sfy & 0xffff) + sfyi,
- dp = dpr += dpryi) {
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
- dp += dprxi,
- sfx = (sfx & 0xffff) + sfxi) {
- /*** READ NEXT PIXEL ***/
- switch (stype) {
- case TYPE_INDEX_8:
- index = srcData[sp] & 0xff;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_4:
- if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f;
- else index = (srcData[sp >> 1] >>> 4) & 0x0f;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_2:
- index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_MSB:
- index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01;
- sp += (sfx >>> 16);
- break;
- case TYPE_INDEX_1_LSB:
- index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01;
- sp += (sfx >>> 16);
- break;
- }
-
- /*** DO SPECIAL PROCESSING IF REQUIRED ***/
- r = srcReds[index] & 0xff;
- g = srcGreens[index] & 0xff;
- b = srcBlues[index] & 0xff;
- switch (alphaMode) {
- case ALPHA_CHANNEL_SEPARATE:
- alpha = ((alphaData[ap] & 0xff) << 16) / 255;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_UNPACKED:
- alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_PACKED:
- alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices
- int i = 0;
- while (i < alphaData.length) {
- if (index == (alphaData[i] & 0xff)) break;
- }
- if (i < alphaData.length) continue;
- } break;
- case ALPHA_MASK_RGB: {
- int i = 0;
- while (i < alphaData.length) {
- if ((r == (alphaData[i] & 0xff)) &&
- (g == (alphaData[i + 1] & 0xff)) &&
- (b == (alphaData[i + 2] & 0xff))) break;
- i += 3;
- }
- if (i < alphaData.length) continue;
- } break;
- }
- if (alpha != 0x10000) {
- if (alpha == 0x0000) continue;
- switch (dtype) {
- case TYPE_GENERIC_8: {
- final int data = destData[dp] & 0xff;
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_MSB: {
- final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_LSB: {
- final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_24: {
- final int data = (( ((destData[dp] & 0xff) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp + 2] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_MSB: {
- final int data = (( (( ((destData[dp] & 0xff) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp + 2] & 0xff)) << 8) |
- (destData[dp + 3] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_LSB: {
- final int data = (( (( ((destData[dp + 3] & 0xff) << 8) |
- (destData[dp + 2] & 0xff)) << 8) |
- (destData[dp + 1] & 0xff)) << 8) |
- (destData[dp] & 0xff);
- rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff;
- gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff;
- bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff;
- aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff;
- } break;
- }
- // Perform alpha blending
- a = aq + ((a - aq) * alpha >> 16);
- r = rq + ((r - rq) * alpha >> 16);
- g = gq + ((g - gq) * alpha >> 16);
- b = bq + ((b - bq) * alpha >> 16);
- }
-
- /*** WRITE NEXT PIXEL ***/
- final int data =
- (r >>> destRedPreShift << destRedShift) |
- (g >>> destGreenPreShift << destGreenShift) |
- (b >>> destBluePreShift << destBlueShift) |
- (a >>> destAlphaPreShift << destAlphaShift);
- switch (dtype) {
- case TYPE_GENERIC_8: {
- destData[dp] = (byte) data;
- } break;
- case TYPE_GENERIC_16_MSB: {
- destData[dp] = (byte) (data >>> 8);
- destData[dp + 1] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_16_LSB: {
- destData[dp] = (byte) (data & 0xff);
- destData[dp + 1] = (byte) (data >>> 8);
- } break;
- case TYPE_GENERIC_24: {
- destData[dp] = (byte) (data >>> 16);
- destData[dp + 1] = (byte) (data >>> 8);
- destData[dp + 2] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_32_MSB: {
- destData[dp] = (byte) (data >>> 24);
- destData[dp + 1] = (byte) (data >>> 16);
- destData[dp + 2] = (byte) (data >>> 8);
- destData[dp + 3] = (byte) (data & 0xff);
- } break;
- case TYPE_GENERIC_32_LSB: {
- destData[dp] = (byte) (data & 0xff);
- destData[dp + 1] = (byte) (data >>> 8);
- destData[dp + 2] = (byte) (data >>> 16);
- destData[dp + 3] = (byte) (data >>> 24);
- } break;
- }
- }
- }
-}
-
-/**
- * Blits a direct palette image into an index palette image.
- * <p>
- * Note: The source and destination masks and palettes must
- * always be fully specified.
- * </p>
- *
- * @param op the blitter operation: a combination of BLIT_xxx flags
- * (see BLIT_xxx constants)
- * @param srcData the source byte array containing image data
- * @param srcDepth the source depth: one of 8, 16, 24, 32
- * @param srcStride the source number of bytes per line
- * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if srcDepth is not 16 or 32
- * @param srcX the top-left x-coord of the source blit region
- * @param srcY the top-left y-coord of the source blit region
- * @param srcWidth the width of the source blit region
- * @param srcHeight the height of the source blit region
- * @param srcRedMask the source red channel mask
- * @param srcGreenMask the source green channel mask
- * @param srcBlueMask the source blue channel mask
- * @param alphaMode the alpha blending or mask mode, may be
- * an integer 0-255 for global alpha; ignored if BLIT_ALPHA
- * not specified in the blitter operations
- * (see ALPHA_MODE_xxx constants)
- * @param alphaData the alpha blending or mask data, varies depending
- * on the value of alphaMode and sometimes ignored
- * @param alphaStride the alpha data number of bytes per line
- * @param alphaX the top-left x-coord of the alpha blit region
- * @param alphaY the top-left y-coord of the alpha blit region
- * @param destData the destination byte array containing image data
- * @param destDepth the destination depth: one of 1, 2, 4, 8
- * @param destStride the destination number of bytes per line
- * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST;
- * ignored if destDepth is not 1
- * @param destX the top-left x-coord of the destination blit region
- * @param destY the top-left y-coord of the destination blit region
- * @param destWidth the width of the destination blit region
- * @param destHeight the height of the destination blit region
- * @param destReds the destination palette red component intensities
- * @param destGreens the destination palette green component intensities
- * @param destBlues the destination palette blue component intensities
- * @param flipX if true the resulting image is flipped along the vertical axis
- * @param flipY if true the resulting image is flipped along the horizontal axis
- */
-static void blit(int op,
- byte[] srcData, int srcDepth, int srcStride, int srcOrder,
- int srcX, int srcY, int srcWidth, int srcHeight,
- int srcRedMask, int srcGreenMask, int srcBlueMask,
- int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY,
- byte[] destData, int destDepth, int destStride, int destOrder,
- int destX, int destY, int destWidth, int destHeight,
- byte[] destReds, byte[] destGreens, byte[] destBlues,
- boolean flipX, boolean flipY) {
- if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return;
-
- // these should be supplied as params later
- final int srcAlphaMask = 0;
-
- /*** Prepare scaling data ***/
- final int dwm1 = destWidth - 1;
- final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0;
- final int dhm1 = destHeight - 1;
- final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0;
-
- /*** Prepare source-related data ***/
- final int sbpp, stype;
- switch (srcDepth) {
- case 8:
- sbpp = 1;
- stype = TYPE_GENERIC_8;
- break;
- case 16:
- sbpp = 2;
- stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB;
- break;
- case 24:
- sbpp = 3;
- stype = TYPE_GENERIC_24;
- break;
- case 32:
- sbpp = 4;
- stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int spr = srcY * srcStride + srcX * sbpp;
-
- /*** Prepare destination-related data ***/
- final int dtype;
- switch (destDepth) {
- case 8:
- dtype = TYPE_INDEX_8;
- break;
- case 4:
- destStride <<= 1;
- dtype = TYPE_INDEX_4;
- break;
- case 2:
- destStride <<= 2;
- dtype = TYPE_INDEX_2;
- break;
- case 1:
- destStride <<= 3;
- dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB;
- break;
- default:
- //throw new IllegalArgumentException("Invalid source type");
- return;
- }
- int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX);
- final int dprxi = (flipX) ? -1 : 1;
- final int dpryi = (flipY) ? -destStride : destStride;
-
- /*** Prepare special processing data ***/
- int apr;
- if ((op & BLIT_ALPHA) != 0) {
- switch (alphaMode) {
- case ALPHA_MASK_UNPACKED:
- case ALPHA_CHANNEL_SEPARATE:
- if (alphaData == null) alphaMode = 0x10000;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_PACKED:
- if (alphaData == null) alphaMode = 0x10000;
- alphaStride <<= 3;
- apr = alphaY * alphaStride + alphaX;
- break;
- case ALPHA_MASK_INDEX:
- //throw new IllegalArgumentException("Invalid alpha type");
- return;
- case ALPHA_MASK_RGB:
- if (alphaData == null) alphaMode = 0x10000;
- apr = 0;
- break;
- default:
- alphaMode = (alphaMode << 16) / 255; // prescale
- case ALPHA_CHANNEL_SOURCE:
- apr = 0;
- break;
- }
- } else {
- alphaMode = 0x10000;
- apr = 0;
- }
- final boolean ditherEnabled = (op & BLIT_DITHER) != 0;
-
- /*** Comprehensive blit (apply transformations) ***/
- final int srcRedShift = getChannelShift(srcRedMask);
- final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)];
- final int srcGreenShift = getChannelShift(srcGreenMask);
- final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)];
- final int srcBlueShift = getChannelShift(srcBlueMask);
- final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)];
- final int srcAlphaShift = getChannelShift(srcAlphaMask);
- final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)];
-
- int dp = dpr;
- int sp = spr;
- int ap = apr, alpha = alphaMode;
- int r = 0, g = 0, b = 0, a = 0;
- int indexq = 0;
- int lastindex = 0, lastr = -1, lastg = -1, lastb = -1;
- final int[] rerr, gerr, berr;
- int destPaletteSize = 1 << destDepth;
- if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length;
- if (ditherEnabled) {
- rerr = new int[destWidth + 2];
- gerr = new int[destWidth + 2];
- berr = new int[destWidth + 2];
- } else {
- rerr = null; gerr = null; berr = null;
- }
- for (int dy = destHeight, sfy = sfyi; dy > 0; --dy,
- sp = spr += (sfy >>> 16) * srcStride,
- ap = apr += (sfy >>> 16) * alphaStride,
- sfy = (sfy & 0xffff) + sfyi,
- dp = dpr += dpryi) {
- int lrerr = 0, lgerr = 0, lberr = 0;
- for (int dx = destWidth, sfx = sfxi; dx > 0; --dx,
- dp += dprxi,
- sfx = (sfx & 0xffff) + sfxi) {
- /*** READ NEXT PIXEL ***/
- switch (stype) {
- case TYPE_GENERIC_8: {
- final int data = srcData[sp] & 0xff;
- sp += (sfx >>> 16);
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_MSB: {
- final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff);
- sp += (sfx >>> 16) * 2;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_16_LSB: {
- final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff);
- sp += (sfx >>> 16) * 2;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_24: {
- final int data = (( ((srcData[sp] & 0xff) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp + 2] & 0xff);
- sp += (sfx >>> 16) * 3;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_MSB: {
- final int data = (( (( ((srcData[sp] & 0xff) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp + 2] & 0xff)) << 8) |
- (srcData[sp + 3] & 0xff);
- sp += (sfx >>> 16) * 4;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- case TYPE_GENERIC_32_LSB: {
- final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) |
- (srcData[sp + 2] & 0xff)) << 8) |
- (srcData[sp + 1] & 0xff)) << 8) |
- (srcData[sp] & 0xff);
- sp += (sfx >>> 16) * 4;
- r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff;
- g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff;
- b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff;
- a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff;
- } break;
- }
-
- /*** DO SPECIAL PROCESSING IF REQUIRED ***/
- switch (alphaMode) {
- case ALPHA_CHANNEL_SEPARATE:
- alpha = ((alphaData[ap] & 0xff) << 16) / 255;
- ap += (sfx >> 16);
- break;
- case ALPHA_CHANNEL_SOURCE:
- alpha = (a << 16) / 255;
- break;
- case ALPHA_MASK_UNPACKED:
- alpha = (alphaData[ap] != 0) ? 0x10000 : 0;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_PACKED:
- alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000;
- ap += (sfx >> 16);
- break;
- case ALPHA_MASK_RGB:
- alpha = 0x10000;
- for (int i = 0; i < alphaData.length; i += 3) {
- if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) {
- alpha = 0x0000;
- break;
- }
- }
- break;
- }
- if (alpha != 0x10000) {
- if (alpha == 0x0000) continue;
- switch (dtype) {
- case TYPE_INDEX_8:
- indexq = destData[dp] & 0xff;
- break;
- case TYPE_INDEX_4:
- if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f;
- else indexq = (destData[dp >> 1] >>> 4) & 0x0f;
- break;
- case TYPE_INDEX_2:
- indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03;
- break;
- case TYPE_INDEX_1_MSB:
- indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01;
- break;
- case TYPE_INDEX_1_LSB:
- indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01;
- break;
- }
- // Perform alpha blending
- final int rq = destReds[indexq] & 0xff;
- final int gq = destGreens[indexq] & 0xff;
- final int bq = destBlues[indexq] & 0xff;
- r = rq + ((r - rq) * alpha >> 16);
- g = gq + ((g - gq) * alpha >> 16);
- b = bq + ((b - bq) * alpha >> 16);
- }
-
- /*** MAP COLOR TO THE PALETTE ***/
- if (ditherEnabled) {
- // Floyd-Steinberg error diffusion
- r += rerr[dx] >> 4;
- if (r < 0) r = 0; else if (r > 255) r = 255;
- g += gerr[dx] >> 4;
- if (g < 0) g = 0; else if (g > 255) g = 255;
- b += berr[dx] >> 4;
- if (b < 0) b = 0; else if (b > 255) b = 255;
- rerr[dx] = lrerr;
- gerr[dx] = lgerr;
- berr[dx] = lberr;
- }
- if (r != lastr || g != lastg || b != lastb) {
- // moving the variable declarations out seems to make the JDK JIT happier...
- for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) {
- dr = (destReds[j] & 0xff) - r;
- dg = (destGreens[j] & 0xff) - g;
- db = (destBlues[j] & 0xff) - b;
- distance = dr * dr + dg * dg + db * db;
- if (distance < minDistance) {
- lastindex = j;
- if (distance == 0) break;
- minDistance = distance;
- }
- }
- lastr = r; lastg = g; lastb = b;
- }
- if (ditherEnabled) {
- // Floyd-Steinberg error diffusion, cont'd...
- final int dxm1 = dx - 1, dxp1 = dx + 1;
- int acc;
- rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr;
- rerr[dx] += acc += lrerr + lrerr;
- rerr[dxm1] += acc + lrerr + lrerr;
- gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr;
- gerr[dx] += acc += lgerr + lgerr;
- gerr[dxm1] += acc + lgerr + lgerr;
- berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr;
- berr[dx] += acc += lberr + lberr;
- berr[dxm1] += acc + lberr + lberr;
- }
-
- /*** WRITE NEXT PIXEL ***/
- switch (dtype) {
- case TYPE_INDEX_8:
- destData[dp] = (byte) lastindex;
- break;
- case TYPE_INDEX_4:
- if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex);
- else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4));
- break;
- case TYPE_INDEX_2: {
- final int shift = 6 - (dp & 3) * 2;
- destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift));
- } break;
- case TYPE_INDEX_1_MSB: {
- final int shift = 7 - (dp & 7);
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
- } break;
- case TYPE_INDEX_1_LSB: {
- final int shift = dp & 7;
- destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift));
- } break;
- }
- }
- }
-}
-
-/**
- * Computes the required channel shift from a mask.
- */
-static int getChannelShift(int mask) {
- if (mask == 0) return 0;
- int i;
- for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) {
- mask >>>= 1;
- }
- return i;
-}
-
-/**
- * Computes the required channel width (depth) from a mask.
- */
-static int getChannelWidth(int mask, int shift) {
- if (mask == 0) return 0;
- int i;
- mask >>>= shift;
- for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) {
- mask >>>= 1;
- }
- return i - shift;
-}
-
-/**
- * Extracts a field from packed RGB data given a mask for that field.
- */
-static byte getChannelField(int data, int mask) {
- final int shift = getChannelShift(mask);
- return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >>> shift];
-}
-
-/**
- * Creates an ImageData containing one band's worth of a gradient filled
- * block. If <code>vertical</code> is true, the band must be tiled
- * horizontally to fill a region, otherwise it must be tiled vertically.
- *
- * @param width the width of the region to be filled
- * @param height the height of the region to be filled
- * @param vertical if true sweeps from top to bottom, else
- * sweeps from left to right
- * @param fromRGB the color to start with
- * @param toRGB the color to end with
- * @param redBits the number of significant red bits, 0 for palette modes
- * @param greenBits the number of significant green bits, 0 for palette modes
- * @param blueBits the number of significant blue bits, 0 for palette modes
- * @return the new ImageData
- */
-static ImageData createGradientBand(
- int width, int height, boolean vertical,
- RGB fromRGB, RGB toRGB,
- int redBits, int greenBits, int blueBits) {
- /* Gradients are drawn as tiled bands */
- final int bandWidth, bandHeight, bitmapDepth;
- final byte[] bitmapData;
- final PaletteData paletteData;
- /* Select an algorithm depending on the depth of the screen */
- if (redBits != 0 && greenBits != 0 && blueBits != 0) {
- paletteData = new PaletteData(0x0000ff00, 0x00ff0000, 0xff000000);
- bitmapDepth = 32;
- if (redBits >= 8 && greenBits >= 8 && blueBits >= 8) {
- /* Precise color */
- final int steps;
- if (vertical) {
- bandWidth = 1;
- bandHeight = height;
- steps = bandHeight > 1 ? bandHeight - 1 : 1;
- } else {
- bandWidth = width;
- bandHeight = 1;
- steps = bandWidth > 1 ? bandWidth - 1 : 1;
- }
- final int bytesPerLine = bandWidth * 4;
- bitmapData = new byte[bandHeight * bytesPerLine];
- buildPreciseGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine);
- buildPreciseGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine);
- buildPreciseGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine);
- } else {
- /* Dithered color */
- final int steps;
- if (vertical) {
- bandWidth = (width < 8) ? width : 8;
- bandHeight = height;
- steps = bandHeight > 1 ? bandHeight - 1 : 1;
- } else {
- bandWidth = width;
- bandHeight = (height < 8) ? height : 8;
- steps = bandWidth > 1 ? bandWidth - 1 : 1;
- }
- final int bytesPerLine = bandWidth * 4;
- bitmapData = new byte[bandHeight * bytesPerLine];
- buildDitheredGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine, blueBits);
- buildDitheredGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine, greenBits);
- buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits);
- }
- } else {
- /* Dithered two tone */
- paletteData = new PaletteData(new RGB[] { fromRGB, toRGB });
- bitmapDepth = 8;
- final int blendi;
- if (vertical) {
- bandWidth = (width < 8) ? width : 8;
- bandHeight = height;
- blendi = (bandHeight > 1) ? 0x1040000 / (bandHeight - 1) + 1 : 1;
- } else {
- bandWidth = width;
- bandHeight = (height < 8) ? height : 8;
- blendi = (bandWidth > 1) ? 0x1040000 / (bandWidth - 1) + 1 : 1;
- }
- final int bytesPerLine = (bandWidth + 3) & -4;
- bitmapData = new byte[bandHeight * bytesPerLine];
- if (vertical) {
- for (int dy = 0, blend = 0, dp = 0; dy < bandHeight;
- ++dy, blend += blendi, dp += bytesPerLine) {
- for (int dx = 0; dx < bandWidth; ++dx) {
- bitmapData[dp + dx] = (blend + DITHER_MATRIX[dy & 7][dx]) <
- 0x1000000 ? (byte)0 : (byte)1;
- }
- }
- } else {
- for (int dx = 0, blend = 0; dx < bandWidth; ++dx, blend += blendi) {
- for (int dy = 0, dptr = dx; dy < bandHeight; ++dy, dptr += bytesPerLine) {
- bitmapData[dptr] = (blend + DITHER_MATRIX[dy][dx & 7]) <
- 0x1000000 ? (byte)0 : (byte)1;
- }
- }
- }
- }
- return new ImageData(bandWidth, bandHeight, bitmapDepth, paletteData, 4, bitmapData);
-}
-
-/*
- * Fill in gradated values for a color channel
- */
-static final void buildPreciseGradientChannel(int from, int to, int steps,
- int bandWidth, int bandHeight, boolean vertical,
- byte[] bitmapData, int dp, int bytesPerLine) {
- int val = from << 16;
- final int inc = ((to << 16) - val) / steps + 1;
- if (vertical) {
- for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) {
- bitmapData[dp] = (byte)(val >>> 16);
- val += inc;
- }
- } else {
- for (int dx = 0; dx < bandWidth; ++dx, dp += 4) {
- bitmapData[dp] = (byte)(val >>> 16);
- val += inc;
- }
- }
-}
-
-/*
- * Fill in dithered gradated values for a color channel
- */
-static final void buildDitheredGradientChannel(int from, int to, int steps,
- int bandWidth, int bandHeight, boolean vertical,
- byte[] bitmapData, int dp, int bytesPerLine, int bits) {
- final int mask = 0xff00 >>> bits;
- int val = from << 16;
- final int inc = ((to << 16) - val) / steps + 1;
- if (vertical) {
- for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) {
- for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) {
- final int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits;
- int temp = val + thresh;
- if (temp > 0xffffff) bitmapData[dptr] = -1;
- else bitmapData[dptr] = (byte)((temp >>> 16) & mask);
- }
- val += inc;
- }
- } else {
- for (int dx = 0; dx < bandWidth; ++dx, dp += 4) {
- for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) {
- final int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits;
- int temp = val + thresh;
- if (temp > 0xffffff) bitmapData[dptr] = -1;
- else bitmapData[dptr] = (byte)((temp >>> 16) & mask);
- }
- val += inc;
- }
- }
-}
-
-/**
- * Renders a gradient onto a GC.
- * <p>
- * This is a GC helper.
- * </p>
- *
- * @param gc the GC to render the gradient onto
- * @param device the device the GC belongs to
- * @param x the top-left x coordinate of the region to be filled
- * @param y the top-left y coordinate of the region to be filled
- * @param width the width of the region to be filled
- * @param height the height of the region to be filled
- * @param vertical if true sweeps from top to bottom, else
- * sweeps from left to right
- * @param fromRGB the color to start with
- * @param toRGB the color to end with
- * @param redBits the number of significant red bits, 0 for palette modes
- * @param greenBits the number of significant green bits, 0 for palette modes
- * @param blueBits the number of significant blue bits, 0 for palette modes
- */
-static void fillGradientRectangle(GC gc, Device device,
- int x, int y, int width, int height, boolean vertical,
- RGB fromRGB, RGB toRGB,
- int redBits, int greenBits, int blueBits) {
- /* Create the bitmap and tile it */
- ImageData band = createGradientBand(width, height, vertical,
- fromRGB, toRGB, redBits, greenBits, blueBits);
- Image image = new Image(device, band);
- if ((band.width == 1) || (band.height == 1)) {
- gc.drawImage(image, 0, 0, band.width, band.height, x, y, width, height);
- } else {
- if (vertical) {
- for (int dx = 0; dx < width; dx += band.width) {
- int blitWidth = width - dx;
- if (blitWidth > band.width) blitWidth = band.width;
- gc.drawImage(image, 0, 0, blitWidth, band.height, dx + x, y, blitWidth, band.height);
- }
- } else {
- for (int dy = 0; dy < height; dy += band.height) {
- int blitHeight = height - dy;
- if (blitHeight > band.height) blitHeight = band.height;
- gc.drawImage(image, 0, 0, band.width, blitHeight, x, dy + y, band.width, blitHeight);
- }
- }
- }
- image.dispose();
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; +import org.eclipse.swt.*; +import org.eclipse.swt.internal.CloneableCompatibility; + +/** + * Instances of this class are device-independent descriptions + * of images. They are typically used as an intermediate format + * between loading from or writing to streams and creating an + * <code>Image</code>. + * <p> + * Note that the public fields <code>x</code>, <code>y</code>, + * <code>disposalMethod</code> and <code>delayTime</code> are + * typically only used when the image is in a set of images used + * for animation. + * </p> + * + * @see Image + * @see ImageLoader + */ + +public final class ImageData implements CloneableCompatibility { + + /** + * the width of the image, in pixels + */ + public int width; + + /** + * the height of the image, in pixels + */ + public int height; + + /** + * the color depth of the image, in bits per pixel + * <p> + * Note that a depth of 8 or less does not necessary + * mean that the image is palette indexed, or + * conversely that a depth greater than 8 means that + * the image is direct color. Check the associated + * PaletteData's isDirect field for such determinations. + */ + public int depth; + + /** + * the scanline padding + * <p> + * If one scanline of the image is not a multiple of + * this number, it will be padded with zeros until it is. + * </p> + */ + public int scanlinePad; + + /** + * the number of bytes per scanline + * <p> + * This is a multiple of the scanline padding. + * </p> + */ + public int bytesPerLine; + + /** + * the pixel data of the image + * <p> + * Note that for 16 bit depth images the pixel data is stored + * in least significant byte order; however, for 24bit and + * 32bit depth images the pixel data is stored in most + * significant byte order. + * </p> + */ + public byte[] data; + + /** + * the color table for the image + */ + public PaletteData palette; + + /** + * the transparent pixel + * <p> + * Pixels with this value are transparent. + * </p><p> + * The default is -1 which means 'no transparent pixel'. + * </p> + */ + public int transparentPixel; + + /** + * icon-specific field containing the data from the icon mask + * <p> + * This is a 1 bit bitmap stored with the most significant + * bit first. The number of bytes per scanline is + * '((width + 7) / 8 + (maskPad - 1)) / maskPad * maskPad'. + * </p><p> + * The default is null which means 'no transparency mask'. + * </p> + */ + public byte[] maskData; + + /** + * icon-specific field containing the scanline pad of the mask + * <p> + * If one scanline of the transparency mask is not a + * multiple of this number, it will be padded with zeros until + * it is. + * </p> + */ + public int maskPad; + + /** + * the alpha data of the image + * <p> + * Every pixel can have an <em>alpha blending</em> value that + * varies from 0, meaning fully transparent, to 255 meaning + * fully opaque. The number of bytes per scanline is + * 'width'. + * </p> + */ + public byte[] alphaData; + + /** + * the global alpha value to be used for every pixel + * <p> + * If this value is set, the <code>alphaData</code> field + * is ignored and when the image is rendered each pixel + * will be blended with the background an amount + * proportional to this value. + * </p><p> + * The default is -1 which means 'no global alpha value' + * </p> + */ + public int alpha; + + /** + * the type of file that the image was read in from, + * expressed as one of the following values: + * <dl> + * <dt><code>IMAGE_BMP</code></dt> + * <dd>Windows BMP file format, no compression</dd> + * <dt><code>IMAGE_BMP_RLE</code></dt> + * <dd>Windows BMP file format, RLE compression if appropriate</dd> + * <dt><code>IMAGE_GIF</code></dt> + * <dd>GIF file format</dd> + * <dt><code>IMAGE_ICO</code></dt> + * <dd>Windows ICO file format</dd> + * <dt><code>IMAGE_JPEG</code></dt> + * <dd>JPEG file format</dd> + * <dt><code>IMAGE_PNG</code></dt> + * <dd>PNG file format</dd> + * </dl> + */ + public int type; + + /** + * the x coordinate of the top left corner of the image + * within the logical screen (this field corresponds to + * the GIF89a Image Left Position value) + */ + public int x; + + /** + * The y coordinate of the top left corner of the image + * within the logical screen (this field corresponds to + * the GIF89a Image Top Position value) + */ + public int y; + + /** + * a description of how to dispose of the current image + * before displaying the next, expressed as one of the + * following values: + * <dl> + * <dt><code>DM_UNSPECIFIED</code></dt> + * <dd>disposal method not specified</dd> + * <dt><code>DM_FILL_NONE</code></dt> + * <dd>do nothing - leave the image in place</dd> + * <dt><code>DM_FILL_BACKGROUND</code></dt> + * <dd>fill with the background color</dd> + * <dt><code>DM_FILL_PREVIOUS</code></dt> + * <dd>restore the previous picture</dd> + * </dl> + * (this field corresponds to the GIF89a Disposal Method value) + */ + public int disposalMethod; + + /** + * the time to delay before displaying the next image + * in an animation (this field corresponds to the GIF89a + * Delay Time value) + */ + public int delayTime; + + /** + * Arbitrary channel width data to 8-bit conversion table + */ + static final byte[][] ANY_TO_EIGHT = new byte[9][]; + static { + for (int b = 0; b < 9; ++b) { + byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b]; + if (b == 0) continue; + int inc = 0; + for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit; + for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8); + } + } + static final byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8]; + + /** + * Scaled 8x8 Bayer dither matrix + */ + static final int[][] DITHER_MATRIX = { + { 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 }, + { 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 }, + { 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 }, + { 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 }, + { 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 }, + { 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 }, + { 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 }, + { 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 } + }; + +/** + * Constructs a new, empty ImageData with the given width, height, + * depth and palette. The data will be initialized to an (all zero) + * array of the appropriate size. + * + * @param width the width of the image + * @param height the height of the image + * @param depth the depth of the image + * @param palette the palette of the image (must not be null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the width or height is negative</li> + * <li>ERROR_NULL_ARGUMENT - if the palette is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH - if the depth argument is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public ImageData(int width, int height, int depth, PaletteData palette) { + this(width, height, depth, palette, + 4, null, 0, null, + null, -1, -1, SWT.IMAGE_UNDEFINED, + 0, 0, 0, 0); +} + +/** + * Constructs a new, empty ImageData with the given width, height, + * depth, palette, scanlinePad and data. + * + * @param width the width of the image + * @param height the height of the image + * @param depth the depth of the image + * @param palette the palette of the image + * @param scanlinePad the padding of each line, in bytes + * @param data the data of the image + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the width or height is negative</li> + * <li>ERROR_NULL_ARGUMENT - if the palette or data is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH - if the depth argument is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public ImageData(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) { + this(width, height, depth, palette, + scanlinePad, checkData(data), 0, null, + null, -1, -1, SWT.IMAGE_UNDEFINED, + 0, 0, 0, 0); +} + +/** + * Constructs an <code>ImageData</code> loaded from the specified + * input stream. Throws an error if an error occurs while loading + * the image, or if the image has an unsupported type. + * <p> + * This constructor is provided for convenience when loading a single + * image only. If the stream contains multiple images, only the first + * one will be loaded. To load multiple images, use + * <code>ImageLoader.load()</code>. + * </p> + * + * @param stream the input stream to load the image from (must not be null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the stream is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li> + * <li>ERROR_IO - if an IO error occurs while reading data</li> + * </ul> + * + * @see ImageLoader#load + */ +public ImageData(InputStream stream) { + ImageData[] data = new ImageLoader().load(stream); + if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE); + ImageData i = data[0]; + setAllFields( + i.width, + i.height, + i.depth, + i.scanlinePad, + i.bytesPerLine, + i.data, + i.palette, + i.transparentPixel, + i.maskData, + i.maskPad, + i.alphaData, + i.alpha, + i.type, + i.x, + i.y, + i.disposalMethod, + i.delayTime); +} + +/** + * Constructs an <code>ImageData</code> loaded from a file with the + * specified name. Throws an error if an error occurs loading the + * image, or if the image has an unsupported type. + * <p> + * This constructor is provided for convenience when loading a single + * image only. If the file contains multiple images, only the first + * one will be loaded. To load multiple images, use + * <code>ImageLoader.load()</code>. + * </p> + * + * @param filename the name of the file to load the image from (must not be null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the file name is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li> + * <li>ERROR_IO if an IO error occurs while reading data</li> + * </ul> + */ +public ImageData(String filename) { + ImageData[] data = new ImageLoader().load(filename); + if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE); + ImageData i = data[0]; + setAllFields( + i.width, + i.height, + i.depth, + i.scanlinePad, + i.bytesPerLine, + i.data, + i.palette, + i.transparentPixel, + i.maskData, + i.maskPad, + i.alphaData, + i.alpha, + i.type, + i.x, + i.y, + i.disposalMethod, + i.delayTime); +} + +/** + * Prevents uninitialized instances from being created outside the package. + */ +ImageData() { +} + +/** + * Constructs an image data by giving values for all non-computable fields. + * <p> + * This method is for internal use, and is not described further. + * </p> + */ +ImageData( + int width, int height, int depth, PaletteData palette, + int scanlinePad, byte[] data, int maskPad, byte[] maskData, + byte[] alphaData, int alpha, int transparentPixel, int type, + int x, int y, int disposalMethod, int delayTime) +{ + + if (palette == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (!(depth == 1 || depth == 2 || depth == 4 || depth == 8 + || depth == 16 || depth == 24 || depth == 32)) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (width <= 0 || height <= 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1)) + / scanlinePad * scanlinePad; + setAllFields( + width, + height, + depth, + scanlinePad, + bytesPerLine, + data != null ? data : new byte[bytesPerLine * height], + palette, + transparentPixel, + maskData, + maskPad, + alphaData, + alpha, + type, + x, + y, + disposalMethod, + delayTime); +} + +/** + * Initializes all fields in the receiver. This method must be called + * by all public constructors to ensure that all fields are initialized + * for a new ImageData object. If a new field is added to the class, + * then it must be added to this method. + * <p> + * This method is for internal use, and is not described further. + * </p> + */ +void setAllFields(int width, int height, int depth, int scanlinePad, + int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel, + byte[] maskData, int maskPad, byte[] alphaData, int alpha, + int type, int x, int y, int disposalMethod, int delayTime) { + + this.width = width; + this.height = height; + this.depth = depth; + this.scanlinePad = scanlinePad; + this.bytesPerLine = bytesPerLine; + this.data = data; + this.palette = palette; + this.transparentPixel = transparentPixel; + this.maskData = maskData; + this.maskPad = maskPad; + this.alphaData = alphaData; + this.alpha = alpha; + this.type = type; + this.x = x; + this.y = y; + this.disposalMethod = disposalMethod; + this.delayTime = delayTime; +} + +/** + * Invokes internal SWT functionality to create a new instance of + * this class. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the public + * API for <code>ImageData</code>. It is marked public only so that it + * can be shared within the packages provided by SWT. It is subject + * to change without notice, and should never be called from + * application code. + * </p> + * <p> + * This method is for internal use, and is not described further. + * </p> + * + * @private + */ +public static ImageData internal_new( + int width, int height, int depth, PaletteData palette, + int scanlinePad, byte[] data, int maskPad, byte[] maskData, + byte[] alphaData, int alpha, int transparentPixel, int type, + int x, int y, int disposalMethod, int delayTime) +{ + return new ImageData( + width, height, depth, palette, scanlinePad, data, maskPad, maskData, + alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime); +} + +ImageData colorMaskImage(int pixel) { + ImageData mask = new ImageData(width, height, 1, bwPalette(), + Image.DEFAULT_SCANLINE_PAD, null, 0, null, + null, -1, -1, SWT.IMAGE_UNDEFINED, + 0, 0, 0, 0); + int[] row = new int[width]; + for (int y = 0; y < height; y++) { + getPixels(0, y, width, row, 0); + for (int i = 0; i < width; i++) { + if (pixel != -1 && row[i] == pixel) { + row[i] = 0; + } else { + row[i] = 1; + } + } + mask.setPixels(0, y, width, row, 0); + } + return mask; +} + +static byte[] checkData(byte [] data) { + if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + return data; +} + +/** + * Returns a new instance of the same class as the receiver, + * whose slots have been filled in with <em>copies</em> of + * the values in the slots of the receiver. That is, the + * returned object is a <em>deep copy</em> of the receiver. + * + * @return a copy of the receiver. + */ +public Object clone() { + byte[] cloneData = new byte[data.length]; + System.arraycopy(data, 0, cloneData, 0, data.length); + byte[] cloneMaskData = null; + if (maskData != null) { + cloneMaskData = new byte[maskData.length]; + System.arraycopy(maskData, 0, cloneMaskData, 0, maskData.length); + } + byte[] cloneAlphaData = null; + if (alphaData != null) { + cloneAlphaData = new byte[alphaData.length]; + System.arraycopy(alphaData, 0, cloneAlphaData, 0, alphaData.length); + } + return new ImageData( + width, + height, + depth, + palette, + scanlinePad, + cloneData, + maskPad, + cloneMaskData, + cloneAlphaData, + alpha, + transparentPixel, + type, + x, + y, + disposalMethod, + delayTime); +} + +/** + * Returns the alpha value at offset <code>x</code> in + * scanline <code>y</code> in the receiver's alpha data. + * + * @param x the x coodinate of the pixel to get the alpha value of + * @param y the y coordinate of the pixel to get the alpha value of + * @return the alpha value at the given coordinates + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if either argument is out of range</li> + * </ul> + */ +public int getAlpha(int x, int y) { + if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + + if (alphaData == null) return 255; + return alphaData[y * width + x] & 0xFF; +} + +/** + * Returns <code>getWidth</code> alpha values starting at offset + * <code>x</code> in scanline <code>y</code> in the receiver's alpha + * data starting at <code>startIndex</code>. + * + * @param x the x position of the pixel to begin getting alpha values + * @param y the y position of the pixel to begin getting alpha values + * @param getWidth the width of the data to get + * @param alphas the buffer in which to put the alpha values + * @param startIndex the offset into the image to begin getting alpha values + * + * @exception IndexOutOfBoundsException if getWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li> + * </ul> + */ +public void getAlphas(int x, int y, int getWidth, byte[] alphas, int startIndex) { + if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (getWidth == 0) return; + + if (alphaData == null) { + int endIndex = startIndex + getWidth; + for (int i = startIndex; i < endIndex; i++) { + alphas[i] = (byte)255; + } + return; + } + // may throw an IndexOutOfBoundsException + System.arraycopy(alphaData, y * width + x, alphas, startIndex, getWidth); +} + +/** + * Returns the pixel value at offset <code>x</code> in + * scanline <code>y</code> in the receiver's data. + * + * @param x the x position of the pixel to get + * @param y the y position of the pixel to get + * @return the pixel at the given coordinates + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if either argument is out of bounds</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public int getPixel(int x, int y) { + if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + int index; + int theByte; + int mask; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + theByte = data[index] & 0xFF; + mask = 1 << (7 - (x & 0x7)); + if ((theByte & mask) == 0) { + return 0; + } else { + return 1; + } + } + if (depth == 2) { + index = (y * bytesPerLine) + (x >> 2); + theByte = data[index] & 0xFF; + int offset = 3 - (x % 4); + mask = 3 << (offset * 2); + return (theByte & mask) >> (offset * 2); + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + theByte = data[index] & 0xFF; + if ((x & 0x1) == 0) { + return theByte >> 4; + } else { + return theByte & 0x0F; + } + } + if (depth == 8) { + index = (y * bytesPerLine) + x ; + return data[index] & 0xFF; + } + if (depth == 16) { + index = (y * bytesPerLine) + (x * 2); + return ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF); + } + if (depth == 24) { + index = (y * bytesPerLine) + (x * 3); + return ((data[index] & 0xFF) << 16) + ((data[index+1] & 0xFF) << 8) + + (data[index+2] & 0xFF); + } + if (depth == 32) { + index = (y * bytesPerLine) + (x * 4); + return ((data[index] & 0xFF) << 24) + ((data[index+1] & 0xFF) << 16) + + ((data[index+2] & 0xFF) << 8) + (data[index+3] & 0xFF); + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + return 0; +} + +/** + * Returns <code>getWidth</code> pixel values starting at offset + * <code>x</code> in scanline <code>y</code> in the receiver's + * data starting at <code>startIndex</code>. + * + * @param x the x position of the first pixel to get + * @param y the y position of the first pixel to get + * @param getWidth the width of the data to get + * @param pixels the buffer in which to put the pixels + * @param startIndex the offset into the byte array to begin storing pixels + * + * @exception IndexOutOfBoundsException if getWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4 or 8 + * (For higher depths, use the int[] version of this method.)</li> + * </ul> + */ +public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) { + if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (getWidth == 0) return; + int index; + int theByte; + int mask = 0; + int n = getWidth; + int i = startIndex; + int srcX = x, srcY = y; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + theByte = data[index] & 0xFF; + while (n > 1) { + mask = 1 << (7 - (srcX & 0x7)); + if ((theByte & mask) == 0) { + pixels[i] = 0; + } else { + pixels[i] = 1; + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + if (n > 0) theByte = data[index] & 0xFF; + srcX = 0; + } else { + if (mask == 1) { + index++; + if (n > 0) theByte = data[index] & 0xFF; + } + } + } + return; + } + if (depth == 2) { + index = (y * bytesPerLine) + (x >> 2); + theByte = data[index] & 0xFF; + int offset; + while (n > 0) { + offset = 3 - (srcX % 4); + mask = 3 << (offset * 2); + pixels[i] = (byte)((theByte & mask) >> (offset * 2)); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + if (n > 0) theByte = data[index] & 0xFF; + srcX = 0; + } else { + if (offset == 0) { + index++; + theByte = data[index] & 0xFF; + } + } + } + return; + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + if ((x & 0x1) == 1) { + theByte = data[index] & 0xFF; + pixels[i] = (byte)(theByte & 0x0F); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + while (n > 1) { + theByte = data[index] & 0xFF; + pixels[i] = (byte)(theByte >> 4); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + pixels[i] = (byte)(theByte & 0x0F); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + } + if (n > 0) { + theByte = data[index] & 0xFF; + pixels[i] = (byte)(theByte >> 4); + } + return; + } + if (depth == 8) { + index = (y * bytesPerLine) + x; + for (int j = 0; j < getWidth; j++) { + pixels[i] = data[index]; + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + return; + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); +} + +/** + * Returns <code>getWidth</code> pixel values starting at offset + * <code>x</code> in scanline <code>y</code> in the receiver's + * data starting at <code>startIndex</code>. + * + * @param x the x position of the first pixel to get + * @param y the y position of the first pixel to get + * @param getWidth the width of the data to get + * @param pixels the buffer in which to put the pixels + * @param startIndex the offset into the buffer to begin storing pixels + * + * @exception IndexOutOfBoundsException if getWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if getWidth is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH - if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) { + if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (getWidth == 0) return; + int index; + int theByte; + int mask; + int n = getWidth; + int i = startIndex; + int srcX = x, srcY = y; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + theByte = data[index] & 0xFF; + while (n > 0) { + mask = 1 << (7 - (srcX & 0x7)); + if ((theByte & mask) == 0) { + pixels[i] = 0; + } else { + pixels[i] = 1; + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + if (n > 0) theByte = data[index] & 0xFF; + srcX = 0; + } else { + if (mask == 1) { + index++; + if (n > 0) theByte = data[index] & 0xFF; + } + } + } + return; + } + if (depth == 2) { + index = (y * bytesPerLine) + (x >> 2); + theByte = data[index] & 0xFF; + int offset; + while (n > 0) { + offset = 3 - (srcX % 4); + mask = 3 << (offset * 2); + pixels[i] = (byte)((theByte & mask) >> (offset * 2)); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + if (n > 0) theByte = data[index] & 0xFF; + srcX = 0; + } else { + if (offset == 0) { + index++; + theByte = data[index] & 0xFF; + } + } + } + return; + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + if ((x & 0x1) == 1) { + theByte = data[index] & 0xFF; + pixels[i] = theByte & 0x0F; + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + while (n > 1) { + theByte = data[index] & 0xFF; + pixels[i] = theByte >> 4; + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + pixels[i] = theByte & 0x0F; + i++; + n--; + srcX++;; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + } + if (n > 0) { + theByte = data[index] & 0xFF; + pixels[i] = theByte >> 4; + } + return; + } + if (depth == 8) { + index = (y * bytesPerLine) + x; + for (int j = 0; j < getWidth; j++) { + pixels[i] = data[index] & 0xFF; + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + return; + } + if (depth == 16) { + index = (y * bytesPerLine) + (x * 2); + for (int j = 0; j < getWidth; j++) { + pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 2; + } + } + return; + } + if (depth == 24) { + index = (y * bytesPerLine) + (x * 3); + for (int j = 0; j < getWidth; j++) { + pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8) + | (data[index+2] & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 3; + } + } + return; + } + if (depth == 32) { + index = (y * bytesPerLine) + (x * 4); + i = startIndex; + for (int j = 0; j < getWidth; j++) { + pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16) + | ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 4; + } + } + return; + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); +} + +/** + * Returns an array of <code>RGB</code>s which comprise the + * indexed color table of the receiver, or null if the receiver + * has a direct color model. + * + * @return the RGB values for the image or null if direct color + * + * @see PaletteData#getRGBs + */ +public RGB[] getRGBs() { + return palette.getRGBs(); +} + +/** + * Returns an <code>ImageData</code> which specifies the + * transparency mask information for the receiver, or null if the + * receiver has no transparency and is not an icon. + * + * @return the transparency mask or null if none exists + */ +public ImageData getTransparencyMask() { + if (getTransparencyType() == SWT.TRANSPARENCY_MASK) { + return new ImageData(width, height, 1, bwPalette(), maskPad, maskData); + } else { + return colorMaskImage(transparentPixel); + } +} + +/** + * Returns the image transparency type. + * + * @return the receiver's transparency type + */ +public int getTransparencyType() { + if (maskData != null) return SWT.TRANSPARENCY_MASK; + if (transparentPixel != -1) return SWT.TRANSPARENCY_PIXEL; + if (alphaData != null) return SWT.TRANSPARENCY_ALPHA; + return SWT.TRANSPARENCY_NONE; +} + +/** + * Returns the byte order of the receiver. + * + * @return MSB_FIRST or LSB_FIRST + */ +int getByteOrder() { + return depth != 16 ? MSB_FIRST : LSB_FIRST; +} + +/** + * Returns a copy of the receiver which has been stretched or + * shrunk to the specified size. If either the width or height + * is negative, the resulting image will be inverted in the + * associated axis. + * + * @param width the width of the new ImageData + * @param height the height of the new ImageData + * @return a scaled copy of the image + */ +public ImageData scaledTo(int width, int height) { + /* Create a destination image with no data */ + final boolean flipX = (width < 0); + if (flipX) width = - width; + final boolean flipY = (height < 0); + if (flipY) height = - height; + + ImageData dest = new ImageData( + width, height, depth, palette, + scanlinePad, null, 0, null, + null, -1, transparentPixel, type, + x, y, disposalMethod, delayTime); + + /* Scale the image contents */ + if (palette.isDirect) blit(BLIT_SRC, + this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, 0, 0, 0, + ALPHA_OPAQUE, null, 0, 0, 0, + dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, 0, 0, 0, + flipX, flipY); + else blit(BLIT_SRC, + this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, null, null, null, + ALPHA_OPAQUE, null, 0, 0, 0, + dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null, + flipX, flipY); + + /* Scale the image mask or alpha */ + if (maskData != null) { + dest.maskPad = this.maskPad; + int destBpl = (dest.width + 7) / 8; + destBpl = (destBpl + (dest.maskPad - 1)) / dest.maskPad * dest.maskPad; + dest.maskData = new byte[destBpl * dest.height]; + int srcBpl = (this.width + 7) / 8; + srcBpl = (srcBpl + (this.maskPad - 1)) / this.maskPad * this.maskPad; + blit(BLIT_SRC, + this.maskData, 1, srcBpl, MSB_FIRST, 0, 0, this.width, this.height, null, null, null, + ALPHA_OPAQUE, null, 0, 0, 0, + dest.maskData, 1, destBpl, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null, + flipX, flipY); + } else if (alpha != -1) { + dest.alpha = this.alpha; + } else if (alphaData != null) { + dest.alphaData = new byte[dest.width * dest.height]; + blit(BLIT_SRC, + this.alphaData, 8, this.width, MSB_FIRST, 0, 0, this.width, this.height, null, null, null, + ALPHA_OPAQUE, null, 0, 0, 0, + dest.alphaData, 8, dest.width, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null, + flipX, flipY); + } + return dest; +} + +/** + * Sets the alpha value at offset <code>x</code> in + * scanline <code>y</code> in the receiver's alpha data. + * + * @param x the x coordinate of the alpha value to set + * @param y the y coordinate of the alpha value to set + * @param alpha the value to set the alpha to + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * </ul> + */ +public void setAlpha(int x, int y, int alpha) { + if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255) + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + + if (alphaData == null) alphaData = new byte[width * height]; + alphaData[y * width + x] = (byte)alpha; +} + +/** + * Sets the alpha values starting at offset <code>x</code> in + * scanline <code>y</code> in the receiver's alpha data to the + * values from the array <code>alphas</code> starting at + * <code>startIndex</code>. + * + * @param x the x coordinate of the pixel to being setting the alpha values + * @param y the y coordinate of the pixel to being setting the alpha values + * @param putWidth the width of the alpha values to set + * @param alphas the alpha values to set + * @param startIndex the index at which to begin setting + * + * @exception IndexOutOfBoundsException if putWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li> + * </ul> + */ +public void setAlphas(int x, int y, int putWidth, byte[] alphas, int startIndex) { + if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (putWidth == 0) return; + + if (alphaData == null) alphaData = new byte[width * height]; + // may throw an IndexOutOfBoundsException + System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth); +} + +/** + * Sets the pixel value at offset <code>x</code> in + * scanline <code>y</code> in the receiver's data. + * + * @param x the x coordinate of the pixel to set + * @param y the y coordinate of the pixel to set + * @param pixelValue the value to set the pixel to + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public void setPixel(int x, int y, int pixelValue) { + if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + int index; + byte theByte; + int mask; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + theByte = data[index]; + mask = 1 << (7 - (x & 0x7)); + if ((pixelValue & 0x1) == 1) { + data[index] = (byte)(theByte | mask); + } else { + data[index] = (byte)(theByte & (mask ^ -1)); + } + return; + } + if (depth == 2) { + index = (y * bytesPerLine) + (x >> 2); + theByte = data[index]; + int offset = 3 - (x % 4); + mask = 0xFF ^ (3 << (offset * 2)); + data[index] = (byte)((data[index] & mask) | (pixelValue << (offset * 2))); + return; + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + if ((x & 0x1) == 0) { + data[index] = (byte)((data[index] & 0x0F) | ((pixelValue & 0x0F) << 4)); + } else { + data[index] = (byte)((data[index] & 0xF0) | (pixelValue & 0x0F)); + } + return; + } + if (depth == 8) { + index = (y * bytesPerLine) + x ; + data[index] = (byte)(pixelValue & 0xFF); + return; + } + if (depth == 16) { + index = (y * bytesPerLine) + (x * 2); + data[index + 1] = (byte)((pixelValue >> 8) & 0xFF); + data[index] = (byte)(pixelValue & 0xFF); + return; + } + if (depth == 24) { + index = (y * bytesPerLine) + (x * 3); + data[index] = (byte)((pixelValue >> 16) & 0xFF); + data[index + 1] = (byte)((pixelValue >> 8) & 0xFF); + data[index + 2] = (byte)(pixelValue & 0xFF); + return; + } + if (depth == 32) { + index = (y * bytesPerLine) + (x * 4); + data[index] = (byte)((pixelValue >> 24) & 0xFF); + data[index + 1] = (byte)((pixelValue >> 16) & 0xFF); + data[index + 2] = (byte)((pixelValue >> 8) & 0xFF); + data[index + 3] = (byte)(pixelValue & 0xFF); + return; + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); +} + +/** + * Sets the pixel values starting at offset <code>x</code> in + * scanline <code>y</code> in the receiver's data to the + * values from the array <code>pixels</code> starting at + * <code>startIndex</code>. + * + * @param x the x position of the pixel to set + * @param y the y position of the pixel to set + * @param putWidth the width of the pixels to set + * @param pixels the pixels to set + * @param startIndex the index at which to begin setting + * + * @exception IndexOutOfBoundsException if putWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8 + * (For higher depths, use the int[] version of this method.)</li> + * </ul> + */ +public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) { + if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (putWidth == 0) return; + int index; + int theByte; + int mask; + int n = putWidth; + int i = startIndex; + int srcX = x, srcY = y; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + while (n > 0) { + mask = 1 << (7 - (srcX & 0x7)); + if ((pixels[i] & 0x1) == 1) { + data[index] = (byte)((data[index] & 0xFF) | mask); + } else { + data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1)); + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + if (mask == 1) { + index++; + } + } + } + return; + } + if (depth == 2) { + byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F }; + index = (y * bytesPerLine) + (x >> 2); + int offset = 3 - (x % 4); + while (n > 0) { + theByte = pixels[i] & 0x3; + data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2))); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + offset = 0; + srcX = 0; + } else { + if (offset == 0) { + index++; + offset = 3; + } else { + offset--; + } + } + } + return; + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + boolean high = (x & 0x1) == 0; + while (n > 0) { + theByte = pixels[i] & 0x0F; + if (high) { + data[index] = (byte)((data[index] & 0x0F) | (theByte << 4)); + } else { + data[index] = (byte)((data[index] & 0xF0) | theByte); + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + high = true; + srcX = 0; + } else { + if (!high) index++; + high = !high; + } + } + return; + } + if (depth == 8) { + index = (y * bytesPerLine) + x; + for (int j = 0; j < putWidth; j++) { + data[index] = (byte)(pixels[i] & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + return; + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); +} + +/** + * Sets the pixel values starting at offset <code>x</code> in + * scanline <code>y</code> in the receiver's data to the + * values from the array <code>pixels</code> starting at + * <code>startIndex</code>. + * + * @param x the x position of the pixel to set + * @param y the y position of the pixel to set + * @param putWidth the width of the pixels to set + * @param pixels the pixels to set + * @param startIndex the index at which to begin setting + * + * @exception IndexOutOfBoundsException if putWidth is too large + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if pixels is null</li> + * <li>ERROR_INVALID_ARGUMENT - if x or y is out of bounds</li> + * <li>ERROR_INVALID_ARGUMENT - if putWidth is negative</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_UNSUPPORTED_DEPTH if the depth is not one of 1, 2, 4, 8, 16, 24 or 32</li> + * </ul> + */ +public void setPixels(int x, int y, int putWidth, int[] pixels, int startIndex) { + if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (putWidth == 0) return; + int index; + int theByte; + int mask; + int n = putWidth; + int i = startIndex; + int pixel; + int srcX = x, srcY = y; + if (depth == 1) { + index = (y * bytesPerLine) + (x >> 3); + while (n > 0) { + mask = 1 << (7 - (srcX & 0x7)); + if ((pixels[i] & 0x1) == 1) { + data[index] = (byte)((data[index] & 0xFF) | mask); + } else { + data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1)); + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + if (mask == 1) { + index++; + } + } + } + return; + } + if (depth == 2) { + byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F }; + index = (y * bytesPerLine) + (x >> 2); + int offset = 3 - (x % 4); + while (n > 0) { + theByte = pixels[i] & 0x3; + data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2))); + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + offset = 3; + srcX = 0; + } else { + if (offset == 0) { + index++; + offset = 3; + } else { + offset--; + } + } + } + return; + } + if (depth == 4) { + index = (y * bytesPerLine) + (x >> 1); + boolean high = (x & 0x1) == 0; + while (n > 0) { + theByte = pixels[i] & 0x0F; + if (high) { + data[index] = (byte)((data[index] & 0x0F) | (theByte << 4)); + } else { + data[index] = (byte)((data[index] & 0xF0) | theByte); + } + i++; + n--; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + high = true; + srcX = 0; + } else { + if (!high) index++; + high = !high; + } + } + return; + } + if (depth == 8) { + index = (y * bytesPerLine) + x; + for (int j = 0; j < putWidth; j++) { + data[index] = (byte)(pixels[i] & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index++; + } + } + return; + + } + if (depth == 16) { + index = (y * bytesPerLine) + (x * 2); + for (int j = 0; j < putWidth; j++) { + pixel = pixels[i]; + data[index] = (byte)(pixel & 0xFF); + data[index + 1] = (byte)((pixel >> 8) & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 2; + } + } + return; + } + if (depth == 24) { + index = (y * bytesPerLine) + (x * 3); + for (int j = 0; j < putWidth; j++) { + pixel = pixels[i]; + data[index] = (byte)((pixel >> 16) & 0xFF); + data[index + 1] = (byte)((pixel >> 8) & 0xFF); + data[index + 2] = (byte)(pixel & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 3; + } + } + return; + } + if (depth == 32) { + index = (y * bytesPerLine) + (x * 4); + for (int j = 0; j < putWidth; j++) { + pixel = pixels[i]; + data[index] = (byte)((pixel >> 24) & 0xFF); + data[index + 1] = (byte)((pixel >> 16) & 0xFF); + data[index + 2] = (byte)((pixel >> 8) & 0xFF); + data[index + 3] = (byte)(pixel & 0xFF); + i++; + srcX++; + if (srcX >= width) { + srcY++; + index = srcY * bytesPerLine; + srcX = 0; + } else { + index += 4; + } + } + return; + } + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); +} + +/** + * Returns a palette with 2 colors: black & white. + */ +static PaletteData bwPalette() { + return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)}); +} + +/** + * Gets the offset of the most significant bit for + * the given mask. + */ +static int getMSBOffset(int mask) { + for (int i = 31; i >= 0; i--) { + if (((mask >> i) & 0x1) != 0) return i + 1; + } + return 0; +} + +/** + * Finds the closest match. + */ +static int closestMatch(int depth, byte red, byte green, byte blue, int redMask, int greenMask, int blueMask, byte[] reds, byte[] greens, byte[] blues) { + if (depth > 8) { + int rshift = 32 - getMSBOffset(redMask); + int gshift = 32 - getMSBOffset(greenMask); + int bshift = 32 - getMSBOffset(blueMask); + return (((red << 24) >>> rshift) & redMask) | + (((green << 24) >>> gshift) & greenMask) | + (((blue << 24) >>> bshift) & blueMask); + } + int r, g, b; + int minDistance = 0x7fffffff; + int nearestPixel = 0; + int n = reds.length; + for (int j = 0; j < n; j++) { + r = (reds[j] & 0xFF) - (red & 0xFF); + g = (greens[j] & 0xFF) - (green & 0xFF); + b = (blues[j] & 0xFF) - (blue & 0xFF); + int distance = r*r + g*g + b*b; + if (distance < minDistance) { + nearestPixel = j; + if (distance == 0) break; + minDistance = distance; + } + } + return nearestPixel; +} + +/** + * Blit operation bits to be OR'ed together to specify the desired operation. + */ +static final int + BLIT_SRC = 1, // copy source directly, else applies logic operations + BLIT_ALPHA = 2, // enable alpha blending + BLIT_DITHER = 4; // enable dithering in low color modes + +/** + * Alpha mode, values 0 - 255 specify global alpha level + */ +static final int + ALPHA_OPAQUE = 255, // Fully opaque (ignores any alpha data) + ALPHA_TRANSPARENT = 0, // Fully transparent (ignores any alpha data) + ALPHA_CHANNEL_SEPARATE = -1, // Use alpha channel from separate alphaData + ALPHA_CHANNEL_SOURCE = -2, // Use alpha channel embedded in sourceData + ALPHA_MASK_UNPACKED = -3, // Use transparency mask formed by bytes in alphaData (non-zero is opaque) + ALPHA_MASK_PACKED = -4, // Use transparency mask formed by packed bits in alphaData + ALPHA_MASK_INDEX = -5, // Consider source palette indices transparent if in alphaData array + ALPHA_MASK_RGB = -6; // Consider source RGBs transparent if in RGB888 format alphaData array + +/** + * Byte and bit order constants. + */ +static final int LSB_FIRST = 0; +static final int MSB_FIRST = 1; + +/** + * Data types (internal) + */ +private static final int + // direct / true color formats with arbitrary masks & shifts + TYPE_GENERIC_8 = 0, + TYPE_GENERIC_16_MSB = 1, + TYPE_GENERIC_16_LSB = 2, + TYPE_GENERIC_24 = 3, + TYPE_GENERIC_32_MSB = 4, + TYPE_GENERIC_32_LSB = 5, + // palette indexed color formats + TYPE_INDEX_8 = 6, + TYPE_INDEX_4 = 7, + TYPE_INDEX_2 = 8, + TYPE_INDEX_1_MSB = 9, + TYPE_INDEX_1_LSB = 10; + +/** + * Blits a direct palette image into a direct palette image. + * <p> + * Note: When the source and destination depth, order and masks + * are pairwise equal and the blitter operation is BLIT_SRC, + * the masks are ignored. Hence when not changing the image + * data format, 0 may be specified for the masks. + * </p> + * + * @param op the blitter operation: a combination of BLIT_xxx flags + * (see BLIT_xxx constants) + * @param srcData the source byte array containing image data + * @param srcDepth the source depth: one of 8, 16, 24, 32 + * @param srcStride the source number of bytes per line + * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if srcDepth is not 16 or 32 + * @param srcX the top-left x-coord of the source blit region + * @param srcY the top-left y-coord of the source blit region + * @param srcWidth the width of the source blit region + * @param srcHeight the height of the source blit region + * @param srcRedMask the source red channel mask + * @param srcGreenMask the source green channel mask + * @param srcBlueMask the source blue channel mask + * @param alphaMode the alpha blending or mask mode, may be + * an integer 0-255 for global alpha; ignored if BLIT_ALPHA + * not specified in the blitter operations + * (see ALPHA_MODE_xxx constants) + * @param alphaData the alpha blending or mask data, varies depending + * on the value of alphaMode and sometimes ignored + * @param alphaStride the alpha data number of bytes per line + * @param alphaX the top-left x-coord of the alpha blit region + * @param alphaY the top-left y-coord of the alpha blit region + * @param destData the destination byte array containing image data + * @param destDepth the destination depth: one of 8, 16, 24, 32 + * @param destStride the destination number of bytes per line + * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if destDepth is not 16 or 32 + * @param destX the top-left x-coord of the destination blit region + * @param destY the top-left y-coord of the destination blit region + * @param destWidth the width of the destination blit region + * @param destHeight the height of the destination blit region + * @param destRedMask the destination red channel mask + * @param destGreenMask the destination green channel mask + * @param destBlueMask the destination blue channel mask + * @param flipX if true the resulting image is flipped along the vertical axis + * @param flipY if true the resulting image is flipped along the horizontal axis + */ +static void blit(int op, + byte[] srcData, int srcDepth, int srcStride, int srcOrder, + int srcX, int srcY, int srcWidth, int srcHeight, + int srcRedMask, int srcGreenMask, int srcBlueMask, + int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, + byte[] destData, int destDepth, int destStride, int destOrder, + int destX, int destY, int destWidth, int destHeight, + int destRedMask, int destGreenMask, int destBlueMask, + boolean flipX, boolean flipY) { + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; + + // these should be supplied as params later + final int srcAlphaMask = 0, destAlphaMask = 0; + + /*** Prepare scaling data ***/ + final int dwm1 = destWidth - 1; + final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; + final int dhm1 = destHeight - 1; + final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; + + /*** Prepare source-related data ***/ + final int sbpp, stype; + switch (srcDepth) { + case 8: + sbpp = 1; + stype = TYPE_GENERIC_8; + break; + case 16: + sbpp = 2; + stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; + break; + case 24: + sbpp = 3; + stype = TYPE_GENERIC_24; + break; + case 32: + sbpp = 4; + stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int spr = srcY * srcStride + srcX * sbpp; + + /*** Prepare destination-related data ***/ + final int dbpp, dtype; + switch (destDepth) { + case 8: + dbpp = 1; + dtype = TYPE_GENERIC_8; + break; + case 16: + dbpp = 2; + dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; + break; + case 24: + dbpp = 3; + dtype = TYPE_GENERIC_24; + break; + case 32: + dbpp = 4; + dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid destination type"); + return; + } + int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; + final int dprxi = (flipX) ? -dbpp : dbpp; + final int dpryi = (flipY) ? -destStride : destStride; + + /*** Prepare special processing data ***/ + int apr; + if ((op & BLIT_ALPHA) != 0) { + switch (alphaMode) { + case ALPHA_MASK_UNPACKED: + case ALPHA_CHANNEL_SEPARATE: + if (alphaData == null) alphaMode = 0x10000; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_PACKED: + if (alphaData == null) alphaMode = 0x10000; + alphaStride <<= 3; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_INDEX: + //throw new IllegalArgumentException("Invalid alpha type"); + return; + case ALPHA_MASK_RGB: + if (alphaData == null) alphaMode = 0x10000; + apr = 0; + break; + default: + alphaMode = (alphaMode << 16) / 255; // prescale + case ALPHA_CHANNEL_SOURCE: + apr = 0; + break; + } + } else { + alphaMode = 0x10000; + apr = 0; + } + + /*** Blit ***/ + int dp = dpr; + int sp = spr; + if ((alphaMode == 0x10000) && (stype == dtype) && + (srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) && + (srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) { + /*** Fast blit (straight copy) ***/ + switch (sbpp) { + case 1: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + destData[dp] = srcData[sp]; + sp += (sfx >>> 16); + } + } + break; + case 2: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + destData[dp] = srcData[sp]; + destData[dp + 1] = srcData[sp + 1]; + sp += (sfx >>> 16) * 2; + } + } + break; + case 3: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + destData[dp] = srcData[sp]; + destData[dp + 1] = srcData[sp + 1]; + destData[dp + 2] = srcData[sp + 2]; + sp += (sfx >>> 16) * 3; + } + } + break; + case 4: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + destData[dp] = srcData[sp]; + destData[dp + 1] = srcData[sp + 1]; + destData[dp + 2] = srcData[sp + 2]; + destData[dp + 3] = srcData[sp + 3]; + sp += (sfx >>> 16) * 4; + } + } + break; + } + return; + } + /*** Comprehensive blit (apply transformations) ***/ + final int srcRedShift = getChannelShift(srcRedMask); + final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; + final int srcGreenShift = getChannelShift(srcGreenMask); + final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; + final int srcBlueShift = getChannelShift(srcBlueMask); + final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; + final int srcAlphaShift = getChannelShift(srcAlphaMask); + final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; + + final int destRedShift = getChannelShift(destRedMask); + final int destRedWidth = getChannelWidth(destRedMask, destRedShift); + final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; + final int destRedPreShift = 8 - destRedWidth; + final int destGreenShift = getChannelShift(destGreenMask); + final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); + final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; + final int destGreenPreShift = 8 - destGreenWidth; + final int destBlueShift = getChannelShift(destBlueMask); + final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); + final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; + final int destBluePreShift = 8 - destBlueWidth; + final int destAlphaShift = getChannelShift(destAlphaMask); + final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); + final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; + final int destAlphaPreShift = 8 - destAlphaWidth; + + int ap = apr, alpha = alphaMode; + int r = 0, g = 0, b = 0, a = 0; + int rq = 0, gq = 0, bq = 0, aq = 0; + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, + sp = spr += (sfy >>> 16) * srcStride, + ap = apr += (sfy >>> 16) * alphaStride, + sfy = (sfy & 0xffff) + sfyi, + dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, + dp += dprxi, + sfx = (sfx & 0xffff) + sfxi) { + /*** READ NEXT PIXEL ***/ + switch (stype) { + case TYPE_GENERIC_8: { + final int data = srcData[sp] & 0xff; + sp += (sfx >>> 16); + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_MSB: { + final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); + sp += (sfx >>> 16) * 2; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_LSB: { + final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); + sp += (sfx >>> 16) * 2; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_24: { + final int data = (( ((srcData[sp] & 0xff) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp + 2] & 0xff); + sp += (sfx >>> 16) * 3; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_MSB: { + final int data = (( (( ((srcData[sp] & 0xff) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp + 2] & 0xff)) << 8) | + (srcData[sp + 3] & 0xff); + sp += (sfx >>> 16) * 4; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_LSB: { + final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | + (srcData[sp + 2] & 0xff)) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp] & 0xff); + sp += (sfx >>> 16) * 4; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + } + + /*** DO SPECIAL PROCESSING IF REQUIRED ***/ + switch (alphaMode) { + case ALPHA_CHANNEL_SEPARATE: + alpha = ((alphaData[ap] & 0xff) << 16) / 255; + ap += (sfx >> 16); + break; + case ALPHA_CHANNEL_SOURCE: + alpha = (a << 16) / 255; + break; + case ALPHA_MASK_UNPACKED: + alpha = (alphaData[ap] != 0) ? 0x10000 : 0; + ap += (sfx >> 16); + break; + case ALPHA_MASK_PACKED: + alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; + ap += (sfx >> 16); + break; + case ALPHA_MASK_RGB: + alpha = 0x10000; + for (int i = 0; i < alphaData.length; i += 3) { + if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) { + alpha = 0x0000; + break; + } + } + break; + } + if (alpha != 0x10000) { + if (alpha == 0x0000) continue; + switch (dtype) { + case TYPE_GENERIC_8: { + final int data = destData[dp] & 0xff; + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_MSB: { + final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_LSB: { + final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_24: { + final int data = (( ((destData[dp] & 0xff) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp + 2] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_MSB: { + final int data = (( (( ((destData[dp] & 0xff) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp + 2] & 0xff)) << 8) | + (destData[dp + 3] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_LSB: { + final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | + (destData[dp + 2] & 0xff)) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + } + // Perform alpha blending + a = aq + ((a - aq) * alpha >> 16); + r = rq + ((r - rq) * alpha >> 16); + g = gq + ((g - gq) * alpha >> 16); + b = bq + ((b - bq) * alpha >> 16); + } + + /*** WRITE NEXT PIXEL ***/ + final int data = + (r >>> destRedPreShift << destRedShift) | + (g >>> destGreenPreShift << destGreenShift) | + (b >>> destBluePreShift << destBlueShift) | + (a >>> destAlphaPreShift << destAlphaShift); + switch (dtype) { + case TYPE_GENERIC_8: { + destData[dp] = (byte) data; + } break; + case TYPE_GENERIC_16_MSB: { + destData[dp] = (byte) (data >>> 8); + destData[dp + 1] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_16_LSB: { + destData[dp] = (byte) (data & 0xff); + destData[dp + 1] = (byte) (data >>> 8); + } break; + case TYPE_GENERIC_24: { + destData[dp] = (byte) (data >>> 16); + destData[dp + 1] = (byte) (data >>> 8); + destData[dp + 2] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_32_MSB: { + destData[dp] = (byte) (data >>> 24); + destData[dp + 1] = (byte) (data >>> 16); + destData[dp + 2] = (byte) (data >>> 8); + destData[dp + 3] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_32_LSB: { + destData[dp] = (byte) (data & 0xff); + destData[dp + 1] = (byte) (data >>> 8); + destData[dp + 2] = (byte) (data >>> 16); + destData[dp + 3] = (byte) (data >>> 24); + } break; + } + } + } +} + +/** + * Blits an index palette image into an index palette image. + * <p> + * Note: The source and destination red, green, and blue + * arrays may be null if no alpha blending or dither is to be + * performed. + * </p> + * + * @param op the blitter operation: a combination of BLIT_xxx flags + * (see BLIT_xxx constants) + * @param srcData the source byte array containing image data + * @param srcDepth the source depth: one of 1, 2, 4, 8 + * @param srcStride the source number of bytes per line + * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if srcDepth is not 1 + * @param srcX the top-left x-coord of the source blit region + * @param srcY the top-left y-coord of the source blit region + * @param srcWidth the width of the source blit region + * @param srcHeight the height of the source blit region + * @param srcReds the source palette red component intensities + * @param srcGreens the source palette green component intensities + * @param srcBlues the source palette blue component intensities + * @param alphaMode the alpha blending or mask mode, may be + * an integer 0-255 for global alpha; ignored if BLIT_ALPHA + * not specified in the blitter operations + * (see ALPHA_MODE_xxx constants) + * @param alphaData the alpha blending or mask data, varies depending + * on the value of alphaMode and sometimes ignored + * @param alphaStride the alpha data number of bytes per line + * @param alphaX the top-left x-coord of the alpha blit region + * @param alphaY the top-left y-coord of the alpha blit region + * @param destData the destination byte array containing image data + * @param destDepth the destination depth: one of 1, 2, 4, 8 + * @param destStride the destination number of bytes per line + * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if destDepth is not 1 + * @param destX the top-left x-coord of the destination blit region + * @param destY the top-left y-coord of the destination blit region + * @param destWidth the width of the destination blit region + * @param destHeight the height of the destination blit region + * @param destReds the destination palette red component intensities + * @param destGreens the destination palette green component intensities + * @param destBlues the destination palette blue component intensities + * @param flipX if true the resulting image is flipped along the vertical axis + * @param flipY if true the resulting image is flipped along the horizontal axis + */ +static void blit(int op, + byte[] srcData, int srcDepth, int srcStride, int srcOrder, + int srcX, int srcY, int srcWidth, int srcHeight, + byte[] srcReds, byte[] srcGreens, byte[] srcBlues, + int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, + byte[] destData, int destDepth, int destStride, int destOrder, + int destX, int destY, int destWidth, int destHeight, + byte[] destReds, byte[] destGreens, byte[] destBlues, + boolean flipX, boolean flipY) { + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; + + /*** Prepare scaling data ***/ + final int dwm1 = destWidth - 1; + final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; + final int dhm1 = destHeight - 1; + final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; + + /*** Prepare source-related data ***/ + final int stype; + switch (srcDepth) { + case 8: + stype = TYPE_INDEX_8; + break; + case 4: + srcStride <<= 1; + stype = TYPE_INDEX_4; + break; + case 2: + srcStride <<= 2; + stype = TYPE_INDEX_2; + break; + case 1: + srcStride <<= 3; + stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int spr = srcY * srcStride + srcX; + + /*** Prepare destination-related data ***/ + final int dtype; + switch (destDepth) { + case 8: + dtype = TYPE_INDEX_8; + break; + case 4: + destStride <<= 1; + dtype = TYPE_INDEX_4; + break; + case 2: + destStride <<= 2; + dtype = TYPE_INDEX_2; + break; + case 1: + destStride <<= 3; + dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); + final int dprxi = (flipX) ? -1 : 1; + final int dpryi = (flipY) ? -destStride : destStride; + + /*** Prepare special processing data ***/ + int apr; + if ((op & BLIT_ALPHA) != 0) { + switch (alphaMode) { + case ALPHA_MASK_UNPACKED: + case ALPHA_CHANNEL_SEPARATE: + if (alphaData == null) alphaMode = 0x10000; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_PACKED: + if (alphaData == null) alphaMode = 0x10000; + alphaStride <<= 3; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_INDEX: + case ALPHA_MASK_RGB: + if (alphaData == null) alphaMode = 0x10000; + apr = 0; + break; + default: + alphaMode = (alphaMode << 16) / 255; // prescale + case ALPHA_CHANNEL_SOURCE: + apr = 0; + break; + } + } else { + alphaMode = 0x10000; + apr = 0; + } + final boolean ditherEnabled = (op & BLIT_DITHER) != 0; + + /*** Blit ***/ + int dp = dpr; + int sp = spr; + int ap = apr; + int destPaletteSize = 1 << destDepth; + if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length; + byte[] paletteMapping = null; + boolean isExactPaletteMapping = true; + switch (alphaMode) { + case 0x10000: + /*** If the palettes and formats are equivalent use a one-to-one mapping ***/ + if ((stype == dtype) && + (srcReds == destReds) && (srcGreens == destGreens) && (srcBlues == destBlues)) { + paletteMapping = ONE_TO_ONE_MAPPING; + break; + /*** If palettes have not been supplied, supply a suitable mapping ***/ + } else if ((srcReds == null) || (destReds == null)) { + if (srcDepth <= destDepth) { + paletteMapping = ONE_TO_ONE_MAPPING; + } else { + paletteMapping = new byte[1 << srcDepth]; + int mask = (0xff << destDepth) >>> 8; + for (int i = 0; i < paletteMapping.length; ++i) paletteMapping[i] = (byte)(i & mask); + } + break; + } + case ALPHA_MASK_UNPACKED: + case ALPHA_MASK_PACKED: + case ALPHA_MASK_INDEX: + case ALPHA_MASK_RGB: + /*** Generate a palette mapping ***/ + int srcPaletteSize = 1 << srcDepth; + paletteMapping = new byte[srcPaletteSize]; + if ((srcReds != null) && (srcReds.length < srcPaletteSize)) srcPaletteSize = srcReds.length; + for (int i = 0, r, g, b, index; i < srcPaletteSize; ++i) { + r = srcReds[i] & 0xff; + g = srcGreens[i] & 0xff; + b = srcBlues[i] & 0xff; + index = 0; + int minDistance = 0x7fffffff; + for (int j = 0, dr, dg, db, distance; j < destPaletteSize; ++j) { + dr = (destReds[j] & 0xff) - r; + dg = (destGreens[j] & 0xff) - g; + db = (destBlues[j] & 0xff) - b; + distance = dr * dr + dg * dg + db * db; + if (distance < minDistance) { + index = j; + if (distance == 0) break; + minDistance = distance; + } + } + paletteMapping[i] = (byte)index; + if (minDistance != 0) isExactPaletteMapping = false; + } + break; + } + if ((paletteMapping != null) && (isExactPaletteMapping || ! ditherEnabled)) { + if ((stype == dtype) && (alphaMode == 0x10000)) { + /*** Fast blit (copy w/ mapping) ***/ + switch (stype) { + case TYPE_INDEX_8: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + destData[dp] = paletteMapping[srcData[sp] & 0xff]; + sp += (sfx >>> 16); + } + } + break; + case TYPE_INDEX_4: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + final int v; + if ((sp & 1) != 0) v = paletteMapping[srcData[sp >> 1] & 0x0f]; + else v = (srcData[sp >> 1] >>> 4) & 0x0f; + sp += (sfx >>> 16); + if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | v); + else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (v << 4)); + } + } + break; + case TYPE_INDEX_2: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + final int index = paletteMapping[(srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03]; + sp += (sfx >>> 16); + final int shift = 6 - (dp & 3) * 2; + destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); + } + } + break; + case TYPE_INDEX_1_MSB: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + final int index = paletteMapping[(srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01]; + sp += (sfx >>> 16); + final int shift = 7 - (dp & 7); + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); + } + } + break; + case TYPE_INDEX_1_LSB: + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { + final int index = paletteMapping[(srcData[sp >> 3] >>> (sp & 7)) & 0x01]; + sp += (sfx >>> 16); + final int shift = dp & 7; + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); + } + } + break; + } + } else { + /*** Convert between indexed modes using mapping and mask ***/ + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, + sp = spr += (sfy >>> 16) * srcStride, + sfy = (sfy & 0xffff) + sfyi, + dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, + dp += dprxi, + sfx = (sfx & 0xffff) + sfxi) { + int index; + /*** READ NEXT PIXEL ***/ + switch (stype) { + case TYPE_INDEX_8: + index = srcData[sp] & 0xff; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_4: + if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; + else index = (srcData[sp >> 1] >>> 4) & 0x0f; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_2: + index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_MSB: + index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_LSB: + index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; + sp += (sfx >>> 16); + break; + default: + return; + } + /*** APPLY MASK ***/ + switch (alphaMode) { + case ALPHA_MASK_UNPACKED: { + final byte mask = alphaData[ap]; + ap += (sfx >> 16); + if (mask == 0) continue; + } break; + case ALPHA_MASK_PACKED: { + final int mask = alphaData[ap >> 3] & (1 << (ap & 7)); + ap += (sfx >> 16); + if (mask == 0) continue; + } break; + case ALPHA_MASK_INDEX: { + int i = 0; + while (i < alphaData.length) { + if (index == (alphaData[i] & 0xff)) break; + } + if (i < alphaData.length) continue; + } break; + case ALPHA_MASK_RGB: { + final byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index]; + int i = 0; + while (i < alphaData.length) { + if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) break; + i += 3; + } + if (i < alphaData.length) continue; + } break; + } + index = paletteMapping[index] & 0xff; + + /*** WRITE NEXT PIXEL ***/ + switch (dtype) { + case TYPE_INDEX_8: + destData[dp] = (byte) index; + break; + case TYPE_INDEX_4: + if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | index); + else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (index << 4)); + break; + case TYPE_INDEX_2: { + final int shift = 6 - (dp & 3) * 2; + destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); + } break; + case TYPE_INDEX_1_MSB: { + final int shift = 7 - (dp & 7); + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); + } break; + case TYPE_INDEX_1_LSB: { + final int shift = dp & 7; + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); + } break; + } + } + } + } + return; + } + + /*** Comprehensive blit (apply transformations) ***/ + int alpha = alphaMode; + int index = 0; + int indexq = 0; + int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; + final int[] rerr, gerr, berr; + if (ditherEnabled) { + rerr = new int[destWidth + 2]; + gerr = new int[destWidth + 2]; + berr = new int[destWidth + 2]; + } else { + rerr = null; gerr = null; berr = null; + } + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, + sp = spr += (sfy >>> 16) * srcStride, + ap = apr += (sfy >>> 16) * alphaStride, + sfy = (sfy & 0xffff) + sfyi, + dp = dpr += dpryi) { + int lrerr = 0, lgerr = 0, lberr = 0; + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, + dp += dprxi, + sfx = (sfx & 0xffff) + sfxi) { + /*** READ NEXT PIXEL ***/ + switch (stype) { + case TYPE_INDEX_8: + index = srcData[sp] & 0xff; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_4: + if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; + else index = (srcData[sp >> 1] >>> 4) & 0x0f; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_2: + index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_MSB: + index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_LSB: + index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; + sp += (sfx >>> 16); + break; + } + + /*** DO SPECIAL PROCESSING IF REQUIRED ***/ + int r = srcReds[index] & 0xff, g = srcGreens[index] & 0xff, b = srcBlues[index] & 0xff; + switch (alphaMode) { + case ALPHA_CHANNEL_SEPARATE: + alpha = ((alphaData[ap] & 0xff) << 16) / 255; + ap += (sfx >> 16); + break; + case ALPHA_MASK_UNPACKED: + alpha = (alphaData[ap] != 0) ? 0x10000 : 0; + ap += (sfx >> 16); + break; + case ALPHA_MASK_PACKED: + alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; + ap += (sfx >> 16); + break; + case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices + int i = 0; + while (i < alphaData.length) { + if (index == (alphaData[i] & 0xff)) break; + } + if (i < alphaData.length) continue; + } break; + case ALPHA_MASK_RGB: { + int i = 0; + while (i < alphaData.length) { + if ((r == (alphaData[i] & 0xff)) && + (g == (alphaData[i + 1] & 0xff)) && + (b == (alphaData[i + 2] & 0xff))) break; + i += 3; + } + if (i < alphaData.length) continue; + } break; + } + if (alpha != 0x10000) { + if (alpha == 0x0000) continue; + switch (dtype) { + case TYPE_INDEX_8: + indexq = destData[dp] & 0xff; + break; + case TYPE_INDEX_4: + if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f; + else indexq = (destData[dp >> 1] >>> 4) & 0x0f; + break; + case TYPE_INDEX_2: + indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03; + break; + case TYPE_INDEX_1_MSB: + indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01; + break; + case TYPE_INDEX_1_LSB: + indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; + break; + } + // Perform alpha blending + final int rq = destReds[indexq] & 0xff; + final int gq = destGreens[indexq] & 0xff; + final int bq = destBlues[indexq] & 0xff; + r = rq + ((r - rq) * alpha >> 16); + g = gq + ((g - gq) * alpha >> 16); + b = bq + ((b - bq) * alpha >> 16); + } + + /*** MAP COLOR TO THE PALETTE ***/ + if (ditherEnabled) { + // Floyd-Steinberg error diffusion + r += rerr[dx] >> 4; + if (r < 0) r = 0; else if (r > 255) r = 255; + g += gerr[dx] >> 4; + if (g < 0) g = 0; else if (g > 255) g = 255; + b += berr[dx] >> 4; + if (b < 0) b = 0; else if (b > 255) b = 255; + rerr[dx] = lrerr; + gerr[dx] = lgerr; + berr[dx] = lberr; + } + if (r != lastr || g != lastg || b != lastb) { + // moving the variable declarations out seems to make the JDK JIT happier... + for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) { + dr = (destReds[j] & 0xff) - r; + dg = (destGreens[j] & 0xff) - g; + db = (destBlues[j] & 0xff) - b; + distance = dr * dr + dg * dg + db * db; + if (distance < minDistance) { + lastindex = j; + if (distance == 0) break; + minDistance = distance; + } + } + lastr = r; lastg = g; lastb = b; + } + if (ditherEnabled) { + // Floyd-Steinberg error diffusion, cont'd... + final int dxm1 = dx - 1, dxp1 = dx + 1; + int acc; + rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; + rerr[dx] += acc += lrerr + lrerr; + rerr[dxm1] += acc + lrerr + lrerr; + gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr; + gerr[dx] += acc += lgerr + lgerr; + gerr[dxm1] += acc + lgerr + lgerr; + berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr; + berr[dx] += acc += lberr + lberr; + berr[dxm1] += acc + lberr + lberr; + } + + /*** WRITE NEXT PIXEL ***/ + switch (dtype) { + case TYPE_INDEX_8: + destData[dp] = (byte) lastindex; + break; + case TYPE_INDEX_4: + if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex); + else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); + break; + case TYPE_INDEX_2: { + final int shift = 6 - (dp & 3) * 2; + destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); + } break; + case TYPE_INDEX_1_MSB: { + final int shift = 7 - (dp & 7); + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); + } break; + case TYPE_INDEX_1_LSB: { + final int shift = dp & 7; + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); + } break; + } + } + } +} + +/** + * Blits an index palette image into a direct palette image. + * <p> + * Note: The source and destination masks and palettes must + * always be fully specified. + * </p> + * + * @param op the blitter operation: a combination of BLIT_xxx flags + * (see BLIT_xxx constants) + * @param srcData the source byte array containing image data + * @param srcDepth the source depth: one of 1, 2, 4, 8 + * @param srcStride the source number of bytes per line + * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if srcDepth is not 1 + * @param srcX the top-left x-coord of the source blit region + * @param srcY the top-left y-coord of the source blit region + * @param srcWidth the width of the source blit region + * @param srcHeight the height of the source blit region + * @param srcReds the source palette red component intensities + * @param srcGreens the source palette green component intensities + * @param srcBlues the source palette blue component intensities + * @param alphaMode the alpha blending or mask mode, may be + * an integer 0-255 for global alpha; ignored if BLIT_ALPHA + * not specified in the blitter operations + * (see ALPHA_MODE_xxx constants) + * @param alphaData the alpha blending or mask data, varies depending + * on the value of alphaMode and sometimes ignored + * @param alphaStride the alpha data number of bytes per line + * @param alphaX the top-left x-coord of the alpha blit region + * @param alphaY the top-left y-coord of the alpha blit region + * @param destData the destination byte array containing image data + * @param destDepth the destination depth: one of 8, 16, 24, 32 + * @param destStride the destination number of bytes per line + * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if destDepth is not 16 or 32 + * @param destX the top-left x-coord of the destination blit region + * @param destY the top-left y-coord of the destination blit region + * @param destWidth the width of the destination blit region + * @param destHeight the height of the destination blit region + * @param destRedMask the destination red channel mask + * @param destGreenMask the destination green channel mask + * @param destBlueMask the destination blue channel mask + * @param flipX if true the resulting image is flipped along the vertical axis + * @param flipY if true the resulting image is flipped along the horizontal axis + */ +static void blit(int op, + byte[] srcData, int srcDepth, int srcStride, int srcOrder, + int srcX, int srcY, int srcWidth, int srcHeight, + byte[] srcReds, byte[] srcGreens, byte[] srcBlues, + int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, + byte[] destData, int destDepth, int destStride, int destOrder, + int destX, int destY, int destWidth, int destHeight, + int destRedMask, int destGreenMask, int destBlueMask, + boolean flipX, boolean flipY) { + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; + + // these should be supplied as params later + final int destAlphaMask = 0; + + /*** Prepare scaling data ***/ + final int dwm1 = destWidth - 1; + final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; + final int dhm1 = destHeight - 1; + final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; + + /*** Prepare source-related data ***/ + final int stype; + switch (srcDepth) { + case 8: + stype = TYPE_INDEX_8; + break; + case 4: + srcStride <<= 1; + stype = TYPE_INDEX_4; + break; + case 2: + srcStride <<= 2; + stype = TYPE_INDEX_2; + break; + case 1: + srcStride <<= 3; + stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int spr = srcY * srcStride + srcX; + + /*** Prepare destination-related data ***/ + final int dbpp, dtype; + switch (destDepth) { + case 8: + dbpp = 1; + dtype = TYPE_GENERIC_8; + break; + case 16: + dbpp = 2; + dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; + break; + case 24: + dbpp = 3; + dtype = TYPE_GENERIC_24; + break; + case 32: + dbpp = 4; + dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid destination type"); + return; + } + int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; + final int dprxi = (flipX) ? -dbpp : dbpp; + final int dpryi = (flipY) ? -destStride : destStride; + + /*** Prepare special processing data ***/ + int apr; + if ((op & BLIT_ALPHA) != 0) { + switch (alphaMode) { + case ALPHA_MASK_UNPACKED: + case ALPHA_CHANNEL_SEPARATE: + if (alphaData == null) alphaMode = 0x10000; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_PACKED: + if (alphaData == null) alphaMode = 0x10000; + alphaStride <<= 3; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_INDEX: + case ALPHA_MASK_RGB: + if (alphaData == null) alphaMode = 0x10000; + apr = 0; + break; + default: + alphaMode = (alphaMode << 16) / 255; // prescale + case ALPHA_CHANNEL_SOURCE: + apr = 0; + break; + } + } else { + alphaMode = 0x10000; + apr = 0; + } + + /*** Comprehensive blit (apply transformations) ***/ + final int destRedShift = getChannelShift(destRedMask); + final int destRedWidth = getChannelWidth(destRedMask, destRedShift); + final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; + final int destRedPreShift = 8 - destRedWidth; + final int destGreenShift = getChannelShift(destGreenMask); + final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); + final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; + final int destGreenPreShift = 8 - destGreenWidth; + final int destBlueShift = getChannelShift(destBlueMask); + final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); + final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; + final int destBluePreShift = 8 - destBlueWidth; + final int destAlphaShift = getChannelShift(destAlphaMask); + final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); + final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; + final int destAlphaPreShift = 8 - destAlphaWidth; + + int dp = dpr; + int sp = spr; + int ap = apr, alpha = alphaMode; + int r = 0, g = 0, b = 0, a = 0, index = 0; + int rq = 0, gq = 0, bq = 0, aq = 0; + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, + sp = spr += (sfy >>> 16) * srcStride, + ap = apr += (sfy >>> 16) * alphaStride, + sfy = (sfy & 0xffff) + sfyi, + dp = dpr += dpryi) { + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, + dp += dprxi, + sfx = (sfx & 0xffff) + sfxi) { + /*** READ NEXT PIXEL ***/ + switch (stype) { + case TYPE_INDEX_8: + index = srcData[sp] & 0xff; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_4: + if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; + else index = (srcData[sp >> 1] >>> 4) & 0x0f; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_2: + index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_MSB: + index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; + sp += (sfx >>> 16); + break; + case TYPE_INDEX_1_LSB: + index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; + sp += (sfx >>> 16); + break; + } + + /*** DO SPECIAL PROCESSING IF REQUIRED ***/ + r = srcReds[index] & 0xff; + g = srcGreens[index] & 0xff; + b = srcBlues[index] & 0xff; + switch (alphaMode) { + case ALPHA_CHANNEL_SEPARATE: + alpha = ((alphaData[ap] & 0xff) << 16) / 255; + ap += (sfx >> 16); + break; + case ALPHA_MASK_UNPACKED: + alpha = (alphaData[ap] != 0) ? 0x10000 : 0; + ap += (sfx >> 16); + break; + case ALPHA_MASK_PACKED: + alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; + ap += (sfx >> 16); + break; + case ALPHA_MASK_INDEX: { // could speed up using binary search if we sorted the indices + int i = 0; + while (i < alphaData.length) { + if (index == (alphaData[i] & 0xff)) break; + } + if (i < alphaData.length) continue; + } break; + case ALPHA_MASK_RGB: { + int i = 0; + while (i < alphaData.length) { + if ((r == (alphaData[i] & 0xff)) && + (g == (alphaData[i + 1] & 0xff)) && + (b == (alphaData[i + 2] & 0xff))) break; + i += 3; + } + if (i < alphaData.length) continue; + } break; + } + if (alpha != 0x10000) { + if (alpha == 0x0000) continue; + switch (dtype) { + case TYPE_GENERIC_8: { + final int data = destData[dp] & 0xff; + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_MSB: { + final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_LSB: { + final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_24: { + final int data = (( ((destData[dp] & 0xff) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp + 2] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_MSB: { + final int data = (( (( ((destData[dp] & 0xff) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp + 2] & 0xff)) << 8) | + (destData[dp + 3] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_LSB: { + final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | + (destData[dp + 2] & 0xff)) << 8) | + (destData[dp + 1] & 0xff)) << 8) | + (destData[dp] & 0xff); + rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; + gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; + bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; + aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; + } break; + } + // Perform alpha blending + a = aq + ((a - aq) * alpha >> 16); + r = rq + ((r - rq) * alpha >> 16); + g = gq + ((g - gq) * alpha >> 16); + b = bq + ((b - bq) * alpha >> 16); + } + + /*** WRITE NEXT PIXEL ***/ + final int data = + (r >>> destRedPreShift << destRedShift) | + (g >>> destGreenPreShift << destGreenShift) | + (b >>> destBluePreShift << destBlueShift) | + (a >>> destAlphaPreShift << destAlphaShift); + switch (dtype) { + case TYPE_GENERIC_8: { + destData[dp] = (byte) data; + } break; + case TYPE_GENERIC_16_MSB: { + destData[dp] = (byte) (data >>> 8); + destData[dp + 1] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_16_LSB: { + destData[dp] = (byte) (data & 0xff); + destData[dp + 1] = (byte) (data >>> 8); + } break; + case TYPE_GENERIC_24: { + destData[dp] = (byte) (data >>> 16); + destData[dp + 1] = (byte) (data >>> 8); + destData[dp + 2] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_32_MSB: { + destData[dp] = (byte) (data >>> 24); + destData[dp + 1] = (byte) (data >>> 16); + destData[dp + 2] = (byte) (data >>> 8); + destData[dp + 3] = (byte) (data & 0xff); + } break; + case TYPE_GENERIC_32_LSB: { + destData[dp] = (byte) (data & 0xff); + destData[dp + 1] = (byte) (data >>> 8); + destData[dp + 2] = (byte) (data >>> 16); + destData[dp + 3] = (byte) (data >>> 24); + } break; + } + } + } +} + +/** + * Blits a direct palette image into an index palette image. + * <p> + * Note: The source and destination masks and palettes must + * always be fully specified. + * </p> + * + * @param op the blitter operation: a combination of BLIT_xxx flags + * (see BLIT_xxx constants) + * @param srcData the source byte array containing image data + * @param srcDepth the source depth: one of 8, 16, 24, 32 + * @param srcStride the source number of bytes per line + * @param srcOrder the source byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if srcDepth is not 16 or 32 + * @param srcX the top-left x-coord of the source blit region + * @param srcY the top-left y-coord of the source blit region + * @param srcWidth the width of the source blit region + * @param srcHeight the height of the source blit region + * @param srcRedMask the source red channel mask + * @param srcGreenMask the source green channel mask + * @param srcBlueMask the source blue channel mask + * @param alphaMode the alpha blending or mask mode, may be + * an integer 0-255 for global alpha; ignored if BLIT_ALPHA + * not specified in the blitter operations + * (see ALPHA_MODE_xxx constants) + * @param alphaData the alpha blending or mask data, varies depending + * on the value of alphaMode and sometimes ignored + * @param alphaStride the alpha data number of bytes per line + * @param alphaX the top-left x-coord of the alpha blit region + * @param alphaY the top-left y-coord of the alpha blit region + * @param destData the destination byte array containing image data + * @param destDepth the destination depth: one of 1, 2, 4, 8 + * @param destStride the destination number of bytes per line + * @param destOrder the destination byte ordering: one of MSB_FIRST or LSB_FIRST; + * ignored if destDepth is not 1 + * @param destX the top-left x-coord of the destination blit region + * @param destY the top-left y-coord of the destination blit region + * @param destWidth the width of the destination blit region + * @param destHeight the height of the destination blit region + * @param destReds the destination palette red component intensities + * @param destGreens the destination palette green component intensities + * @param destBlues the destination palette blue component intensities + * @param flipX if true the resulting image is flipped along the vertical axis + * @param flipY if true the resulting image is flipped along the horizontal axis + */ +static void blit(int op, + byte[] srcData, int srcDepth, int srcStride, int srcOrder, + int srcX, int srcY, int srcWidth, int srcHeight, + int srcRedMask, int srcGreenMask, int srcBlueMask, + int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, + byte[] destData, int destDepth, int destStride, int destOrder, + int destX, int destY, int destWidth, int destHeight, + byte[] destReds, byte[] destGreens, byte[] destBlues, + boolean flipX, boolean flipY) { + if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; + + // these should be supplied as params later + final int srcAlphaMask = 0; + + /*** Prepare scaling data ***/ + final int dwm1 = destWidth - 1; + final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; + final int dhm1 = destHeight - 1; + final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; + + /*** Prepare source-related data ***/ + final int sbpp, stype; + switch (srcDepth) { + case 8: + sbpp = 1; + stype = TYPE_GENERIC_8; + break; + case 16: + sbpp = 2; + stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; + break; + case 24: + sbpp = 3; + stype = TYPE_GENERIC_24; + break; + case 32: + sbpp = 4; + stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int spr = srcY * srcStride + srcX * sbpp; + + /*** Prepare destination-related data ***/ + final int dtype; + switch (destDepth) { + case 8: + dtype = TYPE_INDEX_8; + break; + case 4: + destStride <<= 1; + dtype = TYPE_INDEX_4; + break; + case 2: + destStride <<= 2; + dtype = TYPE_INDEX_2; + break; + case 1: + destStride <<= 3; + dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; + break; + default: + //throw new IllegalArgumentException("Invalid source type"); + return; + } + int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); + final int dprxi = (flipX) ? -1 : 1; + final int dpryi = (flipY) ? -destStride : destStride; + + /*** Prepare special processing data ***/ + int apr; + if ((op & BLIT_ALPHA) != 0) { + switch (alphaMode) { + case ALPHA_MASK_UNPACKED: + case ALPHA_CHANNEL_SEPARATE: + if (alphaData == null) alphaMode = 0x10000; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_PACKED: + if (alphaData == null) alphaMode = 0x10000; + alphaStride <<= 3; + apr = alphaY * alphaStride + alphaX; + break; + case ALPHA_MASK_INDEX: + //throw new IllegalArgumentException("Invalid alpha type"); + return; + case ALPHA_MASK_RGB: + if (alphaData == null) alphaMode = 0x10000; + apr = 0; + break; + default: + alphaMode = (alphaMode << 16) / 255; // prescale + case ALPHA_CHANNEL_SOURCE: + apr = 0; + break; + } + } else { + alphaMode = 0x10000; + apr = 0; + } + final boolean ditherEnabled = (op & BLIT_DITHER) != 0; + + /*** Comprehensive blit (apply transformations) ***/ + final int srcRedShift = getChannelShift(srcRedMask); + final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; + final int srcGreenShift = getChannelShift(srcGreenMask); + final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; + final int srcBlueShift = getChannelShift(srcBlueMask); + final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; + final int srcAlphaShift = getChannelShift(srcAlphaMask); + final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; + + int dp = dpr; + int sp = spr; + int ap = apr, alpha = alphaMode; + int r = 0, g = 0, b = 0, a = 0; + int indexq = 0; + int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; + final int[] rerr, gerr, berr; + int destPaletteSize = 1 << destDepth; + if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length; + if (ditherEnabled) { + rerr = new int[destWidth + 2]; + gerr = new int[destWidth + 2]; + berr = new int[destWidth + 2]; + } else { + rerr = null; gerr = null; berr = null; + } + for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, + sp = spr += (sfy >>> 16) * srcStride, + ap = apr += (sfy >>> 16) * alphaStride, + sfy = (sfy & 0xffff) + sfyi, + dp = dpr += dpryi) { + int lrerr = 0, lgerr = 0, lberr = 0; + for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, + dp += dprxi, + sfx = (sfx & 0xffff) + sfxi) { + /*** READ NEXT PIXEL ***/ + switch (stype) { + case TYPE_GENERIC_8: { + final int data = srcData[sp] & 0xff; + sp += (sfx >>> 16); + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_MSB: { + final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); + sp += (sfx >>> 16) * 2; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_16_LSB: { + final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); + sp += (sfx >>> 16) * 2; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_24: { + final int data = (( ((srcData[sp] & 0xff) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp + 2] & 0xff); + sp += (sfx >>> 16) * 3; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_MSB: { + final int data = (( (( ((srcData[sp] & 0xff) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp + 2] & 0xff)) << 8) | + (srcData[sp + 3] & 0xff); + sp += (sfx >>> 16) * 4; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + case TYPE_GENERIC_32_LSB: { + final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | + (srcData[sp + 2] & 0xff)) << 8) | + (srcData[sp + 1] & 0xff)) << 8) | + (srcData[sp] & 0xff); + sp += (sfx >>> 16) * 4; + r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; + g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; + b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; + a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; + } break; + } + + /*** DO SPECIAL PROCESSING IF REQUIRED ***/ + switch (alphaMode) { + case ALPHA_CHANNEL_SEPARATE: + alpha = ((alphaData[ap] & 0xff) << 16) / 255; + ap += (sfx >> 16); + break; + case ALPHA_CHANNEL_SOURCE: + alpha = (a << 16) / 255; + break; + case ALPHA_MASK_UNPACKED: + alpha = (alphaData[ap] != 0) ? 0x10000 : 0; + ap += (sfx >> 16); + break; + case ALPHA_MASK_PACKED: + alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; + ap += (sfx >> 16); + break; + case ALPHA_MASK_RGB: + alpha = 0x10000; + for (int i = 0; i < alphaData.length; i += 3) { + if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) { + alpha = 0x0000; + break; + } + } + break; + } + if (alpha != 0x10000) { + if (alpha == 0x0000) continue; + switch (dtype) { + case TYPE_INDEX_8: + indexq = destData[dp] & 0xff; + break; + case TYPE_INDEX_4: + if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f; + else indexq = (destData[dp >> 1] >>> 4) & 0x0f; + break; + case TYPE_INDEX_2: + indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03; + break; + case TYPE_INDEX_1_MSB: + indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01; + break; + case TYPE_INDEX_1_LSB: + indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; + break; + } + // Perform alpha blending + final int rq = destReds[indexq] & 0xff; + final int gq = destGreens[indexq] & 0xff; + final int bq = destBlues[indexq] & 0xff; + r = rq + ((r - rq) * alpha >> 16); + g = gq + ((g - gq) * alpha >> 16); + b = bq + ((b - bq) * alpha >> 16); + } + + /*** MAP COLOR TO THE PALETTE ***/ + if (ditherEnabled) { + // Floyd-Steinberg error diffusion + r += rerr[dx] >> 4; + if (r < 0) r = 0; else if (r > 255) r = 255; + g += gerr[dx] >> 4; + if (g < 0) g = 0; else if (g > 255) g = 255; + b += berr[dx] >> 4; + if (b < 0) b = 0; else if (b > 255) b = 255; + rerr[dx] = lrerr; + gerr[dx] = lgerr; + berr[dx] = lberr; + } + if (r != lastr || g != lastg || b != lastb) { + // moving the variable declarations out seems to make the JDK JIT happier... + for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) { + dr = (destReds[j] & 0xff) - r; + dg = (destGreens[j] & 0xff) - g; + db = (destBlues[j] & 0xff) - b; + distance = dr * dr + dg * dg + db * db; + if (distance < minDistance) { + lastindex = j; + if (distance == 0) break; + minDistance = distance; + } + } + lastr = r; lastg = g; lastb = b; + } + if (ditherEnabled) { + // Floyd-Steinberg error diffusion, cont'd... + final int dxm1 = dx - 1, dxp1 = dx + 1; + int acc; + rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; + rerr[dx] += acc += lrerr + lrerr; + rerr[dxm1] += acc + lrerr + lrerr; + gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr; + gerr[dx] += acc += lgerr + lgerr; + gerr[dxm1] += acc + lgerr + lgerr; + berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr; + berr[dx] += acc += lberr + lberr; + berr[dxm1] += acc + lberr + lberr; + } + + /*** WRITE NEXT PIXEL ***/ + switch (dtype) { + case TYPE_INDEX_8: + destData[dp] = (byte) lastindex; + break; + case TYPE_INDEX_4: + if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex); + else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); + break; + case TYPE_INDEX_2: { + final int shift = 6 - (dp & 3) * 2; + destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); + } break; + case TYPE_INDEX_1_MSB: { + final int shift = 7 - (dp & 7); + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); + } break; + case TYPE_INDEX_1_LSB: { + final int shift = dp & 7; + destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); + } break; + } + } + } +} + +/** + * Computes the required channel shift from a mask. + */ +static int getChannelShift(int mask) { + if (mask == 0) return 0; + int i; + for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) { + mask >>>= 1; + } + return i; +} + +/** + * Computes the required channel width (depth) from a mask. + */ +static int getChannelWidth(int mask, int shift) { + if (mask == 0) return 0; + int i; + mask >>>= shift; + for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) { + mask >>>= 1; + } + return i - shift; +} + +/** + * Extracts a field from packed RGB data given a mask for that field. + */ +static byte getChannelField(int data, int mask) { + final int shift = getChannelShift(mask); + return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >>> shift]; +} + +/** + * Creates an ImageData containing one band's worth of a gradient filled + * block. If <code>vertical</code> is true, the band must be tiled + * horizontally to fill a region, otherwise it must be tiled vertically. + * + * @param width the width of the region to be filled + * @param height the height of the region to be filled + * @param vertical if true sweeps from top to bottom, else + * sweeps from left to right + * @param fromRGB the color to start with + * @param toRGB the color to end with + * @param redBits the number of significant red bits, 0 for palette modes + * @param greenBits the number of significant green bits, 0 for palette modes + * @param blueBits the number of significant blue bits, 0 for palette modes + * @return the new ImageData + */ +static ImageData createGradientBand( + int width, int height, boolean vertical, + RGB fromRGB, RGB toRGB, + int redBits, int greenBits, int blueBits) { + /* Gradients are drawn as tiled bands */ + final int bandWidth, bandHeight, bitmapDepth; + final byte[] bitmapData; + final PaletteData paletteData; + /* Select an algorithm depending on the depth of the screen */ + if (redBits != 0 && greenBits != 0 && blueBits != 0) { + paletteData = new PaletteData(0x0000ff00, 0x00ff0000, 0xff000000); + bitmapDepth = 32; + if (redBits >= 8 && greenBits >= 8 && blueBits >= 8) { + /* Precise color */ + final int steps; + if (vertical) { + bandWidth = 1; + bandHeight = height; + steps = bandHeight > 1 ? bandHeight - 1 : 1; + } else { + bandWidth = width; + bandHeight = 1; + steps = bandWidth > 1 ? bandWidth - 1 : 1; + } + final int bytesPerLine = bandWidth * 4; + bitmapData = new byte[bandHeight * bytesPerLine]; + buildPreciseGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine); + buildPreciseGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine); + buildPreciseGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine); + } else { + /* Dithered color */ + final int steps; + if (vertical) { + bandWidth = (width < 8) ? width : 8; + bandHeight = height; + steps = bandHeight > 1 ? bandHeight - 1 : 1; + } else { + bandWidth = width; + bandHeight = (height < 8) ? height : 8; + steps = bandWidth > 1 ? bandWidth - 1 : 1; + } + final int bytesPerLine = bandWidth * 4; + bitmapData = new byte[bandHeight * bytesPerLine]; + buildDitheredGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine, blueBits); + buildDitheredGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine, greenBits); + buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits); + } + } else { + /* Dithered two tone */ + paletteData = new PaletteData(new RGB[] { fromRGB, toRGB }); + bitmapDepth = 8; + final int blendi; + if (vertical) { + bandWidth = (width < 8) ? width : 8; + bandHeight = height; + blendi = (bandHeight > 1) ? 0x1040000 / (bandHeight - 1) + 1 : 1; + } else { + bandWidth = width; + bandHeight = (height < 8) ? height : 8; + blendi = (bandWidth > 1) ? 0x1040000 / (bandWidth - 1) + 1 : 1; + } + final int bytesPerLine = (bandWidth + 3) & -4; + bitmapData = new byte[bandHeight * bytesPerLine]; + if (vertical) { + for (int dy = 0, blend = 0, dp = 0; dy < bandHeight; + ++dy, blend += blendi, dp += bytesPerLine) { + for (int dx = 0; dx < bandWidth; ++dx) { + bitmapData[dp + dx] = (blend + DITHER_MATRIX[dy & 7][dx]) < + 0x1000000 ? (byte)0 : (byte)1; + } + } + } else { + for (int dx = 0, blend = 0; dx < bandWidth; ++dx, blend += blendi) { + for (int dy = 0, dptr = dx; dy < bandHeight; ++dy, dptr += bytesPerLine) { + bitmapData[dptr] = (blend + DITHER_MATRIX[dy][dx & 7]) < + 0x1000000 ? (byte)0 : (byte)1; + } + } + } + } + return new ImageData(bandWidth, bandHeight, bitmapDepth, paletteData, 4, bitmapData); +} + +/* + * Fill in gradated values for a color channel + */ +static final void buildPreciseGradientChannel(int from, int to, int steps, + int bandWidth, int bandHeight, boolean vertical, + byte[] bitmapData, int dp, int bytesPerLine) { + int val = from << 16; + final int inc = ((to << 16) - val) / steps + 1; + if (vertical) { + for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { + bitmapData[dp] = (byte)(val >>> 16); + val += inc; + } + } else { + for (int dx = 0; dx < bandWidth; ++dx, dp += 4) { + bitmapData[dp] = (byte)(val >>> 16); + val += inc; + } + } +} + +/* + * Fill in dithered gradated values for a color channel + */ +static final void buildDitheredGradientChannel(int from, int to, int steps, + int bandWidth, int bandHeight, boolean vertical, + byte[] bitmapData, int dp, int bytesPerLine, int bits) { + final int mask = 0xff00 >>> bits; + int val = from << 16; + final int inc = ((to << 16) - val) / steps + 1; + if (vertical) { + for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { + for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) { + final int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits; + int temp = val + thresh; + if (temp > 0xffffff) bitmapData[dptr] = -1; + else bitmapData[dptr] = (byte)((temp >>> 16) & mask); + } + val += inc; + } + } else { + for (int dx = 0; dx < bandWidth; ++dx, dp += 4) { + for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) { + final int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits; + int temp = val + thresh; + if (temp > 0xffffff) bitmapData[dptr] = -1; + else bitmapData[dptr] = (byte)((temp >>> 16) & mask); + } + val += inc; + } + } +} + +/** + * Renders a gradient onto a GC. + * <p> + * This is a GC helper. + * </p> + * + * @param gc the GC to render the gradient onto + * @param device the device the GC belongs to + * @param x the top-left x coordinate of the region to be filled + * @param y the top-left y coordinate of the region to be filled + * @param width the width of the region to be filled + * @param height the height of the region to be filled + * @param vertical if true sweeps from top to bottom, else + * sweeps from left to right + * @param fromRGB the color to start with + * @param toRGB the color to end with + * @param redBits the number of significant red bits, 0 for palette modes + * @param greenBits the number of significant green bits, 0 for palette modes + * @param blueBits the number of significant blue bits, 0 for palette modes + */ +static void fillGradientRectangle(GC gc, Device device, + int x, int y, int width, int height, boolean vertical, + RGB fromRGB, RGB toRGB, + int redBits, int greenBits, int blueBits) { + /* Create the bitmap and tile it */ + ImageData band = createGradientBand(width, height, vertical, + fromRGB, toRGB, redBits, greenBits, blueBits); + Image image = new Image(device, band); + if ((band.width == 1) || (band.height == 1)) { + gc.drawImage(image, 0, 0, band.width, band.height, x, y, width, height); + } else { + if (vertical) { + for (int dx = 0; dx < width; dx += band.width) { + int blitWidth = width - dx; + if (blitWidth > band.width) blitWidth = band.width; + gc.drawImage(image, 0, 0, blitWidth, band.height, dx + x, y, blitWidth, band.height); + } + } else { + for (int dy = 0; dy < height; dy += band.height) { + int blitHeight = height - dy; + if (blitHeight > band.height) blitHeight = band.height; + gc.drawImage(image, 0, 0, band.width, blitHeight, x, dy + y, band.width, blitHeight); + } + } + } + image.dispose(); +} + }
\ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java index e0c9dd4b14..abb4931eb1 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java @@ -1,294 +1,294 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-import java.util.Vector;
-import org.eclipse.swt.*;
-import org.eclipse.swt.internal.Compatibility;
-import org.eclipse.swt.internal.image.*;
-
-/**
- * Instances of this class are used to load images from,
- * and save images to, a file or stream.
- * <p>
- * Currently supported image formats are:
- * </p><ul>
- * <li>BMP (Windows Bitmap)</li>
- * <li>ICO (Windows Icon)</li>
- * <li>JPEG</li>
- * <li>GIF</li>
- * <li>PNG</li>
- * </ul>
- * <code>ImageLoaders</code> can be used to:
- * <ul>
- * <li>load/save single images in all formats</li>
- * <li>load/save multiple images (GIF/ICO)</li>
- * <li>load/save animated GIF images</li>
- * <li>load interlaced GIF/PNG images</li>
- * <li>load progressive JPEG images</li>
- * </ul>
- */
-
-public class ImageLoader {
-
- /**
- * the array of ImageData objects in this ImageLoader.
- * This array is read in when the load method is called,
- * and it is written out when the save method is called
- */
- public ImageData[] data;
-
- /**
- * the width of the logical screen on which the images
- * reside, in pixels (this corresponds to the GIF89a
- * Logical Screen Width value)
- */
- public int logicalScreenWidth;
-
- /**
- * the height of the logical screen on which the images
- * reside, in pixels (this corresponds to the GIF89a
- * Logical Screen Height value)
- */
- public int logicalScreenHeight;
-
- /**
- * the background pixel for the logical screen (this
- * corresponds to the GIF89a Background Color Index value).
- * The default is -1 which means 'unspecified background'
- *
- */
- public int backgroundPixel;
-
- /**
- * the number of times to repeat the display of a sequence
- * of animated images (this corresponds to the commonly-used
- * GIF application extension for "NETSCAPE 2.0 01")
- */
- public int repeatCount;
-
- /*
- * the set of ImageLoader event listeners, created on demand
- */
- Vector imageLoaderListeners;
-
-/**
- * Construct a new empty ImageLoader.
- */
-public ImageLoader() {
- reset();
-}
-
-/**
- * Resets the fields of the ImageLoader, except for the
- * <code>imageLoaderListeners</code> field.
- */
-void reset() {
- data = null;
- logicalScreenWidth = 0;
- logicalScreenHeight = 0;
- backgroundPixel = -1;
- repeatCount = 1;
-}
-
-/**
- * Loads an array of <code>ImageData</code> objects from the
- * specified input stream. Throws an error if either an error
- * occurs while loading the images, or if the images are not
- * of a supported type. Returns the loaded image data array.
- *
- * @param stream the input stream to load the images from
- * @return an array of <code>ImageData</code> objects loaded from the specified input stream
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
- * <li>ERROR_IO - if an input/output error occurs while reading data</li>
- * </ul>
- */
-public ImageData[] load(InputStream stream) {
- if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- reset();
- data = FileFormat.load(stream, this);
- return data;
-}
-
-/**
- * Loads an array of <code>ImageData</code> objects from the
- * file with the specified name. Throws an error if either
- * an error occurs while loading the images, or if the images are
- * not of a supported type. Returns the loaded image data array.
- *
- * @param filename the name of the file to load the images from
- * @return an array of <code>ImageData</code> objects loaded from the specified file
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li>
- * <li>ERROR_IO - if an IO error occurs while reading data</li>
- * </ul>
- */
-public ImageData[] load(String filename) {
- if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- InputStream stream = null;
- try {
- stream = Compatibility.newFileInputStream(filename);
- return load(stream);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- } finally {
- try {
- if (stream != null) stream.close();
- } catch (IOException e) {
- // Ignore error
- }
- }
- return null;
-}
-
-/**
- * Saves the image data in this ImageLoader to the specified stream.
- * The format parameter can have one of the following values:
- * <dl>
- * <dt><code>IMAGE_BMP</code></dt>
- * <dd>Windows BMP file format, no compression</dd>
- * <dt><code>IMAGE_BMP_RLE</code></dt>
- * <dd>Windows BMP file format, RLE compression if appropriate</dd>
- * <dt><code>IMAGE_GIF</code></dt>
- * <dd>GIF file format</dd>
- * <dt><code>IMAGE_ICO</code></dt>
- * <dd>Windows ICO file format</dd>
- * <dt><code>IMAGE_JPEG</code></dt>
- * <dd>JPEG file format</dd>
- * <dt><code>IMAGE_PNG</code></dt>
- * <dd>PNG file format</dd>
- * </dl>
- *
- * @param stream the output stream to write the images to
- * @param format the format to write the images in
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the stream is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE if the image data contains invalid data</li>
- * <li>ERROR_IO if an IO error occurs while writing to the stream</li>
- * </ul>
- */
-public void save(OutputStream stream, int format) {
- if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- FileFormat.save(stream, format, this);
-}
-
-/**
- * Saves the image data in this ImageLoader to a file with the specified name.
- * The format parameter can have one of the following values:
- * <dl>
- * <dt><code>IMAGE_BMP</code></dt>
- * <dd>Windows BMP file format, no compression</dd>
- * <dt><code>IMAGE_BMP_RLE</code></dt>
- * <dd>Windows BMP file format, RLE compression if appropriate</dd>
- * <dt><code>IMAGE_GIF</code></dt>
- * <dd>GIF file format</dd>
- * <dt><code>IMAGE_ICO</code></dt>
- * <dd>Windows ICO file format</dd>
- * <dt><code>IMAGE_JPEG</code></dt>
- * <dd>JPEG file format</dd>
- * <dt><code>IMAGE_PNG</code></dt>
- * <dd>PNG file format</dd>
- * </dl>
- *
- * @param filename the name of the file to write the images to
- * @param format the format to write the images in
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the file name is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_IMAGE if the image data contains invalid data</li>
- * <li>ERROR_IO if an IO error occurs while writing to the file</li>
- * </ul>
- */
-public void save(String filename, int format) {
- if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- OutputStream stream = null;
- try {
- stream = Compatibility.newFileOutputStream(filename);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- save(stream, format);
-}
-
-/**
- * Adds a listener to receive image loader events.
- * <p>
- * An ImageLoaderListener should be added before invoking
- * one of the receiver's load methods. The listener's
- * <code>imageDataLoaded</code> method is called when image
- * data has been partially loaded, as is supported by interlaced
- * GIF/PNG or progressive JPEG images.
- *
- * @param listener the ImageLoaderListener to add
- *
- * @see ImageLoaderListener
- * @see ImageLoaderEvent
- */
-public void addImageLoaderListener(ImageLoaderListener listener) {
- if (imageLoaderListeners == null) {
- imageLoaderListeners = new Vector();
- }
- imageLoaderListeners.addElement(listener);
-}
-
-/**
- * Removes a listener that was receiving image loader events.
- *
- * @param listener the ImageLoaderListener to remove
- *
- * @see #addImageLoaderListener
- */
-public void removeImageLoaderListener(ImageLoaderListener listener) {
- if (imageLoaderListeners == null) return;
- imageLoaderListeners.removeElement(listener);
-}
-
-/**
- * Returns <code>true</code> if the receiver has image loader
- * listeners, and <code>false</code> otherwise.
- *
- * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise
- *
- * @see #addImageLoaderListener
- * @see #removeImageLoaderListener
- */
-public boolean hasListeners() {
- return imageLoaderListeners != null && imageLoaderListeners.size() > 0;
-}
-
-/**
- * Notifies all image loader listeners that an image loader event
- * has occurred. Pass the specified event object to each listener.
- *
- * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code>
- */
-public void notifyListeners(ImageLoaderEvent event) {
- if (!hasListeners()) return;
- int size = imageLoaderListeners.size();
- for (int i = 0; i < size; i++) {
- ImageLoaderListener listener = (ImageLoaderListener) imageLoaderListeners.elementAt(i);
- listener.imageDataLoaded(event);
- }
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; +import java.util.Vector; +import org.eclipse.swt.*; +import org.eclipse.swt.internal.Compatibility; +import org.eclipse.swt.internal.image.*; + +/** + * Instances of this class are used to load images from, + * and save images to, a file or stream. + * <p> + * Currently supported image formats are: + * </p><ul> + * <li>BMP (Windows Bitmap)</li> + * <li>ICO (Windows Icon)</li> + * <li>JPEG</li> + * <li>GIF</li> + * <li>PNG</li> + * </ul> + * <code>ImageLoaders</code> can be used to: + * <ul> + * <li>load/save single images in all formats</li> + * <li>load/save multiple images (GIF/ICO)</li> + * <li>load/save animated GIF images</li> + * <li>load interlaced GIF/PNG images</li> + * <li>load progressive JPEG images</li> + * </ul> + */ + +public class ImageLoader { + + /** + * the array of ImageData objects in this ImageLoader. + * This array is read in when the load method is called, + * and it is written out when the save method is called + */ + public ImageData[] data; + + /** + * the width of the logical screen on which the images + * reside, in pixels (this corresponds to the GIF89a + * Logical Screen Width value) + */ + public int logicalScreenWidth; + + /** + * the height of the logical screen on which the images + * reside, in pixels (this corresponds to the GIF89a + * Logical Screen Height value) + */ + public int logicalScreenHeight; + + /** + * the background pixel for the logical screen (this + * corresponds to the GIF89a Background Color Index value). + * The default is -1 which means 'unspecified background' + * + */ + public int backgroundPixel; + + /** + * the number of times to repeat the display of a sequence + * of animated images (this corresponds to the commonly-used + * GIF application extension for "NETSCAPE 2.0 01") + */ + public int repeatCount; + + /* + * the set of ImageLoader event listeners, created on demand + */ + Vector imageLoaderListeners; + +/** + * Construct a new empty ImageLoader. + */ +public ImageLoader() { + reset(); +} + +/** + * Resets the fields of the ImageLoader, except for the + * <code>imageLoaderListeners</code> field. + */ +void reset() { + data = null; + logicalScreenWidth = 0; + logicalScreenHeight = 0; + backgroundPixel = -1; + repeatCount = 1; +} + +/** + * Loads an array of <code>ImageData</code> objects from the + * specified input stream. Throws an error if either an error + * occurs while loading the images, or if the images are not + * of a supported type. Returns the loaded image data array. + * + * @param stream the input stream to load the images from + * @return an array of <code>ImageData</code> objects loaded from the specified input stream + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the stream is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li> + * <li>ERROR_IO - if an input/output error occurs while reading data</li> + * </ul> + */ +public ImageData[] load(InputStream stream) { + if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + reset(); + data = FileFormat.load(stream, this); + return data; +} + +/** + * Loads an array of <code>ImageData</code> objects from the + * file with the specified name. Throws an error if either + * an error occurs while loading the images, or if the images are + * not of a supported type. Returns the loaded image data array. + * + * @param filename the name of the file to load the images from + * @return an array of <code>ImageData</code> objects loaded from the specified file + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the file name is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data</li> + * <li>ERROR_IO - if an IO error occurs while reading data</li> + * </ul> + */ +public ImageData[] load(String filename) { + if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + InputStream stream = null; + try { + stream = Compatibility.newFileInputStream(filename); + return load(stream); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } finally { + try { + if (stream != null) stream.close(); + } catch (IOException e) { + // Ignore error + } + } + return null; +} + +/** + * Saves the image data in this ImageLoader to the specified stream. + * The format parameter can have one of the following values: + * <dl> + * <dt><code>IMAGE_BMP</code></dt> + * <dd>Windows BMP file format, no compression</dd> + * <dt><code>IMAGE_BMP_RLE</code></dt> + * <dd>Windows BMP file format, RLE compression if appropriate</dd> + * <dt><code>IMAGE_GIF</code></dt> + * <dd>GIF file format</dd> + * <dt><code>IMAGE_ICO</code></dt> + * <dd>Windows ICO file format</dd> + * <dt><code>IMAGE_JPEG</code></dt> + * <dd>JPEG file format</dd> + * <dt><code>IMAGE_PNG</code></dt> + * <dd>PNG file format</dd> + * </dl> + * + * @param stream the output stream to write the images to + * @param format the format to write the images in + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the stream is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE if the image data contains invalid data</li> + * <li>ERROR_IO if an IO error occurs while writing to the stream</li> + * </ul> + */ +public void save(OutputStream stream, int format) { + if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + FileFormat.save(stream, format, this); +} + +/** + * Saves the image data in this ImageLoader to a file with the specified name. + * The format parameter can have one of the following values: + * <dl> + * <dt><code>IMAGE_BMP</code></dt> + * <dd>Windows BMP file format, no compression</dd> + * <dt><code>IMAGE_BMP_RLE</code></dt> + * <dd>Windows BMP file format, RLE compression if appropriate</dd> + * <dt><code>IMAGE_GIF</code></dt> + * <dd>GIF file format</dd> + * <dt><code>IMAGE_ICO</code></dt> + * <dd>Windows ICO file format</dd> + * <dt><code>IMAGE_JPEG</code></dt> + * <dd>JPEG file format</dd> + * <dt><code>IMAGE_PNG</code></dt> + * <dd>PNG file format</dd> + * </dl> + * + * @param filename the name of the file to write the images to + * @param format the format to write the images in + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the file name is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_INVALID_IMAGE if the image data contains invalid data</li> + * <li>ERROR_IO if an IO error occurs while writing to the file</li> + * </ul> + */ +public void save(String filename, int format) { + if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + OutputStream stream = null; + try { + stream = Compatibility.newFileOutputStream(filename); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + save(stream, format); +} + +/** + * Adds a listener to receive image loader events. + * <p> + * An ImageLoaderListener should be added before invoking + * one of the receiver's load methods. The listener's + * <code>imageDataLoaded</code> method is called when image + * data has been partially loaded, as is supported by interlaced + * GIF/PNG or progressive JPEG images. + * + * @param listener the ImageLoaderListener to add + * + * @see ImageLoaderListener + * @see ImageLoaderEvent + */ +public void addImageLoaderListener(ImageLoaderListener listener) { + if (imageLoaderListeners == null) { + imageLoaderListeners = new Vector(); + } + imageLoaderListeners.addElement(listener); +} + +/** + * Removes a listener that was receiving image loader events. + * + * @param listener the ImageLoaderListener to remove + * + * @see #addImageLoaderListener + */ +public void removeImageLoaderListener(ImageLoaderListener listener) { + if (imageLoaderListeners == null) return; + imageLoaderListeners.removeElement(listener); +} + +/** + * Returns <code>true</code> if the receiver has image loader + * listeners, and <code>false</code> otherwise. + * + * @return <code>true</code> if there are <code>ImageLoaderListener</code>s, and <code>false</code> otherwise + * + * @see #addImageLoaderListener + * @see #removeImageLoaderListener + */ +public boolean hasListeners() { + return imageLoaderListeners != null && imageLoaderListeners.size() > 0; +} + +/** + * Notifies all image loader listeners that an image loader event + * has occurred. Pass the specified event object to each listener. + * + * @param event the <code>ImageLoaderEvent</code> to send to each <code>ImageLoaderListener</code> + */ +public void notifyListeners(ImageLoaderEvent event) { + if (!hasListeners()) return; + int size = imageLoaderListeners.size(); + for (int i = 0; i < size; i++) { + ImageLoaderListener listener = (ImageLoaderListener) imageLoaderListeners.elementAt(i); + listener.imageDataLoaded(event); + } +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderEvent.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderEvent.java index 012d70d716..10796c777b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderEvent.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderEvent.java @@ -1,80 +1,80 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventObject;
-
-/**
- * Instances of this class are sent as a result of the incremental
- * loading of image data.
- * <p>
- * <b>Notes:</b>
- * </p><ul>
- * <li>The number of events which will be sent when loading images
- * is not constant. It varies by image type, and for JPEG images it
- * varies from image to image.</li>
- * <li>For image sources which contain multiple images, the
- * <code>endOfImage</code> flag in the event will be set to true
- * after each individual image is loaded.</li>
- * </ul>
- *
- * @see ImageLoader
- * @see ImageLoaderListener
- */
-
-public class ImageLoaderEvent extends SWTEventObject {
-
- /**
- * if the <code>endOfImage</code> flag is false, then this is a
- * partially complete copy of the current <code>ImageData</code>,
- * otherwise this is a completely loaded <code>ImageData</code>
- */
- public ImageData imageData;
-
- /**
- * the zero-based count of image data increments -- this is
- * equivalent to the number of events that have been generated
- * while loading a particular image
- */
- public int incrementCount;
-
- /**
- * If this flag is true, then the current image data has been
- * completely loaded, otherwise the image data is only partially
- * loaded, and further ImageLoader events will occur unless an
- * exception is thrown
- */
- public boolean endOfImage;
-
-/**
- * Constructs a new instance of this class given the event source and
- * the values to store in its fields.
- *
- * @param source the ImageLoader that was loading when the event occurred
- * @param imageData the image data for the event
- * @param incrementCount the image data increment for the event
- * @param endOfImage the end of image flag for the event
- */
-public ImageLoaderEvent(ImageLoader source, ImageData imageData, int incrementCount, boolean endOfImage) {
- super(source);
- this.imageData = imageData;
- this.incrementCount = incrementCount;
- this.endOfImage = endOfImage;
-}
-
-/**
- * Returns a string containing a concise, human-readable
- * description of the receiver.
- *
- * @return a string representation of the event
- */
-public String toString () {
- return "ImageLoaderEvent {source=" + source + " imageData=" + imageData + " incrementCount=" + incrementCount + " endOfImage=" + endOfImage + "}";
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventObject; + +/** + * Instances of this class are sent as a result of the incremental + * loading of image data. + * <p> + * <b>Notes:</b> + * </p><ul> + * <li>The number of events which will be sent when loading images + * is not constant. It varies by image type, and for JPEG images it + * varies from image to image.</li> + * <li>For image sources which contain multiple images, the + * <code>endOfImage</code> flag in the event will be set to true + * after each individual image is loaded.</li> + * </ul> + * + * @see ImageLoader + * @see ImageLoaderListener + */ + +public class ImageLoaderEvent extends SWTEventObject { + + /** + * if the <code>endOfImage</code> flag is false, then this is a + * partially complete copy of the current <code>ImageData</code>, + * otherwise this is a completely loaded <code>ImageData</code> + */ + public ImageData imageData; + + /** + * the zero-based count of image data increments -- this is + * equivalent to the number of events that have been generated + * while loading a particular image + */ + public int incrementCount; + + /** + * If this flag is true, then the current image data has been + * completely loaded, otherwise the image data is only partially + * loaded, and further ImageLoader events will occur unless an + * exception is thrown + */ + public boolean endOfImage; + +/** + * Constructs a new instance of this class given the event source and + * the values to store in its fields. + * + * @param source the ImageLoader that was loading when the event occurred + * @param imageData the image data for the event + * @param incrementCount the image data increment for the event + * @param endOfImage the end of image flag for the event + */ +public ImageLoaderEvent(ImageLoader source, ImageData imageData, int incrementCount, boolean endOfImage) { + super(source); + this.imageData = imageData; + this.incrementCount = incrementCount; + this.endOfImage = endOfImage; +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the event + */ +public String toString () { + return "ImageLoaderEvent {source=" + source + " imageData=" + imageData + " incrementCount=" + incrementCount + " endOfImage=" + endOfImage + "}"; +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderListener.java index b566ec435d..e6097a02fe 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoaderListener.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-/**
- * Classes which implement this interface provide methods
- * that deal with the incremental loading of image data.
- * <p>
- * After creating an instance of a class that implements
- * this interface it can be added to an image loader using the
- * <code>addImageLoaderListener</code> method and removed using
- * the <code>removeImageLoaderListener</code> method. When
- * image data is either partially or completely loaded, this
- * method will be invoked.
- * </p>
- *
- * @see ImageLoader
- * @see ImageLoaderEvent
- */
-
-public interface ImageLoaderListener extends SWTEventListener {
-
-/**
- * Sent when image data is either partially or completely loaded.
- * <p>
- * The timing of when this method is called varies depending on
- * the format of the image being loaded.
- * </p>
- *
- * @param e an event containing information about the image loading operation
- */
-public void imageDataLoaded(ImageLoaderEvent e);
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + +/** + * Classes which implement this interface provide methods + * that deal with the incremental loading of image data. + * <p> + * After creating an instance of a class that implements + * this interface it can be added to an image loader using the + * <code>addImageLoaderListener</code> method and removed using + * the <code>removeImageLoaderListener</code> method. When + * image data is either partially or completely loaded, this + * method will be invoked. + * </p> + * + * @see ImageLoader + * @see ImageLoaderEvent + */ + +public interface ImageLoaderListener extends SWTEventListener { + +/** + * Sent when image data is either partially or completely loaded. + * <p> + * The timing of when this method is called varies depending on + * the format of the image being loaded. + * </p> + * + * @param e an event containing information about the image loading operation + */ +public void imageDataLoaded(ImageLoaderEvent e); + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/PaletteData.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/PaletteData.java index e8aaf581f4..7ee714d91d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/PaletteData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/PaletteData.java @@ -1,207 +1,207 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-/**
- * Instances of this class describe the color data used by an image.
- * <p>
- * Depending on the depth of the image, the PaletteData can take one
- * of two forms, indicated by the isDirect field:
- * </p>
- * <dl>
- * <dt>
- * <em>isDirect is false</em>
- * </dt>
- * <dd>
- * If isDirect is <code>false</code>, this palette is an indexed
- * palette which maps pixel values to RGBs. The actual RGB values
- * may be retrieved by using the getRGBs() method.
- * </dd>
- * <dt>
- * <em>isDirect is true</em>
- * </dt>
- * <dd>
- * If isDirect is <code>true</code>, this palette is a direct color
- * palette. Instead of containing RGB values, it contains red,
- * green and blue mask and shift information which indicates how
- * the color components may be extracted from a given pixel.
- * This means that the RGB value is actually encoded in the pixel value.
- * <p>
- * In this case, the shift data is the number of bits required to shift
- * the RGB value to the left in order to align the high bit of the
- * corresponding mask with the high bit of the first byte. This number
- * may be negative, so care must be taken when shifting. For example,
- * with a red mask of 0xFF0000, the red shift would be -16. With a red
- * mask of 0x1F, the red shift would be 3.
- * </p>
- * </dd>
- * </dl>
- *
- * @see Image
- * @see RGB
- */
-
-public final class PaletteData {
-
- /**
- * true if the receiver is a direct palette,
- * and false otherwise
- */
- public boolean isDirect;
-
- /**
- * the RGB values for an indexed palette, where the
- * indices of the array correspond to pixel values
- */
- public RGB[] colors;
-
- /**
- * the red mask for a direct palette
- */
- public int redMask;
-
- /**
- * the green mask for a direct palette
- */
- public int greenMask;
-
- /**
- * the blue mask for a direct palette
- */
- public int blueMask;
-
- /**
- * the red shift for a direct palette
- */
- public int redShift;
-
- /**
- * the green shift for a direct palette
- */
- public int greenShift;
-
- /**
- * the blue shift for a direct palette
- */
- public int blueShift;
-
-/**
- * Constructs a new indexed palette given an array of RGB values.
- *
- * @param colors the array of <code>RGB</code>s for the palette
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- */
-public PaletteData(RGB[] colors) {
- if (colors == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- this.colors = colors;
- this.isDirect = false;
-}
-
-/**
- * Constructs a new direct palette given the red, green and blue masks.
- *
- * @param redMask the red mask
- * @param greenMask the green mask
- * @param blueMask the blue mask
- */
-public PaletteData(int redMask, int greenMask, int blueMask) {
- this.redMask = redMask;
- this.greenMask = greenMask;
- this.blueMask = blueMask;
- this.isDirect = true;
- this.redShift = shiftForMask(redMask);
- this.greenShift = shiftForMask(greenMask);
- this.blueShift = shiftForMask(blueMask);
-}
-
-/**
- * Returns the pixel value corresponding to the given <code>RBG</code>.
- *
- * @return the pixel value for the given RGB
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li>
- * </ul>
- */
-public int getPixel(RGB rgb) {
- if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (isDirect) {
- int pixel = 0;
- pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask;
- pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask;
- pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask;
- return pixel;
- } else {
- for (int i = 0; i < colors.length; i++) {
- if (colors[i].equals(rgb)) return i;
- }
- /* The RGB did not exist in the palette */
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- return 0;
- }
-}
-
-/**
- * Returns an <code>RGB</code> corresponding to the given pixel value.
- *
- * @return the RGB value for the given pixel
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li>
- * </ul>
- */
-public RGB getRGB(int pixel) {
- if (isDirect) {
- int r = pixel & redMask;
- r = (redShift < 0) ? r >>> -redShift : r << redShift;
- int g = pixel & greenMask;
- g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
- int b = pixel & blueMask;
- b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
- return new RGB(r, g, b);
- } else {
- if (pixel < 0 || pixel >= colors.length) {
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
- return colors[pixel];
- }
-}
-
-/**
- * Returns all the RGB values in the receiver if it is an
- * indexed palette, or null if it is a direct palette.
- *
- * @return the <code>RGB</code>s for the receiver or null
- */
-public RGB[] getRGBs() {
- return colors;
-}
-
-/**
- * Computes the shift value for a given mask.
- *
- * @param mask the mask to compute the shift for
- * @return the shift amount
- *
- * @see PaletteData
- */
-int shiftForMask(int mask) {
- for (int i = 31; i >= 0; i--) {
- if (((mask >> i) & 0x1) != 0) return 7 - i;
- }
- return 32;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +/** + * Instances of this class describe the color data used by an image. + * <p> + * Depending on the depth of the image, the PaletteData can take one + * of two forms, indicated by the isDirect field: + * </p> + * <dl> + * <dt> + * <em>isDirect is false</em> + * </dt> + * <dd> + * If isDirect is <code>false</code>, this palette is an indexed + * palette which maps pixel values to RGBs. The actual RGB values + * may be retrieved by using the getRGBs() method. + * </dd> + * <dt> + * <em>isDirect is true</em> + * </dt> + * <dd> + * If isDirect is <code>true</code>, this palette is a direct color + * palette. Instead of containing RGB values, it contains red, + * green and blue mask and shift information which indicates how + * the color components may be extracted from a given pixel. + * This means that the RGB value is actually encoded in the pixel value. + * <p> + * In this case, the shift data is the number of bits required to shift + * the RGB value to the left in order to align the high bit of the + * corresponding mask with the high bit of the first byte. This number + * may be negative, so care must be taken when shifting. For example, + * with a red mask of 0xFF0000, the red shift would be -16. With a red + * mask of 0x1F, the red shift would be 3. + * </p> + * </dd> + * </dl> + * + * @see Image + * @see RGB + */ + +public final class PaletteData { + + /** + * true if the receiver is a direct palette, + * and false otherwise + */ + public boolean isDirect; + + /** + * the RGB values for an indexed palette, where the + * indices of the array correspond to pixel values + */ + public RGB[] colors; + + /** + * the red mask for a direct palette + */ + public int redMask; + + /** + * the green mask for a direct palette + */ + public int greenMask; + + /** + * the blue mask for a direct palette + */ + public int blueMask; + + /** + * the red shift for a direct palette + */ + public int redShift; + + /** + * the green shift for a direct palette + */ + public int greenShift; + + /** + * the blue shift for a direct palette + */ + public int blueShift; + +/** + * Constructs a new indexed palette given an array of RGB values. + * + * @param colors the array of <code>RGB</code>s for the palette + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + */ +public PaletteData(RGB[] colors) { + if (colors == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + this.colors = colors; + this.isDirect = false; +} + +/** + * Constructs a new direct palette given the red, green and blue masks. + * + * @param redMask the red mask + * @param greenMask the green mask + * @param blueMask the blue mask + */ +public PaletteData(int redMask, int greenMask, int blueMask) { + this.redMask = redMask; + this.greenMask = greenMask; + this.blueMask = blueMask; + this.isDirect = true; + this.redShift = shiftForMask(redMask); + this.greenShift = shiftForMask(greenMask); + this.blueShift = shiftForMask(blueMask); +} + +/** + * Returns the pixel value corresponding to the given <code>RBG</code>. + * + * @return the pixel value for the given RGB + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * <li>ERROR_INVALID_ARGUMENT - if the RGB is not found in the palette</li> + * </ul> + */ +public int getPixel(RGB rgb) { + if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (isDirect) { + int pixel = 0; + pixel |= (redShift < 0 ? rgb.red << -redShift : rgb.red >>> redShift) & redMask; + pixel |= (greenShift < 0 ? rgb.green << -greenShift : rgb.green >>> greenShift) & greenMask; + pixel |= (blueShift < 0 ? rgb.blue << -blueShift : rgb.blue >>> blueShift) & blueMask; + return pixel; + } else { + for (int i = 0; i < colors.length; i++) { + if (colors[i].equals(rgb)) return i; + } + /* The RGB did not exist in the palette */ + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + return 0; + } +} + +/** + * Returns an <code>RGB</code> corresponding to the given pixel value. + * + * @return the RGB value for the given pixel + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * <li>ERROR_INVALID_ARGUMENT - if the pixel does not exist in the palette</li> + * </ul> + */ +public RGB getRGB(int pixel) { + if (isDirect) { + int r = pixel & redMask; + r = (redShift < 0) ? r >>> -redShift : r << redShift; + int g = pixel & greenMask; + g = (greenShift < 0) ? g >>> -greenShift : g << greenShift; + int b = pixel & blueMask; + b = (blueShift < 0) ? b >>> -blueShift : b << blueShift; + return new RGB(r, g, b); + } else { + if (pixel < 0 || pixel >= colors.length) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + return colors[pixel]; + } +} + +/** + * Returns all the RGB values in the receiver if it is an + * indexed palette, or null if it is a direct palette. + * + * @return the <code>RGB</code>s for the receiver or null + */ +public RGB[] getRGBs() { + return colors; +} + +/** + * Computes the shift value for a given mask. + * + * @param mask the mask to compute the shift for + * @return the shift amount + * + * @see PaletteData + */ +int shiftForMask(int mask) { + for (int i = 31; i >= 0; i--) { + if (((mask >> i) & 0x1) != 0) return 7 - i; + } + return 32; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java index 33eaedd022..7ef2794e7c 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Point.java @@ -1,95 +1,95 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SerializableCompatibility;
-
-/**
- * Instances of this class represent places on the (x, y)
- * coordinate plane.
- * <p>
- * The coordinate space for rectangles and points is considered
- * to have increasing values downward and to the right from its
- * origin making this the normal, computer graphics oriented notion
- * of (x, y) coordinates rather than the strict mathematical one.
- * </p>
- * <p>
- * Application code does <em>not</em> need to explicitly release the
- * resources managed by each instance when those instances are no longer
- * required, and thus no <code>dispose()</code> method is provided.
- * </p>
- *
- * @see Rectangle
- */
-
-public final class Point implements SerializableCompatibility {
-
- /**
- * the x coordinate of the point
- */
- public int x;
-
- /**
- * the y coordinate of the point
- */
- public int y;
-
-/**
- * Constructs a new point with the given x and y coordinates.
- *
- * @param x the x coordinate of the new point
- * @param y the y coordinate of the new point
- */
-public Point (int x, int y) {
- this.x = x;
- this.y = y;
-}
-
-/**
- * Compares the argument to the receiver, and returns true
- * if they represent the <em>same</em> object using a class
- * specific comparison.
- *
- * @param object the object to compare with this object
- * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
- *
- * @see #hashCode
- */
-public boolean equals (Object object) {
- if (object == this) return true;
- if (!(object instanceof Point)) return false;
- Point p = (Point)object;
- return (p.x == this.x) && (p.y == this.y);
-}
-
-/**
- * Returns an integer hash code for the receiver. Any two
- * objects which return <code>true</code> when passed to
- * <code>equals</code> must return the same value for this
- * method.
- *
- * @return the receiver's hash
- *
- * @see #equals
- */
-public int hashCode () {
- return x ^ y;
-}
-
-/**
- * Returns a string containing a concise, human-readable
- * description of the receiver.
- *
- * @return a string representation of the point
- */
-public String toString () {
- return "Point {" + x + ", " + y + "}";
-}
-
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SerializableCompatibility; + +/** + * Instances of this class represent places on the (x, y) + * coordinate plane. + * <p> + * The coordinate space for rectangles and points is considered + * to have increasing values downward and to the right from its + * origin making this the normal, computer graphics oriented notion + * of (x, y) coordinates rather than the strict mathematical one. + * </p> + * <p> + * Application code does <em>not</em> need to explicitly release the + * resources managed by each instance when those instances are no longer + * required, and thus no <code>dispose()</code> method is provided. + * </p> + * + * @see Rectangle + */ + +public final class Point implements SerializableCompatibility { + + /** + * the x coordinate of the point + */ + public int x; + + /** + * the y coordinate of the point + */ + public int y; + +/** + * Constructs a new point with the given x and y coordinates. + * + * @param x the x coordinate of the new point + * @param y the y coordinate of the new point + */ +public Point (int x, int y) { + this.x = x; + this.y = y; +} + +/** + * Compares the argument to the receiver, and returns true + * if they represent the <em>same</em> object using a class + * specific comparison. + * + * @param object the object to compare with this object + * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise + * + * @see #hashCode + */ +public boolean equals (Object object) { + if (object == this) return true; + if (!(object instanceof Point)) return false; + Point p = (Point)object; + return (p.x == this.x) && (p.y == this.y); +} + +/** + * Returns an integer hash code for the receiver. Any two + * objects which return <code>true</code> when passed to + * <code>equals</code> must return the same value for this + * method. + * + * @return the receiver's hash + * + * @see #equals + */ +public int hashCode () { + return x ^ y; +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the point + */ +public String toString () { + return "Point {" + x + ", " + y + "}"; +} + +} + diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/RGB.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/RGB.java index 954846ad27..d8bba1da67 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/RGB.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/RGB.java @@ -1,110 +1,110 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SerializableCompatibility;
-import org.eclipse.swt.*;
-
-/**
- * Instances of this class are descriptions of colors in
- * terms of the primary additive color model (red, green and
- * blue). A color may be described in terms of the relative
- * intensities of these three primary colors. The brightness
- * of each color is specified by a value in the range 0 to 255,
- * where 0 indicates no color (blackness) and 255 indicates
- * maximum intensity.
- * <p>
- * Application code does <em>not</em> need to explicitly release the
- * resources managed by each instance when those instances are no longer
- * required, and thus no <code>dispose()</code> method is provided.
- * </p>
- *
- * @see Color
- */
-
-public final class RGB implements SerializableCompatibility {
-
- /**
- * the red component of the RGB
- */
- public int red;
-
- /**
- * the green component of the RGB
- */
- public int green;
-
- /**
- * the blue component of the RGB
- */
- public int blue;
-
-/**
- * Constructs an instance of this class with the given
- * red, green and blue values.
- *
- * @param red the red component of the new instance
- * @param green the green component of the new instance
- * @param blue the blue component of the new instance
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
- * </ul>
- */
-public RGB(int red, int green, int blue) {
- if ((red > 255) || (red < 0) ||
- (green > 255) || (green < 0) ||
- (blue > 255) || (blue < 0))
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- this.red = red;
- this.green = green;
- this.blue = blue;
-}
-
-/**
- * Compares the argument to the receiver, and returns true
- * if they represent the <em>same</em> object using a class
- * specific comparison.
- *
- * @param object the object to compare with this object
- * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
- *
- * @see #hashCode
- */
-public boolean equals (Object object) {
- if (object == this) return true;
- if (!(object instanceof RGB)) return false;
- RGB rgb = (RGB)object;
- return (rgb.red == this.red) && (rgb.green == this.green) && (rgb.blue == this.blue);
-}
-
-/**
- * Returns an integer hash code for the receiver. Any two
- * objects which return <code>true</code> when passed to
- * <code>equals</code> must return the same value for this
- * method.
- *
- * @return the receiver's hash
- *
- * @see #equals
- */
-public int hashCode () {
- return (blue << 16) | (green << 8) | red;
-}
-
-/**
- * Returns a string containing a concise, human-readable
- * description of the receiver.
- *
- * @return a string representation of the <code>RGB</code>
- */
-public String toString () {
- return "RGB {" + red + ", " + green + ", " + blue + "}";
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SerializableCompatibility; +import org.eclipse.swt.*; + +/** + * Instances of this class are descriptions of colors in + * terms of the primary additive color model (red, green and + * blue). A color may be described in terms of the relative + * intensities of these three primary colors. The brightness + * of each color is specified by a value in the range 0 to 255, + * where 0 indicates no color (blackness) and 255 indicates + * maximum intensity. + * <p> + * Application code does <em>not</em> need to explicitly release the + * resources managed by each instance when those instances are no longer + * required, and thus no <code>dispose()</code> method is provided. + * </p> + * + * @see Color + */ + +public final class RGB implements SerializableCompatibility { + + /** + * the red component of the RGB + */ + public int red; + + /** + * the green component of the RGB + */ + public int green; + + /** + * the blue component of the RGB + */ + public int blue; + +/** + * Constructs an instance of this class with the given + * red, green and blue values. + * + * @param red the red component of the new instance + * @param green the green component of the new instance + * @param blue the blue component of the new instance + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li> + * </ul> + */ +public RGB(int red, int green, int blue) { + if ((red > 255) || (red < 0) || + (green > 255) || (green < 0) || + (blue > 255) || (blue < 0)) + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + this.red = red; + this.green = green; + this.blue = blue; +} + +/** + * Compares the argument to the receiver, and returns true + * if they represent the <em>same</em> object using a class + * specific comparison. + * + * @param object the object to compare with this object + * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise + * + * @see #hashCode + */ +public boolean equals (Object object) { + if (object == this) return true; + if (!(object instanceof RGB)) return false; + RGB rgb = (RGB)object; + return (rgb.red == this.red) && (rgb.green == this.green) && (rgb.blue == this.blue); +} + +/** + * Returns an integer hash code for the receiver. Any two + * objects which return <code>true</code> when passed to + * <code>equals</code> must return the same value for this + * method. + * + * @return the receiver's hash + * + * @see #equals + */ +public int hashCode () { + return (blue << 16) | (green << 8) | red; +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the <code>RGB</code> + */ +public String toString () { + return "RGB {" + red + ", " + green + ", " + blue + "}"; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java index 269c532827..708e5ca03b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/Rectangle.java @@ -1,275 +1,275 @@ -package org.eclipse.swt.graphics;
-
-/*
+package org.eclipse.swt.graphics; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SerializableCompatibility;
-import org.eclipse.swt.*;
-
-/**
- * Instances of this class represent rectangular areas in an
- * (x, y) coordinate system. The top left corner of the rectangle
- * is specified by its x and y values, and the extent of the
- * rectangle is specified by its width and height.
- * <p>
- * The coordinate space for rectangles and points is considered
- * to have increasing values downward and to the right from its
- * origin making this the normal, computer graphics oriented notion
- * of (x, y) coordinates rather than the strict mathematical one.
- * </p>
- * <p>
- * Application code does <em>not</em> need to explicitly release the
- * resources managed by each instance when those instances are no longer
- * required, and thus no <code>dispose()</code> method is provided.
- * </p>
- *
- * @see Point
- */
-
-public final class Rectangle implements SerializableCompatibility {
-
- /**
- * the x coordinate of the rectangle
- */
- public int x;
-
- /**
- * the y coordinate of the rectangle
- */
- public int y;
-
- /**
- * the width of the rectangle
- */
- public int width;
-
- /**
- * the height of the rectangle
- */
- public int height;
-
-/**
- * Construct a new instance of this class given the
- * x, y, width and height values.
- *
- * @param x the x coordinate of the origin of the rectangle
- * @param y the y coordinate of the origin of the rectangle
- * @param width the width of the rectangle
- * @param height the height of the rectangle
- */
-public Rectangle (int x, int y, int width, int height) {
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
-}
-
-/**
- * Destructively replaces the x, y, width and height values
- * in the receiver with ones which represent the union of the
- * rectangles specified by the receiver and the given rectangle.
- * <p>
- * The union of two rectangles is the smallest single rectangle
- * that completely covers both of the areas covered by the two
- * given rectangles.
- * </p>
- *
- * @param rect the rectangle to merge with the receiver
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- */
-public void add (Rectangle rect) {
- if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- int left = x < rect.x ? x : rect.x;
- int top = y < rect.y ? y : rect.y;
- int lhs = x + width;
- int rhs = rect.x + rect.width;
- int right = lhs > rhs ? lhs : rhs;
- lhs = y + height;
- rhs = rect.y + rect.height;
- int bottom = lhs > rhs ? lhs : rhs;
- x = left; y = top; width = right - left; height = bottom - top;
-}
-
-/**
- * Returns <code>true</code> if the point specified by the
- * arguments is inside the area specified by the receiver,
- * and <code>false</code> otherwise.
- *
- * @param x the x coordinate of the point to test for containment
- * @param y the y coordinate of the point to test for containment
- * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
- */
-public boolean contains (int x, int y) {
- return (x >= this.x) && (y >= this.y) && ((x - this.x) < width) && ((y - this.y) < height);
-}
-
-/**
- * Returns <code>true</code> if the given point is inside the
- * area specified by the receiver, and <code>false</code>
- * otherwise.
- *
- * @param pt the point to test for containment
- * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- */
-public boolean contains (Point pt) {
- if (pt == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- return contains(pt.x, pt.y);
-}
-
-/**
- * Compares the argument to the receiver, and returns true
- * if they represent the <em>same</em> object using a class
- * specific comparison.
- *
- * @param object the object to compare with this object
- * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
- *
- * @see #hashCode
- */
-public boolean equals (Object object) {
- if (object == this) return true;
- if (!(object instanceof Rectangle)) return false;
- Rectangle r = (Rectangle)object;
- return (r.x == this.x) && (r.y == this.y) && (r.width == this.width) && (r.height == this.height);
-}
-
-/**
- * Returns an integer hash code for the receiver. Any two
- * objects which return <code>true</code> when passed to
- * <code>equals</code> must return the same value for this
- * method.
- *
- * @return the receiver's hash
- *
- * @see #equals
- */
-public int hashCode () {
- return x ^ y ^ width ^ height;
-}
-
-/**
- * Returns a new rectangle which represents the intersection
- * of the receiver and the given rectangle.
- * <p>
- * The intersection of two rectangles is the rectangle that
- * covers the area which is contained within both rectangles.
- * </p>
- *
- * @param rect the rectangle to intersect with the receiver
- * @return the intersection of the receiver and the argument
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- */
-public Rectangle intersection (Rectangle rect) {
- if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- if (this == rect) return new Rectangle (x, y, width, height);
- int left = x > rect.x ? x : rect.x;
- int top = y > rect.y ? y : rect.y;
- int lhs = x + width;
- int rhs = rect.x + rect.width;
- int right = lhs < rhs ? lhs : rhs;
- lhs = y + height;
- rhs = rect.y + rect.height;
- int bottom = lhs < rhs ? lhs : rhs;
- return new Rectangle (
- right < left ? 0 : left,
- bottom < top ? 0 : top,
- right < left ? 0 : right - left,
- bottom < top ? 0 : bottom - top);
-}
-
-/**
- * Returns <code>true</code> if the given rectangle intersects
- * with the receiver and <code>false</code> otherwise.
- * <p>
- * Two rectangles intersect if the area of the rectangle
- * representing their intersection is not empty.
- * </p>
- *
- * @param rect the rectangle to test for intersection
- * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- *
- * @see #intersection
- * @see #isEmpty
- */
-public boolean intersects (Rectangle rect) {
- if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- return (rect == this) || (rect.x < x + width) && (rect.y < y + height) &&
- (rect.x + rect.width > x) && (rect.y + rect.height > y);
-}
-
-/**
- * Returns <code>true</code> if the receiver does not cover any
- * area in the (x, y) coordinate plane, and <code>false</code> if
- * the receiver does cover some area in the plane.
- * <p>
- * A rectangle is considered to <em>cover area</em> in the
- * (x, y) coordinate plane if both its width and height are
- * non-zero.
- * </p>
- *
- * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise
- */
-public boolean isEmpty () {
- return (width <= 0) || (height <= 0);
-}
-
-/**
- * Returns a string containing a concise, human-readable
- * description of the receiver.
- *
- * @return a string representation of the rectangle
- */
-public String toString () {
- return "Rectangle {" + x + ", " + y + ", " + width + ", " + height + "}";
-}
-
-/**
- * Returns a new rectangle which represents the union of
- * the receiver and the given rectangle.
- * <p>
- * The union of two rectangles is the smallest single rectangle
- * that completely covers both of the areas covered by the two
- * given rectangles.
- * </p>
- *
- * @param rect the rectangle to perform union with
- * @return the union of the receiver and the argument
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
- * </ul>
- *
- * @see #add
- */
-public Rectangle union (Rectangle rect) {
- if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
- int left = x < rect.x ? x : rect.x;
- int top = y < rect.y ? y : rect.y;
- int lhs = x + width;
- int rhs = rect.x + rect.width;
- int right = lhs > rhs ? lhs : rhs;
- lhs = y + height;
- rhs = rect.y + rect.height;
- int bottom = lhs > rhs ? lhs : rhs;
- return new Rectangle (left, top, right - left, bottom - top);
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SerializableCompatibility; +import org.eclipse.swt.*; + +/** + * Instances of this class represent rectangular areas in an + * (x, y) coordinate system. The top left corner of the rectangle + * is specified by its x and y values, and the extent of the + * rectangle is specified by its width and height. + * <p> + * The coordinate space for rectangles and points is considered + * to have increasing values downward and to the right from its + * origin making this the normal, computer graphics oriented notion + * of (x, y) coordinates rather than the strict mathematical one. + * </p> + * <p> + * Application code does <em>not</em> need to explicitly release the + * resources managed by each instance when those instances are no longer + * required, and thus no <code>dispose()</code> method is provided. + * </p> + * + * @see Point + */ + +public final class Rectangle implements SerializableCompatibility { + + /** + * the x coordinate of the rectangle + */ + public int x; + + /** + * the y coordinate of the rectangle + */ + public int y; + + /** + * the width of the rectangle + */ + public int width; + + /** + * the height of the rectangle + */ + public int height; + +/** + * Construct a new instance of this class given the + * x, y, width and height values. + * + * @param x the x coordinate of the origin of the rectangle + * @param y the y coordinate of the origin of the rectangle + * @param width the width of the rectangle + * @param height the height of the rectangle + */ +public Rectangle (int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; +} + +/** + * Destructively replaces the x, y, width and height values + * in the receiver with ones which represent the union of the + * rectangles specified by the receiver and the given rectangle. + * <p> + * The union of two rectangles is the smallest single rectangle + * that completely covers both of the areas covered by the two + * given rectangles. + * </p> + * + * @param rect the rectangle to merge with the receiver + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + */ +public void add (Rectangle rect) { + if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + int left = x < rect.x ? x : rect.x; + int top = y < rect.y ? y : rect.y; + int lhs = x + width; + int rhs = rect.x + rect.width; + int right = lhs > rhs ? lhs : rhs; + lhs = y + height; + rhs = rect.y + rect.height; + int bottom = lhs > rhs ? lhs : rhs; + x = left; y = top; width = right - left; height = bottom - top; +} + +/** + * Returns <code>true</code> if the point specified by the + * arguments is inside the area specified by the receiver, + * and <code>false</code> otherwise. + * + * @param x the x coordinate of the point to test for containment + * @param y the y coordinate of the point to test for containment + * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise + */ +public boolean contains (int x, int y) { + return (x >= this.x) && (y >= this.y) && ((x - this.x) < width) && ((y - this.y) < height); +} + +/** + * Returns <code>true</code> if the given point is inside the + * area specified by the receiver, and <code>false</code> + * otherwise. + * + * @param pt the point to test for containment + * @return <code>true</code> if the rectangle contains the point and <code>false</code> otherwise + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + */ +public boolean contains (Point pt) { + if (pt == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + return contains(pt.x, pt.y); +} + +/** + * Compares the argument to the receiver, and returns true + * if they represent the <em>same</em> object using a class + * specific comparison. + * + * @param object the object to compare with this object + * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise + * + * @see #hashCode + */ +public boolean equals (Object object) { + if (object == this) return true; + if (!(object instanceof Rectangle)) return false; + Rectangle r = (Rectangle)object; + return (r.x == this.x) && (r.y == this.y) && (r.width == this.width) && (r.height == this.height); +} + +/** + * Returns an integer hash code for the receiver. Any two + * objects which return <code>true</code> when passed to + * <code>equals</code> must return the same value for this + * method. + * + * @return the receiver's hash + * + * @see #equals + */ +public int hashCode () { + return x ^ y ^ width ^ height; +} + +/** + * Returns a new rectangle which represents the intersection + * of the receiver and the given rectangle. + * <p> + * The intersection of two rectangles is the rectangle that + * covers the area which is contained within both rectangles. + * </p> + * + * @param rect the rectangle to intersect with the receiver + * @return the intersection of the receiver and the argument + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + */ +public Rectangle intersection (Rectangle rect) { + if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + if (this == rect) return new Rectangle (x, y, width, height); + int left = x > rect.x ? x : rect.x; + int top = y > rect.y ? y : rect.y; + int lhs = x + width; + int rhs = rect.x + rect.width; + int right = lhs < rhs ? lhs : rhs; + lhs = y + height; + rhs = rect.y + rect.height; + int bottom = lhs < rhs ? lhs : rhs; + return new Rectangle ( + right < left ? 0 : left, + bottom < top ? 0 : top, + right < left ? 0 : right - left, + bottom < top ? 0 : bottom - top); +} + +/** + * Returns <code>true</code> if the given rectangle intersects + * with the receiver and <code>false</code> otherwise. + * <p> + * Two rectangles intersect if the area of the rectangle + * representing their intersection is not empty. + * </p> + * + * @param rect the rectangle to test for intersection + * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + * + * @see #intersection + * @see #isEmpty + */ +public boolean intersects (Rectangle rect) { + if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + return (rect == this) || (rect.x < x + width) && (rect.y < y + height) && + (rect.x + rect.width > x) && (rect.y + rect.height > y); +} + +/** + * Returns <code>true</code> if the receiver does not cover any + * area in the (x, y) coordinate plane, and <code>false</code> if + * the receiver does cover some area in the plane. + * <p> + * A rectangle is considered to <em>cover area</em> in the + * (x, y) coordinate plane if both its width and height are + * non-zero. + * </p> + * + * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise + */ +public boolean isEmpty () { + return (width <= 0) || (height <= 0); +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the rectangle + */ +public String toString () { + return "Rectangle {" + x + ", " + y + ", " + width + ", " + height + "}"; +} + +/** + * Returns a new rectangle which represents the union of + * the receiver and the given rectangle. + * <p> + * The union of two rectangles is the smallest single rectangle + * that completely covers both of the areas covered by the two + * given rectangles. + * </p> + * + * @param rect the rectangle to perform union with + * @return the union of the receiver and the argument + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> + * </ul> + * + * @see #add + */ +public Rectangle union (Rectangle rect) { + if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + int left = x < rect.x ? x : rect.x; + int top = y < rect.y ? y : rect.y; + int lhs = x + width; + int rhs = rect.x + rect.width; + int right = lhs > rhs ? lhs : rhs; + lhs = y + height; + rhs = rect.y + rect.height; + int bottom = lhs > rhs ? lhs : rhs; + return new Rectangle (left, top, right - left, bottom - top); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/Callback.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/Callback.java index 6e02365662..1b9246a8db 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/Callback.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/Callback.java @@ -1,189 +1,189 @@ -package org.eclipse.swt.internal;
-
-/*
+package org.eclipse.swt.internal; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * Instances of this class represent entry points into Java
- * which can be invoked from operating system level callback
- * routines.
- * <p>
- * IMPORTANT: A callback is only valid when invoked on the
- * thread which created it. The results are undefined (and
- * typically bad) when a callback is passed out to the
- * operating system (or other code) in such a way that the
- * callback is called from a different thread.
- */
-
-public class Callback {
-
- Object object;
- String method, signature;
- int argCount, address;
- boolean isStatic, isArrayBased;
-
- /* Load the SWT library */
- static {
- Library.loadLibrary ("swt");
- }
-
-/**
- * Constructs a new instance of this class given an object
- * to send the message to, a string naming the method to
- * invoke and an argument count. Note that, if the object
- * is an instance of <code>Class</code> it is assumed that
- * the method is a static method on that class.
- *
- * @param object the object to send the message to
- * @param method the name of the method to invoke
- * @param argCount the number of arguments that the method takes
- */
-public Callback (Object object, String method, int argCount) {
- this (object, method, argCount, false);
-}
-
-/**
- * Constructs a new instance of this class given an object
- * to send the message to, a string naming the method to
- * invoke, an argument count and a flag indicating whether
- * or not the arguments will be passed in an array. Note
- * that, if the object is an instance of <code>Class</code>
- * it is assumed that the method is a static method on that
- * class.
- *
- * @param object the object to send the message to
- * @param method the name of the method to invoke
- * @param argCount the number of arguments that the method takes
- * @param isArrayBased <code>true</code> if the arguments should be passed in an array and false otherwise
- */
-public Callback (Object object, String method, int argCount, boolean isArrayBased) {
-
- /* Set the callback fields */
- this.object = object;
- this.method = method;
- this.argCount = argCount;
- isStatic = object instanceof Class;
- this.isArrayBased = isArrayBased;
-
- /* Inline the common cases */
- if (isArrayBased) {
- signature = "([I)I";
- } else {
- switch (argCount) {
- case 0: signature = "()I"; break;
- case 1: signature = "(I)I"; break;
- case 2: signature = "(II)I"; break;
- case 3: signature = "(III)I"; break;
- case 4: signature = "(IIII)I"; break;
- default:
- signature = "(";
- for (int i=0; i<argCount; i++) signature += "I";
- signature += ")I";
- }
- }
-
- /* Bind the address */
- address = bind (this);
-}
-
-/**
- * Allocates the native level resources associated with the
- * callback. This method is only invoked from within the
- * constructor for the argument.
- *
- * @param callback the callback to bind
- */
-static native synchronized int bind (Callback callback);
-
-/**
- * Releases the native level resources associated with the callback,
- * and removes all references between the callback and
- * other objects. This helps to prevent (bad) application code
- * from accidentally holding onto extraneous garbage.
- */
-public void dispose () {
- if (object == null) return;
- unbind (this);
- object = method = signature = null;
- address = 0;
-}
-
-/**
- * Returns the address of a block of machine code which will
- * invoke the callback represented by the receiver.
- *
- * @return the callback address
- */
-public int getAddress () {
- return address;
-}
-
-/**
- * Returns the SWT platform name.
- *
- * @return the platform name of the currently running SWT
- */
-public static native String getPlatform ();
-
-/**
- * Indicates whether or not callbacks which are triggered at the
- * native level should cause the messages described by the matching
- * <code>Callback</code> objects to be invoked. This method is used
- * to safely shut down SWT when it is run within environments
- * which can generate spurious events.
- * <p>
- * Note: This should not be called by application code.
- * </p>
- *
- * @param ignore true if callbacks should not be invoked
- */
-public static final native synchronized void setEnabled (boolean enable);
-
-/**
- * Returns whether or not callbacks which are triggered at the
- * native level should cause the messages described by the matching
- * <code>Callback</code> objects to be invoked. This method is used
- * to safely shut down SWT when it is run within environments
- * which can generate spurious events.
- * <p>
- * Note: This should not be called by application code.
- * </p>
- *
- * @return true if callbacks should not be invoked
- */
-public static final native synchronized boolean getEnabled ();
-
-/**
- * This might be called directly from native code in environments
- * which can generate spurious events. Check before removing it.
- *
- * @deprecated
- *
- * @param ignore true if callbacks should not be invoked
- */
-static final void ignoreCallbacks (boolean ignore) {
- setEnabled (!ignore);
-}
-
-/**
- * Immediately wipes out all native level state associated
- * with <em>all</em> callbacks.
- * <p>
- * <b>WARNING:</b> This operation is <em>extremely</em> dangerous,
- * and should never be performed by application code.
- * </p>
- */
-public static final native synchronized void reset ();
-
-/**
- * Releases the native level resources associated with the callback.
- *
- * @see #dispose
- */
-static final native synchronized void unbind (Callback callback);
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * Instances of this class represent entry points into Java + * which can be invoked from operating system level callback + * routines. + * <p> + * IMPORTANT: A callback is only valid when invoked on the + * thread which created it. The results are undefined (and + * typically bad) when a callback is passed out to the + * operating system (or other code) in such a way that the + * callback is called from a different thread. + */ + +public class Callback { + + Object object; + String method, signature; + int argCount, address; + boolean isStatic, isArrayBased; + + /* Load the SWT library */ + static { + Library.loadLibrary ("swt"); + } + +/** + * Constructs a new instance of this class given an object + * to send the message to, a string naming the method to + * invoke and an argument count. Note that, if the object + * is an instance of <code>Class</code> it is assumed that + * the method is a static method on that class. + * + * @param object the object to send the message to + * @param method the name of the method to invoke + * @param argCount the number of arguments that the method takes + */ +public Callback (Object object, String method, int argCount) { + this (object, method, argCount, false); +} + +/** + * Constructs a new instance of this class given an object + * to send the message to, a string naming the method to + * invoke, an argument count and a flag indicating whether + * or not the arguments will be passed in an array. Note + * that, if the object is an instance of <code>Class</code> + * it is assumed that the method is a static method on that + * class. + * + * @param object the object to send the message to + * @param method the name of the method to invoke + * @param argCount the number of arguments that the method takes + * @param isArrayBased <code>true</code> if the arguments should be passed in an array and false otherwise + */ +public Callback (Object object, String method, int argCount, boolean isArrayBased) { + + /* Set the callback fields */ + this.object = object; + this.method = method; + this.argCount = argCount; + isStatic = object instanceof Class; + this.isArrayBased = isArrayBased; + + /* Inline the common cases */ + if (isArrayBased) { + signature = "([I)I"; + } else { + switch (argCount) { + case 0: signature = "()I"; break; + case 1: signature = "(I)I"; break; + case 2: signature = "(II)I"; break; + case 3: signature = "(III)I"; break; + case 4: signature = "(IIII)I"; break; + default: + signature = "("; + for (int i=0; i<argCount; i++) signature += "I"; + signature += ")I"; + } + } + + /* Bind the address */ + address = bind (this); +} + +/** + * Allocates the native level resources associated with the + * callback. This method is only invoked from within the + * constructor for the argument. + * + * @param callback the callback to bind + */ +static native synchronized int bind (Callback callback); + +/** + * Releases the native level resources associated with the callback, + * and removes all references between the callback and + * other objects. This helps to prevent (bad) application code + * from accidentally holding onto extraneous garbage. + */ +public void dispose () { + if (object == null) return; + unbind (this); + object = method = signature = null; + address = 0; +} + +/** + * Returns the address of a block of machine code which will + * invoke the callback represented by the receiver. + * + * @return the callback address + */ +public int getAddress () { + return address; +} + +/** + * Returns the SWT platform name. + * + * @return the platform name of the currently running SWT + */ +public static native String getPlatform (); + +/** + * Indicates whether or not callbacks which are triggered at the + * native level should cause the messages described by the matching + * <code>Callback</code> objects to be invoked. This method is used + * to safely shut down SWT when it is run within environments + * which can generate spurious events. + * <p> + * Note: This should not be called by application code. + * </p> + * + * @param ignore true if callbacks should not be invoked + */ +public static final native synchronized void setEnabled (boolean enable); + +/** + * Returns whether or not callbacks which are triggered at the + * native level should cause the messages described by the matching + * <code>Callback</code> objects to be invoked. This method is used + * to safely shut down SWT when it is run within environments + * which can generate spurious events. + * <p> + * Note: This should not be called by application code. + * </p> + * + * @return true if callbacks should not be invoked + */ +public static final native synchronized boolean getEnabled (); + +/** + * This might be called directly from native code in environments + * which can generate spurious events. Check before removing it. + * + * @deprecated + * + * @param ignore true if callbacks should not be invoked + */ +static final void ignoreCallbacks (boolean ignore) { + setEnabled (!ignore); +} + +/** + * Immediately wipes out all native level state associated + * with <em>all</em> callbacks. + * <p> + * <b>WARNING:</b> This operation is <em>extremely</em> dangerous, + * and should never be performed by application code. + * </p> + */ +public static final native synchronized void reset (); + +/** + * Releases the native level resources associated with the callback. + * + * @see #dispose + */ +static final native synchronized void unbind (Callback callback); + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java index 9804a02af7..633f2f2539 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java @@ -1,110 +1,110 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-
-public abstract class FileFormat {
- static final String FORMAT_PACKAGE = "org.eclipse.swt.internal.image";
- static final String FORMAT_SUFFIX = "FileFormat";
- static final String[] FORMATS = {"WinBMP", "WinBMP", "GIF", "WinICO", "JPEG", "PNG"};
-
- LEDataInputStream inputStream;
- LEDataOutputStream outputStream;
- ImageLoader loader;
- int compression;
-
-byte[] bitInvertData(byte[] data, int startIndex, int endIndex) {
- // Destructively bit invert data in the given byte array.
- for (int i = startIndex; i < endIndex; i++) {
- data[i] = (byte)(255 - data[i - startIndex]);
- }
- return data;
-}
-
-/**
- * Return whether or not the specified input stream
- * represents a supported file format.
- */
-abstract boolean isFileFormat(LEDataInputStream stream);
-
-abstract ImageData[] loadFromByteStream();
-
-public ImageData[] loadFromStream(LEDataInputStream stream) {
- try {
- inputStream = stream;
- return loadFromByteStream();
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
-}
-
-public static ImageData[] load(InputStream is, ImageLoader loader) {
- FileFormat fileFormat = null;
- LEDataInputStream stream = new LEDataInputStream(is);
- boolean isSupported = false;
- for (int i = 1; i < FORMATS.length; i++) {
- if (FORMATS[i] != null) {
- try {
- Class clazz = Class.forName(FORMAT_PACKAGE + '.' + FORMATS[i] + FORMAT_SUFFIX);
- fileFormat = (FileFormat) clazz.newInstance();
- if (fileFormat.isFileFormat(stream)) {
- isSupported = true;
- break;
- }
- } catch (ClassNotFoundException e) {
- FORMATS[i] = null;
- } catch (Exception e) {
- }
- }
- }
- if (!isSupported) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
- fileFormat.loader = loader;
- return fileFormat.loadFromStream(stream);
-}
-
-public static void save(OutputStream os, int format, ImageLoader loader) {
- if (format < 0 || format >= FORMATS.length) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- if (FORMATS[format] == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-
- /* We do not currently support writing multi-image files,
- * so we use the first image data in the loader's array. */
- ImageData data = loader.data[0];
- LEDataOutputStream stream = new LEDataOutputStream(os);
- FileFormat fileFormat = null;
- try {
- Class clazz = Class.forName(FORMAT_PACKAGE + '.' + FORMATS[format] + FORMAT_SUFFIX);
- fileFormat = (FileFormat) clazz.newInstance();
- } catch (Exception e) {
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
- if (format == SWT.IMAGE_BMP_RLE) {
- switch (data.depth) {
- case 8: fileFormat.compression = 1; break;
- case 4: fileFormat.compression = 2; break;
- }
- }
- fileFormat.unloadIntoStream(data, stream);
-}
-
-abstract void unloadIntoByteStream(ImageData image);
-
-public void unloadIntoStream(ImageData image, LEDataOutputStream stream) {
- try {
- outputStream = stream;
- unloadIntoByteStream(image);
- outputStream.close();
- } catch (Exception e) {
- try {outputStream.close();} catch (Exception f) {}
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; + +public abstract class FileFormat { + static final String FORMAT_PACKAGE = "org.eclipse.swt.internal.image"; + static final String FORMAT_SUFFIX = "FileFormat"; + static final String[] FORMATS = {"WinBMP", "WinBMP", "GIF", "WinICO", "JPEG", "PNG"}; + + LEDataInputStream inputStream; + LEDataOutputStream outputStream; + ImageLoader loader; + int compression; + +byte[] bitInvertData(byte[] data, int startIndex, int endIndex) { + // Destructively bit invert data in the given byte array. + for (int i = startIndex; i < endIndex; i++) { + data[i] = (byte)(255 - data[i - startIndex]); + } + return data; +} + +/** + * Return whether or not the specified input stream + * represents a supported file format. + */ +abstract boolean isFileFormat(LEDataInputStream stream); + +abstract ImageData[] loadFromByteStream(); + +public ImageData[] loadFromStream(LEDataInputStream stream) { + try { + inputStream = stream; + return loadFromByteStream(); + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } +} + +public static ImageData[] load(InputStream is, ImageLoader loader) { + FileFormat fileFormat = null; + LEDataInputStream stream = new LEDataInputStream(is); + boolean isSupported = false; + for (int i = 1; i < FORMATS.length; i++) { + if (FORMATS[i] != null) { + try { + Class clazz = Class.forName(FORMAT_PACKAGE + '.' + FORMATS[i] + FORMAT_SUFFIX); + fileFormat = (FileFormat) clazz.newInstance(); + if (fileFormat.isFileFormat(stream)) { + isSupported = true; + break; + } + } catch (ClassNotFoundException e) { + FORMATS[i] = null; + } catch (Exception e) { + } + } + } + if (!isSupported) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); + fileFormat.loader = loader; + return fileFormat.loadFromStream(stream); +} + +public static void save(OutputStream os, int format, ImageLoader loader) { + if (format < 0 || format >= FORMATS.length) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + if (FORMATS[format] == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT); + + /* We do not currently support writing multi-image files, + * so we use the first image data in the loader's array. */ + ImageData data = loader.data[0]; + LEDataOutputStream stream = new LEDataOutputStream(os); + FileFormat fileFormat = null; + try { + Class clazz = Class.forName(FORMAT_PACKAGE + '.' + FORMATS[format] + FORMAT_SUFFIX); + fileFormat = (FileFormat) clazz.newInstance(); + } catch (Exception e) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + if (format == SWT.IMAGE_BMP_RLE) { + switch (data.depth) { + case 8: fileFormat.compression = 1; break; + case 4: fileFormat.compression = 2; break; + } + } + fileFormat.unloadIntoStream(data, stream); +} + +abstract void unloadIntoByteStream(ImageData image); + +public void unloadIntoStream(ImageData image, LEDataOutputStream stream) { + try { + outputStream = stream; + unloadIntoByteStream(image); + outputStream.close(); + } catch (Exception e) { + try {outputStream.close();} catch (Exception f) {} + SWT.error(SWT.ERROR_IO, e); + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/GIFFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/GIFFileFormat.java index f63aa72196..8b62ec6fce 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/GIFFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/GIFFileFormat.java @@ -1,527 +1,527 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import java.io.*;
-
-final class GIFFileFormat extends FileFormat {
- String signature, version;
- boolean sorted;
- int screenWidth, screenHeight, backgroundPixel, aspect, bitsPerPixel, defaultDepth;
- boolean userInput = false;
- int disposalMethod = 0;
- int delayTime = 0;
- int transparentPixel = -1;
- int repeatCount = 1;
-
- static final int GIF_APPLICATION_EXTENSION_BLOCK_ID = 0xFF;
- static final int GIF_GRAPHICS_CONTROL_BLOCK_ID = 0xF9;
- static final int GIF_PLAIN_TEXT_BLOCK_ID = 0x01;
- static final int GIF_COMMENT_BLOCK_ID = 0xFE;
- static final int GIF_EXTENSION_BLOCK_ID = 0x21;
- static final int GIF_IMAGE_BLOCK_ID = 0x2C;
- static final int GIF_TRAILER_ID = 0x3B;
-
- /**
- * Answer a palette containing numGrays
- * shades of gray, ranging from black to white.
- */
- static PaletteData grayRamp(int numGrays) {
- int n = numGrays - 1;
- RGB[] colors = new RGB[numGrays];
- for (int i = 0; i < numGrays; i++) {
- int intensity = (byte)((i * 3) * 256 / n);
- colors[i] = new RGB(intensity, intensity, intensity);
- }
- return new PaletteData(colors);
- }
-
- boolean isFileFormat(LEDataInputStream stream) {
- try {
- byte[] signature = new byte[3];
- stream.read(signature);
- stream.unread(signature);
- return new String(signature).equals("GIF");
- } catch (Exception e) {
- return false;
- }
- }
-
- /**
- * Load the GIF image(s) stored in the input stream.
- * Return an array of ImageData representing the image(s).
- */
- ImageData[] loadFromByteStream() {
- byte[] signatureBytes = new byte[3];
- byte[] versionBytes = new byte[3];
- byte[] block = new byte[7];
- try {
- inputStream.read(signatureBytes);
- signature = new String(signatureBytes);
- if (!signature.equals("GIF"))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- inputStream.read(versionBytes);
- version = new String(versionBytes);
-
- inputStream.read(block);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- screenWidth = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8);
- loader.logicalScreenWidth = screenWidth;
- screenHeight = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8);
- loader.logicalScreenHeight = screenHeight;
- byte bitField = block[4];
- backgroundPixel = block[5] & 0xFF;
- aspect = block[6] & 0xFF;
- bitsPerPixel = ((bitField >> 4) & 0x07) + 1;
- defaultDepth = (bitField & 0x7) + 1;
- PaletteData palette = null;
- if ((bitField & 0x80) != 0) {
- // Global palette.
- sorted = (bitField & 0x8) != 0;
- palette = readPalette(1 << defaultDepth);
- } else {
- // No global palette.
- sorted = false;
- backgroundPixel = -1;
- defaultDepth = bitsPerPixel;
- }
- loader.backgroundPixel = backgroundPixel;
-
- getExtensions();
- int id = readID();
- ImageData[] images = new ImageData[0];
- while (id == GIF_IMAGE_BLOCK_ID) {
- ImageData image = readImageBlock(palette);
- if (loader.hasListeners()) {
- loader.notifyListeners(new ImageLoaderEvent(loader, image, 3, true));
- }
- ImageData[] oldImages = images;
- images = new ImageData[oldImages.length + 1];
- System.arraycopy(oldImages, 0, images, 0, oldImages.length);
- images[images.length - 1] = image;
- try {
- /* Read the 0-byte terminator at the end of the image. */
- id = inputStream.read();
- if (id > 0) {
- /* We read the terminator earlier. */
- inputStream.unread(new byte[] {(byte)id});
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- getExtensions();
- id = readID();
- }
- return images;
- }
-
- /**
- * Read and return the next block or extension identifier from the file.
- */
- int readID() {
- try {
- return inputStream.read();
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return -1;
- }
-
- /**
- * Read extensions until an image descriptor appears.
- * In the future, if we care about the extensions, they
- * should be properly grouped with the image data before
- * which they appeared. Right now, the interesting parts
- * of some extensions are kept, but the rest is discarded.
- * Throw an error if an error occurs.
- */
- void getExtensions() {
- int id = readID();
- while (id != GIF_IMAGE_BLOCK_ID && id != GIF_TRAILER_ID && id > 0) {
- if (id == GIF_EXTENSION_BLOCK_ID) {
- readExtension();
- } else {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- id = readID();
- }
- if (id == GIF_IMAGE_BLOCK_ID || id == GIF_TRAILER_ID) {
- try {
- inputStream.unread(new byte[] {(byte)id});
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
- }
-
- /**
- * Read a control extension.
- * Return the extension block data.
- */
- byte[] readExtension() {
- int extensionID = readID();
- if (extensionID == GIF_COMMENT_BLOCK_ID)
- return readCommentExtension();
- if (extensionID == GIF_PLAIN_TEXT_BLOCK_ID)
- return readPlainTextExtension();
- if (extensionID == GIF_GRAPHICS_CONTROL_BLOCK_ID)
- return readGraphicsControlExtension();
- if (extensionID == GIF_APPLICATION_EXTENSION_BLOCK_ID)
- return readApplicationExtension();
- // Otherwise, we don't recognize the block. If the
- // field size is correct, we can just skip over
- // the block contents.
- try {
- int extSize = inputStream.read();
- if (extSize < 0) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- byte[] ext = new byte[extSize];
- inputStream.read(ext, 0, extSize);
- return ext;
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
-
- /**
- * We have just read the Comment extension identifier
- * from the input stream. Read in the rest of the comment
- * and return it. GIF comment blocks are variable size.
- */
- byte[] readCommentExtension() {
- try {
- byte[] comment = new byte[0];
- byte[] block = new byte[255];
- int size = inputStream.read();
- while ((size > 0) && (inputStream.read(block, 0, size) != -1)) {
- byte[] oldComment = comment;
- comment = new byte[oldComment.length + size];
- System.arraycopy(oldComment, 0, comment, 0, oldComment.length);
- System.arraycopy(block, 0, comment, oldComment.length, size);
- size = inputStream.read();
- }
- return comment;
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
-
- /**
- * We have just read the PlainText extension identifier
- * from the input stream. Read in the plain text info and text,
- * and return the text. GIF plain text blocks are variable size.
- */
- byte[] readPlainTextExtension() {
- try {
- // Read size of block = 0x0C.
- inputStream.read();
- // Read the text information (x, y, width, height, colors).
- byte[] info = new byte[12];
- inputStream.read(info);
- // Read the text.
- byte[] text = new byte[0];
- byte[] block = new byte[255];
- int size = inputStream.read();
- while ((size > 0) && (inputStream.read(block, 0, size) != -1)) {
- byte[] oldText = text;
- text = new byte[oldText.length + size];
- System.arraycopy(oldText, 0, text, 0, oldText.length);
- System.arraycopy(block, 0, text, oldText.length, size);
- size = inputStream.read();
- }
- return text;
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
-
- /**
- * We have just read the GraphicsControl extension identifier
- * from the input stream. Read in the control information, store
- * it, and return it.
- */
- byte[] readGraphicsControlExtension() {
- try {
- // Read size of block = 0x04.
- inputStream.read();
- // Read the control block.
- byte[] controlBlock = new byte[4];
- inputStream.read(controlBlock);
- byte bitField = controlBlock[0];
- // Store the user input field.
- userInput = (bitField & 0x02) != 0;
- // Store the disposal method.
- disposalMethod = (bitField >> 2) & 0x07;
- // Store the delay time.
- delayTime = (controlBlock[1] & 0xFF) | ((controlBlock[2] & 0xFF) << 8);
- // Store the transparent color.
- if ((bitField & 0x01) != 0) {
- int colorIndex = controlBlock[3] & 0xFF;
- /* Work around: a customer has a GIF that specifies an
- * invalid color index that is larger than the number
- * of entries in the palette. Detect this case, and
- * ignore the specified color index. */
- if (colorIndex <= 1 << defaultDepth) {
- transparentPixel = colorIndex;
- }
- } else {
- transparentPixel = -1;
- }
- // Read block terminator.
- inputStream.read();
- return controlBlock;
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
-
- /**
- * We have just read the Application extension identifier
- * from the input stream. Read in the rest of the extension,
- * look for and store 'number of repeats', and return the data.
- */
- byte[] readApplicationExtension() {
- try {
- // Read size of block = 0x0B.
- inputStream.read();
- // Read application identifier.
- byte[] applicationBytes = new byte[8];
- inputStream.read(applicationBytes);
- String application = new String(applicationBytes);
- // Read authentication code.
- byte[] authenticationBytes = new byte[3];
- inputStream.read(authenticationBytes);
- String authentication = new String(authenticationBytes);
- // Read application data.
- byte[] data = new byte[0];
- byte[] block = new byte[255];
- int size = inputStream.read();
- while ((size > 0) && (inputStream.read(block, 0, size) != -1)) {
- byte[] oldData = data;
- data = new byte[oldData.length + size];
- System.arraycopy(oldData, 0, data, 0, oldData.length);
- System.arraycopy(block, 0, data, oldData.length, size);
- size = inputStream.read();
- }
- // Look for the NETSCAPE 'repeat count' field for an animated GIF.
- if (application.equals("NETSCAPE") && authentication.equals("2.0") && data[0] == 01) {
- repeatCount = (data[1] & 0xFF) | ((data[2] & 0xFF) << 8);
- loader.repeatCount = repeatCount;
- }
- return data;
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
-
- /**
- * Return a DeviceIndependentImage representing the
- * image block at the current position in the input stream.
- * Throw an error if an error occurs.
- */
- ImageData readImageBlock(PaletteData defaultPalette) {
- int depth;
- PaletteData palette;
- byte[] block = new byte[9];
- try {
- inputStream.read(block);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- int left = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8);
- int top = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8);
- int width = (block[4] & 0xFF) | ((block[5] & 0xFF) << 8);
- int height = (block[6] & 0xFF) | ((block[7] & 0xFF) << 8);
- byte bitField = block[8];
- boolean interlaced = (bitField & 0x40) != 0;
-// boolean sorted = (bitField & 0x20) != 0;
- if ((bitField & 0x80) != 0) {
- // Local palette.
- depth = (bitField & 0x7) + 1;
- palette = readPalette(1 << depth);
- } else {
- // No local palette.
- depth = defaultDepth;
- palette = defaultPalette;
- }
- // Promote depth to next highest supported value.
- if (!(depth == 1 || depth == 4 || depth == 8)) {
- if (depth < 4)
- depth = 4;
- else
- depth = 8;
- }
- if (palette == null) {
- palette = grayRamp(1 << depth);
- }
- int initialCodeSize = -1;
- try {
- initialCodeSize = inputStream.read();
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- if (initialCodeSize < 0) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- ImageData image = ImageData.internal_new(
- width,
- height,
- depth,
- palette,
- 4,
- null,
- 0,
- null,
- null,
- -1,
- transparentPixel,
- SWT.IMAGE_GIF,
- left,
- top,
- disposalMethod,
- delayTime);
- LZWCodec codec = new LZWCodec();
- codec.decode(inputStream, loader, image, interlaced, initialCodeSize);
- return image;
- }
-
- /**
- * Read a palette from the input stream.
- */
- PaletteData readPalette(int numColors) {
- byte[] bytes = new byte[numColors * 3];
- try {
- if (inputStream.read(bytes) != bytes.length)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- RGB[] colors = new RGB[numColors];
- for (int i = 0; i < numColors; i++)
- colors[i] = new RGB(bytes[i*3] & 0xFF,
- bytes[i*3+1] & 0xFF, bytes[i*3+2] & 0xFF);
- return new PaletteData(colors);
- }
-
- /**
- * Write the specified device independent image
- * to the output stream.
- */
- void unloadIntoByteStream(ImageData image) {
- if (!((image.depth == 1) || (image.depth == 4) || (image.depth == 8))) {
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
- }
- byte bitField = (byte)((0x80 & 0xF8 & 0xF7 & 0x8F) + (image.depth - 1) + ((image.depth - 1) * 16));
- try {
- outputStream.write(new byte[] { (byte)'G', (byte)'I', (byte)'F' });
- outputStream.write(new byte[] { (byte)'8', (byte)'9', (byte)'a' });
- outputStream.writeShort((short)image.width);
- outputStream.writeShort((short)image.height);
- outputStream.writeByte(bitField);
- outputStream.writeByte((byte)0);
- outputStream.writeByte((byte)0);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- writePalette(image.palette, image.depth);
- if (image.transparentPixel != -1 || image.disposalMethod != 0 || image.delayTime != 0) {
- writeGraphicsControlBlock(image);
- }
- writeImageBlock(image);
- }
-
- /**
- * Write out a GraphicsControlBlock to describe
- * the specified device independent image.
- */
- void writeGraphicsControlBlock(ImageData image) {
- try {
- outputStream.write(GIF_EXTENSION_BLOCK_ID);
- outputStream.write(GIF_GRAPHICS_CONTROL_BLOCK_ID);
- outputStream.write(0x04); // size of block
- byte[] gcBlock = new byte[4];
- gcBlock[0] = (byte)0xFD;
- gcBlock[1] = 0;
- gcBlock[2] = 0;
- gcBlock[3] = 0;
- if (image.transparentPixel == -1) {
- gcBlock[0] = (byte)(gcBlock[0] & 0xFE);
- } else {
- gcBlock[0] = (byte)(gcBlock[0] | 0x01);
- gcBlock[3] = (byte)image.transparentPixel;
- }
- if (image.disposalMethod != 0) {
- gcBlock[0] = (byte)(gcBlock[0] | ((image.disposalMethod & 0x07) << 2));
- }
- if (image.delayTime != 0) {
- gcBlock[1] = (byte)(image.delayTime & 0xFF);
- gcBlock[2] = (byte)((image.delayTime >> 8) & 0xFF);
- }
- outputStream.write(gcBlock);
- outputStream.write(0); // block terminator
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-
- /**
- * Write the specified device independent image
- * to the current position in the output stream.
- */
- void writeImageBlock(ImageData image) {
- try {
- outputStream.write(GIF_IMAGE_BLOCK_ID);
- byte[] block = new byte[9];
- block[0] = (byte)(image.x & 0xFF);
- block[1] = (byte)((image.x >> 8) & 0xFF);
- block[2] = (byte)(image.y & 0xFF);
- block[3] = (byte)((image.y >> 8) & 0xFF);
- block[4] = (byte)(image.width & 0xFF);
- block[5] = (byte)((image.width >> 8) & 0xFF);
- block[6] = (byte)(image.height & 0xFF);
- block[7] = (byte)((image.height >> 8) & 0xFF);
- block[8] = 0; // no interlace, no sort, no local palette
- outputStream.write(block);
- outputStream.write(image.depth);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- new LZWCodec().encode(outputStream, image);
- }
-
- /**
- * Write the specified palette to the output stream.
- */
- void writePalette(PaletteData palette, int depth) {
- byte[] bytes = new byte[(1 << depth) * 3];
- int offset = 0;
- for (int i = 0; i < palette.colors.length; i++) {
- RGB color = palette.colors[i];
- bytes[offset] = (byte)color.red;
- bytes[offset + 1] = (byte)color.green;
- bytes[offset + 2] = (byte)color.blue;
- offset += 3;;
- }
- try {
- outputStream.write(bytes);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import java.io.*; + +final class GIFFileFormat extends FileFormat { + String signature, version; + boolean sorted; + int screenWidth, screenHeight, backgroundPixel, aspect, bitsPerPixel, defaultDepth; + boolean userInput = false; + int disposalMethod = 0; + int delayTime = 0; + int transparentPixel = -1; + int repeatCount = 1; + + static final int GIF_APPLICATION_EXTENSION_BLOCK_ID = 0xFF; + static final int GIF_GRAPHICS_CONTROL_BLOCK_ID = 0xF9; + static final int GIF_PLAIN_TEXT_BLOCK_ID = 0x01; + static final int GIF_COMMENT_BLOCK_ID = 0xFE; + static final int GIF_EXTENSION_BLOCK_ID = 0x21; + static final int GIF_IMAGE_BLOCK_ID = 0x2C; + static final int GIF_TRAILER_ID = 0x3B; + + /** + * Answer a palette containing numGrays + * shades of gray, ranging from black to white. + */ + static PaletteData grayRamp(int numGrays) { + int n = numGrays - 1; + RGB[] colors = new RGB[numGrays]; + for (int i = 0; i < numGrays; i++) { + int intensity = (byte)((i * 3) * 256 / n); + colors[i] = new RGB(intensity, intensity, intensity); + } + return new PaletteData(colors); + } + + boolean isFileFormat(LEDataInputStream stream) { + try { + byte[] signature = new byte[3]; + stream.read(signature); + stream.unread(signature); + return new String(signature).equals("GIF"); + } catch (Exception e) { + return false; + } + } + + /** + * Load the GIF image(s) stored in the input stream. + * Return an array of ImageData representing the image(s). + */ + ImageData[] loadFromByteStream() { + byte[] signatureBytes = new byte[3]; + byte[] versionBytes = new byte[3]; + byte[] block = new byte[7]; + try { + inputStream.read(signatureBytes); + signature = new String(signatureBytes); + if (!signature.equals("GIF")) + SWT.error(SWT.ERROR_INVALID_IMAGE); + + inputStream.read(versionBytes); + version = new String(versionBytes); + + inputStream.read(block); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + screenWidth = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8); + loader.logicalScreenWidth = screenWidth; + screenHeight = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8); + loader.logicalScreenHeight = screenHeight; + byte bitField = block[4]; + backgroundPixel = block[5] & 0xFF; + aspect = block[6] & 0xFF; + bitsPerPixel = ((bitField >> 4) & 0x07) + 1; + defaultDepth = (bitField & 0x7) + 1; + PaletteData palette = null; + if ((bitField & 0x80) != 0) { + // Global palette. + sorted = (bitField & 0x8) != 0; + palette = readPalette(1 << defaultDepth); + } else { + // No global palette. + sorted = false; + backgroundPixel = -1; + defaultDepth = bitsPerPixel; + } + loader.backgroundPixel = backgroundPixel; + + getExtensions(); + int id = readID(); + ImageData[] images = new ImageData[0]; + while (id == GIF_IMAGE_BLOCK_ID) { + ImageData image = readImageBlock(palette); + if (loader.hasListeners()) { + loader.notifyListeners(new ImageLoaderEvent(loader, image, 3, true)); + } + ImageData[] oldImages = images; + images = new ImageData[oldImages.length + 1]; + System.arraycopy(oldImages, 0, images, 0, oldImages.length); + images[images.length - 1] = image; + try { + /* Read the 0-byte terminator at the end of the image. */ + id = inputStream.read(); + if (id > 0) { + /* We read the terminator earlier. */ + inputStream.unread(new byte[] {(byte)id}); + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + getExtensions(); + id = readID(); + } + return images; + } + + /** + * Read and return the next block or extension identifier from the file. + */ + int readID() { + try { + return inputStream.read(); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return -1; + } + + /** + * Read extensions until an image descriptor appears. + * In the future, if we care about the extensions, they + * should be properly grouped with the image data before + * which they appeared. Right now, the interesting parts + * of some extensions are kept, but the rest is discarded. + * Throw an error if an error occurs. + */ + void getExtensions() { + int id = readID(); + while (id != GIF_IMAGE_BLOCK_ID && id != GIF_TRAILER_ID && id > 0) { + if (id == GIF_EXTENSION_BLOCK_ID) { + readExtension(); + } else { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + id = readID(); + } + if (id == GIF_IMAGE_BLOCK_ID || id == GIF_TRAILER_ID) { + try { + inputStream.unread(new byte[] {(byte)id}); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + } + + /** + * Read a control extension. + * Return the extension block data. + */ + byte[] readExtension() { + int extensionID = readID(); + if (extensionID == GIF_COMMENT_BLOCK_ID) + return readCommentExtension(); + if (extensionID == GIF_PLAIN_TEXT_BLOCK_ID) + return readPlainTextExtension(); + if (extensionID == GIF_GRAPHICS_CONTROL_BLOCK_ID) + return readGraphicsControlExtension(); + if (extensionID == GIF_APPLICATION_EXTENSION_BLOCK_ID) + return readApplicationExtension(); + // Otherwise, we don't recognize the block. If the + // field size is correct, we can just skip over + // the block contents. + try { + int extSize = inputStream.read(); + if (extSize < 0) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + byte[] ext = new byte[extSize]; + inputStream.read(ext, 0, extSize); + return ext; + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + + /** + * We have just read the Comment extension identifier + * from the input stream. Read in the rest of the comment + * and return it. GIF comment blocks are variable size. + */ + byte[] readCommentExtension() { + try { + byte[] comment = new byte[0]; + byte[] block = new byte[255]; + int size = inputStream.read(); + while ((size > 0) && (inputStream.read(block, 0, size) != -1)) { + byte[] oldComment = comment; + comment = new byte[oldComment.length + size]; + System.arraycopy(oldComment, 0, comment, 0, oldComment.length); + System.arraycopy(block, 0, comment, oldComment.length, size); + size = inputStream.read(); + } + return comment; + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + + /** + * We have just read the PlainText extension identifier + * from the input stream. Read in the plain text info and text, + * and return the text. GIF plain text blocks are variable size. + */ + byte[] readPlainTextExtension() { + try { + // Read size of block = 0x0C. + inputStream.read(); + // Read the text information (x, y, width, height, colors). + byte[] info = new byte[12]; + inputStream.read(info); + // Read the text. + byte[] text = new byte[0]; + byte[] block = new byte[255]; + int size = inputStream.read(); + while ((size > 0) && (inputStream.read(block, 0, size) != -1)) { + byte[] oldText = text; + text = new byte[oldText.length + size]; + System.arraycopy(oldText, 0, text, 0, oldText.length); + System.arraycopy(block, 0, text, oldText.length, size); + size = inputStream.read(); + } + return text; + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + + /** + * We have just read the GraphicsControl extension identifier + * from the input stream. Read in the control information, store + * it, and return it. + */ + byte[] readGraphicsControlExtension() { + try { + // Read size of block = 0x04. + inputStream.read(); + // Read the control block. + byte[] controlBlock = new byte[4]; + inputStream.read(controlBlock); + byte bitField = controlBlock[0]; + // Store the user input field. + userInput = (bitField & 0x02) != 0; + // Store the disposal method. + disposalMethod = (bitField >> 2) & 0x07; + // Store the delay time. + delayTime = (controlBlock[1] & 0xFF) | ((controlBlock[2] & 0xFF) << 8); + // Store the transparent color. + if ((bitField & 0x01) != 0) { + int colorIndex = controlBlock[3] & 0xFF; + /* Work around: a customer has a GIF that specifies an + * invalid color index that is larger than the number + * of entries in the palette. Detect this case, and + * ignore the specified color index. */ + if (colorIndex <= 1 << defaultDepth) { + transparentPixel = colorIndex; + } + } else { + transparentPixel = -1; + } + // Read block terminator. + inputStream.read(); + return controlBlock; + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + + /** + * We have just read the Application extension identifier + * from the input stream. Read in the rest of the extension, + * look for and store 'number of repeats', and return the data. + */ + byte[] readApplicationExtension() { + try { + // Read size of block = 0x0B. + inputStream.read(); + // Read application identifier. + byte[] applicationBytes = new byte[8]; + inputStream.read(applicationBytes); + String application = new String(applicationBytes); + // Read authentication code. + byte[] authenticationBytes = new byte[3]; + inputStream.read(authenticationBytes); + String authentication = new String(authenticationBytes); + // Read application data. + byte[] data = new byte[0]; + byte[] block = new byte[255]; + int size = inputStream.read(); + while ((size > 0) && (inputStream.read(block, 0, size) != -1)) { + byte[] oldData = data; + data = new byte[oldData.length + size]; + System.arraycopy(oldData, 0, data, 0, oldData.length); + System.arraycopy(block, 0, data, oldData.length, size); + size = inputStream.read(); + } + // Look for the NETSCAPE 'repeat count' field for an animated GIF. + if (application.equals("NETSCAPE") && authentication.equals("2.0") && data[0] == 01) { + repeatCount = (data[1] & 0xFF) | ((data[2] & 0xFF) << 8); + loader.repeatCount = repeatCount; + } + return data; + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + + /** + * Return a DeviceIndependentImage representing the + * image block at the current position in the input stream. + * Throw an error if an error occurs. + */ + ImageData readImageBlock(PaletteData defaultPalette) { + int depth; + PaletteData palette; + byte[] block = new byte[9]; + try { + inputStream.read(block); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + int left = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8); + int top = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8); + int width = (block[4] & 0xFF) | ((block[5] & 0xFF) << 8); + int height = (block[6] & 0xFF) | ((block[7] & 0xFF) << 8); + byte bitField = block[8]; + boolean interlaced = (bitField & 0x40) != 0; +// boolean sorted = (bitField & 0x20) != 0; + if ((bitField & 0x80) != 0) { + // Local palette. + depth = (bitField & 0x7) + 1; + palette = readPalette(1 << depth); + } else { + // No local palette. + depth = defaultDepth; + palette = defaultPalette; + } + // Promote depth to next highest supported value. + if (!(depth == 1 || depth == 4 || depth == 8)) { + if (depth < 4) + depth = 4; + else + depth = 8; + } + if (palette == null) { + palette = grayRamp(1 << depth); + } + int initialCodeSize = -1; + try { + initialCodeSize = inputStream.read(); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + if (initialCodeSize < 0) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + ImageData image = ImageData.internal_new( + width, + height, + depth, + palette, + 4, + null, + 0, + null, + null, + -1, + transparentPixel, + SWT.IMAGE_GIF, + left, + top, + disposalMethod, + delayTime); + LZWCodec codec = new LZWCodec(); + codec.decode(inputStream, loader, image, interlaced, initialCodeSize); + return image; + } + + /** + * Read a palette from the input stream. + */ + PaletteData readPalette(int numColors) { + byte[] bytes = new byte[numColors * 3]; + try { + if (inputStream.read(bytes) != bytes.length) + SWT.error(SWT.ERROR_INVALID_IMAGE); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + RGB[] colors = new RGB[numColors]; + for (int i = 0; i < numColors; i++) + colors[i] = new RGB(bytes[i*3] & 0xFF, + bytes[i*3+1] & 0xFF, bytes[i*3+2] & 0xFF); + return new PaletteData(colors); + } + + /** + * Write the specified device independent image + * to the output stream. + */ + void unloadIntoByteStream(ImageData image) { + if (!((image.depth == 1) || (image.depth == 4) || (image.depth == 8))) { + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + } + byte bitField = (byte)((0x80 & 0xF8 & 0xF7 & 0x8F) + (image.depth - 1) + ((image.depth - 1) * 16)); + try { + outputStream.write(new byte[] { (byte)'G', (byte)'I', (byte)'F' }); + outputStream.write(new byte[] { (byte)'8', (byte)'9', (byte)'a' }); + outputStream.writeShort((short)image.width); + outputStream.writeShort((short)image.height); + outputStream.writeByte(bitField); + outputStream.writeByte((byte)0); + outputStream.writeByte((byte)0); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + writePalette(image.palette, image.depth); + if (image.transparentPixel != -1 || image.disposalMethod != 0 || image.delayTime != 0) { + writeGraphicsControlBlock(image); + } + writeImageBlock(image); + } + + /** + * Write out a GraphicsControlBlock to describe + * the specified device independent image. + */ + void writeGraphicsControlBlock(ImageData image) { + try { + outputStream.write(GIF_EXTENSION_BLOCK_ID); + outputStream.write(GIF_GRAPHICS_CONTROL_BLOCK_ID); + outputStream.write(0x04); // size of block + byte[] gcBlock = new byte[4]; + gcBlock[0] = (byte)0xFD; + gcBlock[1] = 0; + gcBlock[2] = 0; + gcBlock[3] = 0; + if (image.transparentPixel == -1) { + gcBlock[0] = (byte)(gcBlock[0] & 0xFE); + } else { + gcBlock[0] = (byte)(gcBlock[0] | 0x01); + gcBlock[3] = (byte)image.transparentPixel; + } + if (image.disposalMethod != 0) { + gcBlock[0] = (byte)(gcBlock[0] | ((image.disposalMethod & 0x07) << 2)); + } + if (image.delayTime != 0) { + gcBlock[1] = (byte)(image.delayTime & 0xFF); + gcBlock[2] = (byte)((image.delayTime >> 8) & 0xFF); + } + outputStream.write(gcBlock); + outputStream.write(0); // block terminator + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + + /** + * Write the specified device independent image + * to the current position in the output stream. + */ + void writeImageBlock(ImageData image) { + try { + outputStream.write(GIF_IMAGE_BLOCK_ID); + byte[] block = new byte[9]; + block[0] = (byte)(image.x & 0xFF); + block[1] = (byte)((image.x >> 8) & 0xFF); + block[2] = (byte)(image.y & 0xFF); + block[3] = (byte)((image.y >> 8) & 0xFF); + block[4] = (byte)(image.width & 0xFF); + block[5] = (byte)((image.width >> 8) & 0xFF); + block[6] = (byte)(image.height & 0xFF); + block[7] = (byte)((image.height >> 8) & 0xFF); + block[8] = 0; // no interlace, no sort, no local palette + outputStream.write(block); + outputStream.write(image.depth); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + new LZWCodec().encode(outputStream, image); + } + + /** + * Write the specified palette to the output stream. + */ + void writePalette(PaletteData palette, int depth) { + byte[] bytes = new byte[(1 << depth) * 3]; + int offset = 0; + for (int i = 0; i < palette.colors.length; i++) { + RGB color = palette.colors[i]; + bytes[offset] = (byte)color.red; + bytes[offset + 1] = (byte)color.green; + bytes[offset + 2] = (byte)color.blue; + offset += 3;; + } + try { + outputStream.write(bytes); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGAppn.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGAppn.java index 9598910863..82046aef0e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGAppn.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGAppn.java @@ -1,24 +1,24 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGAppn extends JPEGVariableSizeSegment {
-
- public JPEGAppn(byte[] reference) {
- super(reference);
- }
-
- public JPEGAppn(LEDataInputStream byteStream) {
- super(byteStream);
- }
-
- public boolean verify() {
- int marker = getSegmentMarker();
- return marker >= JPEGFileFormat.APP0 && marker <= JPEGFileFormat.APP15;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGAppn extends JPEGVariableSizeSegment { + + public JPEGAppn(byte[] reference) { + super(reference); + } + + public JPEGAppn(LEDataInputStream byteStream) { + super(byteStream); + } + + public boolean verify() { + int marker = getSegmentMarker(); + return marker >= JPEGFileFormat.APP0 && marker <= JPEGFileFormat.APP15; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGArithmeticConditioningTable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGArithmeticConditioningTable.java index 6fe82d3ecb..f0ce9f436b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGArithmeticConditioningTable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGArithmeticConditioningTable.java @@ -1,19 +1,19 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGArithmeticConditioningTable extends JPEGVariableSizeSegment {
-
- public JPEGArithmeticConditioningTable(LEDataInputStream byteStream) {
- super(byteStream);
- }
-
- public int signature() {
- return JPEGFileFormat.DAC;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGArithmeticConditioningTable extends JPEGVariableSizeSegment { + + public JPEGArithmeticConditioningTable(LEDataInputStream byteStream) { + super(byteStream); + } + + public int signature() { + return JPEGFileFormat.DAC; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGComment.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGComment.java index 7348adeea8..e5bfffa4d8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGComment.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGComment.java @@ -1,23 +1,23 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGComment extends JPEGVariableSizeSegment {
-
- public JPEGComment(byte[] reference) {
- super(reference);
- }
-
- public JPEGComment(LEDataInputStream byteStream) {
- super(byteStream);
- }
-
- public int signature() {
- return JPEGFileFormat.COM;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGComment extends JPEGVariableSizeSegment { + + public JPEGComment(byte[] reference) { + super(reference); + } + + public JPEGComment(LEDataInputStream byteStream) { + super(byteStream); + } + + public int signature() { + return JPEGFileFormat.COM; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGEndOfImage.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGEndOfImage.java index 354ed570e8..a70ca5f919 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGEndOfImage.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGEndOfImage.java @@ -1,27 +1,27 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGEndOfImage extends JPEGFixedSizeSegment {
-
- public JPEGEndOfImage() {
- super();
- }
-
- public JPEGEndOfImage(byte[] reference) {
- super(reference);
- }
-
- public int signature() {
- return JPEGFileFormat.EOI;
- }
-
- public int fixedSize() {
- return 2;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGEndOfImage extends JPEGFixedSizeSegment { + + public JPEGEndOfImage() { + super(); + } + + public JPEGEndOfImage(byte[] reference) { + super(reference); + } + + public int signature() { + return JPEGFileFormat.EOI; + } + + public int fixedSize() { + return 2; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFileFormat.java index 407ec66238..1370110464 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFileFormat.java @@ -1,1892 +1,1892 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import java.io.*;
-
-final class JPEGFileFormat extends FileFormat {
- int restartInterval;
- JPEGFrameHeader frameHeader;
- int imageWidth, imageHeight;
- int interleavedMcuCols, interleavedMcuRows;
- int maxV, maxH;
- boolean progressive;
- int samplePrecision;
- int nComponents;
- int[][] frameComponents;
- int[] componentIds;
- byte[][] imageComponents;
- int[] dataUnit;
- int[][][] dataUnits;
- int[] precedingDCs;
- JPEGScanHeader scanHeader;
- byte[] dataBuffer;
- int currentBitCount;
- int bufferCurrentPosition;
- int restartsToGo;
- int nextRestartNumber;
- JPEGArithmeticConditioningTable arithmeticTables;
- JPEGHuffmanTable[] acHuffmanTables;
- JPEGHuffmanTable[] dcHuffmanTables;
- int[][] quantizationTables;
- int currentByte;
- int decoderQFactor;
- int encoderQFactor = 75;
- int eobrun = 0;
- /* JPEGConstants */
- public static final int DCTSIZE = 8;
- public static final int DCTSIZESQR = 64;
- /* JPEGFixedPointConstants */
- public static final int FIX_0_899976223 = 7373;
- public static final int FIX_1_961570560 = 16069;
- public static final int FIX_2_053119869 = 16819;
- public static final int FIX_0_298631336 = 2446;
- public static final int FIX_1_847759065 = 15137;
- public static final int FIX_1_175875602 = 9633;
- public static final int FIX_3_072711026 = 25172;
- public static final int FIX_0_765366865 = 6270;
- public static final int FIX_2_562915447 = 20995;
- public static final int FIX_0_541196100 = 4433;
- public static final int FIX_0_390180644 = 3196;
- public static final int FIX_1_501321110 = 12299;
- /* JPEGMarkerCodes */
- public static final int APP0 = 0xFFE0;
- public static final int APP15 = 0xFFEF;
- public static final int COM = 0xFFFE;
- public static final int DAC = 0xFFCC;
- public static final int DHP = 0xFFDE;
- public static final int DHT = 0xFFC4;
- public static final int DNL = 0xFFDC;
- public static final int DRI = 0xFFDD;
- public static final int DQT = 0xFFDB;
- public static final int EOI = 0xFFD9;
- public static final int EXP = 0xFFDF;
- public static final int JPG = 0xFFC8;
- public static final int JPG0 = 0xFFF0;
- public static final int JPG13 = 0xFFFD;
- public static final int RST0 = 0xFFD0;
- public static final int RST1 = 0xFFD1;
- public static final int RST2 = 0xFFD2;
- public static final int RST3 = 0xFFD3;
- public static final int RST4 = 0xFFD4;
- public static final int RST5 = 0xFFD5;
- public static final int RST6 = 0xFFD6;
- public static final int RST7 = 0xFFD7;
- public static final int SOF0 = 0xFFC0;
- public static final int SOF1 = 0xFFC1;
- public static final int SOF2 = 0xFFC2;
- public static final int SOF3 = 0xFFC3;
- public static final int SOF5 = 0xFFC5;
- public static final int SOF6 = 0xFFC6;
- public static final int SOF7 = 0xFFC7;
- public static final int SOF9 = 0xFFC9;
- public static final int SOF10 = 0xFFCA;
- public static final int SOF11 = 0xFFCB;
- public static final int SOF13 = 0xFFCD;
- public static final int SOF14 = 0xFFCE;
- public static final int SOF15 = 0xFFCF;
- public static final int SOI = 0xFFD8;
- public static final int SOS = 0xFFDA;
- public static final int TEM = 0xFF01;
- /* JPEGFrameComponentParameterConstants */
- public static final int TQI = 0;
- public static final int HI = 1;
- public static final int VI = 2;
- public static final int CW = 3;
- public static final int CH = 4;
- /* JPEGScanComponentParameterConstants */
- public static final int DC = 0;
- public static final int AC = 1;
- /* JFIF Component Constants */
- public static final int ID_Y = 1 - 1;
- public static final int ID_CB = 2 - 1;
- public static final int ID_CR = 3 - 1;
-
- public static final int[] ExtendTest = {
- 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
- 4096, 8192, 16384, 32768, 65536, 131072, 262144
- };
- public static final int[] ExtendOffset = new int[] {
- 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047,
- -4095, -8191, -16383, -32767, -65535, -131071, -262143
- };
- public static final int[] ZigZag8x8 = {
- 0, 1, 8, 16, 9, 2, 3, 10,
- 17, 24, 32, 25, 18, 11, 4, 5,
- 12, 19, 26, 33, 40, 48, 41, 34,
- 27, 20, 13, 6, 7, 14, 21, 28,
- 35, 42, 49, 56, 57, 50, 43, 36,
- 29, 22, 15, 23, 30, 37, 44, 51,
- 58, 59, 52, 45, 38, 31, 39, 46,
- 53, 60, 61, 54, 47, 55, 62, 63
- };
- public static int[] CrRTable, CbBTable, CrGTable, CbGTable;
- public static int[] RYTable, GYTable, BYTable,
- RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;
- static {
- initialize();
- }
-void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
- int srcWidth = image.width;
- int srcHeight = image.height;
- int vhFactor = maxV * maxH;
- int[] frameComponent;
- imageComponents = new byte[nComponents][];
- for (int i = 0; i < nComponents; i++) {
- frameComponent = frameComponents[componentIds[i]];
- imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]];
- }
- frameComponent = frameComponents[componentIds[ID_Y]];
- for (int yPos = 0; yPos < srcHeight; yPos++) {
- int srcOfs = yPos * srcWidth;
- int dstOfs = yPos * frameComponent[CW];
- System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth);
- }
- frameComponent = frameComponents[componentIds[ID_CB]];
- for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
- int destRowIndex = yPos * frameComponent[CW];
- for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
- int sum = 0;
- for (int iv = 0; iv < maxV; iv++) {
- int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
- for (int ih = 0; ih < maxH; ih++) {
- sum += dataCbComp[srcIndex + ih] & 0xFF;
- }
- }
- imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor);
- }
- }
- frameComponent = frameComponents[componentIds[ID_CR]];
- for (int yPos = 0; yPos < srcHeight / maxV; yPos++) {
- int destRowIndex = yPos * frameComponent[CW];
- for (int xPos = 0; xPos < srcWidth / maxH; xPos++) {
- int sum = 0;
- for (int iv = 0; iv < maxV; iv++) {
- int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH);
- for (int ih = 0; ih < maxH; ih++) {
- sum += dataCrComp[srcIndex + ih] & 0xFF;
- }
- }
- imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor);
- }
- }
- for (int iComp = 0; iComp < nComponents; iComp++) {
- byte[] imageComponent = imageComponents[iComp];
- frameComponent = frameComponents[componentIds[iComp]];
- int hFactor = frameComponent[HI];
- int vFactor = frameComponent[VI];
- int componentWidth = frameComponent[CW];
- int componentHeight = frameComponent[CH];
- int compressedWidth = srcWidth / (maxH / hFactor);
- int compressedHeight = srcHeight / (maxV / vFactor);
- if (compressedWidth < componentWidth) {
- int delta = componentWidth - compressedWidth;
- for (int yPos = 0; yPos < compressedHeight; yPos++) {
- int dstOfs = ((yPos + 1) * componentWidth - delta);
- int dataValue = imageComponent[dstOfs - 1] & 0xFF;
- for (int i = 0; i < delta; i++) {
- imageComponent[dstOfs + i] = (byte)dataValue;
- }
- }
- }
- if (compressedHeight < componentHeight) {
- int srcOfs = (compressedHeight - 1) * componentWidth;
- for (int yPos = compressedHeight; yPos <= componentHeight; yPos++) {
- int dstOfs = (yPos - 1) * componentWidth;
- System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth);
- }
- }
- }
-}
-void convert4BitRGBToYCbCr(ImageData image) {
- RGB[] rgbs = image.getRGBs();
- int paletteSize = rgbs.length;
- byte[] yComp = new byte[paletteSize];
- byte[] cbComp = new byte[paletteSize];
- byte[] crComp = new byte[paletteSize];
- int srcWidth = image.width;
- int srcHeight = image.height;
- for (int i = 0; i < paletteSize; i++) {
- RGB color = rgbs[i];
- int r = color.red;
- int g = color.green;
- int b = color.blue;
- int n = RYTable[r] + GYTable[g] + BYTable[b];
- yComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) yComp[i]--;
- n = RCbTable[r] + GCbTable[g] + BCbTable[b];
- cbComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) cbComp[i]--;
- n = RCrTable[r] + GCrTable[g] + BCrTable[b];
- crComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) crComp[i]--;
- }
- int bSize = srcWidth * srcHeight;
- byte[] dataYComp = new byte[bSize];
- byte[] dataCbComp = new byte[bSize];
- byte[] dataCrComp = new byte[bSize];
- byte[] origData = image.data;
- for (int yPos = 0; yPos < srcHeight; yPos++) {
- for (int xPos = 0; xPos < srcWidth / 2; xPos++) {
- int srcIndex = yPos * (srcWidth / 2) + xPos;
- int dstIndex = yPos * srcWidth + (xPos * 2);
- int value2 = origData[srcIndex] & 0xFF;
- int value1 = value2 / 16;
- value2 = value2 % 16;
- dataYComp[dstIndex] = yComp[value1];
- dataCbComp[dstIndex] = cbComp[value1];
- dataCrComp[dstIndex] = crComp[value1];
- dataYComp[dstIndex + 1] = yComp[value2];
- dataCbComp[dstIndex + 1] = cbComp[value2];
- dataCrComp[dstIndex + 1] = crComp[value2];
- }
- }
- compress(image, dataYComp, dataCbComp, dataCrComp);
-}
-void convert8BitRGBToYCbCr(ImageData image) {
- RGB[] rgbs = image.getRGBs();
- int paletteSize = rgbs.length;
- byte[] yComp = new byte[paletteSize];
- byte[] cbComp = new byte[paletteSize];
- byte[] crComp = new byte[paletteSize];
- int srcWidth = image.width;
- int srcHeight = image.height;
- for (int i = 0; i < paletteSize; i++) {
- RGB color = rgbs[i];
- int r = color.red;
- int g = color.green;
- int b = color.blue;
- int n = RYTable[r] + GYTable[g] + BYTable[b];
- yComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) yComp[i]--;
- n = RCbTable[r] + GCbTable[g] + BCbTable[b];
- cbComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) cbComp[i]--;
- n = RCrTable[r] + GCrTable[g] + BCrTable[b];
- crComp[i] = (byte)(n / 65536);
- if ((n < 0) && (n % 65536 != 0)) crComp[i]--;
- }
- int dstWidth = image.width;
- int dstHeight = srcHeight;
- int stride = (srcWidth + 3) / 4 * 4;
- int bSize = dstWidth * dstHeight;
- byte[] dataYComp = new byte[bSize];
- byte[] dataCbComp = new byte[bSize];
- byte[] dataCrComp = new byte[bSize];
- byte[] origData = image.data;
- for (int yPos = 0; yPos < srcHeight; yPos++) {
- int srcRowIndex = yPos * stride;
- int dstRowIndex = yPos * dstWidth;
- for (int xPos = 0; xPos < srcWidth; xPos++) {
- int value = origData[srcRowIndex + xPos] & 0xFF;
- int dstIndex = dstRowIndex + xPos;
- dataYComp[dstIndex] = yComp[value];
- dataCbComp[dstIndex] = cbComp[value];
- dataCrComp[dstIndex] = crComp[value];
- }
- }
- compress(image, dataYComp, dataCbComp, dataCrComp);
-}
-byte[] convertCMYKToRGB() {
- /* Unsupported CMYK format. Answer an empty byte array. */
- return new byte[0];
-}
-void convertImageToYCbCr(ImageData image) {
- switch (image.depth) {
- case 4:
- convert4BitRGBToYCbCr(image);
- return;
- case 8:
- convert8BitRGBToYCbCr(image);
- return;
- case 16:
- case 24:
- case 32:
- convertMultiRGBToYCbCr(image);
- return;
- default:
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
- }
- return;
-}
-void convertMultiRGBToYCbCr(ImageData image) {
- int srcWidth = image.width;
- int srcHeight = image.height;
- int bSize = srcWidth * srcHeight;
- byte[] dataYComp = new byte[bSize];
- byte[] dataCbComp = new byte[bSize];
- byte[] dataCrComp = new byte[bSize];
- PaletteData palette = image.palette;
- int[] buffer = new int[srcWidth];
- if (palette.isDirect) {
- int redMask = palette.redMask;
- int greenMask = palette.greenMask;
- int blueMask = palette.blueMask;
- int redShift = palette.redShift;
- int greenShift = palette.greenShift;
- int blueShift = palette.blueShift;
- for (int yPos = 0; yPos < srcHeight; yPos++) {
- image.getPixels(0, yPos, srcWidth, buffer, 0);
- int dstRowIndex = yPos * srcWidth;
- for (int xPos = 0; xPos < srcWidth; xPos++) {
- int pixel = buffer[xPos];
- int dstDataIndex = dstRowIndex + xPos;
- int r = pixel & redMask;
- r = (redShift < 0) ? r >>> -redShift : r << redShift;
- int g = pixel & greenMask;
- g = (greenShift < 0) ? g >>> -greenShift : g << greenShift;
- int b = pixel & blueMask;
- b = (blueShift < 0) ? b >>> -blueShift : b << blueShift;
- dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) / 65536);
- dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536);
- dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536);
- }
- }
- } else {
- for (int yPos = 0; yPos < srcHeight; yPos++) {
- image.getPixels(0, yPos, srcWidth, buffer, 0);
- int dstRowIndex = yPos * srcWidth;
- for (int xPos = 0; xPos < srcWidth; xPos++) {
- int pixel = buffer[xPos];
- int dstDataIndex = dstRowIndex + xPos;
- RGB rgb = palette.getRGB(pixel);
- int r = rgb.red;
- int g = rgb.green;
- int b = rgb.blue;
- dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) / 65536);
- dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536);
- dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536);
- }
- }
- }
- compress(image, dataYComp, dataCbComp, dataCrComp);
-}
-byte[] convertYToRGB() {
- int compWidth = frameComponents[componentIds[ID_Y]][CW];
- int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4;
- byte[] data = new byte[bytesPerLine * imageHeight];
- byte[] yComp = imageComponents[ID_Y];
- int destIndex = 0;
- for (int i = 0; i < imageHeight; i++) {
- int srcIndex = i * compWidth;
- for (int j = 0; j < bytesPerLine; j++) {
- int y = yComp[srcIndex] & 0xFF;
- if (y < 0) {
- y = 0;
- } else {
- if (y > 255) y = 255;
- }
- if (j >= imageWidth) {
- y = 0;
- }
- data[destIndex] = (byte)y;
- srcIndex++;
- destIndex++;
- }
- }
- return data;
-}
-byte[] convertYCbCrToRGB() {
- /**
- * Convert existing image components into an RGB format.
- * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
- * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
- * The conversion equations to be implemented are therefore
- * R = Y + 1.40200 * Cr
- * G = Y - 0.34414 * Cb - 0.71414 * Cr
- * B = Y + 1.77200 * Cb
- * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
- * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
- *
- * To avoid floating-point arithmetic, we represent the fractional constants
- * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
- * the products by 2^16, with appropriate rounding, to get the correct answer.
- * Notice that Y, being an integral input, does not contribute any fraction
- * so it need not participate in the rounding.
- *
- * For even more speed, we avoid doing any multiplications in the inner loop
- * by precalculating the constants times Cb and Cr for all possible values.
- * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
- * for 12-bit samples it is still acceptable. It's not very reasonable for
- * 16-bit samples, but if you want lossless storage you shouldn't be changing
- * colorspace anyway.
- * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
- * values for the G calculation are left scaled up, since we must add them
- * together before rounding.
- */
- int bSize = imageWidth * imageHeight * nComponents;
- byte[] rgbData = new byte[bSize];
- int destIndex = 0;
- expandImageComponents();
- byte[] yComp = imageComponents[ID_Y];
- byte[] cbComp = imageComponents[ID_CB];
- byte[] crComp = imageComponents[ID_CR];
- int compWidth = frameComponents[componentIds[ID_Y]][CW];
- for (int v = 0; v < imageHeight; v++) {
- int srcIndex = v * compWidth;
- for (int i = 0; i < imageWidth; i++) {
- int y = yComp[srcIndex] & 0xFF;
- int cb = cbComp[srcIndex] & 0xFF;
- int cr = crComp[srcIndex] & 0xFF;
- int r = y + CrRTable[cr];
- int g = y + ((CbGTable[cb] + CrGTable[cr]) / 65536);
- int b = y + CbBTable[cb];
- if (r < 0) {
- r = 0;
- } else {
- if (r > 255) r = 255;
- }
- if (g < 0) {
- g = 0;
- } else {
- if (g > 255) g = 255;
- }
- if (b < 0) {
- b = 0;
- } else {
- if (b > 255) b = 255;
- }
- rgbData[destIndex] = (byte)b;
- rgbData[destIndex + 1] = (byte)g;
- rgbData[destIndex + 2] = (byte)r;
- destIndex += 3;
- srcIndex++;
- }
- }
- return rgbData;
-}
-byte[] convertYIQToRGB() {
- /* Unsupported CMYK format. Answer an empty byte array. */
- return new byte[0];
-}
-void decodeACCoefficients(int[] dataUnit, int iComp) {
- int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
- JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
- int k = 1;
- while (k < 64) {
- int rs = decodeUsingTable(acTable);
- int r = rs >> 4;
- int s = rs & 0xF;
- if (s == 0) {
- if (r == 15) {
- k += 16;
- } else {
- break;
- }
- } else {
- k += r;
- int bits = receive(s);
- dataUnit[ZigZag8x8[k]] = extendBy(bits, s);
- k++;
- }
- }
-}
-void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
- if (eobrun > 0) {
- eobrun--;
- return;
- }
- int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
- JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
- int k = start;
- while (k <= end) {
- int rs = decodeUsingTable(acTable);
- int r = rs >> 4;
- int s = rs & 0xF;
- if (s == 0) {
- if (r == 15) {
- k += 16;
- } else {
- eobrun = (1 << r) + receive(r) - 1;
- break;
- }
- } else {
- k += r;
- int bits = receive(s);
- dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit;
- k++;
- }
- }
-}
-void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) {
- int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
- JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
- int k = start;
- while (k <= end) {
- if (eobrun > 0) {
- while (k <= end) {
- int zzIndex = ZigZag8x8[k];
- if (dataUnit[zzIndex] != 0) {
- dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
- }
- k++;
- }
- eobrun--;
- } else {
- int rs = decodeUsingTable(acTable);
- int r = rs >> 4;
- int s = rs & 0xF;
- if (s == 0) {
- if (r == 15) {
- int zeros = 0;
- while (zeros < 16 && k <= end) {
- int zzIndex = ZigZag8x8[k];
- if (dataUnit[zzIndex] != 0) {
- dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
- } else {
- zeros++;
- }
- k++;
- }
- } else {
- eobrun = (1 << r) + receive(r);
- }
- } else {
- int bit = receive(s);
- int zeros = 0;
- int zzIndex = ZigZag8x8[k];
- while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) {
- if (dataUnit[zzIndex] != 0) {
- dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit);
- } else {
- zeros++;
- }
- k++;
- zzIndex = ZigZag8x8[k];
- }
- if (bit != 0) {
- dataUnit[zzIndex] = 1 << approxBit;
- } else {
- dataUnit[zzIndex] = -1 << approxBit;
- }
- k++;
- }
- }
- }
-}
-int refineAC(int ac, int approxBit) {
- if (ac > 0) {
- int bit = nextBit();
- if (bit != 0) {
- ac = ac + (1 << approxBit);
- }
- } else if (ac < 0) {
- int bit = nextBit();
- if (bit != 0) {
- ac = ac + (-1 << approxBit);
- }
- }
- return ac;
-}
-void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) {
- int[] sParams = scanHeader.componentParameters[componentIds[iComp]];
- JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
- int lastDC = 0;
- if (progressive && !first) {
- int bit = nextBit();
- lastDC = dataUnit[0] + (bit << approxBit);
- } else {
- lastDC = precedingDCs[iComp];
- int nBits = decodeUsingTable(dcTable);
- if (nBits != 0) {
- int bits = receive(nBits);
- int diff = extendBy(bits, nBits);
- lastDC = lastDC + diff;
- precedingDCs[iComp] = lastDC;
- }
- if (progressive) {
- lastDC = lastDC << approxBit;
- }
- }
- dataUnit[0] = lastDC;
-}
-void dequantize(int[] dataUnit, int iComp) {
- int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
- for (int i = 0; i < dataUnit.length; i++) {
- int zzIndex = ZigZag8x8[i];
- dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i];
- }
-}
-byte[] decodeImageComponents() {
- int[] compIds = new int[nComponents];
- int compIdsIndex = 0;
- for (int i = 0; i < nComponents; i++) {
- compIds[compIdsIndex] = i + 1;
- compIdsIndex++;
- }
- if ((compIds.length == 3) &&
- (compIds[0] == 1) &&
- (compIds[1] == 2) &&
- (compIds[2] == 3)) {
- return convertYCbCrToRGB();
- }
- if ((compIds.length == 3) &&
- (compIds[0] == 1) &&
- (compIds[1] == 4) &&
- (compIds[2] == 5)) {
- return convertYIQToRGB();
- }
- if (compIds.length == 4) {
- return convertCMYKToRGB();
- }
- return convertYToRGB();
-}
-void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) {
- for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
- int scanComponent = iComp;
- while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
- scanComponent++;
- }
- int[] frameComponent = frameComponents[componentIds[scanComponent]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- if (nComponentsInScan == 1) {
- hi = 1;
- vi = 1;
- }
- int compWidth = frameComponent[CW];
- for (int ivi = 0; ivi < vi; ivi++) {
- for (int ihi = 0; ihi < hi; ihi++) {
- if (progressive) {
- // Progressive: First scan - create a new data unit.
- // Subsequent scans - refine the existing data unit.
- int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
- dataUnit = dataUnits[scanComponent][index];
- if (dataUnit == null) {
- dataUnit = new int[64];
- dataUnits[scanComponent][index] = dataUnit;
- }
- } else {
- // Sequential: Clear and reuse the data unit buffer.
- for (int i = 0; i < dataUnit.length; i++) {
- dataUnit[i] = 0;
- }
- }
- if (!progressive || scanHeader.isDCProgressiveScan()) {
- decodeDCCoefficient(dataUnit, scanComponent, first, approxBit);
- }
- if (!progressive) {
- decodeACCoefficients(dataUnit, scanComponent);
- } else {
- if (scanHeader.isACProgressiveScan()) {
- if (first) {
- decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit);
- } else {
- decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit);
- }
- }
- if (loader.hasListeners()) {
- // Dequantization, IDCT, up-sampling and color conversion
- // are done on a copy of the coefficient data in order to
- // display the image incrementally.
- int[] temp = dataUnit;
- dataUnit = new int[64];
- System.arraycopy(temp, 0, dataUnit, 0, 64);
- }
- }
- if (!progressive || (progressive && loader.hasListeners())) {
- dequantize(dataUnit, scanComponent);
- inverseDCT(dataUnit);
- storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi);
- }
- }
- }
- }
-}
-void decodeScan() {
- if (progressive && !scanHeader.verifyProgressiveScan()) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- int nComponentsInScan = scanHeader.getNumberOfImageComponents();
- int mcuRowsInScan = interleavedMcuRows;
- int mcusPerRow = interleavedMcuCols;
- if (nComponentsInScan == 1) {
- // Non-interleaved.
- int scanComponent = 0;
- while (scanHeader.componentParameters[componentIds[scanComponent]] == null) {
- scanComponent++;
- }
- int[] frameComponent = frameComponents[componentIds[scanComponent]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- int mcuWidth = DCTSIZE * maxH / hi;
- int mcuHeight = DCTSIZE * maxV / vi;
- mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth;
- mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight;
- }
- boolean first = scanHeader.isFirstScan();
- int start = scanHeader.getStartOfSpectralSelection();
- int end = scanHeader.getEndOfSpectralSelection();
- int approxBit = scanHeader.getApproxBitPositionLow();
- restartsToGo = restartInterval;
- nextRestartNumber = 0;
- for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) {
- for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) {
- if (restartInterval != 0) {
- if (restartsToGo == 0) processRestartInterval();
- restartsToGo--;
- }
- decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit);
- }
- }
-}
-int decodeUsingTable(JPEGHuffmanTable huffmanTable) {
- int i = 0;
- int[] maxCodes = huffmanTable.getDhMaxCodes();
- int[] minCodes = huffmanTable.getDhMinCodes();
- int[] valPtrs = huffmanTable.getDhValPtrs();
- int[] huffVals = huffmanTable.getDhValues();
- int code = nextBit();
- while (code > maxCodes[i]) {
- code = code * 2 + nextBit();
- i++;
- }
- int j = valPtrs[i];
- j = j + code - minCodes[i];
- return huffVals[j];
-}
-void emit(int huffCode, int nBits) {
- if (nBits == 0) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- int[] power2m1 = new int[] {
- 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191,
- 16383, 32767, 65535, 131125
- };
- int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount);
- byte[] codeBuffer = new byte[4];
- codeBuffer[0] = (byte)(code % 256);
- codeBuffer[1] = (byte)((code / 256) % 256);
- codeBuffer[2] = (byte)((code / 65536) % 256);
- codeBuffer[3] = (byte)((code / 16777216) % 256);
- int abs = nBits - (8 - currentBitCount);
- if (abs < 0) abs = -abs;
- if ((abs / 8) > 0) {
- currentByte += codeBuffer[2];
- emitByte((byte)currentByte);
- emitByte((byte)codeBuffer[1]);
- currentByte = codeBuffer[0];
- currentBitCount += nBits - 16;
- } else {
- currentBitCount += nBits;
- if (currentBitCount >= 8) {
- currentByte += codeBuffer[2];
- emitByte((byte)currentByte);
- currentByte = codeBuffer[1];
- currentBitCount -= 8;
- } else {
- currentByte += codeBuffer[2];
- }
- }
-}
-void emitByte(byte byteValue) {
- if (bufferCurrentPosition >= 512) {
- resetOutputBuffer();
- }
- dataBuffer[bufferCurrentPosition] = byteValue;
- bufferCurrentPosition++;
- if (byteValue == -1) {
- emitByte((byte)0);
- }
-}
-void encodeACCoefficients(int[] dataUnit, int iComp) {
- int[] sParams = scanHeader.componentParameters[iComp];
- JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]];
- int[] ehCodes = acTable.ehCodes;
- byte[] ehSizes = acTable.ehCodeLengths;
- int r = 0;
- int k = 1;
- while (k < 64) {
- k++;
- int acValue = dataUnit[ZigZag8x8[k - 1]];
- if (acValue == 0) {
- if (k == 64) {
- emit(ehCodes[0], ehSizes[0] & 0xFF);
- } else {
- r++;
- }
- } else {
- while (r > 15) {
- emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF);
- r -= 16;
- }
- if (acValue < 0) {
- int absACValue = acValue;
- if (absACValue < 0) absACValue = -absACValue;
- int nBits = NBitsTable[absACValue];
- int rs = r * 16 + nBits;
- emit(ehCodes[rs], ehSizes[rs] & 0xFF);
- emit(0xFFFFFF - absACValue, nBits);
- } else {
- int nBits = NBitsTable[acValue];
- int rs = r * 16 + nBits;
- emit(ehCodes[rs], ehSizes[rs] & 0xFF);
- emit(acValue, nBits);
- }
- r = 0;
- }
- }
-}
-void encodeDCCoefficients(int[] dataUnit, int iComp) {
- int[] sParams = scanHeader.componentParameters[iComp];
- JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]];
- int lastDC = precedingDCs[iComp];
- int dcValue = dataUnit[0];
- int diff = dcValue - lastDC;
- precedingDCs[iComp] = dcValue;
- if (diff < 0) {
- int absDiff = 0 - diff;
- int nBits = NBitsTable[absDiff];
- emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
- emit(0xFFFFFF - absDiff, nBits);
- } else {
- int nBits = NBitsTable[diff];
- emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]);
- if (nBits != 0) {
- emit(diff, nBits);
- }
- }
-}
-void encodeMCUAtXAndY(int xmcu, int ymcu) {
- int nComponentsInScan = scanHeader.getNumberOfImageComponents();
- dataUnit = new int[64];
- for (int iComp = 0; iComp < nComponentsInScan; iComp++) {
- int[] frameComponent = frameComponents[componentIds[iComp]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- for (int ivi = 0; ivi < vi; ivi++) {
- for (int ihi = 0; ihi < hi; ihi++) {
- extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi);
- forwardDCT(dataUnit);
- quantizeData(dataUnit, iComp);
- encodeDCCoefficients(dataUnit, iComp);
- encodeACCoefficients(dataUnit, iComp);
- }
- }
- }
-}
-void encodeScan() {
- for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
- for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
- encodeMCUAtXAndY(xmcu, ymcu);
- }
- }
- if (currentBitCount != 0) {
- emitByte((byte)currentByte);
- }
- resetOutputBuffer();
-}
-void expandImageComponents() {
- for (int iComp = 0; iComp < nComponents; iComp++) {
- int[] frameComponent = frameComponents[componentIds[iComp]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- int upH = maxH / hi;
- int upV = maxV / vi;
- if ((upH * upV) > 1) {
- byte[] component = imageComponents[iComp];
- int compWidth = frameComponent[CW];
- int compHeight = frameComponent[CH];
- int upCompWidth = compWidth * upH;
- int upCompHeight = compHeight * upV;
- RGB[] rgbs = new RGB[] {
- new RGB(0,0,0),
- new RGB(0x80,0,0),
- new RGB(0,0x80,0),
- new RGB(0x80,0x80,0),
- new RGB(0,0,0x80),
- new RGB(0x80,0,0x80),
- new RGB(0,0x80,0x80),
- new RGB(0xC0,0xC0,0xC0),
- new RGB(0x80,0x80,0x80),
- new RGB(0xFF,0,0),
- new RGB(0,0xFF,0),
- new RGB(0xFF,0xFF,0),
- new RGB(0,0,0xFF),
- new RGB(0xFF,0,0xFF),
- new RGB(0,0xFF,0xFF),
- new RGB(0xFF,0xFF,0xFF),
- };
- ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(rgbs), 4, component);
- ImageData dest = src.scaledTo(upCompWidth, upCompHeight);
- imageComponents[iComp] = dest.data;
- }
- }
-}
-int extendBy(int diff, int t) {
- if (diff < ExtendTest[t]) {
- return diff + ExtendOffset[t];
- } else {
- return diff;
- }
-}
-void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) {
- byte[] compImage = imageComponents[iComp];
- int[] frameComponent = frameComponents[componentIds[iComp]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- int compWidth = frameComponent[CW];
- int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
- int destIndex = 0;
- for (int i = 0; i < DCTSIZE; i++) {
- for (int col = 0; col < DCTSIZE; col++) {
- dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128;
- destIndex++;
- }
- srcIndex += compWidth;
- }
-}
-void forwardDCT(int[] dataUnit) {
- for (int row = 0; row < 8; row++) {
- int rIndex = row * DCTSIZE;
- int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7];
- int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7];
- int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6];
- int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6];
- int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5];
- int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5];
- int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4];
- int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4];
-
- /**
- * Even part per LL&M figure 1 --- note that published figure
- * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
- */
- int tmp10 = tmp0 + tmp3;
- int tmp13 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp12 = tmp1 - tmp2;
-
- dataUnit[rIndex] = (tmp10 + tmp11) * 4;
- dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4;
-
- int z1 = (tmp12 + tmp13) * FIX_0_541196100;
- int scaleFactor1 = ExtendTest[11];
- int scaleFactor2 = ExtendTest[12];
- int n = z1 + (tmp13 * FIX_0_765366865) + scaleFactor1;
- dataUnit[rIndex + 2] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 2]--;
- n = z1 + (tmp12 * (0 - FIX_1_847759065)) + scaleFactor1;
- dataUnit[rIndex + 6] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 6]--;
-
- /**
- * Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
- z1 = tmp4 + tmp7;
- int z2 = tmp5 + tmp6;
- int z3 = tmp4 + tmp6;
- int z4 = tmp5 + tmp7;
- int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
-
- tmp4 = tmp4 * FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
- tmp5 = tmp5 * FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
- tmp6 = tmp6 * FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
- tmp7 = tmp7 * FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
- z1 = z1 * (0 - FIX_0_899976223); // sqrt(2) * (c7-c3)
- z2 = z2 * (0 - FIX_2_562915447); // sqrt(2) * (-c1-c3)
- z3 = z3 * (0 - FIX_1_961570560); // sqrt(2) * (-c3-c5)
- z4 = z4 * (0 - FIX_0_390180644); // sqrt(2) * (c5-c3)
-
- z3 = z3 + z5;
- z4 = z4 + z5;
-
- n = tmp4 + z1 + z3 + scaleFactor1;
- dataUnit[rIndex + 7] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 7]--;
- n = tmp5 + z2 + z4 + scaleFactor1;
- dataUnit[rIndex + 5] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 5]--;
- n = tmp6 + z2 + z3 + scaleFactor1;
- dataUnit[rIndex + 3] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 3]--;
- n = tmp7 + z1 + z4 + scaleFactor1;
- dataUnit[rIndex + 1] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 1]--;
- }
-
- /**
- * Pass 2: process columns.
- * Note that we must descale the results by a factor of 8 == 2**3,
- * and also undo the PASS1_BITS scaling.
- */
- for (int col = 0; col < 8; col++) {
- int c0 = col;
- int c1 = col + 8;
- int c2 = col + 16;
- int c3 = col + 24;
- int c4 = col + 32;
- int c5 = col + 40;
- int c6 = col + 48;
- int c7 = col + 56;
- int tmp0 = dataUnit[c0] + dataUnit[c7];
- int tmp7 = dataUnit[c0] - dataUnit[c7];
- int tmp1 = dataUnit[c1] + dataUnit[c6];
- int tmp6 = dataUnit[c1] - dataUnit[c6];
- int tmp2 = dataUnit[c2] + dataUnit[c5];
- int tmp5 = dataUnit[c2] - dataUnit[c5];
- int tmp3 = dataUnit[c3] + dataUnit[c4];
- int tmp4 = dataUnit[c3] - dataUnit[c4];
-
- /**
- * Even part per LL&M figure 1 --- note that published figure
- * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'.
- */
- int tmp10 = tmp0 + tmp3;
- int tmp13 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp12 = tmp1 - tmp2;
-
- int scaleFactor1 = ExtendTest[5];
- int scaleFactor2 = ExtendTest[6];
- int n = tmp10 + tmp11 + scaleFactor1;
- dataUnit[c0] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c0]--;
- n = tmp10 - tmp11 + scaleFactor1;
- dataUnit[c4] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c4]--;
-
- int z1 = (tmp12 + tmp13) * FIX_0_541196100;
- scaleFactor1 = ExtendTest[18];
- scaleFactor2 = ExtendTest[19];
- n = z1 + (tmp13 * FIX_0_765366865) + scaleFactor1;
- dataUnit[c2] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c2]--;
- n = z1 + (tmp12 * (0 - FIX_1_847759065)) + scaleFactor1;
- dataUnit[c6] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c6]--;
-
- /**
- * Odd part per figure 8 --- note paper omits factor of sqrt(2).
- * cK represents cos(K*pi/16).
- * i0..i3 in the paper are tmp4..tmp7 here.
- */
- z1 = tmp4 + tmp7;
- int z2 = tmp5 + tmp6;
- int z3 = tmp4 + tmp6;
- int z4 = tmp5 + tmp7;
- int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3
-
- tmp4 = tmp4 * FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7)
- tmp5 = tmp5 * FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7)
- tmp6 = tmp6 * FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7)
- tmp7 = tmp7 * FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7)
- z1 = z1 * (0 - FIX_0_899976223); // sqrt(2) * (c7-c3)
- z2 = z2 * (0 - FIX_2_562915447); // sqrt(2) * (-c1-c3)
- z3 = z3 * (0 - FIX_1_961570560); // sqrt(2) * (-c3-c5)
- z4 = z4 * (0 - FIX_0_390180644); // sqrt(2) * (c5-c3)
-
- z3 = z3 + z5;
- z4 = z4 + z5;
-
- n = tmp4 + z1 + z3 + scaleFactor1;
- dataUnit[c7] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c7]--;
- n = tmp5 + z2 + z4 + scaleFactor1;
- dataUnit[c5] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c5]--;
- n = tmp6 + z2 + z3 + scaleFactor1;
- dataUnit[c3] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c3]--;
- n = tmp7 + z1 + z4 + scaleFactor1;
- dataUnit[c1] = n / scaleFactor2;
- if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c1]--;
- }
-}
-void getAPP0() {
- JPEGAppn appn = new JPEGAppn(inputStream);
- if (!appn.verify()) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-}
-void getCOM() {
- new JPEGComment(inputStream);
-}
-void getDAC() {
- JPEGArithmeticConditioningTable dac = new JPEGArithmeticConditioningTable(inputStream);
- arithmeticTables = dac;
-}
-void getDHT() {
- JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream);
- if (!dht.verify()) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- if (acHuffmanTables == null) {
- acHuffmanTables = new JPEGHuffmanTable[4];
- }
- if (dcHuffmanTables == null) {
- dcHuffmanTables = new JPEGHuffmanTable[4];
- }
- JPEGHuffmanTable[] dhtTables = dht.getAllTables();
- for (int i = 0; i < dhtTables.length; i++) {
- JPEGHuffmanTable dhtTable = dhtTables[i];
- if (dhtTable.getTableClass() == 0) {
- dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
- } else {
- acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable;
- }
- }
-}
-void getDNL() {
- new JPEGRestartInterval(inputStream);
-}
-void getDQT() {
- JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream);
- int[][] currentTables = quantizationTables;
- if (currentTables == null) {
- currentTables = new int[4][];
- }
- int[] dqtTablesKeys = dqt.getQuantizationTablesKeys();
- int[][] dqtTablesValues = dqt.getQuantizationTablesValues();
- for (int i = 0; i < dqtTablesKeys.length; i++) {
- int index = dqtTablesKeys[i];
- currentTables[index] = dqtTablesValues[i];
- }
- quantizationTables = currentTables;
-}
-void getDRI() {
- JPEGRestartInterval dri = new JPEGRestartInterval(inputStream);
- if (!dri.verify()) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- restartInterval = dri.getRestartInterval();
-}
-static void initialize() {
- initializeRGBYCbCrTables();
- initializeYCbCrRGBTables();
- initializeBitCountTable();
-}
-static void initializeBitCountTable() {
- int nBits = 1;
- int power2 = 2;
- NBitsTable = new int[2048];
- NBitsTable[0] = 0;
- for (int i = 1; i < NBitsTable.length; i++) {
- if (!(i < power2)) {
- nBits++;
- power2 *= 2;
- }
- NBitsTable[i] = nBits;
- }
-}
-static void initializeRGBYCbCrTables() {
- RYTable = new int[256];
- GYTable = new int[256];
- BYTable = new int[256];
- RCbTable = new int[256];
- GCbTable = new int[256];
- BCbTable = new int[256];
- RCrTable = BCbTable;
- GCrTable = new int[256];
- BCrTable = new int[256];
- for (int i = 0; i < 256; i++) {
- RYTable[i] = i * 19595;
- GYTable[i] = i * 38470;
- BYTable[i] = i * 7471 + 32768;
- RCbTable[i] = i * -11059;
- GCbTable[i] = i * -21709;
- BCbTable[i] = i * 32768 + 8388608;
- GCrTable[i] = i * -27439;
- BCrTable[i] = i * -5329;
- }
-}
-static void initializeYCbCrRGBTables() {
- CrRTable = new int[256];
- CbBTable = new int[256];
- CrGTable = new int[256];
- CbGTable = new int[256];
- for (int i = 0; i < 256; i++) {
- int x2 = 2 * i - 255;
- CrRTable[i] = (45941 * x2 + 32768) / 65536;
- CbBTable[i] = (58065 * x2 + 32768) / 65536;
- CrGTable[i] = -23401 * x2;
- CbGTable[i] = -11277 * x2 + 32768;
- }
-}
-void inverseDCT(int[] dataUnit) {
- for (int row = 0; row < 8; row++) {
- int rIndex = row * DCTSIZE;
- /**
- * Due to quantization, we will usually find that many of the input
- * coefficients are zero, especially the AC terms. We can exploit this
- * by short-circuiting the IDCT calculation for any row in which all
- * the AC terms are zero. In that case each output is equal to the
- * DC coefficient (with scale factor as needed).
- * With typical images and quantization tables, half or more of the
- * row DCT calculations can be simplified this way.
- */
- if (isZeroInRow(dataUnit, rIndex)) {
- int dcVal = dataUnit[rIndex] * 4;
- for (int i = rIndex; i < rIndex + 8; i++) {
- dataUnit[i] = dcVal;
- }
- } else {
- /**
- * Even part: reverse the even part of the forward DCT.
- * The rotator is sqrt(2)*c(-6).
- */
- int z2 = dataUnit[rIndex + 2];
- int z3 = dataUnit[rIndex + 6];
- int z1 = (z2 + z3) * FIX_0_541196100;
- int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
- int tmp3 = z1 + (z2 * FIX_0_765366865);
- int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) * 8192;
- int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) * 8192;
- int tmp10 = tmp0 + tmp3;
- int tmp13 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp12 = tmp1 - tmp2;
- /**
- * Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
- tmp0 = dataUnit[rIndex + 7];
- tmp1 = dataUnit[rIndex + 5];
- tmp2 = dataUnit[rIndex + 3];
- tmp3 = dataUnit[rIndex + 1];
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- int z4 = tmp1 + tmp3;
- int z5 = (z3 + z4)* FIX_1_175875602; /* sqrt(2) * c3 */
-
- tmp0 = tmp0 * FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = tmp1 * FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = tmp2 * FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = tmp3 * FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = z1 * (0 - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = z2 * (0 - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = z3 * (0 - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = z4 * (0 - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 = z3 + z5;
- z4 = z4 + z5;
- tmp0 = tmp0 + z1 + z3;
- tmp1 = tmp1 + z2 + z4;
- tmp2 = tmp2 + z2 + z3;
- tmp3 = tmp3 + z1 + z4;
-
- int descaleFactor1 = ExtendTest[11];
- int descaleFactor2 = ExtendTest[12];
- dataUnit[rIndex] = (tmp10 + tmp3 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 7] = (tmp10 - tmp3 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 1] = (tmp11 + tmp2 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 6] = (tmp11 - tmp2 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 2] = (tmp12 + tmp1 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 5] = (tmp12 - tmp1 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 3] = (tmp13 + tmp0 + descaleFactor1) / descaleFactor2;
- dataUnit[rIndex + 4] = (tmp13 - tmp0 + descaleFactor1) / descaleFactor2;
- }
- }
- /**
- * Pass 2: process columns.
- * Note that we must descale the results by a factor of 8 == 2**3,
- * and also undo the PASS1_BITS scaling.
- */
- for (int col = 0; col < 8; col++) {
- int c0 = col;
- int c1 = col + 8;
- int c2 = col + 16;
- int c3 = col + 24;
- int c4 = col + 32;
- int c5 = col + 40;
- int c6 = col + 48;
- int c7 = col + 56;
- if (isZeroInColumn(dataUnit, col)) {
- int dcVal = (dataUnit[c0] + 16) / 32;
- dataUnit[c0] = dcVal;
- dataUnit[c1] = dcVal;
- dataUnit[c2] = dcVal;
- dataUnit[c3] = dcVal;
- dataUnit[c4] = dcVal;
- dataUnit[c5] = dcVal;
- dataUnit[c6] = dcVal;
- dataUnit[c7] = dcVal;
- } else {
- /**
- * Even part: reverse the even part of the forward DCT.
- * The rotator is sqrt(2)*c(-6).
- */
- int z2 = dataUnit[c2];
- int z3 = dataUnit[c6];
- int z1 = (z2 + z3) * FIX_0_541196100;
- int tmp2 = z1 + (z3 * (0 - FIX_1_847759065));
- int tmp3 = z1 + (z2 * FIX_0_765366865);
- int tmp0 = (dataUnit[c0] + dataUnit[c4]) * 8192;
- int tmp1 = (dataUnit[c0] - dataUnit[c4]) * 8192;
- int tmp10 = tmp0 + tmp3;
- int tmp13 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp12 = tmp1 - tmp2;
- /**
- * Odd part per figure 8; the matrix is unitary and hence its
- * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
- */
- tmp0 = dataUnit[c7];;
- tmp1 = dataUnit[c5];
- tmp2 = dataUnit[c3];
- tmp3 = dataUnit[c1];
- z1 = tmp0 + tmp3;
- z2 = tmp1 + tmp2;
- z3 = tmp0 + tmp2;
- int z4 = tmp1 + tmp3;
- int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */
-
- tmp0 = tmp0 * FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */
- tmp1 = tmp1 * FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */
- tmp2 = tmp2 * FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */
- tmp3 = tmp3 * FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */
- z1 = z1 * (0 - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
- z2 = z2 * (0 - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
- z3 = z3 * (0 - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
- z4 = z4 * (0 - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
-
- z3 = z3 + z5;
- z4 = z4 + z5;
-
- tmp0 = tmp0 + z1 + z3;
- tmp1 = tmp1 + z2 + z4;
- tmp2 = tmp2 + z2 + z3;
- tmp3 = tmp3 + z1 + z4;
-
- /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
- int descaleFactor1 = ExtendTest[18];
- int descaleFactor2 = ExtendTest[19];
- dataUnit[c0] = (tmp10 + tmp3 + descaleFactor1) / descaleFactor2;
- dataUnit[c7] = (tmp10 - tmp3 + descaleFactor1) / descaleFactor2;
- dataUnit[c1] = (tmp11 + tmp2 + descaleFactor1) / descaleFactor2;
- dataUnit[c6] = (tmp11 - tmp2 + descaleFactor1) / descaleFactor2;
- dataUnit[c2] = (tmp12 + tmp1 + descaleFactor1) / descaleFactor2;
- dataUnit[c5] = (tmp12 - tmp1 + descaleFactor1) / descaleFactor2;
- dataUnit[c3] = (tmp13 + tmp0 + descaleFactor1) / descaleFactor2;
- dataUnit[c4] = (tmp13 - tmp0 + descaleFactor1) / descaleFactor2;
- }
- }
-}
-boolean isFileFormat(LEDataInputStream stream) {
- try {
- JPEGStartOfImage soi = new JPEGStartOfImage(stream);
- stream.unread(soi.reference);
- return soi.verify(); // we no longer check for appN
- } catch (Exception e) {
- return false;
- }
-}
-boolean isZeroInColumn(int[] dataUnit, int col) {
- return (dataUnit[col + 8] + dataUnit[col + 16] +
- dataUnit[col + 24] + dataUnit[col + 32] +
- dataUnit[col + 40] + dataUnit[col + 48] +
- dataUnit[col + 56]) == 0;
-}
-boolean isZeroInRow(int[] dataUnit, int rIndex) {
- return (dataUnit[rIndex + 1] + dataUnit[rIndex + 2] +
- dataUnit[rIndex + 3] + dataUnit[rIndex + 4] +
- dataUnit[rIndex + 5] + dataUnit[rIndex + 6] +
- dataUnit[rIndex + 7]) == 0;
-}
-ImageData[] loadFromByteStream() {
- JPEGStartOfImage soi = new JPEGStartOfImage(inputStream);
- if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
- restartInterval = 0;
-
- /* Process the tables preceding the frame header. */
- processTables();
-
- /* Start of Frame. */
- frameHeader = new JPEGFrameHeader(inputStream);
- if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
- imageWidth = frameHeader.getSamplesPerLine();
- imageHeight = frameHeader.getNumberOfLines();
- maxH = frameHeader.getMaxHFactor();
- maxV = frameHeader.getMaxVFactor();
- int mcuWidth = maxH * DCTSIZE;
- int mcuHeight = maxV * DCTSIZE;
- interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
- interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
- progressive = frameHeader.isProgressive();
- samplePrecision = frameHeader.getSamplePrecision();
- nComponents = frameHeader.getNumberOfImageComponents();
- frameComponents = frameHeader.componentParameters;
- componentIds = frameHeader.componentIdentifiers;
- imageComponents = new byte[nComponents][];
- if (progressive) {
- // Progressive jpeg: need to keep all of the data units.
- dataUnits = new int[nComponents][][];
- } else {
- // Sequential jpeg: only need one data unit.
- dataUnit = new int[8 * 8];
- }
- for (int i = 0; i < nComponents; i++) {
- int[] frameComponent = frameComponents[componentIds[i]];
- int bufferSize = frameComponent[CW] * frameComponent[CH];
- imageComponents[i] = new byte[bufferSize];
- if (progressive) {
- dataUnits[i] = new int[bufferSize][];
- }
- }
-
- /* Process the tables preceding the scan header. */
- processTables();
-
- /* Start of Scan. */
- scanHeader = new JPEGScanHeader(inputStream);
- if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- /* Process scan(s) and further tables until EOI. */
- int progressiveScanCount = 0;
- boolean done = false;
- while(!done) {
- resetInputBuffer();
- precedingDCs = new int[4];
- decodeScan();
- if (progressive && loader.hasListeners()) {
- ImageData imageData = createImageData();
- loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false));
- progressiveScanCount++;
- }
-
- /* Unread any buffered data before looking for tables again. */
- int delta = 512 - bufferCurrentPosition - 1;
- if (delta > 0) {
- byte[] unreadBuffer = new byte[delta];
- System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta);
- try {
- inputStream.unread(unreadBuffer);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-
- /* Process the tables preceding the next scan header. */
- JPEGSegment jpegSegment = processTables();
- if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) {
- done = true;
- } else {
- scanHeader = new JPEGScanHeader(inputStream);
- if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- }
-
- if (progressive) {
- for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) {
- for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) {
- for (int iComp = 0; iComp < nComponents; iComp++) {
- int[] frameComponent = frameComponents[componentIds[iComp]];
- int hi = frameComponent[HI];
- int vi = frameComponent[VI];
- int compWidth = frameComponent[CW];
- for (int ivi = 0; ivi < vi; ivi++) {
- for (int ihi = 0; ihi < hi; ihi++) {
- int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi;
- dataUnit = dataUnits[iComp][index];
- dequantize(dataUnit, iComp);
- inverseDCT(dataUnit);
- storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi);
- }
- }
- }
- }
- }
- }
- ImageData imageData = createImageData();
- if (progressive && loader.hasListeners()) {
- loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true));
- }
- return new ImageData[] {imageData};
-}
-ImageData createImageData() {
- return ImageData.internal_new(
- imageWidth,
- imageHeight,
- nComponents * samplePrecision,
- setUpPalette(),
- nComponents == 1 ? 4 : 1,
- decodeImageComponents(),
- 0,
- null,
- null,
- -1,
- -1,
- SWT.IMAGE_JPEG,
- 0,
- 0,
- 0,
- 0);
-}
-int nextBit() {
- if (currentBitCount != 0) {
- currentBitCount--;
- currentByte *= 2;
- if (currentByte > 255) {
- currentByte -= 256;
- return 1;
- } else {
- return 0;
- }
- }
- bufferCurrentPosition++;
- if (bufferCurrentPosition >= 512) {
- resetInputBuffer();
- bufferCurrentPosition = 0;
- }
- currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
- currentBitCount = 8;
- byte nextByte;
- if (bufferCurrentPosition == 511) {
- resetInputBuffer();
- currentBitCount = 8;
- nextByte = dataBuffer[0];
- } else {
- nextByte = dataBuffer[bufferCurrentPosition + 1];
- }
- if (currentByte == 0xFF) {
- if (nextByte == 0) {
- bufferCurrentPosition ++;
- currentBitCount--;
- currentByte *= 2;
- if (currentByte > 255) {
- currentByte -= 256;
- return 1;
- } else {
- return 0;
- }
- } else {
- if ((nextByte & 0xFF) + 0xFF00 == DNL) {
- getDNL();
- return 0;
- } else {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return 0;
- }
- }
- } else {
- currentBitCount--;
- currentByte *= 2;
- if (currentByte > 255) {
- currentByte -= 256;
- return 1;
- } else {
- return 0;
- }
- }
-}
-void processRestartInterval() {
- do {
- bufferCurrentPosition++;
- if (bufferCurrentPosition > 511) {
- resetInputBuffer();
- bufferCurrentPosition = 0;
- }
- currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
- } while (currentByte != 0xFF);
- while (currentByte == 0xFF) {
- bufferCurrentPosition++;
- if (bufferCurrentPosition > 511) {
- resetInputBuffer();
- bufferCurrentPosition = 0;
- }
- currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
- }
- if (currentByte != ((RST0 + nextRestartNumber) % 256)) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- bufferCurrentPosition++;
- if (bufferCurrentPosition > 511) {
- resetInputBuffer();
- bufferCurrentPosition = 0;
- }
- currentByte = dataBuffer[bufferCurrentPosition] & 0xFF;
- currentBitCount = 8;
- restartsToGo = restartInterval;
- nextRestartNumber = (nextRestartNumber + 1) % 8;
- precedingDCs = new int[4];
- eobrun = 0;
-}
-/* Process all markers until a frame header, scan header, or EOI is found. */
-JPEGSegment processTables() {
- while (true) {
- JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream);
- if (jpegSegment == null) return null;
- JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference);
- if (sof.verify()) {
- return jpegSegment;
- }
- int marker = jpegSegment.getSegmentMarker();
- switch (marker) {
- case SOI: // there should only be one SOI per file
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- case EOI:
- case SOS:
- return jpegSegment;
- case DQT:
- getDQT();
- break;
- case DHT:
- getDHT();
- break;
- case DAC:
- getDAC();
- break;
- case DRI:
- getDRI();
- break;
- case APP0:
- getAPP0();
- break;
- case COM:
- getCOM();
- break;
- default:
- skipSegmentFrom(inputStream);
-
- }
- }
-}
-void quantizeData(int[] dataUnit, int iComp) {
- int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]];
- for (int i = 0; i < dataUnit.length; i++) {
- int zzIndex = ZigZag8x8[i];
- int data = dataUnit[zzIndex];
- int absData = data < 0 ? 0 - data : data;
- int qValue = qTable[i];
- int q2 = qValue / 2;
- absData += q2;
- if (absData < qValue) {
- dataUnit[zzIndex] = 0;
- } else {
- absData /= qValue;
- if (data >= 0) {
- dataUnit[zzIndex] = absData;
- } else {
- dataUnit[zzIndex] = 0 - absData;
- }
- }
- }
-}
-int receive(int nBits) {
- int v = 0;
- for (int i = 0; i < nBits; i++) {
- v = v * 2 + nextBit();
- }
- return v;
-}
-void resetInputBuffer() {
- if (dataBuffer == null) {
- dataBuffer = new byte[512];
- }
- try {
- inputStream.read(dataBuffer);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- currentBitCount = 0;
- bufferCurrentPosition = -1;
-}
-void resetOutputBuffer() {
- if (dataBuffer == null) {
- dataBuffer = new byte[512];
- } else {
- try {
- outputStream.write(dataBuffer, 0, bufferCurrentPosition);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
- bufferCurrentPosition = 0;
-}
-static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) {
- byte[] byteArray = new byte[2];
- try {
- while (true) {
- if (byteStream.read(byteArray, 0, 1) != 1) return null;
- if (byteArray[0] == (byte) 0xFF) {
- if (byteStream.read(byteArray, 1, 1) != 1) return null;
- if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) {
- byteStream.unread(byteArray);
- return new JPEGSegment(byteArray);
- }
- }
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return null;
-}
-PaletteData setUpPalette() {
- if (nComponents == 1) {
- RGB[] entries = new RGB[256];
- for (int i = 0; i < 256; i++) {
- entries[i] = new RGB(i, i, i);
- }
- return new PaletteData(entries);
- }
- return new PaletteData(0xFF, 0xFF00, 0xFF0000);
-}
-static void skipSegmentFrom(LEDataInputStream byteStream) {
- try {
- byte[] byteArray = new byte[4];
- JPEGSegment jpegSegment = new JPEGSegment(byteArray);
-
- if (byteStream.read(byteArray) != byteArray.length) {
- throw new SWTError(SWT.ERROR_INVALID_IMAGE);
- }
- if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) {
- throw new SWTError(SWT.ERROR_INVALID_IMAGE);
- }
- int delta = jpegSegment.getSegmentLength() - 2;
- byteStream.skip(delta);
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) {
- byte[] compImage = imageComponents[iComp];
- int[] frameComponent = frameComponents[componentIds[iComp]];
- int compWidth = frameComponent[CW];
- int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE);
- int srcIndex = 0;
- for (int i = 0; i < DCTSIZE; i++) {
- for (int col = 0; col < DCTSIZE; col++) {
- int x = dataUnit[srcIndex] + 128;
- if (x < 0) {
- x = 0;
- } else {
- if (x > 255) x = 255;
- }
- compImage[destIndex + col] = (byte)x;
- srcIndex++;
- }
- destIndex += compWidth;
- }
-}
-void unloadIntoByteStream(ImageData image) {
- if (!new JPEGStartOfImage().writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- JPEGAppn appn = new JPEGAppn(new byte[] {(byte)0xFF, (byte)0xE0, 0, 0x10, 0x4A, 0x46, 0x49, 0x46, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0});
- if (!appn.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- quantizationTables = new int[4][];
- JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable();
- chromDQT.scaleBy(encoderQFactor);
- int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys();
- int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues();
- for (int i = 0; i < jpegDQTKeys.length; i++) {
- quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
- }
- JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable();
- lumDQT.scaleBy(encoderQFactor);
- jpegDQTKeys = lumDQT.getQuantizationTablesKeys();
- jpegDQTValues = lumDQT.getQuantizationTablesValues();
- for (int i = 0; i < jpegDQTKeys.length; i++) {
- quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i];
- }
- if (!lumDQT.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- if (!chromDQT.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- int frameLength, scanLength, precision;
- int[][] frameParams, scanParams;
- if (image.depth == 1) {
- frameLength = 11;
- frameParams = new int[1][];
- frameParams[0] = new int[] {1, 1, 1, 0, 0};
- scanParams = new int[1][];
- scanParams[0] = new int[] {0, 0};
- scanLength = 8;
- nComponents = 1;
- precision = 1;
- } else {
- frameLength = 17;
- frameParams = new int[3][];
- frameParams[0] = new int[] {0, 2, 2, 0, 0};
- frameParams[1] = new int[] {1, 1, 1, 0, 0};
- frameParams[2] = new int[] {1, 1, 1, 0, 0};
- scanParams = new int[3][];
- scanParams[0] = new int[] {0, 0};
- scanParams[1] = new int[] {1, 1};
- scanParams[2] = new int[] {1, 1};
- scanLength = 12;
- nComponents = 3;
- precision = 8;
- }
- imageWidth = image.width;
- imageHeight = image.height;
- frameHeader = new JPEGFrameHeader(new byte[19]);
- frameHeader.setSegmentMarker(SOF0);
- frameHeader.setSegmentLength(frameLength);
- frameHeader.setSamplePrecision(precision);
- frameHeader.setSamplesPerLine(imageWidth);
- frameHeader.setNumberOfLines(imageHeight);
- frameHeader.setNumberOfImageComponents(nComponents);
- frameHeader.componentParameters = frameParams;
- frameHeader.componentIdentifiers = new int[] {0, 1, 2};
- frameHeader.initializeContents();
- if (!frameHeader.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- frameComponents = frameParams;
- componentIds = frameHeader.componentIdentifiers;
- maxH = frameHeader.getMaxHFactor();
- maxV = frameHeader.getMaxVFactor();
- int mcuWidth = maxH * DCTSIZE;
- int mcuHeight = maxV * DCTSIZE;
- interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth;
- interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight;
- acHuffmanTables = new JPEGHuffmanTable[4];
- dcHuffmanTables = new JPEGHuffmanTable[4];
- JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] {
- JPEGHuffmanTable.getDefaultDCLuminanceTable(),
- JPEGHuffmanTable.getDefaultDCChrominanceTable(),
- JPEGHuffmanTable.getDefaultACLuminanceTable(),
- JPEGHuffmanTable.getDefaultACChrominanceTable()
- };
- for (int i = 0; i < dhtTables.length; i++) {
- JPEGHuffmanTable dhtTable = dhtTables[i];
- if (!dhtTable.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- JPEGHuffmanTable[] allTables = dhtTable.getAllTables();
- for (int j = 0; j < allTables.length; j++) {
- JPEGHuffmanTable huffmanTable = allTables[j];
- if (huffmanTable.getTableClass() == 0) {
- dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
- } else {
- acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable;
- }
- }
- }
- precedingDCs = new int[4];
- scanHeader = new JPEGScanHeader(new byte[14]);
- scanHeader.setSegmentMarker(SOS);
- scanHeader.setSegmentLength(scanLength);
- scanHeader.setNumberOfImageComponents(nComponents);
- scanHeader.setStartOfSpectralSelection(0);
- scanHeader.setEndOfSpectralSelection(63);
- scanHeader.componentParameters = scanParams;
- scanHeader.initializeContents();
- if (!scanHeader.writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
- convertImageToYCbCr(image);
- resetOutputBuffer();
- currentByte = 0;
- currentBitCount = 0;
- encodeScan();
- if (!new JPEGEndOfImage().writeToStream(outputStream)) {
- SWT.error(SWT.ERROR_IO);
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import java.io.*; + +final class JPEGFileFormat extends FileFormat { + int restartInterval; + JPEGFrameHeader frameHeader; + int imageWidth, imageHeight; + int interleavedMcuCols, interleavedMcuRows; + int maxV, maxH; + boolean progressive; + int samplePrecision; + int nComponents; + int[][] frameComponents; + int[] componentIds; + byte[][] imageComponents; + int[] dataUnit; + int[][][] dataUnits; + int[] precedingDCs; + JPEGScanHeader scanHeader; + byte[] dataBuffer; + int currentBitCount; + int bufferCurrentPosition; + int restartsToGo; + int nextRestartNumber; + JPEGArithmeticConditioningTable arithmeticTables; + JPEGHuffmanTable[] acHuffmanTables; + JPEGHuffmanTable[] dcHuffmanTables; + int[][] quantizationTables; + int currentByte; + int decoderQFactor; + int encoderQFactor = 75; + int eobrun = 0; + /* JPEGConstants */ + public static final int DCTSIZE = 8; + public static final int DCTSIZESQR = 64; + /* JPEGFixedPointConstants */ + public static final int FIX_0_899976223 = 7373; + public static final int FIX_1_961570560 = 16069; + public static final int FIX_2_053119869 = 16819; + public static final int FIX_0_298631336 = 2446; + public static final int FIX_1_847759065 = 15137; + public static final int FIX_1_175875602 = 9633; + public static final int FIX_3_072711026 = 25172; + public static final int FIX_0_765366865 = 6270; + public static final int FIX_2_562915447 = 20995; + public static final int FIX_0_541196100 = 4433; + public static final int FIX_0_390180644 = 3196; + public static final int FIX_1_501321110 = 12299; + /* JPEGMarkerCodes */ + public static final int APP0 = 0xFFE0; + public static final int APP15 = 0xFFEF; + public static final int COM = 0xFFFE; + public static final int DAC = 0xFFCC; + public static final int DHP = 0xFFDE; + public static final int DHT = 0xFFC4; + public static final int DNL = 0xFFDC; + public static final int DRI = 0xFFDD; + public static final int DQT = 0xFFDB; + public static final int EOI = 0xFFD9; + public static final int EXP = 0xFFDF; + public static final int JPG = 0xFFC8; + public static final int JPG0 = 0xFFF0; + public static final int JPG13 = 0xFFFD; + public static final int RST0 = 0xFFD0; + public static final int RST1 = 0xFFD1; + public static final int RST2 = 0xFFD2; + public static final int RST3 = 0xFFD3; + public static final int RST4 = 0xFFD4; + public static final int RST5 = 0xFFD5; + public static final int RST6 = 0xFFD6; + public static final int RST7 = 0xFFD7; + public static final int SOF0 = 0xFFC0; + public static final int SOF1 = 0xFFC1; + public static final int SOF2 = 0xFFC2; + public static final int SOF3 = 0xFFC3; + public static final int SOF5 = 0xFFC5; + public static final int SOF6 = 0xFFC6; + public static final int SOF7 = 0xFFC7; + public static final int SOF9 = 0xFFC9; + public static final int SOF10 = 0xFFCA; + public static final int SOF11 = 0xFFCB; + public static final int SOF13 = 0xFFCD; + public static final int SOF14 = 0xFFCE; + public static final int SOF15 = 0xFFCF; + public static final int SOI = 0xFFD8; + public static final int SOS = 0xFFDA; + public static final int TEM = 0xFF01; + /* JPEGFrameComponentParameterConstants */ + public static final int TQI = 0; + public static final int HI = 1; + public static final int VI = 2; + public static final int CW = 3; + public static final int CH = 4; + /* JPEGScanComponentParameterConstants */ + public static final int DC = 0; + public static final int AC = 1; + /* JFIF Component Constants */ + public static final int ID_Y = 1 - 1; + public static final int ID_CB = 2 - 1; + public static final int ID_CR = 3 - 1; + + public static final int[] ExtendTest = { + 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768, 65536, 131072, 262144 + }; + public static final int[] ExtendOffset = new int[] { + 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, + -4095, -8191, -16383, -32767, -65535, -131071, -262143 + }; + public static final int[] ZigZag8x8 = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 + }; + public static int[] CrRTable, CbBTable, CrGTable, CbGTable; + public static int[] RYTable, GYTable, BYTable, + RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable; + static { + initialize(); + } +void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) { + int srcWidth = image.width; + int srcHeight = image.height; + int vhFactor = maxV * maxH; + int[] frameComponent; + imageComponents = new byte[nComponents][]; + for (int i = 0; i < nComponents; i++) { + frameComponent = frameComponents[componentIds[i]]; + imageComponents[i] = new byte[frameComponent[CW] * frameComponent[CH]]; + } + frameComponent = frameComponents[componentIds[ID_Y]]; + for (int yPos = 0; yPos < srcHeight; yPos++) { + int srcOfs = yPos * srcWidth; + int dstOfs = yPos * frameComponent[CW]; + System.arraycopy(dataYComp, srcOfs, imageComponents[ID_Y], dstOfs, srcWidth); + } + frameComponent = frameComponents[componentIds[ID_CB]]; + for (int yPos = 0; yPos < srcHeight / maxV; yPos++) { + int destRowIndex = yPos * frameComponent[CW]; + for (int xPos = 0; xPos < srcWidth / maxH; xPos++) { + int sum = 0; + for (int iv = 0; iv < maxV; iv++) { + int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH); + for (int ih = 0; ih < maxH; ih++) { + sum += dataCbComp[srcIndex + ih] & 0xFF; + } + } + imageComponents[ID_CB][destRowIndex + xPos] = (byte)(sum / vhFactor); + } + } + frameComponent = frameComponents[componentIds[ID_CR]]; + for (int yPos = 0; yPos < srcHeight / maxV; yPos++) { + int destRowIndex = yPos * frameComponent[CW]; + for (int xPos = 0; xPos < srcWidth / maxH; xPos++) { + int sum = 0; + for (int iv = 0; iv < maxV; iv++) { + int srcIndex = (yPos * maxV + iv) * srcWidth + (xPos * maxH); + for (int ih = 0; ih < maxH; ih++) { + sum += dataCrComp[srcIndex + ih] & 0xFF; + } + } + imageComponents[ID_CR][destRowIndex + xPos] = (byte)(sum / vhFactor); + } + } + for (int iComp = 0; iComp < nComponents; iComp++) { + byte[] imageComponent = imageComponents[iComp]; + frameComponent = frameComponents[componentIds[iComp]]; + int hFactor = frameComponent[HI]; + int vFactor = frameComponent[VI]; + int componentWidth = frameComponent[CW]; + int componentHeight = frameComponent[CH]; + int compressedWidth = srcWidth / (maxH / hFactor); + int compressedHeight = srcHeight / (maxV / vFactor); + if (compressedWidth < componentWidth) { + int delta = componentWidth - compressedWidth; + for (int yPos = 0; yPos < compressedHeight; yPos++) { + int dstOfs = ((yPos + 1) * componentWidth - delta); + int dataValue = imageComponent[dstOfs - 1] & 0xFF; + for (int i = 0; i < delta; i++) { + imageComponent[dstOfs + i] = (byte)dataValue; + } + } + } + if (compressedHeight < componentHeight) { + int srcOfs = (compressedHeight - 1) * componentWidth; + for (int yPos = compressedHeight; yPos <= componentHeight; yPos++) { + int dstOfs = (yPos - 1) * componentWidth; + System.arraycopy(imageComponent, srcOfs, imageComponent, dstOfs, componentWidth); + } + } + } +} +void convert4BitRGBToYCbCr(ImageData image) { + RGB[] rgbs = image.getRGBs(); + int paletteSize = rgbs.length; + byte[] yComp = new byte[paletteSize]; + byte[] cbComp = new byte[paletteSize]; + byte[] crComp = new byte[paletteSize]; + int srcWidth = image.width; + int srcHeight = image.height; + for (int i = 0; i < paletteSize; i++) { + RGB color = rgbs[i]; + int r = color.red; + int g = color.green; + int b = color.blue; + int n = RYTable[r] + GYTable[g] + BYTable[b]; + yComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) yComp[i]--; + n = RCbTable[r] + GCbTable[g] + BCbTable[b]; + cbComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) cbComp[i]--; + n = RCrTable[r] + GCrTable[g] + BCrTable[b]; + crComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) crComp[i]--; + } + int bSize = srcWidth * srcHeight; + byte[] dataYComp = new byte[bSize]; + byte[] dataCbComp = new byte[bSize]; + byte[] dataCrComp = new byte[bSize]; + byte[] origData = image.data; + for (int yPos = 0; yPos < srcHeight; yPos++) { + for (int xPos = 0; xPos < srcWidth / 2; xPos++) { + int srcIndex = yPos * (srcWidth / 2) + xPos; + int dstIndex = yPos * srcWidth + (xPos * 2); + int value2 = origData[srcIndex] & 0xFF; + int value1 = value2 / 16; + value2 = value2 % 16; + dataYComp[dstIndex] = yComp[value1]; + dataCbComp[dstIndex] = cbComp[value1]; + dataCrComp[dstIndex] = crComp[value1]; + dataYComp[dstIndex + 1] = yComp[value2]; + dataCbComp[dstIndex + 1] = cbComp[value2]; + dataCrComp[dstIndex + 1] = crComp[value2]; + } + } + compress(image, dataYComp, dataCbComp, dataCrComp); +} +void convert8BitRGBToYCbCr(ImageData image) { + RGB[] rgbs = image.getRGBs(); + int paletteSize = rgbs.length; + byte[] yComp = new byte[paletteSize]; + byte[] cbComp = new byte[paletteSize]; + byte[] crComp = new byte[paletteSize]; + int srcWidth = image.width; + int srcHeight = image.height; + for (int i = 0; i < paletteSize; i++) { + RGB color = rgbs[i]; + int r = color.red; + int g = color.green; + int b = color.blue; + int n = RYTable[r] + GYTable[g] + BYTable[b]; + yComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) yComp[i]--; + n = RCbTable[r] + GCbTable[g] + BCbTable[b]; + cbComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) cbComp[i]--; + n = RCrTable[r] + GCrTable[g] + BCrTable[b]; + crComp[i] = (byte)(n / 65536); + if ((n < 0) && (n % 65536 != 0)) crComp[i]--; + } + int dstWidth = image.width; + int dstHeight = srcHeight; + int stride = (srcWidth + 3) / 4 * 4; + int bSize = dstWidth * dstHeight; + byte[] dataYComp = new byte[bSize]; + byte[] dataCbComp = new byte[bSize]; + byte[] dataCrComp = new byte[bSize]; + byte[] origData = image.data; + for (int yPos = 0; yPos < srcHeight; yPos++) { + int srcRowIndex = yPos * stride; + int dstRowIndex = yPos * dstWidth; + for (int xPos = 0; xPos < srcWidth; xPos++) { + int value = origData[srcRowIndex + xPos] & 0xFF; + int dstIndex = dstRowIndex + xPos; + dataYComp[dstIndex] = yComp[value]; + dataCbComp[dstIndex] = cbComp[value]; + dataCrComp[dstIndex] = crComp[value]; + } + } + compress(image, dataYComp, dataCbComp, dataCrComp); +} +byte[] convertCMYKToRGB() { + /* Unsupported CMYK format. Answer an empty byte array. */ + return new byte[0]; +} +void convertImageToYCbCr(ImageData image) { + switch (image.depth) { + case 4: + convert4BitRGBToYCbCr(image); + return; + case 8: + convert8BitRGBToYCbCr(image); + return; + case 16: + case 24: + case 32: + convertMultiRGBToYCbCr(image); + return; + default: + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + } + return; +} +void convertMultiRGBToYCbCr(ImageData image) { + int srcWidth = image.width; + int srcHeight = image.height; + int bSize = srcWidth * srcHeight; + byte[] dataYComp = new byte[bSize]; + byte[] dataCbComp = new byte[bSize]; + byte[] dataCrComp = new byte[bSize]; + PaletteData palette = image.palette; + int[] buffer = new int[srcWidth]; + if (palette.isDirect) { + int redMask = palette.redMask; + int greenMask = palette.greenMask; + int blueMask = palette.blueMask; + int redShift = palette.redShift; + int greenShift = palette.greenShift; + int blueShift = palette.blueShift; + for (int yPos = 0; yPos < srcHeight; yPos++) { + image.getPixels(0, yPos, srcWidth, buffer, 0); + int dstRowIndex = yPos * srcWidth; + for (int xPos = 0; xPos < srcWidth; xPos++) { + int pixel = buffer[xPos]; + int dstDataIndex = dstRowIndex + xPos; + int r = pixel & redMask; + r = (redShift < 0) ? r >>> -redShift : r << redShift; + int g = pixel & greenMask; + g = (greenShift < 0) ? g >>> -greenShift : g << greenShift; + int b = pixel & blueMask; + b = (blueShift < 0) ? b >>> -blueShift : b << blueShift; + dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) / 65536); + dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536); + dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536); + } + } + } else { + for (int yPos = 0; yPos < srcHeight; yPos++) { + image.getPixels(0, yPos, srcWidth, buffer, 0); + int dstRowIndex = yPos * srcWidth; + for (int xPos = 0; xPos < srcWidth; xPos++) { + int pixel = buffer[xPos]; + int dstDataIndex = dstRowIndex + xPos; + RGB rgb = palette.getRGB(pixel); + int r = rgb.red; + int g = rgb.green; + int b = rgb.blue; + dataYComp[dstDataIndex] = (byte)((RYTable[r] + GYTable[g] + BYTable[b]) / 65536); + dataCbComp[dstDataIndex] = (byte)((RCbTable[r] + GCbTable[g] + BCbTable[b]) / 65536); + dataCrComp[dstDataIndex] = (byte)((RCrTable[r] + GCrTable[g] + BCrTable[b]) / 65536); + } + } + } + compress(image, dataYComp, dataCbComp, dataCrComp); +} +byte[] convertYToRGB() { + int compWidth = frameComponents[componentIds[ID_Y]][CW]; + int bytesPerLine = (((imageWidth * 8 + 7) / 8) + 3) / 4 * 4; + byte[] data = new byte[bytesPerLine * imageHeight]; + byte[] yComp = imageComponents[ID_Y]; + int destIndex = 0; + for (int i = 0; i < imageHeight; i++) { + int srcIndex = i * compWidth; + for (int j = 0; j < bytesPerLine; j++) { + int y = yComp[srcIndex] & 0xFF; + if (y < 0) { + y = 0; + } else { + if (y > 255) y = 255; + } + if (j >= imageWidth) { + y = 0; + } + data[destIndex] = (byte)y; + srcIndex++; + destIndex++; + } + } + return data; +} +byte[] convertYCbCrToRGB() { + /** + * Convert existing image components into an RGB format. + * YCbCr is defined per CCIR 601-1, except that Cb and Cr are + * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. + * The conversion equations to be implemented are therefore + * R = Y + 1.40200 * Cr + * G = Y - 0.34414 * Cb - 0.71414 * Cr + * B = Y + 1.77200 * Cb + * where Cb and Cr represent the incoming values less MAXJSAMPLE/2. + * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) + * + * To avoid floating-point arithmetic, we represent the fractional constants + * as integers scaled up by 2^16 (about 4 digits precision); we have to divide + * the products by 2^16, with appropriate rounding, to get the correct answer. + * Notice that Y, being an integral input, does not contribute any fraction + * so it need not participate in the rounding. + * + * For even more speed, we avoid doing any multiplications in the inner loop + * by precalculating the constants times Cb and Cr for all possible values. + * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); + * for 12-bit samples it is still acceptable. It's not very reasonable for + * 16-bit samples, but if you want lossless storage you shouldn't be changing + * colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; the + * values for the G calculation are left scaled up, since we must add them + * together before rounding. + */ + int bSize = imageWidth * imageHeight * nComponents; + byte[] rgbData = new byte[bSize]; + int destIndex = 0; + expandImageComponents(); + byte[] yComp = imageComponents[ID_Y]; + byte[] cbComp = imageComponents[ID_CB]; + byte[] crComp = imageComponents[ID_CR]; + int compWidth = frameComponents[componentIds[ID_Y]][CW]; + for (int v = 0; v < imageHeight; v++) { + int srcIndex = v * compWidth; + for (int i = 0; i < imageWidth; i++) { + int y = yComp[srcIndex] & 0xFF; + int cb = cbComp[srcIndex] & 0xFF; + int cr = crComp[srcIndex] & 0xFF; + int r = y + CrRTable[cr]; + int g = y + ((CbGTable[cb] + CrGTable[cr]) / 65536); + int b = y + CbBTable[cb]; + if (r < 0) { + r = 0; + } else { + if (r > 255) r = 255; + } + if (g < 0) { + g = 0; + } else { + if (g > 255) g = 255; + } + if (b < 0) { + b = 0; + } else { + if (b > 255) b = 255; + } + rgbData[destIndex] = (byte)b; + rgbData[destIndex + 1] = (byte)g; + rgbData[destIndex + 2] = (byte)r; + destIndex += 3; + srcIndex++; + } + } + return rgbData; +} +byte[] convertYIQToRGB() { + /* Unsupported CMYK format. Answer an empty byte array. */ + return new byte[0]; +} +void decodeACCoefficients(int[] dataUnit, int iComp) { + int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; + JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; + int k = 1; + while (k < 64) { + int rs = decodeUsingTable(acTable); + int r = rs >> 4; + int s = rs & 0xF; + if (s == 0) { + if (r == 15) { + k += 16; + } else { + break; + } + } else { + k += r; + int bits = receive(s); + dataUnit[ZigZag8x8[k]] = extendBy(bits, s); + k++; + } + } +} +void decodeACFirstCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) { + if (eobrun > 0) { + eobrun--; + return; + } + int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; + JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; + int k = start; + while (k <= end) { + int rs = decodeUsingTable(acTable); + int r = rs >> 4; + int s = rs & 0xF; + if (s == 0) { + if (r == 15) { + k += 16; + } else { + eobrun = (1 << r) + receive(r) - 1; + break; + } + } else { + k += r; + int bits = receive(s); + dataUnit[ZigZag8x8[k]] = extendBy(bits, s) << approxBit; + k++; + } + } +} +void decodeACRefineCoefficients(int[] dataUnit, int iComp, int start, int end, int approxBit) { + int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; + JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; + int k = start; + while (k <= end) { + if (eobrun > 0) { + while (k <= end) { + int zzIndex = ZigZag8x8[k]; + if (dataUnit[zzIndex] != 0) { + dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); + } + k++; + } + eobrun--; + } else { + int rs = decodeUsingTable(acTable); + int r = rs >> 4; + int s = rs & 0xF; + if (s == 0) { + if (r == 15) { + int zeros = 0; + while (zeros < 16 && k <= end) { + int zzIndex = ZigZag8x8[k]; + if (dataUnit[zzIndex] != 0) { + dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); + } else { + zeros++; + } + k++; + } + } else { + eobrun = (1 << r) + receive(r); + } + } else { + int bit = receive(s); + int zeros = 0; + int zzIndex = ZigZag8x8[k]; + while ((zeros < r || dataUnit[zzIndex] != 0) && k <= end) { + if (dataUnit[zzIndex] != 0) { + dataUnit[zzIndex] = refineAC(dataUnit[zzIndex], approxBit); + } else { + zeros++; + } + k++; + zzIndex = ZigZag8x8[k]; + } + if (bit != 0) { + dataUnit[zzIndex] = 1 << approxBit; + } else { + dataUnit[zzIndex] = -1 << approxBit; + } + k++; + } + } + } +} +int refineAC(int ac, int approxBit) { + if (ac > 0) { + int bit = nextBit(); + if (bit != 0) { + ac = ac + (1 << approxBit); + } + } else if (ac < 0) { + int bit = nextBit(); + if (bit != 0) { + ac = ac + (-1 << approxBit); + } + } + return ac; +} +void decodeDCCoefficient(int[] dataUnit, int iComp, boolean first, int approxBit) { + int[] sParams = scanHeader.componentParameters[componentIds[iComp]]; + JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]]; + int lastDC = 0; + if (progressive && !first) { + int bit = nextBit(); + lastDC = dataUnit[0] + (bit << approxBit); + } else { + lastDC = precedingDCs[iComp]; + int nBits = decodeUsingTable(dcTable); + if (nBits != 0) { + int bits = receive(nBits); + int diff = extendBy(bits, nBits); + lastDC = lastDC + diff; + precedingDCs[iComp] = lastDC; + } + if (progressive) { + lastDC = lastDC << approxBit; + } + } + dataUnit[0] = lastDC; +} +void dequantize(int[] dataUnit, int iComp) { + int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]]; + for (int i = 0; i < dataUnit.length; i++) { + int zzIndex = ZigZag8x8[i]; + dataUnit[zzIndex] = dataUnit[zzIndex] * qTable[i]; + } +} +byte[] decodeImageComponents() { + int[] compIds = new int[nComponents]; + int compIdsIndex = 0; + for (int i = 0; i < nComponents; i++) { + compIds[compIdsIndex] = i + 1; + compIdsIndex++; + } + if ((compIds.length == 3) && + (compIds[0] == 1) && + (compIds[1] == 2) && + (compIds[2] == 3)) { + return convertYCbCrToRGB(); + } + if ((compIds.length == 3) && + (compIds[0] == 1) && + (compIds[1] == 4) && + (compIds[2] == 5)) { + return convertYIQToRGB(); + } + if (compIds.length == 4) { + return convertCMYKToRGB(); + } + return convertYToRGB(); +} +void decodeMCUAtXAndY(int xmcu, int ymcu, int nComponentsInScan, boolean first, int start, int end, int approxBit) { + for (int iComp = 0; iComp < nComponentsInScan; iComp++) { + int scanComponent = iComp; + while (scanHeader.componentParameters[componentIds[scanComponent]] == null) { + scanComponent++; + } + int[] frameComponent = frameComponents[componentIds[scanComponent]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + if (nComponentsInScan == 1) { + hi = 1; + vi = 1; + } + int compWidth = frameComponent[CW]; + for (int ivi = 0; ivi < vi; ivi++) { + for (int ihi = 0; ihi < hi; ihi++) { + if (progressive) { + // Progressive: First scan - create a new data unit. + // Subsequent scans - refine the existing data unit. + int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi; + dataUnit = dataUnits[scanComponent][index]; + if (dataUnit == null) { + dataUnit = new int[64]; + dataUnits[scanComponent][index] = dataUnit; + } + } else { + // Sequential: Clear and reuse the data unit buffer. + for (int i = 0; i < dataUnit.length; i++) { + dataUnit[i] = 0; + } + } + if (!progressive || scanHeader.isDCProgressiveScan()) { + decodeDCCoefficient(dataUnit, scanComponent, first, approxBit); + } + if (!progressive) { + decodeACCoefficients(dataUnit, scanComponent); + } else { + if (scanHeader.isACProgressiveScan()) { + if (first) { + decodeACFirstCoefficients(dataUnit, scanComponent, start, end, approxBit); + } else { + decodeACRefineCoefficients(dataUnit, scanComponent, start, end, approxBit); + } + } + if (loader.hasListeners()) { + // Dequantization, IDCT, up-sampling and color conversion + // are done on a copy of the coefficient data in order to + // display the image incrementally. + int[] temp = dataUnit; + dataUnit = new int[64]; + System.arraycopy(temp, 0, dataUnit, 0, 64); + } + } + if (!progressive || (progressive && loader.hasListeners())) { + dequantize(dataUnit, scanComponent); + inverseDCT(dataUnit); + storeData(dataUnit, scanComponent, xmcu, ymcu, hi, ihi, vi, ivi); + } + } + } + } +} +void decodeScan() { + if (progressive && !scanHeader.verifyProgressiveScan()) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + int nComponentsInScan = scanHeader.getNumberOfImageComponents(); + int mcuRowsInScan = interleavedMcuRows; + int mcusPerRow = interleavedMcuCols; + if (nComponentsInScan == 1) { + // Non-interleaved. + int scanComponent = 0; + while (scanHeader.componentParameters[componentIds[scanComponent]] == null) { + scanComponent++; + } + int[] frameComponent = frameComponents[componentIds[scanComponent]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + int mcuWidth = DCTSIZE * maxH / hi; + int mcuHeight = DCTSIZE * maxV / vi; + mcusPerRow = (imageWidth + mcuWidth - 1) / mcuWidth; + mcuRowsInScan = (imageHeight + mcuHeight - 1) / mcuHeight; + } + boolean first = scanHeader.isFirstScan(); + int start = scanHeader.getStartOfSpectralSelection(); + int end = scanHeader.getEndOfSpectralSelection(); + int approxBit = scanHeader.getApproxBitPositionLow(); + restartsToGo = restartInterval; + nextRestartNumber = 0; + for (int ymcu = 0; ymcu < mcuRowsInScan; ymcu++) { + for (int xmcu = 0; xmcu < mcusPerRow; xmcu++) { + if (restartInterval != 0) { + if (restartsToGo == 0) processRestartInterval(); + restartsToGo--; + } + decodeMCUAtXAndY(xmcu, ymcu, nComponentsInScan, first, start, end, approxBit); + } + } +} +int decodeUsingTable(JPEGHuffmanTable huffmanTable) { + int i = 0; + int[] maxCodes = huffmanTable.getDhMaxCodes(); + int[] minCodes = huffmanTable.getDhMinCodes(); + int[] valPtrs = huffmanTable.getDhValPtrs(); + int[] huffVals = huffmanTable.getDhValues(); + int code = nextBit(); + while (code > maxCodes[i]) { + code = code * 2 + nextBit(); + i++; + } + int j = valPtrs[i]; + j = j + code - minCodes[i]; + return huffVals[j]; +} +void emit(int huffCode, int nBits) { + if (nBits == 0) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + int[] power2m1 = new int[] { + 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, + 16383, 32767, 65535, 131125 + }; + int code = (huffCode & power2m1[nBits - 1]) << (24 - nBits - currentBitCount); + byte[] codeBuffer = new byte[4]; + codeBuffer[0] = (byte)(code % 256); + codeBuffer[1] = (byte)((code / 256) % 256); + codeBuffer[2] = (byte)((code / 65536) % 256); + codeBuffer[3] = (byte)((code / 16777216) % 256); + int abs = nBits - (8 - currentBitCount); + if (abs < 0) abs = -abs; + if ((abs / 8) > 0) { + currentByte += codeBuffer[2]; + emitByte((byte)currentByte); + emitByte((byte)codeBuffer[1]); + currentByte = codeBuffer[0]; + currentBitCount += nBits - 16; + } else { + currentBitCount += nBits; + if (currentBitCount >= 8) { + currentByte += codeBuffer[2]; + emitByte((byte)currentByte); + currentByte = codeBuffer[1]; + currentBitCount -= 8; + } else { + currentByte += codeBuffer[2]; + } + } +} +void emitByte(byte byteValue) { + if (bufferCurrentPosition >= 512) { + resetOutputBuffer(); + } + dataBuffer[bufferCurrentPosition] = byteValue; + bufferCurrentPosition++; + if (byteValue == -1) { + emitByte((byte)0); + } +} +void encodeACCoefficients(int[] dataUnit, int iComp) { + int[] sParams = scanHeader.componentParameters[iComp]; + JPEGHuffmanTable acTable = acHuffmanTables[sParams[AC]]; + int[] ehCodes = acTable.ehCodes; + byte[] ehSizes = acTable.ehCodeLengths; + int r = 0; + int k = 1; + while (k < 64) { + k++; + int acValue = dataUnit[ZigZag8x8[k - 1]]; + if (acValue == 0) { + if (k == 64) { + emit(ehCodes[0], ehSizes[0] & 0xFF); + } else { + r++; + } + } else { + while (r > 15) { + emit(ehCodes[0xF0], ehSizes[0xF0] & 0xFF); + r -= 16; + } + if (acValue < 0) { + int absACValue = acValue; + if (absACValue < 0) absACValue = -absACValue; + int nBits = NBitsTable[absACValue]; + int rs = r * 16 + nBits; + emit(ehCodes[rs], ehSizes[rs] & 0xFF); + emit(0xFFFFFF - absACValue, nBits); + } else { + int nBits = NBitsTable[acValue]; + int rs = r * 16 + nBits; + emit(ehCodes[rs], ehSizes[rs] & 0xFF); + emit(acValue, nBits); + } + r = 0; + } + } +} +void encodeDCCoefficients(int[] dataUnit, int iComp) { + int[] sParams = scanHeader.componentParameters[iComp]; + JPEGHuffmanTable dcTable = dcHuffmanTables[sParams[DC]]; + int lastDC = precedingDCs[iComp]; + int dcValue = dataUnit[0]; + int diff = dcValue - lastDC; + precedingDCs[iComp] = dcValue; + if (diff < 0) { + int absDiff = 0 - diff; + int nBits = NBitsTable[absDiff]; + emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]); + emit(0xFFFFFF - absDiff, nBits); + } else { + int nBits = NBitsTable[diff]; + emit(dcTable.ehCodes[nBits], dcTable.ehCodeLengths[nBits]); + if (nBits != 0) { + emit(diff, nBits); + } + } +} +void encodeMCUAtXAndY(int xmcu, int ymcu) { + int nComponentsInScan = scanHeader.getNumberOfImageComponents(); + dataUnit = new int[64]; + for (int iComp = 0; iComp < nComponentsInScan; iComp++) { + int[] frameComponent = frameComponents[componentIds[iComp]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + for (int ivi = 0; ivi < vi; ivi++) { + for (int ihi = 0; ihi < hi; ihi++) { + extractData(dataUnit, iComp, xmcu, ymcu, ihi, ivi); + forwardDCT(dataUnit); + quantizeData(dataUnit, iComp); + encodeDCCoefficients(dataUnit, iComp); + encodeACCoefficients(dataUnit, iComp); + } + } + } +} +void encodeScan() { + for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) { + for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) { + encodeMCUAtXAndY(xmcu, ymcu); + } + } + if (currentBitCount != 0) { + emitByte((byte)currentByte); + } + resetOutputBuffer(); +} +void expandImageComponents() { + for (int iComp = 0; iComp < nComponents; iComp++) { + int[] frameComponent = frameComponents[componentIds[iComp]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + int upH = maxH / hi; + int upV = maxV / vi; + if ((upH * upV) > 1) { + byte[] component = imageComponents[iComp]; + int compWidth = frameComponent[CW]; + int compHeight = frameComponent[CH]; + int upCompWidth = compWidth * upH; + int upCompHeight = compHeight * upV; + RGB[] rgbs = new RGB[] { + new RGB(0,0,0), + new RGB(0x80,0,0), + new RGB(0,0x80,0), + new RGB(0x80,0x80,0), + new RGB(0,0,0x80), + new RGB(0x80,0,0x80), + new RGB(0,0x80,0x80), + new RGB(0xC0,0xC0,0xC0), + new RGB(0x80,0x80,0x80), + new RGB(0xFF,0,0), + new RGB(0,0xFF,0), + new RGB(0xFF,0xFF,0), + new RGB(0,0,0xFF), + new RGB(0xFF,0,0xFF), + new RGB(0,0xFF,0xFF), + new RGB(0xFF,0xFF,0xFF), + }; + ImageData src = new ImageData(compWidth, compHeight, 8, new PaletteData(rgbs), 4, component); + ImageData dest = src.scaledTo(upCompWidth, upCompHeight); + imageComponents[iComp] = dest.data; + } + } +} +int extendBy(int diff, int t) { + if (diff < ExtendTest[t]) { + return diff + ExtendOffset[t]; + } else { + return diff; + } +} +void extractData(int[] dataUnit, int iComp, int xmcu, int ymcu, int ihi, int ivi) { + byte[] compImage = imageComponents[iComp]; + int[] frameComponent = frameComponents[componentIds[iComp]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + int compWidth = frameComponent[CW]; + int srcIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE); + int destIndex = 0; + for (int i = 0; i < DCTSIZE; i++) { + for (int col = 0; col < DCTSIZE; col++) { + dataUnit[destIndex] = (compImage[srcIndex + col] & 0xFF) - 128; + destIndex++; + } + srcIndex += compWidth; + } +} +void forwardDCT(int[] dataUnit) { + for (int row = 0; row < 8; row++) { + int rIndex = row * DCTSIZE; + int tmp0 = dataUnit[rIndex] + dataUnit[rIndex + 7]; + int tmp7 = dataUnit[rIndex] - dataUnit[rIndex + 7]; + int tmp1 = dataUnit[rIndex + 1] + dataUnit[rIndex + 6]; + int tmp6 = dataUnit[rIndex + 1] - dataUnit[rIndex + 6]; + int tmp2 = dataUnit[rIndex + 2] + dataUnit[rIndex + 5]; + int tmp5 = dataUnit[rIndex + 2] - dataUnit[rIndex + 5]; + int tmp3 = dataUnit[rIndex + 3] + dataUnit[rIndex + 4]; + int tmp4 = dataUnit[rIndex + 3] - dataUnit[rIndex + 4]; + + /** + * Even part per LL&M figure 1 --- note that published figure + * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'. + */ + int tmp10 = tmp0 + tmp3; + int tmp13 = tmp0 - tmp3; + int tmp11 = tmp1 + tmp2; + int tmp12 = tmp1 - tmp2; + + dataUnit[rIndex] = (tmp10 + tmp11) * 4; + dataUnit[rIndex + 4] = (tmp10 - tmp11) * 4; + + int z1 = (tmp12 + tmp13) * FIX_0_541196100; + int scaleFactor1 = ExtendTest[11]; + int scaleFactor2 = ExtendTest[12]; + int n = z1 + (tmp13 * FIX_0_765366865) + scaleFactor1; + dataUnit[rIndex + 2] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 2]--; + n = z1 + (tmp12 * (0 - FIX_1_847759065)) + scaleFactor1; + dataUnit[rIndex + 6] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 6]--; + + /** + * Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + z1 = tmp4 + tmp7; + int z2 = tmp5 + tmp6; + int z3 = tmp4 + tmp6; + int z4 = tmp5 + tmp7; + int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3 + + tmp4 = tmp4 * FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7) + tmp5 = tmp5 * FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7) + tmp6 = tmp6 * FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7) + tmp7 = tmp7 * FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7) + z1 = z1 * (0 - FIX_0_899976223); // sqrt(2) * (c7-c3) + z2 = z2 * (0 - FIX_2_562915447); // sqrt(2) * (-c1-c3) + z3 = z3 * (0 - FIX_1_961570560); // sqrt(2) * (-c3-c5) + z4 = z4 * (0 - FIX_0_390180644); // sqrt(2) * (c5-c3) + + z3 = z3 + z5; + z4 = z4 + z5; + + n = tmp4 + z1 + z3 + scaleFactor1; + dataUnit[rIndex + 7] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 7]--; + n = tmp5 + z2 + z4 + scaleFactor1; + dataUnit[rIndex + 5] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 5]--; + n = tmp6 + z2 + z3 + scaleFactor1; + dataUnit[rIndex + 3] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 3]--; + n = tmp7 + z1 + z4 + scaleFactor1; + dataUnit[rIndex + 1] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[rIndex + 1]--; + } + + /** + * Pass 2: process columns. + * Note that we must descale the results by a factor of 8 == 2**3, + * and also undo the PASS1_BITS scaling. + */ + for (int col = 0; col < 8; col++) { + int c0 = col; + int c1 = col + 8; + int c2 = col + 16; + int c3 = col + 24; + int c4 = col + 32; + int c5 = col + 40; + int c6 = col + 48; + int c7 = col + 56; + int tmp0 = dataUnit[c0] + dataUnit[c7]; + int tmp7 = dataUnit[c0] - dataUnit[c7]; + int tmp1 = dataUnit[c1] + dataUnit[c6]; + int tmp6 = dataUnit[c1] - dataUnit[c6]; + int tmp2 = dataUnit[c2] + dataUnit[c5]; + int tmp5 = dataUnit[c2] - dataUnit[c5]; + int tmp3 = dataUnit[c3] + dataUnit[c4]; + int tmp4 = dataUnit[c3] - dataUnit[c4]; + + /** + * Even part per LL&M figure 1 --- note that published figure + * is faulty; rotator 'sqrt(2)*c1' should be 'sqrt(2)*c6'. + */ + int tmp10 = tmp0 + tmp3; + int tmp13 = tmp0 - tmp3; + int tmp11 = tmp1 + tmp2; + int tmp12 = tmp1 - tmp2; + + int scaleFactor1 = ExtendTest[5]; + int scaleFactor2 = ExtendTest[6]; + int n = tmp10 + tmp11 + scaleFactor1; + dataUnit[c0] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c0]--; + n = tmp10 - tmp11 + scaleFactor1; + dataUnit[c4] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c4]--; + + int z1 = (tmp12 + tmp13) * FIX_0_541196100; + scaleFactor1 = ExtendTest[18]; + scaleFactor2 = ExtendTest[19]; + n = z1 + (tmp13 * FIX_0_765366865) + scaleFactor1; + dataUnit[c2] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c2]--; + n = z1 + (tmp12 * (0 - FIX_1_847759065)) + scaleFactor1; + dataUnit[c6] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c6]--; + + /** + * Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + z1 = tmp4 + tmp7; + int z2 = tmp5 + tmp6; + int z3 = tmp4 + tmp6; + int z4 = tmp5 + tmp7; + int z5 = (z3 + z4) * FIX_1_175875602; // sqrt(2) * c3 + + tmp4 = tmp4 * FIX_0_298631336; // sqrt(2) * (-c1+c3+c5-c7) + tmp5 = tmp5 * FIX_2_053119869; // sqrt(2) * ( c1+c3-c5+c7) + tmp6 = tmp6 * FIX_3_072711026; // sqrt(2) * ( c1+c3+c5-c7) + tmp7 = tmp7 * FIX_1_501321110; // sqrt(2) * ( c1+c3-c5-c7) + z1 = z1 * (0 - FIX_0_899976223); // sqrt(2) * (c7-c3) + z2 = z2 * (0 - FIX_2_562915447); // sqrt(2) * (-c1-c3) + z3 = z3 * (0 - FIX_1_961570560); // sqrt(2) * (-c3-c5) + z4 = z4 * (0 - FIX_0_390180644); // sqrt(2) * (c5-c3) + + z3 = z3 + z5; + z4 = z4 + z5; + + n = tmp4 + z1 + z3 + scaleFactor1; + dataUnit[c7] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c7]--; + n = tmp5 + z2 + z4 + scaleFactor1; + dataUnit[c5] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c5]--; + n = tmp6 + z2 + z3 + scaleFactor1; + dataUnit[c3] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c3]--; + n = tmp7 + z1 + z4 + scaleFactor1; + dataUnit[c1] = n / scaleFactor2; + if ((n < 0) && (n % scaleFactor2 != 0)) dataUnit[c1]--; + } +} +void getAPP0() { + JPEGAppn appn = new JPEGAppn(inputStream); + if (!appn.verify()) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } +} +void getCOM() { + new JPEGComment(inputStream); +} +void getDAC() { + JPEGArithmeticConditioningTable dac = new JPEGArithmeticConditioningTable(inputStream); + arithmeticTables = dac; +} +void getDHT() { + JPEGHuffmanTable dht = new JPEGHuffmanTable(inputStream); + if (!dht.verify()) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + if (acHuffmanTables == null) { + acHuffmanTables = new JPEGHuffmanTable[4]; + } + if (dcHuffmanTables == null) { + dcHuffmanTables = new JPEGHuffmanTable[4]; + } + JPEGHuffmanTable[] dhtTables = dht.getAllTables(); + for (int i = 0; i < dhtTables.length; i++) { + JPEGHuffmanTable dhtTable = dhtTables[i]; + if (dhtTable.getTableClass() == 0) { + dcHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable; + } else { + acHuffmanTables[dhtTable.getTableIdentifier()] = dhtTable; + } + } +} +void getDNL() { + new JPEGRestartInterval(inputStream); +} +void getDQT() { + JPEGQuantizationTable dqt = new JPEGQuantizationTable(inputStream); + int[][] currentTables = quantizationTables; + if (currentTables == null) { + currentTables = new int[4][]; + } + int[] dqtTablesKeys = dqt.getQuantizationTablesKeys(); + int[][] dqtTablesValues = dqt.getQuantizationTablesValues(); + for (int i = 0; i < dqtTablesKeys.length; i++) { + int index = dqtTablesKeys[i]; + currentTables[index] = dqtTablesValues[i]; + } + quantizationTables = currentTables; +} +void getDRI() { + JPEGRestartInterval dri = new JPEGRestartInterval(inputStream); + if (!dri.verify()) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + restartInterval = dri.getRestartInterval(); +} +static void initialize() { + initializeRGBYCbCrTables(); + initializeYCbCrRGBTables(); + initializeBitCountTable(); +} +static void initializeBitCountTable() { + int nBits = 1; + int power2 = 2; + NBitsTable = new int[2048]; + NBitsTable[0] = 0; + for (int i = 1; i < NBitsTable.length; i++) { + if (!(i < power2)) { + nBits++; + power2 *= 2; + } + NBitsTable[i] = nBits; + } +} +static void initializeRGBYCbCrTables() { + RYTable = new int[256]; + GYTable = new int[256]; + BYTable = new int[256]; + RCbTable = new int[256]; + GCbTable = new int[256]; + BCbTable = new int[256]; + RCrTable = BCbTable; + GCrTable = new int[256]; + BCrTable = new int[256]; + for (int i = 0; i < 256; i++) { + RYTable[i] = i * 19595; + GYTable[i] = i * 38470; + BYTable[i] = i * 7471 + 32768; + RCbTable[i] = i * -11059; + GCbTable[i] = i * -21709; + BCbTable[i] = i * 32768 + 8388608; + GCrTable[i] = i * -27439; + BCrTable[i] = i * -5329; + } +} +static void initializeYCbCrRGBTables() { + CrRTable = new int[256]; + CbBTable = new int[256]; + CrGTable = new int[256]; + CbGTable = new int[256]; + for (int i = 0; i < 256; i++) { + int x2 = 2 * i - 255; + CrRTable[i] = (45941 * x2 + 32768) / 65536; + CbBTable[i] = (58065 * x2 + 32768) / 65536; + CrGTable[i] = -23401 * x2; + CbGTable[i] = -11277 * x2 + 32768; + } +} +void inverseDCT(int[] dataUnit) { + for (int row = 0; row < 8; row++) { + int rIndex = row * DCTSIZE; + /** + * Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any row in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * row DCT calculations can be simplified this way. + */ + if (isZeroInRow(dataUnit, rIndex)) { + int dcVal = dataUnit[rIndex] * 4; + for (int i = rIndex; i < rIndex + 8; i++) { + dataUnit[i] = dcVal; + } + } else { + /** + * Even part: reverse the even part of the forward DCT. + * The rotator is sqrt(2)*c(-6). + */ + int z2 = dataUnit[rIndex + 2]; + int z3 = dataUnit[rIndex + 6]; + int z1 = (z2 + z3) * FIX_0_541196100; + int tmp2 = z1 + (z3 * (0 - FIX_1_847759065)); + int tmp3 = z1 + (z2 * FIX_0_765366865); + int tmp0 = (dataUnit[rIndex] + dataUnit[rIndex + 4]) * 8192; + int tmp1 = (dataUnit[rIndex] - dataUnit[rIndex + 4]) * 8192; + int tmp10 = tmp0 + tmp3; + int tmp13 = tmp0 - tmp3; + int tmp11 = tmp1 + tmp2; + int tmp12 = tmp1 - tmp2; + /** + * Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + tmp0 = dataUnit[rIndex + 7]; + tmp1 = dataUnit[rIndex + 5]; + tmp2 = dataUnit[rIndex + 3]; + tmp3 = dataUnit[rIndex + 1]; + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + int z4 = tmp1 + tmp3; + int z5 = (z3 + z4)* FIX_1_175875602; /* sqrt(2) * c3 */ + + tmp0 = tmp0 * FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = tmp1 * FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = tmp2 * FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = tmp3 * FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = z1 * (0 - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = z2 * (0 - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = z3 * (0 - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = z4 * (0 - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 = z3 + z5; + z4 = z4 + z5; + tmp0 = tmp0 + z1 + z3; + tmp1 = tmp1 + z2 + z4; + tmp2 = tmp2 + z2 + z3; + tmp3 = tmp3 + z1 + z4; + + int descaleFactor1 = ExtendTest[11]; + int descaleFactor2 = ExtendTest[12]; + dataUnit[rIndex] = (tmp10 + tmp3 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 7] = (tmp10 - tmp3 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 1] = (tmp11 + tmp2 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 6] = (tmp11 - tmp2 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 2] = (tmp12 + tmp1 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 5] = (tmp12 - tmp1 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 3] = (tmp13 + tmp0 + descaleFactor1) / descaleFactor2; + dataUnit[rIndex + 4] = (tmp13 - tmp0 + descaleFactor1) / descaleFactor2; + } + } + /** + * Pass 2: process columns. + * Note that we must descale the results by a factor of 8 == 2**3, + * and also undo the PASS1_BITS scaling. + */ + for (int col = 0; col < 8; col++) { + int c0 = col; + int c1 = col + 8; + int c2 = col + 16; + int c3 = col + 24; + int c4 = col + 32; + int c5 = col + 40; + int c6 = col + 48; + int c7 = col + 56; + if (isZeroInColumn(dataUnit, col)) { + int dcVal = (dataUnit[c0] + 16) / 32; + dataUnit[c0] = dcVal; + dataUnit[c1] = dcVal; + dataUnit[c2] = dcVal; + dataUnit[c3] = dcVal; + dataUnit[c4] = dcVal; + dataUnit[c5] = dcVal; + dataUnit[c6] = dcVal; + dataUnit[c7] = dcVal; + } else { + /** + * Even part: reverse the even part of the forward DCT. + * The rotator is sqrt(2)*c(-6). + */ + int z2 = dataUnit[c2]; + int z3 = dataUnit[c6]; + int z1 = (z2 + z3) * FIX_0_541196100; + int tmp2 = z1 + (z3 * (0 - FIX_1_847759065)); + int tmp3 = z1 + (z2 * FIX_0_765366865); + int tmp0 = (dataUnit[c0] + dataUnit[c4]) * 8192; + int tmp1 = (dataUnit[c0] - dataUnit[c4]) * 8192; + int tmp10 = tmp0 + tmp3; + int tmp13 = tmp0 - tmp3; + int tmp11 = tmp1 + tmp2; + int tmp12 = tmp1 - tmp2; + /** + * Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + tmp0 = dataUnit[c7];; + tmp1 = dataUnit[c5]; + tmp2 = dataUnit[c3]; + tmp3 = dataUnit[c1]; + z1 = tmp0 + tmp3; + z2 = tmp1 + tmp2; + z3 = tmp0 + tmp2; + int z4 = tmp1 + tmp3; + int z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ + + tmp0 = tmp0 * FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp1 = tmp1 * FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp2 = tmp2 * FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp3 = tmp3 * FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = z1 * (0 - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = z2 * (0 - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = z3 * (0 - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = z4 * (0 - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 = z3 + z5; + z4 = z4 + z5; + + tmp0 = tmp0 + z1 + z3; + tmp1 = tmp1 + z2 + z4; + tmp2 = tmp2 + z2 + z3; + tmp3 = tmp3 + z1 + z4; + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + int descaleFactor1 = ExtendTest[18]; + int descaleFactor2 = ExtendTest[19]; + dataUnit[c0] = (tmp10 + tmp3 + descaleFactor1) / descaleFactor2; + dataUnit[c7] = (tmp10 - tmp3 + descaleFactor1) / descaleFactor2; + dataUnit[c1] = (tmp11 + tmp2 + descaleFactor1) / descaleFactor2; + dataUnit[c6] = (tmp11 - tmp2 + descaleFactor1) / descaleFactor2; + dataUnit[c2] = (tmp12 + tmp1 + descaleFactor1) / descaleFactor2; + dataUnit[c5] = (tmp12 - tmp1 + descaleFactor1) / descaleFactor2; + dataUnit[c3] = (tmp13 + tmp0 + descaleFactor1) / descaleFactor2; + dataUnit[c4] = (tmp13 - tmp0 + descaleFactor1) / descaleFactor2; + } + } +} +boolean isFileFormat(LEDataInputStream stream) { + try { + JPEGStartOfImage soi = new JPEGStartOfImage(stream); + stream.unread(soi.reference); + return soi.verify(); // we no longer check for appN + } catch (Exception e) { + return false; + } +} +boolean isZeroInColumn(int[] dataUnit, int col) { + return (dataUnit[col + 8] + dataUnit[col + 16] + + dataUnit[col + 24] + dataUnit[col + 32] + + dataUnit[col + 40] + dataUnit[col + 48] + + dataUnit[col + 56]) == 0; +} +boolean isZeroInRow(int[] dataUnit, int rIndex) { + return (dataUnit[rIndex + 1] + dataUnit[rIndex + 2] + + dataUnit[rIndex + 3] + dataUnit[rIndex + 4] + + dataUnit[rIndex + 5] + dataUnit[rIndex + 6] + + dataUnit[rIndex + 7]) == 0; +} +ImageData[] loadFromByteStream() { + JPEGStartOfImage soi = new JPEGStartOfImage(inputStream); + if (!soi.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); + restartInterval = 0; + + /* Process the tables preceding the frame header. */ + processTables(); + + /* Start of Frame. */ + frameHeader = new JPEGFrameHeader(inputStream); + if (!frameHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); + imageWidth = frameHeader.getSamplesPerLine(); + imageHeight = frameHeader.getNumberOfLines(); + maxH = frameHeader.getMaxHFactor(); + maxV = frameHeader.getMaxVFactor(); + int mcuWidth = maxH * DCTSIZE; + int mcuHeight = maxV * DCTSIZE; + interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth; + interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight; + progressive = frameHeader.isProgressive(); + samplePrecision = frameHeader.getSamplePrecision(); + nComponents = frameHeader.getNumberOfImageComponents(); + frameComponents = frameHeader.componentParameters; + componentIds = frameHeader.componentIdentifiers; + imageComponents = new byte[nComponents][]; + if (progressive) { + // Progressive jpeg: need to keep all of the data units. + dataUnits = new int[nComponents][][]; + } else { + // Sequential jpeg: only need one data unit. + dataUnit = new int[8 * 8]; + } + for (int i = 0; i < nComponents; i++) { + int[] frameComponent = frameComponents[componentIds[i]]; + int bufferSize = frameComponent[CW] * frameComponent[CH]; + imageComponents[i] = new byte[bufferSize]; + if (progressive) { + dataUnits[i] = new int[bufferSize][]; + } + } + + /* Process the tables preceding the scan header. */ + processTables(); + + /* Start of Scan. */ + scanHeader = new JPEGScanHeader(inputStream); + if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); + + /* Process scan(s) and further tables until EOI. */ + int progressiveScanCount = 0; + boolean done = false; + while(!done) { + resetInputBuffer(); + precedingDCs = new int[4]; + decodeScan(); + if (progressive && loader.hasListeners()) { + ImageData imageData = createImageData(); + loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, false)); + progressiveScanCount++; + } + + /* Unread any buffered data before looking for tables again. */ + int delta = 512 - bufferCurrentPosition - 1; + if (delta > 0) { + byte[] unreadBuffer = new byte[delta]; + System.arraycopy(dataBuffer, bufferCurrentPosition + 1, unreadBuffer, 0, delta); + try { + inputStream.unread(unreadBuffer); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + + /* Process the tables preceding the next scan header. */ + JPEGSegment jpegSegment = processTables(); + if (jpegSegment == null || jpegSegment.getSegmentMarker() == EOI) { + done = true; + } else { + scanHeader = new JPEGScanHeader(inputStream); + if (!scanHeader.verify()) SWT.error(SWT.ERROR_INVALID_IMAGE); + } + } + + if (progressive) { + for (int ymcu = 0; ymcu < interleavedMcuRows; ymcu++) { + for (int xmcu = 0; xmcu < interleavedMcuCols; xmcu++) { + for (int iComp = 0; iComp < nComponents; iComp++) { + int[] frameComponent = frameComponents[componentIds[iComp]]; + int hi = frameComponent[HI]; + int vi = frameComponent[VI]; + int compWidth = frameComponent[CW]; + for (int ivi = 0; ivi < vi; ivi++) { + for (int ihi = 0; ihi < hi; ihi++) { + int index = (ymcu * vi + ivi) * compWidth + xmcu * hi + ihi; + dataUnit = dataUnits[iComp][index]; + dequantize(dataUnit, iComp); + inverseDCT(dataUnit); + storeData(dataUnit, iComp, xmcu, ymcu, hi, ihi, vi, ivi); + } + } + } + } + } + } + ImageData imageData = createImageData(); + if (progressive && loader.hasListeners()) { + loader.notifyListeners(new ImageLoaderEvent(loader, imageData, progressiveScanCount, true)); + } + return new ImageData[] {imageData}; +} +ImageData createImageData() { + return ImageData.internal_new( + imageWidth, + imageHeight, + nComponents * samplePrecision, + setUpPalette(), + nComponents == 1 ? 4 : 1, + decodeImageComponents(), + 0, + null, + null, + -1, + -1, + SWT.IMAGE_JPEG, + 0, + 0, + 0, + 0); +} +int nextBit() { + if (currentBitCount != 0) { + currentBitCount--; + currentByte *= 2; + if (currentByte > 255) { + currentByte -= 256; + return 1; + } else { + return 0; + } + } + bufferCurrentPosition++; + if (bufferCurrentPosition >= 512) { + resetInputBuffer(); + bufferCurrentPosition = 0; + } + currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; + currentBitCount = 8; + byte nextByte; + if (bufferCurrentPosition == 511) { + resetInputBuffer(); + currentBitCount = 8; + nextByte = dataBuffer[0]; + } else { + nextByte = dataBuffer[bufferCurrentPosition + 1]; + } + if (currentByte == 0xFF) { + if (nextByte == 0) { + bufferCurrentPosition ++; + currentBitCount--; + currentByte *= 2; + if (currentByte > 255) { + currentByte -= 256; + return 1; + } else { + return 0; + } + } else { + if ((nextByte & 0xFF) + 0xFF00 == DNL) { + getDNL(); + return 0; + } else { + SWT.error(SWT.ERROR_INVALID_IMAGE); + return 0; + } + } + } else { + currentBitCount--; + currentByte *= 2; + if (currentByte > 255) { + currentByte -= 256; + return 1; + } else { + return 0; + } + } +} +void processRestartInterval() { + do { + bufferCurrentPosition++; + if (bufferCurrentPosition > 511) { + resetInputBuffer(); + bufferCurrentPosition = 0; + } + currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; + } while (currentByte != 0xFF); + while (currentByte == 0xFF) { + bufferCurrentPosition++; + if (bufferCurrentPosition > 511) { + resetInputBuffer(); + bufferCurrentPosition = 0; + } + currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; + } + if (currentByte != ((RST0 + nextRestartNumber) % 256)) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + bufferCurrentPosition++; + if (bufferCurrentPosition > 511) { + resetInputBuffer(); + bufferCurrentPosition = 0; + } + currentByte = dataBuffer[bufferCurrentPosition] & 0xFF; + currentBitCount = 8; + restartsToGo = restartInterval; + nextRestartNumber = (nextRestartNumber + 1) % 8; + precedingDCs = new int[4]; + eobrun = 0; +} +/* Process all markers until a frame header, scan header, or EOI is found. */ +JPEGSegment processTables() { + while (true) { + JPEGSegment jpegSegment = seekUnspecifiedMarker(inputStream); + if (jpegSegment == null) return null; + JPEGFrameHeader sof = new JPEGFrameHeader(jpegSegment.reference); + if (sof.verify()) { + return jpegSegment; + } + int marker = jpegSegment.getSegmentMarker(); + switch (marker) { + case SOI: // there should only be one SOI per file + SWT.error(SWT.ERROR_INVALID_IMAGE); + case EOI: + case SOS: + return jpegSegment; + case DQT: + getDQT(); + break; + case DHT: + getDHT(); + break; + case DAC: + getDAC(); + break; + case DRI: + getDRI(); + break; + case APP0: + getAPP0(); + break; + case COM: + getCOM(); + break; + default: + skipSegmentFrom(inputStream); + + } + } +} +void quantizeData(int[] dataUnit, int iComp) { + int[] qTable = quantizationTables[frameComponents[componentIds[iComp]][TQI]]; + for (int i = 0; i < dataUnit.length; i++) { + int zzIndex = ZigZag8x8[i]; + int data = dataUnit[zzIndex]; + int absData = data < 0 ? 0 - data : data; + int qValue = qTable[i]; + int q2 = qValue / 2; + absData += q2; + if (absData < qValue) { + dataUnit[zzIndex] = 0; + } else { + absData /= qValue; + if (data >= 0) { + dataUnit[zzIndex] = absData; + } else { + dataUnit[zzIndex] = 0 - absData; + } + } + } +} +int receive(int nBits) { + int v = 0; + for (int i = 0; i < nBits; i++) { + v = v * 2 + nextBit(); + } + return v; +} +void resetInputBuffer() { + if (dataBuffer == null) { + dataBuffer = new byte[512]; + } + try { + inputStream.read(dataBuffer); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + currentBitCount = 0; + bufferCurrentPosition = -1; +} +void resetOutputBuffer() { + if (dataBuffer == null) { + dataBuffer = new byte[512]; + } else { + try { + outputStream.write(dataBuffer, 0, bufferCurrentPosition); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + bufferCurrentPosition = 0; +} +static JPEGSegment seekUnspecifiedMarker(LEDataInputStream byteStream) { + byte[] byteArray = new byte[2]; + try { + while (true) { + if (byteStream.read(byteArray, 0, 1) != 1) return null; + if (byteArray[0] == (byte) 0xFF) { + if (byteStream.read(byteArray, 1, 1) != 1) return null; + if (byteArray[1] != (byte) 0xFF && byteArray[1] != 0) { + byteStream.unread(byteArray); + return new JPEGSegment(byteArray); + } + } + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return null; +} +PaletteData setUpPalette() { + if (nComponents == 1) { + RGB[] entries = new RGB[256]; + for (int i = 0; i < 256; i++) { + entries[i] = new RGB(i, i, i); + } + return new PaletteData(entries); + } + return new PaletteData(0xFF, 0xFF00, 0xFF0000); +} +static void skipSegmentFrom(LEDataInputStream byteStream) { + try { + byte[] byteArray = new byte[4]; + JPEGSegment jpegSegment = new JPEGSegment(byteArray); + + if (byteStream.read(byteArray) != byteArray.length) { + throw new SWTError(SWT.ERROR_INVALID_IMAGE); + } + if (!(byteArray[0] == -1 && byteArray[1] != 0 && byteArray[1] != -1)) { + throw new SWTError(SWT.ERROR_INVALID_IMAGE); + } + int delta = jpegSegment.getSegmentLength() - 2; + byteStream.skip(delta); + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } +} +void storeData(int[] dataUnit, int iComp, int xmcu, int ymcu, int hi, int ihi, int vi, int ivi) { + byte[] compImage = imageComponents[iComp]; + int[] frameComponent = frameComponents[componentIds[iComp]]; + int compWidth = frameComponent[CW]; + int destIndex = ((ymcu * vi + ivi) * compWidth * DCTSIZE) + ((xmcu * hi + ihi) * DCTSIZE); + int srcIndex = 0; + for (int i = 0; i < DCTSIZE; i++) { + for (int col = 0; col < DCTSIZE; col++) { + int x = dataUnit[srcIndex] + 128; + if (x < 0) { + x = 0; + } else { + if (x > 255) x = 255; + } + compImage[destIndex + col] = (byte)x; + srcIndex++; + } + destIndex += compWidth; + } +} +void unloadIntoByteStream(ImageData image) { + if (!new JPEGStartOfImage().writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + JPEGAppn appn = new JPEGAppn(new byte[] {(byte)0xFF, (byte)0xE0, 0, 0x10, 0x4A, 0x46, 0x49, 0x46, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0}); + if (!appn.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + quantizationTables = new int[4][]; + JPEGQuantizationTable chromDQT = JPEGQuantizationTable.defaultChrominanceTable(); + chromDQT.scaleBy(encoderQFactor); + int[] jpegDQTKeys = chromDQT.getQuantizationTablesKeys(); + int[][] jpegDQTValues = chromDQT.getQuantizationTablesValues(); + for (int i = 0; i < jpegDQTKeys.length; i++) { + quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i]; + } + JPEGQuantizationTable lumDQT = JPEGQuantizationTable.defaultLuminanceTable(); + lumDQT.scaleBy(encoderQFactor); + jpegDQTKeys = lumDQT.getQuantizationTablesKeys(); + jpegDQTValues = lumDQT.getQuantizationTablesValues(); + for (int i = 0; i < jpegDQTKeys.length; i++) { + quantizationTables[jpegDQTKeys[i]] = jpegDQTValues[i]; + } + if (!lumDQT.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + if (!chromDQT.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + int frameLength, scanLength, precision; + int[][] frameParams, scanParams; + if (image.depth == 1) { + frameLength = 11; + frameParams = new int[1][]; + frameParams[0] = new int[] {1, 1, 1, 0, 0}; + scanParams = new int[1][]; + scanParams[0] = new int[] {0, 0}; + scanLength = 8; + nComponents = 1; + precision = 1; + } else { + frameLength = 17; + frameParams = new int[3][]; + frameParams[0] = new int[] {0, 2, 2, 0, 0}; + frameParams[1] = new int[] {1, 1, 1, 0, 0}; + frameParams[2] = new int[] {1, 1, 1, 0, 0}; + scanParams = new int[3][]; + scanParams[0] = new int[] {0, 0}; + scanParams[1] = new int[] {1, 1}; + scanParams[2] = new int[] {1, 1}; + scanLength = 12; + nComponents = 3; + precision = 8; + } + imageWidth = image.width; + imageHeight = image.height; + frameHeader = new JPEGFrameHeader(new byte[19]); + frameHeader.setSegmentMarker(SOF0); + frameHeader.setSegmentLength(frameLength); + frameHeader.setSamplePrecision(precision); + frameHeader.setSamplesPerLine(imageWidth); + frameHeader.setNumberOfLines(imageHeight); + frameHeader.setNumberOfImageComponents(nComponents); + frameHeader.componentParameters = frameParams; + frameHeader.componentIdentifiers = new int[] {0, 1, 2}; + frameHeader.initializeContents(); + if (!frameHeader.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + frameComponents = frameParams; + componentIds = frameHeader.componentIdentifiers; + maxH = frameHeader.getMaxHFactor(); + maxV = frameHeader.getMaxVFactor(); + int mcuWidth = maxH * DCTSIZE; + int mcuHeight = maxV * DCTSIZE; + interleavedMcuCols = (imageWidth + mcuWidth - 1) / mcuWidth; + interleavedMcuRows = (imageHeight + mcuHeight - 1) / mcuHeight; + acHuffmanTables = new JPEGHuffmanTable[4]; + dcHuffmanTables = new JPEGHuffmanTable[4]; + JPEGHuffmanTable[] dhtTables = new JPEGHuffmanTable[] { + JPEGHuffmanTable.getDefaultDCLuminanceTable(), + JPEGHuffmanTable.getDefaultDCChrominanceTable(), + JPEGHuffmanTable.getDefaultACLuminanceTable(), + JPEGHuffmanTable.getDefaultACChrominanceTable() + }; + for (int i = 0; i < dhtTables.length; i++) { + JPEGHuffmanTable dhtTable = dhtTables[i]; + if (!dhtTable.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + JPEGHuffmanTable[] allTables = dhtTable.getAllTables(); + for (int j = 0; j < allTables.length; j++) { + JPEGHuffmanTable huffmanTable = allTables[j]; + if (huffmanTable.getTableClass() == 0) { + dcHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable; + } else { + acHuffmanTables[huffmanTable.getTableIdentifier()] = huffmanTable; + } + } + } + precedingDCs = new int[4]; + scanHeader = new JPEGScanHeader(new byte[14]); + scanHeader.setSegmentMarker(SOS); + scanHeader.setSegmentLength(scanLength); + scanHeader.setNumberOfImageComponents(nComponents); + scanHeader.setStartOfSpectralSelection(0); + scanHeader.setEndOfSpectralSelection(63); + scanHeader.componentParameters = scanParams; + scanHeader.initializeContents(); + if (!scanHeader.writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } + convertImageToYCbCr(image); + resetOutputBuffer(); + currentByte = 0; + currentBitCount = 0; + encodeScan(); + if (!new JPEGEndOfImage().writeToStream(outputStream)) { + SWT.error(SWT.ERROR_IO); + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFixedSizeSegment.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFixedSizeSegment.java index 3f168acba1..13c7482385 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFixedSizeSegment.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFixedSizeSegment.java @@ -1,40 +1,40 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-abstract class JPEGFixedSizeSegment extends JPEGSegment {
-
- public JPEGFixedSizeSegment() {
- reference = new byte[fixedSize()];
- setSegmentMarker(signature());
- }
-
- public JPEGFixedSizeSegment(byte[] reference) {
- super(reference);
- }
-
- public JPEGFixedSizeSegment(LEDataInputStream byteStream) {
- reference = new byte[fixedSize()];
- try {
- byteStream.read(reference);
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-
- abstract public int fixedSize();
-
- public int getSegmentLength() {
- return fixedSize() - 2;
- }
-
- public void setSegmentLength(int length) {
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +abstract class JPEGFixedSizeSegment extends JPEGSegment { + + public JPEGFixedSizeSegment() { + reference = new byte[fixedSize()]; + setSegmentMarker(signature()); + } + + public JPEGFixedSizeSegment(byte[] reference) { + super(reference); + } + + public JPEGFixedSizeSegment(LEDataInputStream byteStream) { + reference = new byte[fixedSize()]; + try { + byteStream.read(reference); + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } + } + + abstract public int fixedSize(); + + public int getSegmentLength() { + return fixedSize() - 2; + } + + public void setSegmentLength(int length) { + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFrameHeader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFrameHeader.java index 59a1af75e4..c5e4106c08 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFrameHeader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGFrameHeader.java @@ -1,210 +1,210 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-final class JPEGFrameHeader extends JPEGVariableSizeSegment {
- int maxVFactor;
- int maxHFactor;
- public int[] componentIdentifiers;
- public int[][] componentParameters;
-
- public JPEGFrameHeader(byte[] reference) {
- super(reference);
- }
-
- public JPEGFrameHeader(LEDataInputStream byteStream) {
- super(byteStream);
- initializeComponentParameters();
- }
-
- public int getSamplePrecision() {
- return reference[4] & 0xFF;
- }
-
- public int getNumberOfLines() {
- return (reference[5] & 0xFF) << 8 | (reference[6] & 0xFF);
- }
-
- public int getSamplesPerLine() {
- return (reference[7] & 0xFF) << 8 | (reference[8] & 0xFF);
- }
-
- public int getNumberOfImageComponents() {
- return reference[9] & 0xFF;
- }
-
- public void setSamplePrecision(int precision) {
- reference[4] = (byte)(precision & 0xFF);
- }
-
- public void setNumberOfLines(int anInteger) {
- reference[5] = (byte)((anInteger & 0xFF00) >> 8);
- reference[6] = (byte)(anInteger & 0xFF);
- }
-
- public void setSamplesPerLine(int samples) {
- reference[7] = (byte)((samples & 0xFF00) >> 8);
- reference[8] = (byte)(samples & 0xFF);
- }
-
- public void setNumberOfImageComponents(int anInteger) {
- reference[9] = (byte)(anInteger & 0xFF);
- }
-
- public int getMaxHFactor() {
- return maxHFactor;
- }
-
- public int getMaxVFactor() {
- return maxVFactor;
- }
-
- public void setMaxHFactor(int anInteger) {
- maxHFactor = anInteger;
- }
-
- public void setMaxVFactor(int anInteger) {
- maxVFactor = anInteger;
- }
-
- /* Used when decoding. */
- void initializeComponentParameters() {
- int nf = getNumberOfImageComponents();
- componentIdentifiers = new int[nf];
- int[][] compSpecParams = new int[0][];
- int hmax = 1;
- int vmax = 1;
- for (int i = 0; i < nf; i++) {
- int ofs = i * 3 + 10;
- int ci = reference[ofs] & 0xFF;
- componentIdentifiers[i] = ci - 1;
- int hi = (reference[ofs + 1] & 0xFF) / 16;
- int vi = (reference[ofs + 1] & 0xFF) % 16;
- int tqi = reference[ofs + 2] & 0xFF;
- if (hi > hmax) {
- hmax = hi;
- }
- if (vi > vmax) {
- vmax = vi;
- }
- int[] compParam = new int[5];
- compParam[0] = tqi;
- compParam[1] = hi;
- compParam[2] = vi;
- if (compSpecParams.length < ci) {
- int[][] newParams = new int[ci][];
- System.arraycopy(compSpecParams, 0, newParams, 0, compSpecParams.length);
- compSpecParams = newParams;
- }
- compSpecParams[ci - 1] = compParam;
- }
- int x = getSamplesPerLine();
- int y = getNumberOfLines();
- int[] multiples = new int[] { 8, 16, 24, 32 };
- for (int i = 0; i < nf; i++) {
- int[] compParam = compSpecParams[componentIdentifiers[i]];
- int hi = compParam[1];
- int vi = compParam[2];
- int compWidth = (x * hi + hmax - 1) / hmax;
- int compHeight = (y * vi + vmax - 1) / vmax;
- int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]);
- int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]);
- compParam[3] = dsWidth;
- compParam[4] = dsHeight;
- }
- setMaxHFactor(hmax);
- setMaxVFactor(vmax);
- componentParameters = compSpecParams;
- }
-
- /* Used when encoding. */
- public void initializeContents() {
- int nf = getNumberOfImageComponents();
- if (nf == 0 || nf != componentParameters.length) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- int hmax = 0;
- int vmax = 0;
- int[][] compSpecParams = componentParameters;
- for (int i = 0; i < nf; i++) {
- int ofs = i * 3 + 10;
- int[] compParam = compSpecParams[componentIdentifiers[i]];
- int hi = compParam[1];
- int vi = compParam[2];
- if (hi * vi > 4) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- reference[ofs] = (byte)(i + 1);
- reference[ofs + 1] = (byte)(hi * 16 + vi);
- reference[ofs + 2] = (byte)(compParam[0]);
- if (hi > hmax) hmax = hi;
- if (vi > vmax) vmax = vi;
- }
- int x = getSamplesPerLine();
- int y = getNumberOfLines();
- int[] multiples = new int[] {8, 16, 24, 32};
- for (int i = 0; i < nf; i++) {
- int[] compParam = compSpecParams[componentIdentifiers[i]];
- int hi = compParam[1];
- int vi = compParam[2];
- int compWidth = (x * hi + hmax - 1) / hmax;
- int compHeight = (y * vi + vmax - 1) / vmax;
- int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]);
- int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]);
- compParam[3] = dsWidth;
- compParam[4] = dsHeight;
- }
- setMaxHFactor(hmax);
- setMaxVFactor(vmax);
- }
-
- int roundUpToMultiple(int anInteger, int mInteger) {
- int a = anInteger + mInteger - 1;
- return a - (a % mInteger);
- }
-
- /*
- * Verify the information contained in the receiver is correct.
- * Answer true if the header contains a valid marker. Otherwise,
- * answer false. Valid Start Of Frame markers are:
- * SOF_0 - Baseline DCT, Huffman coding
- * SOF_1 - Extended sequential DCT, Huffman coding
- * SOF_2 - Progressive DCT, Huffman coding
- * SOF_3 - Lossless (sequential), Huffman coding
- * SOF_5 - Differential sequential, Huffman coding
- * SOF_6 - Differential progressive, Huffman coding
- * SOF_7 - Differential lossless, Huffman coding
- * SOF_9 - Extended sequential DCT, arithmetic coding
- * SOF_10 - Progressive DCT, arithmetic coding
- * SOF_11 - Lossless (sequential), arithmetic coding
- * SOF_13 - Differential sequential, arithmetic coding
- * SOF_14 - Differential progressive, arithmetic coding
- * SOF_15 - Differential lossless, arithmetic coding
- */
- public boolean verify() {
- int marker = getSegmentMarker();
- return (marker >= JPEGFileFormat.SOF0 && marker <= JPEGFileFormat.SOF3) ||
- (marker >= JPEGFileFormat.SOF5 && marker <= JPEGFileFormat.SOF7) ||
- (marker >= JPEGFileFormat.SOF9 && marker <= JPEGFileFormat.SOF11) ||
- (marker >= JPEGFileFormat.SOF13 && marker <= JPEGFileFormat.SOF15);
- }
-
- public boolean isProgressive() {
- int marker = getSegmentMarker();
- return marker == JPEGFileFormat.SOF2
- || marker == JPEGFileFormat.SOF6
- || marker == JPEGFileFormat.SOF10
- || marker == JPEGFileFormat.SOF14;
- }
-
- public boolean isArithmeticCoding() {
- return getSegmentMarker() >= JPEGFileFormat.SOF9;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +final class JPEGFrameHeader extends JPEGVariableSizeSegment { + int maxVFactor; + int maxHFactor; + public int[] componentIdentifiers; + public int[][] componentParameters; + + public JPEGFrameHeader(byte[] reference) { + super(reference); + } + + public JPEGFrameHeader(LEDataInputStream byteStream) { + super(byteStream); + initializeComponentParameters(); + } + + public int getSamplePrecision() { + return reference[4] & 0xFF; + } + + public int getNumberOfLines() { + return (reference[5] & 0xFF) << 8 | (reference[6] & 0xFF); + } + + public int getSamplesPerLine() { + return (reference[7] & 0xFF) << 8 | (reference[8] & 0xFF); + } + + public int getNumberOfImageComponents() { + return reference[9] & 0xFF; + } + + public void setSamplePrecision(int precision) { + reference[4] = (byte)(precision & 0xFF); + } + + public void setNumberOfLines(int anInteger) { + reference[5] = (byte)((anInteger & 0xFF00) >> 8); + reference[6] = (byte)(anInteger & 0xFF); + } + + public void setSamplesPerLine(int samples) { + reference[7] = (byte)((samples & 0xFF00) >> 8); + reference[8] = (byte)(samples & 0xFF); + } + + public void setNumberOfImageComponents(int anInteger) { + reference[9] = (byte)(anInteger & 0xFF); + } + + public int getMaxHFactor() { + return maxHFactor; + } + + public int getMaxVFactor() { + return maxVFactor; + } + + public void setMaxHFactor(int anInteger) { + maxHFactor = anInteger; + } + + public void setMaxVFactor(int anInteger) { + maxVFactor = anInteger; + } + + /* Used when decoding. */ + void initializeComponentParameters() { + int nf = getNumberOfImageComponents(); + componentIdentifiers = new int[nf]; + int[][] compSpecParams = new int[0][]; + int hmax = 1; + int vmax = 1; + for (int i = 0; i < nf; i++) { + int ofs = i * 3 + 10; + int ci = reference[ofs] & 0xFF; + componentIdentifiers[i] = ci - 1; + int hi = (reference[ofs + 1] & 0xFF) / 16; + int vi = (reference[ofs + 1] & 0xFF) % 16; + int tqi = reference[ofs + 2] & 0xFF; + if (hi > hmax) { + hmax = hi; + } + if (vi > vmax) { + vmax = vi; + } + int[] compParam = new int[5]; + compParam[0] = tqi; + compParam[1] = hi; + compParam[2] = vi; + if (compSpecParams.length < ci) { + int[][] newParams = new int[ci][]; + System.arraycopy(compSpecParams, 0, newParams, 0, compSpecParams.length); + compSpecParams = newParams; + } + compSpecParams[ci - 1] = compParam; + } + int x = getSamplesPerLine(); + int y = getNumberOfLines(); + int[] multiples = new int[] { 8, 16, 24, 32 }; + for (int i = 0; i < nf; i++) { + int[] compParam = compSpecParams[componentIdentifiers[i]]; + int hi = compParam[1]; + int vi = compParam[2]; + int compWidth = (x * hi + hmax - 1) / hmax; + int compHeight = (y * vi + vmax - 1) / vmax; + int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]); + int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]); + compParam[3] = dsWidth; + compParam[4] = dsHeight; + } + setMaxHFactor(hmax); + setMaxVFactor(vmax); + componentParameters = compSpecParams; + } + + /* Used when encoding. */ + public void initializeContents() { + int nf = getNumberOfImageComponents(); + if (nf == 0 || nf != componentParameters.length) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + int hmax = 0; + int vmax = 0; + int[][] compSpecParams = componentParameters; + for (int i = 0; i < nf; i++) { + int ofs = i * 3 + 10; + int[] compParam = compSpecParams[componentIdentifiers[i]]; + int hi = compParam[1]; + int vi = compParam[2]; + if (hi * vi > 4) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + reference[ofs] = (byte)(i + 1); + reference[ofs + 1] = (byte)(hi * 16 + vi); + reference[ofs + 2] = (byte)(compParam[0]); + if (hi > hmax) hmax = hi; + if (vi > vmax) vmax = vi; + } + int x = getSamplesPerLine(); + int y = getNumberOfLines(); + int[] multiples = new int[] {8, 16, 24, 32}; + for (int i = 0; i < nf; i++) { + int[] compParam = compSpecParams[componentIdentifiers[i]]; + int hi = compParam[1]; + int vi = compParam[2]; + int compWidth = (x * hi + hmax - 1) / hmax; + int compHeight = (y * vi + vmax - 1) / vmax; + int dsWidth = roundUpToMultiple(compWidth, multiples[hi - 1]); + int dsHeight = roundUpToMultiple(compHeight, multiples[vi - 1]); + compParam[3] = dsWidth; + compParam[4] = dsHeight; + } + setMaxHFactor(hmax); + setMaxVFactor(vmax); + } + + int roundUpToMultiple(int anInteger, int mInteger) { + int a = anInteger + mInteger - 1; + return a - (a % mInteger); + } + + /* + * Verify the information contained in the receiver is correct. + * Answer true if the header contains a valid marker. Otherwise, + * answer false. Valid Start Of Frame markers are: + * SOF_0 - Baseline DCT, Huffman coding + * SOF_1 - Extended sequential DCT, Huffman coding + * SOF_2 - Progressive DCT, Huffman coding + * SOF_3 - Lossless (sequential), Huffman coding + * SOF_5 - Differential sequential, Huffman coding + * SOF_6 - Differential progressive, Huffman coding + * SOF_7 - Differential lossless, Huffman coding + * SOF_9 - Extended sequential DCT, arithmetic coding + * SOF_10 - Progressive DCT, arithmetic coding + * SOF_11 - Lossless (sequential), arithmetic coding + * SOF_13 - Differential sequential, arithmetic coding + * SOF_14 - Differential progressive, arithmetic coding + * SOF_15 - Differential lossless, arithmetic coding + */ + public boolean verify() { + int marker = getSegmentMarker(); + return (marker >= JPEGFileFormat.SOF0 && marker <= JPEGFileFormat.SOF3) || + (marker >= JPEGFileFormat.SOF5 && marker <= JPEGFileFormat.SOF7) || + (marker >= JPEGFileFormat.SOF9 && marker <= JPEGFileFormat.SOF11) || + (marker >= JPEGFileFormat.SOF13 && marker <= JPEGFileFormat.SOF15); + } + + public boolean isProgressive() { + int marker = getSegmentMarker(); + return marker == JPEGFileFormat.SOF2 + || marker == JPEGFileFormat.SOF6 + || marker == JPEGFileFormat.SOF10 + || marker == JPEGFileFormat.SOF14; + } + + public boolean isArithmeticCoding() { + return getSegmentMarker() >= JPEGFileFormat.SOF9; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGHuffmanTable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGHuffmanTable.java index 55f9c581b5..7990ff5583 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGHuffmanTable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGHuffmanTable.java @@ -1,264 +1,264 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * JPEGHuffmanTable class actually represents two types of object:
- * 1) A DHT (Define Huffman Tables) segment, which may represent
- * as many as 4 Huffman tables. In this case, the tables are
- * stored in the allTables array.
- * 2) A single Huffman table. In this case, the allTables array
- * will be null.
- * The 'reference' field is stored in both types of object, but
- * 'initialize' is only called if the object represents a DHT.
- */
-final class JPEGHuffmanTable extends JPEGVariableSizeSegment {
- JPEGHuffmanTable[] allTables;
- int tableClass;
- int tableIdentifier;
- int[] dhCodes;
- int[] dhCodeLengths;
- int[] dhMaxCodes;
- int[] dhMinCodes;
- int[] dhValPtrs;
- int[] dhValues;
- int[] ehCodes;
- byte[] ehCodeLengths;
- static byte[] DCLuminanceTable = {
- (byte)255, (byte)196, 0, 31, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
- };
- static byte[] DCChrominanceTable = {
- (byte)255, (byte)196, 0, 31, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
- };
- static byte[] ACLuminanceTable = {
- (byte)255, (byte)196, 0, (byte)181, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125,
- 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20,
- 50, (byte)129, (byte)145, (byte)161, 8, 35, 66, (byte)177, (byte)193, 21, 82, (byte)209, (byte)240, 36, 51, 98,
- 114, (byte)130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53,
- 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87,
- 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118,
- 119, 120, 121, 122, (byte)131, (byte)132, (byte)133, (byte)134, (byte)135, (byte)136, (byte)137, (byte)138, (byte)146, (byte)147, (byte)148,
- (byte)149, (byte)150, (byte)151, (byte)152, (byte)153, (byte)154, (byte)162, (byte)163, (byte)164, (byte)165, (byte)166, (byte)167, (byte)168, (byte)169, (byte)170,
- (byte)178, (byte)179, (byte)180, (byte)181, (byte)182, (byte)183, (byte)184, (byte)185, (byte)186, (byte)194, (byte)195, (byte)196, (byte)197, (byte)198, (byte)199,
- (byte)200, (byte)201, (byte)202, (byte)210, (byte)211, (byte)212, (byte)213, (byte)214, (byte)215, (byte)216, (byte)217, (byte)218, (byte)225, (byte)226, (byte)227,
- (byte)228, (byte)229, (byte)230, (byte)231, (byte)232, (byte)233, (byte)234, (byte)241, (byte)242, (byte)243, (byte)244, (byte)245, (byte)246, (byte)247, (byte)248,
- (byte)249, (byte)250
- };
- static byte[] ACChrominanceTable = {
- (byte)255, (byte)196, 0, (byte)181, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0,
- 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34,
- 50, (byte)129, 8, 20, 66, (byte)145, (byte)161, (byte)177, (byte)193, 9, 35,
- 51, 82, (byte)240, 21, 98, 114, (byte)209, 10, 22, 36, 52, (byte)225, 37,
- (byte)241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67,
- 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102,
- 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, (byte)130,
- (byte)131, (byte)132, (byte)133, (byte)134, (byte)135, (byte)136, (byte)137,
- (byte)138, (byte)146, (byte)147, (byte)148, (byte)149, (byte)150, (byte)151,
- (byte)152, (byte)153, (byte)154, (byte)162, (byte)163, (byte)164, (byte)165,
- (byte)166, (byte)167, (byte)168, (byte)169, (byte)170, (byte)178, (byte)179,
- (byte)180, (byte)181, (byte)182, (byte)183, (byte)184, (byte)185, (byte)186,
- (byte)194, (byte)195, (byte)196, (byte)197, (byte)198, (byte)199, (byte)200,
- (byte)201, (byte)202, (byte)210, (byte)211, (byte)212, (byte)213, (byte)214,
- (byte)215, (byte)216, (byte)217, (byte)218, (byte)226, (byte)227, (byte)228,
- (byte)229, (byte)230, (byte)231, (byte)232, (byte)233, (byte)234, (byte)242,
- (byte)243, (byte)244, (byte)245, (byte)246, (byte)247, (byte)248, (byte)249,
- (byte)250
- };
-
-public JPEGHuffmanTable(byte[] reference) {
- super(reference);
-}
-
-public JPEGHuffmanTable(LEDataInputStream byteStream) {
- super(byteStream);
- initialize();
-}
-
-public JPEGHuffmanTable[] getAllTables() {
- return allTables;
-}
-
-public static JPEGHuffmanTable getDefaultACChrominanceTable() {
- JPEGHuffmanTable result = new JPEGHuffmanTable(ACChrominanceTable);
- result.initialize();
- return result;
-}
-
-public static JPEGHuffmanTable getDefaultACLuminanceTable() {
- JPEGHuffmanTable result = new JPEGHuffmanTable(ACLuminanceTable);
- result.initialize();
- return result;
-}
-
-public static JPEGHuffmanTable getDefaultDCChrominanceTable() {
- JPEGHuffmanTable result = new JPEGHuffmanTable(DCChrominanceTable);
- result.initialize();
- return result;
-}
-
-public static JPEGHuffmanTable getDefaultDCLuminanceTable() {
- JPEGHuffmanTable result = new JPEGHuffmanTable(DCLuminanceTable);
- result.initialize();
- return result;
-}
-
-public int[] getDhMaxCodes() {
- return dhMaxCodes;
-}
-
-public int[] getDhMinCodes() {
- return dhMinCodes;
-}
-
-public int[] getDhValPtrs() {
- return dhValPtrs;
-}
-
-public int[] getDhValues() {
- return dhValues;
-}
-
-public int getTableClass() {
- return tableClass;
-}
-
-public int getTableIdentifier() {
- return tableIdentifier;
-}
-
-void initialize() {
- int totalLength = getSegmentLength() - 2;
- int ofs = 4;
- int[] bits = new int[16];
- JPEGHuffmanTable[] huffTables = new JPEGHuffmanTable[8]; // maximum is 4 AC + 4 DC
- int huffTableCount = 0;
- while (totalLength > 0) {
- int tc = (reference[ofs] & 0xFF) / 16; // table class: AC (1) or DC (0)
- int tid = (reference[ofs] & 0xFF) % 16; // table id: 0-1 baseline, 0-3 prog/ext
- ofs++;
-
- /* Read the 16 count bytes and add them together to get the table size. */
- int count = 0;
- for (int i = 0; i < bits.length; i++) {
- int bCount = reference[ofs + i] & 0xFF;
- bits[i] = bCount;
- count += bCount;
- }
- ofs += 16;
- totalLength -= 17;
-
- /* Read the table. */
- int[] huffVals = new int[count];
- for (int i = 0; i < count; i++) {
- huffVals[i] = reference[ofs + i] & 0xFF;
- }
- ofs += count;
- totalLength -= count;
-
- /* Calculate the lengths. */
- int[] huffCodeLengths = new int[50]; // start with 50 and increment as needed
- int huffCodeLengthsIndex = 0;
- for (int i = 0; i < 16; i++) {
- for (int j = 0; j < bits[i]; j++) {
- if (huffCodeLengthsIndex >= huffCodeLengths.length) {
- int[] newHuffCodeLengths = new int[huffCodeLengths.length + 50];
- System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengths.length);
- huffCodeLengths = newHuffCodeLengths;
- }
- huffCodeLengths[huffCodeLengthsIndex] = i + 1;
- huffCodeLengthsIndex++;
- }
- }
-
- /* Truncate huffCodeLengths to the correct size. */
- if (huffCodeLengthsIndex < huffCodeLengths.length) {
- int[] newHuffCodeLengths = new int[huffCodeLengthsIndex];
- System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengthsIndex);
- huffCodeLengths = newHuffCodeLengths;
- }
-
- /* Calculate the Huffman codes. */
- int[] huffCodes = new int[50]; // start with 50 and increment as needed
- int huffCodesIndex = 0;
- int k = 1;
- int code = 0;
- int si = huffCodeLengths[0];
- int p = 0;
- while (p < huffCodeLengthsIndex) {
- while ((p < huffCodeLengthsIndex) && (huffCodeLengths[p] == si)) {
- if (huffCodesIndex >= huffCodes.length) {
- int[] newHuffCodes = new int[huffCodes.length + 50];
- System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodes.length);
- huffCodes = newHuffCodes;
- }
- huffCodes[huffCodesIndex] = code;
- huffCodesIndex++;
- code++;
- p++;
- }
- code *= 2;
- si++;
- }
-
- /* Truncate huffCodes to the correct size. */
- if (huffCodesIndex < huffCodes.length) {
- int[] newHuffCodes = new int[huffCodesIndex];
- System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodesIndex);
- huffCodes = newHuffCodes;
- }
-
- /* Calculate the maximum and minimum codes */
- k = 0;
- int[] maxCodes = new int[16];
- int[] minCodes = new int[16];
- int[] valPtrs = new int[16];
- for (int i = 0; i < 16; i++) {
- int bSize = bits[i];
- if (bSize == 0) {
- maxCodes[i] = -1;
- } else {
- valPtrs[i] = k;
- minCodes[i] = huffCodes[k];
- k += bSize;
- maxCodes[i] = huffCodes[k - 1];
- }
- }
-
- /* Calculate the eHuffman codes and lengths. */
- int[] eHuffCodes = new int[256];
- byte[] eHuffSize = new byte[256];
- for (int i = 0; i < huffCodesIndex; i++) {
- eHuffCodes[huffVals[i]] = huffCodes[i];
- eHuffSize[huffVals[i]] = (byte)huffCodeLengths[i];
- }
-
- /* Create the new JPEGHuffmanTable and add it to the allTables array. */
- JPEGHuffmanTable dhtTable = new JPEGHuffmanTable(reference);
- dhtTable.tableClass = tc;
- dhtTable.tableIdentifier = tid;
- dhtTable.dhValues = huffVals;
- dhtTable.dhCodes = huffCodes;
- dhtTable.dhCodeLengths = huffCodeLengths;
- dhtTable.dhMinCodes = minCodes;
- dhtTable.dhMaxCodes = maxCodes;
- dhtTable.dhValPtrs = valPtrs;
- dhtTable.ehCodes = eHuffCodes;
- dhtTable.ehCodeLengths = eHuffSize;
- huffTables[huffTableCount] = dhtTable;
- huffTableCount++;
- }
- allTables = new JPEGHuffmanTable[huffTableCount];
- System.arraycopy(huffTables, 0, allTables, 0, huffTableCount);
-}
-
-public int signature() {
- return JPEGFileFormat.DHT;
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * JPEGHuffmanTable class actually represents two types of object: + * 1) A DHT (Define Huffman Tables) segment, which may represent + * as many as 4 Huffman tables. In this case, the tables are + * stored in the allTables array. + * 2) A single Huffman table. In this case, the allTables array + * will be null. + * The 'reference' field is stored in both types of object, but + * 'initialize' is only called if the object represents a DHT. + */ +final class JPEGHuffmanTable extends JPEGVariableSizeSegment { + JPEGHuffmanTable[] allTables; + int tableClass; + int tableIdentifier; + int[] dhCodes; + int[] dhCodeLengths; + int[] dhMaxCodes; + int[] dhMinCodes; + int[] dhValPtrs; + int[] dhValues; + int[] ehCodes; + byte[] ehCodeLengths; + static byte[] DCLuminanceTable = { + (byte)255, (byte)196, 0, 31, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + }; + static byte[] DCChrominanceTable = { + (byte)255, (byte)196, 0, 31, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + }; + static byte[] ACLuminanceTable = { + (byte)255, (byte)196, 0, (byte)181, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, + 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, + 50, (byte)129, (byte)145, (byte)161, 8, 35, 66, (byte)177, (byte)193, 21, 82, (byte)209, (byte)240, 36, 51, 98, + 114, (byte)130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, + 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, + 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, + 119, 120, 121, 122, (byte)131, (byte)132, (byte)133, (byte)134, (byte)135, (byte)136, (byte)137, (byte)138, (byte)146, (byte)147, (byte)148, + (byte)149, (byte)150, (byte)151, (byte)152, (byte)153, (byte)154, (byte)162, (byte)163, (byte)164, (byte)165, (byte)166, (byte)167, (byte)168, (byte)169, (byte)170, + (byte)178, (byte)179, (byte)180, (byte)181, (byte)182, (byte)183, (byte)184, (byte)185, (byte)186, (byte)194, (byte)195, (byte)196, (byte)197, (byte)198, (byte)199, + (byte)200, (byte)201, (byte)202, (byte)210, (byte)211, (byte)212, (byte)213, (byte)214, (byte)215, (byte)216, (byte)217, (byte)218, (byte)225, (byte)226, (byte)227, + (byte)228, (byte)229, (byte)230, (byte)231, (byte)232, (byte)233, (byte)234, (byte)241, (byte)242, (byte)243, (byte)244, (byte)245, (byte)246, (byte)247, (byte)248, + (byte)249, (byte)250 + }; + static byte[] ACChrominanceTable = { + (byte)255, (byte)196, 0, (byte)181, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, + 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, + 50, (byte)129, 8, 20, 66, (byte)145, (byte)161, (byte)177, (byte)193, 9, 35, + 51, 82, (byte)240, 21, 98, 114, (byte)209, 10, 22, 36, 52, (byte)225, 37, + (byte)241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, + 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, + 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, (byte)130, + (byte)131, (byte)132, (byte)133, (byte)134, (byte)135, (byte)136, (byte)137, + (byte)138, (byte)146, (byte)147, (byte)148, (byte)149, (byte)150, (byte)151, + (byte)152, (byte)153, (byte)154, (byte)162, (byte)163, (byte)164, (byte)165, + (byte)166, (byte)167, (byte)168, (byte)169, (byte)170, (byte)178, (byte)179, + (byte)180, (byte)181, (byte)182, (byte)183, (byte)184, (byte)185, (byte)186, + (byte)194, (byte)195, (byte)196, (byte)197, (byte)198, (byte)199, (byte)200, + (byte)201, (byte)202, (byte)210, (byte)211, (byte)212, (byte)213, (byte)214, + (byte)215, (byte)216, (byte)217, (byte)218, (byte)226, (byte)227, (byte)228, + (byte)229, (byte)230, (byte)231, (byte)232, (byte)233, (byte)234, (byte)242, + (byte)243, (byte)244, (byte)245, (byte)246, (byte)247, (byte)248, (byte)249, + (byte)250 + }; + +public JPEGHuffmanTable(byte[] reference) { + super(reference); +} + +public JPEGHuffmanTable(LEDataInputStream byteStream) { + super(byteStream); + initialize(); +} + +public JPEGHuffmanTable[] getAllTables() { + return allTables; +} + +public static JPEGHuffmanTable getDefaultACChrominanceTable() { + JPEGHuffmanTable result = new JPEGHuffmanTable(ACChrominanceTable); + result.initialize(); + return result; +} + +public static JPEGHuffmanTable getDefaultACLuminanceTable() { + JPEGHuffmanTable result = new JPEGHuffmanTable(ACLuminanceTable); + result.initialize(); + return result; +} + +public static JPEGHuffmanTable getDefaultDCChrominanceTable() { + JPEGHuffmanTable result = new JPEGHuffmanTable(DCChrominanceTable); + result.initialize(); + return result; +} + +public static JPEGHuffmanTable getDefaultDCLuminanceTable() { + JPEGHuffmanTable result = new JPEGHuffmanTable(DCLuminanceTable); + result.initialize(); + return result; +} + +public int[] getDhMaxCodes() { + return dhMaxCodes; +} + +public int[] getDhMinCodes() { + return dhMinCodes; +} + +public int[] getDhValPtrs() { + return dhValPtrs; +} + +public int[] getDhValues() { + return dhValues; +} + +public int getTableClass() { + return tableClass; +} + +public int getTableIdentifier() { + return tableIdentifier; +} + +void initialize() { + int totalLength = getSegmentLength() - 2; + int ofs = 4; + int[] bits = new int[16]; + JPEGHuffmanTable[] huffTables = new JPEGHuffmanTable[8]; // maximum is 4 AC + 4 DC + int huffTableCount = 0; + while (totalLength > 0) { + int tc = (reference[ofs] & 0xFF) / 16; // table class: AC (1) or DC (0) + int tid = (reference[ofs] & 0xFF) % 16; // table id: 0-1 baseline, 0-3 prog/ext + ofs++; + + /* Read the 16 count bytes and add them together to get the table size. */ + int count = 0; + for (int i = 0; i < bits.length; i++) { + int bCount = reference[ofs + i] & 0xFF; + bits[i] = bCount; + count += bCount; + } + ofs += 16; + totalLength -= 17; + + /* Read the table. */ + int[] huffVals = new int[count]; + for (int i = 0; i < count; i++) { + huffVals[i] = reference[ofs + i] & 0xFF; + } + ofs += count; + totalLength -= count; + + /* Calculate the lengths. */ + int[] huffCodeLengths = new int[50]; // start with 50 and increment as needed + int huffCodeLengthsIndex = 0; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < bits[i]; j++) { + if (huffCodeLengthsIndex >= huffCodeLengths.length) { + int[] newHuffCodeLengths = new int[huffCodeLengths.length + 50]; + System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengths.length); + huffCodeLengths = newHuffCodeLengths; + } + huffCodeLengths[huffCodeLengthsIndex] = i + 1; + huffCodeLengthsIndex++; + } + } + + /* Truncate huffCodeLengths to the correct size. */ + if (huffCodeLengthsIndex < huffCodeLengths.length) { + int[] newHuffCodeLengths = new int[huffCodeLengthsIndex]; + System.arraycopy(huffCodeLengths, 0, newHuffCodeLengths, 0, huffCodeLengthsIndex); + huffCodeLengths = newHuffCodeLengths; + } + + /* Calculate the Huffman codes. */ + int[] huffCodes = new int[50]; // start with 50 and increment as needed + int huffCodesIndex = 0; + int k = 1; + int code = 0; + int si = huffCodeLengths[0]; + int p = 0; + while (p < huffCodeLengthsIndex) { + while ((p < huffCodeLengthsIndex) && (huffCodeLengths[p] == si)) { + if (huffCodesIndex >= huffCodes.length) { + int[] newHuffCodes = new int[huffCodes.length + 50]; + System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodes.length); + huffCodes = newHuffCodes; + } + huffCodes[huffCodesIndex] = code; + huffCodesIndex++; + code++; + p++; + } + code *= 2; + si++; + } + + /* Truncate huffCodes to the correct size. */ + if (huffCodesIndex < huffCodes.length) { + int[] newHuffCodes = new int[huffCodesIndex]; + System.arraycopy(huffCodes, 0, newHuffCodes, 0, huffCodesIndex); + huffCodes = newHuffCodes; + } + + /* Calculate the maximum and minimum codes */ + k = 0; + int[] maxCodes = new int[16]; + int[] minCodes = new int[16]; + int[] valPtrs = new int[16]; + for (int i = 0; i < 16; i++) { + int bSize = bits[i]; + if (bSize == 0) { + maxCodes[i] = -1; + } else { + valPtrs[i] = k; + minCodes[i] = huffCodes[k]; + k += bSize; + maxCodes[i] = huffCodes[k - 1]; + } + } + + /* Calculate the eHuffman codes and lengths. */ + int[] eHuffCodes = new int[256]; + byte[] eHuffSize = new byte[256]; + for (int i = 0; i < huffCodesIndex; i++) { + eHuffCodes[huffVals[i]] = huffCodes[i]; + eHuffSize[huffVals[i]] = (byte)huffCodeLengths[i]; + } + + /* Create the new JPEGHuffmanTable and add it to the allTables array. */ + JPEGHuffmanTable dhtTable = new JPEGHuffmanTable(reference); + dhtTable.tableClass = tc; + dhtTable.tableIdentifier = tid; + dhtTable.dhValues = huffVals; + dhtTable.dhCodes = huffCodes; + dhtTable.dhCodeLengths = huffCodeLengths; + dhtTable.dhMinCodes = minCodes; + dhtTable.dhMaxCodes = maxCodes; + dhtTable.dhValPtrs = valPtrs; + dhtTable.ehCodes = eHuffCodes; + dhtTable.ehCodeLengths = eHuffSize; + huffTables[huffTableCount] = dhtTable; + huffTableCount++; + } + allTables = new JPEGHuffmanTable[huffTableCount]; + System.arraycopy(huffTables, 0, allTables, 0, huffTableCount); +} + +public int signature() { + return JPEGFileFormat.DHT; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGQuantizationTable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGQuantizationTable.java index f5c5911914..a41b1d1d7d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGQuantizationTable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGQuantizationTable.java @@ -1,161 +1,161 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGQuantizationTable extends JPEGVariableSizeSegment {
- public static byte[] DefaultLuminanceQTable = {
- (byte)255, (byte)219, 0, 67, 0,
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
- };
- public static byte[] DefaultChrominanceQTable = {
- (byte)255, (byte)219, 0, 67, 1,
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- };
-
-public JPEGQuantizationTable(byte[] reference) {
- super(reference);
-}
-
-public JPEGQuantizationTable(LEDataInputStream byteStream) {
- super(byteStream);
-}
-
-public static JPEGQuantizationTable defaultChrominanceTable() {
- byte[] data = new byte[DefaultChrominanceQTable.length];
- System.arraycopy(DefaultChrominanceQTable, 0, data, 0, data.length);
- return new JPEGQuantizationTable(data);
-}
-
-public static JPEGQuantizationTable defaultLuminanceTable() {
- byte[] data = new byte[DefaultLuminanceQTable.length];
- System.arraycopy(DefaultLuminanceQTable, 0, data, 0, data.length);
- return new JPEGQuantizationTable(data);
-}
-
-public int[] getQuantizationTablesKeys() {
- int[] keys = new int[4];
- int keysIndex = 0;
- int totalLength = getSegmentLength() - 2;
- int ofs = 4;
- while (totalLength > 64) {
- int tq = (reference[ofs] & 0xFF) % 16;
- int pq = (reference[ofs] & 0xFF) / 16;
- if (pq == 0) {
- ofs += 65;
- totalLength -= 65;
- } else {
- ofs += 129;
- totalLength -= 129;
- }
- if (keysIndex >= keys.length) {
- int[] newKeys = new int[keys.length + 4];
- System.arraycopy(keys, 0, newKeys, 0, keys.length);
- keys = newKeys;
- }
- keys[keysIndex] = tq;
- keysIndex++;
- }
- int[] newKeys = new int[keysIndex];
- System.arraycopy(keys, 0, newKeys, 0, keysIndex);
- return newKeys;
-}
-
-public int[][] getQuantizationTablesValues() {
- int[][] values = new int[4][];
- int valuesIndex = 0;
- int totalLength = getSegmentLength() - 2;
- int ofs = 4;
- while (totalLength > 64) {
- int[] qk = new int[64];
- int pq = (reference[ofs] & 0xFF) / 16;
- if (pq == 0) {
- for (int i = 0; i < qk.length; i++) {
- qk[i] = reference[ofs + i + 1];
- }
- ofs += 65;
- totalLength -= 65;
- } else {
- for (int i = 0; i < qk.length; i++) {
- int idx = (i - 1) * 2 ;
- qk[i] = (reference[ofs + idx + 1] & 0xFF) * 256 + (reference[ofs + idx + 2] & 0xFF);
- }
- ofs += 129;
- totalLength -= 129;
- }
- if (valuesIndex >= values.length) {
- int[][] newValues = new int[values.length + 4][];
- System.arraycopy(values, 0, newValues, 0, values.length);
- values = newValues;
- }
- values[valuesIndex] = qk;
- valuesIndex++;
- }
- int[][] newValues = new int[valuesIndex][];
- System.arraycopy(values, 0, newValues, 0, valuesIndex);
- return newValues;
-}
-
-public void scaleBy(int qualityFactor) {
- int qFactor = qualityFactor;
- if (qFactor <= 0) {
- qFactor = 1;
- }
- if (qFactor > 100) {
- qFactor = 100;
- }
- if (qFactor < 50) {
- qFactor = 5000 / qFactor;
- } else {
- qFactor = 200 - (qFactor * 2);
- }
- int totalLength = getSegmentLength() - 2;
- int ofs = 4;
- while (totalLength > 64) {
-// int tq = (reference[ofs] & 0xFF) % 16;
- int pq = (reference[ofs] & 0xFF) / 16;
- if (pq == 0) {
- for (int i = ofs + 1; i <= ofs + 64; i++) {
- int temp = ((reference[i] & 0xFF) * qFactor + 50) / 100;
- if (temp <= 0) temp = 1;
- if (temp > 255) temp = 255;
- reference[i] = (byte)temp;
- }
- ofs += 65;
- totalLength -= 65;
- } else {
- for (int i = ofs + 1; i <= ofs + 128; i += 2) {
- int temp = (((reference[i] & 0xFF) * 256 + (reference[i + 1] & 0xFF)) * qFactor + 50) / 100;
- if (temp <= 0) temp = 1;
- if (temp > 32767) temp = 32767;
- reference[i] = (byte)(temp / 256);
- reference[i + 1] = (byte)(temp % 256);
- }
- ofs += 129;
- totalLength -= 129;
- }
- }
-}
-
-public int signature() {
- return JPEGFileFormat.DQT;
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGQuantizationTable extends JPEGVariableSizeSegment { + public static byte[] DefaultLuminanceQTable = { + (byte)255, (byte)219, 0, 67, 0, + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 + }; + public static byte[] DefaultChrominanceQTable = { + (byte)255, (byte)219, 0, 67, 1, + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }; + +public JPEGQuantizationTable(byte[] reference) { + super(reference); +} + +public JPEGQuantizationTable(LEDataInputStream byteStream) { + super(byteStream); +} + +public static JPEGQuantizationTable defaultChrominanceTable() { + byte[] data = new byte[DefaultChrominanceQTable.length]; + System.arraycopy(DefaultChrominanceQTable, 0, data, 0, data.length); + return new JPEGQuantizationTable(data); +} + +public static JPEGQuantizationTable defaultLuminanceTable() { + byte[] data = new byte[DefaultLuminanceQTable.length]; + System.arraycopy(DefaultLuminanceQTable, 0, data, 0, data.length); + return new JPEGQuantizationTable(data); +} + +public int[] getQuantizationTablesKeys() { + int[] keys = new int[4]; + int keysIndex = 0; + int totalLength = getSegmentLength() - 2; + int ofs = 4; + while (totalLength > 64) { + int tq = (reference[ofs] & 0xFF) % 16; + int pq = (reference[ofs] & 0xFF) / 16; + if (pq == 0) { + ofs += 65; + totalLength -= 65; + } else { + ofs += 129; + totalLength -= 129; + } + if (keysIndex >= keys.length) { + int[] newKeys = new int[keys.length + 4]; + System.arraycopy(keys, 0, newKeys, 0, keys.length); + keys = newKeys; + } + keys[keysIndex] = tq; + keysIndex++; + } + int[] newKeys = new int[keysIndex]; + System.arraycopy(keys, 0, newKeys, 0, keysIndex); + return newKeys; +} + +public int[][] getQuantizationTablesValues() { + int[][] values = new int[4][]; + int valuesIndex = 0; + int totalLength = getSegmentLength() - 2; + int ofs = 4; + while (totalLength > 64) { + int[] qk = new int[64]; + int pq = (reference[ofs] & 0xFF) / 16; + if (pq == 0) { + for (int i = 0; i < qk.length; i++) { + qk[i] = reference[ofs + i + 1]; + } + ofs += 65; + totalLength -= 65; + } else { + for (int i = 0; i < qk.length; i++) { + int idx = (i - 1) * 2 ; + qk[i] = (reference[ofs + idx + 1] & 0xFF) * 256 + (reference[ofs + idx + 2] & 0xFF); + } + ofs += 129; + totalLength -= 129; + } + if (valuesIndex >= values.length) { + int[][] newValues = new int[values.length + 4][]; + System.arraycopy(values, 0, newValues, 0, values.length); + values = newValues; + } + values[valuesIndex] = qk; + valuesIndex++; + } + int[][] newValues = new int[valuesIndex][]; + System.arraycopy(values, 0, newValues, 0, valuesIndex); + return newValues; +} + +public void scaleBy(int qualityFactor) { + int qFactor = qualityFactor; + if (qFactor <= 0) { + qFactor = 1; + } + if (qFactor > 100) { + qFactor = 100; + } + if (qFactor < 50) { + qFactor = 5000 / qFactor; + } else { + qFactor = 200 - (qFactor * 2); + } + int totalLength = getSegmentLength() - 2; + int ofs = 4; + while (totalLength > 64) { +// int tq = (reference[ofs] & 0xFF) % 16; + int pq = (reference[ofs] & 0xFF) / 16; + if (pq == 0) { + for (int i = ofs + 1; i <= ofs + 64; i++) { + int temp = ((reference[i] & 0xFF) * qFactor + 50) / 100; + if (temp <= 0) temp = 1; + if (temp > 255) temp = 255; + reference[i] = (byte)temp; + } + ofs += 65; + totalLength -= 65; + } else { + for (int i = ofs + 1; i <= ofs + 128; i += 2) { + int temp = (((reference[i] & 0xFF) * 256 + (reference[i + 1] & 0xFF)) * qFactor + 50) / 100; + if (temp <= 0) temp = 1; + if (temp > 32767) temp = 32767; + reference[i] = (byte)(temp / 256); + reference[i + 1] = (byte)(temp % 256); + } + ofs += 129; + totalLength -= 129; + } + } +} + +public int signature() { + return JPEGFileFormat.DQT; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGRestartInterval.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGRestartInterval.java index 4facb96066..c97510a3a8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGRestartInterval.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGRestartInterval.java @@ -1,27 +1,27 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGRestartInterval extends JPEGFixedSizeSegment {
-
- public JPEGRestartInterval(LEDataInputStream byteStream) {
- super(byteStream);
- }
-
- public int signature() {
- return JPEGFileFormat.DRI;
- }
-
- public int getRestartInterval() {
- return ((reference[4] & 0xFF) << 8 | (reference[5] & 0xFF));
- }
-
- public int fixedSize() {
- return 6;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGRestartInterval extends JPEGFixedSizeSegment { + + public JPEGRestartInterval(LEDataInputStream byteStream) { + super(byteStream); + } + + public int signature() { + return JPEGFileFormat.DRI; + } + + public int getRestartInterval() { + return ((reference[4] & 0xFF) << 8 | (reference[5] & 0xFF)); + } + + public int fixedSize() { + return 6; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGScanHeader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGScanHeader.java index e69a1eaa1c..604d237d61 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGScanHeader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGScanHeader.java @@ -1,119 +1,119 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-final class JPEGScanHeader extends JPEGVariableSizeSegment {
- public int[][] componentParameters;
-
-public JPEGScanHeader(byte[] reference) {
- super(reference);
-}
-
-public JPEGScanHeader(LEDataInputStream byteStream) {
- super(byteStream);
- initializeComponentParameters();
-}
-
-public int getApproxBitPositionHigh() {
- return (reference[(2 * getNumberOfImageComponents()) + 7] & 0xFF) / 16;
-}
-
-public int getApproxBitPositionLow() {
- return (reference[(2 * getNumberOfImageComponents()) + 7] & 0xFF) % 16;
-}
-
-public int getEndOfSpectralSelection() {
- return (reference[(2 * getNumberOfImageComponents()) + 6] & 0xFF);
-}
-
-public int getNumberOfImageComponents() {
- return (reference[4] & 0xFF);
-}
-
-public int getStartOfSpectralSelection() {
- return (reference[(2 * getNumberOfImageComponents()) + 5] & 0xFF);
-}
-
-/* Used when decoding. */
-void initializeComponentParameters() {
- int compCount = getNumberOfImageComponents();
- componentParameters = new int[0][];
- for (int i = 0; i < compCount; i++) {
- int ofs = 5 + i * 2;
- int cid = reference[ofs] & 0xFF;
- int dc = (reference[ofs + 1] & 0xFF) / 16;
- int ac = (reference[ofs + 1] & 0xFF) % 16;
- if (componentParameters.length < cid) {
- int[][] newParams = new int[cid][];
- System.arraycopy(componentParameters, 0, newParams, 0, componentParameters.length);
- componentParameters = newParams;
- }
- componentParameters[cid - 1] = new int[] { dc, ac };
- }
-}
-
-/* Used when encoding. */
-public void initializeContents() {
- int compCount = getNumberOfImageComponents();
- int[][] compSpecParams = componentParameters;
- if (compCount == 0 || compCount != compSpecParams.length) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- for (int i = 0; i < compCount; i++) {
- int ofs = i * 2 + 5;
- int[] compParams = compSpecParams[i];
- reference[ofs] = (byte)(i + 1);
- reference[ofs + 1] = (byte)(compParams[0] * 16 + compParams[1]);
- }
-}
-
-public void setEndOfSpectralSelection(int anInteger) {
- reference[(2 * getNumberOfImageComponents()) + 6] = (byte)anInteger;
-}
-
-public void setNumberOfImageComponents(int anInteger) {
- reference[4] = (byte)(anInteger & 0xFF);
-}
-
-public void setStartOfSpectralSelection(int anInteger) {
- reference[(2 * getNumberOfImageComponents()) + 5] = (byte)anInteger;
-}
-
-public int signature() {
- return JPEGFileFormat.SOS;
-}
-
-public boolean verifyProgressiveScan() {
- int start = getStartOfSpectralSelection();
- int end = getEndOfSpectralSelection();
- int low = getApproxBitPositionLow();
- int high = getApproxBitPositionHigh();
- int count = getNumberOfImageComponents();
- if ((start == 0 && end == 00) || (start <= end && end <= 63)) {
- if (low <= 13 && high <= 13 && (high == 0 || high == low + 1)) {
- return start == 0 || (start > 0 && count == 1);
- }
- }
- return false;
-}
-
-public boolean isACProgressiveScan() {
- return getStartOfSpectralSelection() != 0 && getEndOfSpectralSelection() != 0;
-}
-
-public boolean isDCProgressiveScan() {
- return getStartOfSpectralSelection() == 0 && getEndOfSpectralSelection() == 0;
-}
-
-public boolean isFirstScan() {
- return getApproxBitPositionHigh() == 0;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +final class JPEGScanHeader extends JPEGVariableSizeSegment { + public int[][] componentParameters; + +public JPEGScanHeader(byte[] reference) { + super(reference); +} + +public JPEGScanHeader(LEDataInputStream byteStream) { + super(byteStream); + initializeComponentParameters(); +} + +public int getApproxBitPositionHigh() { + return (reference[(2 * getNumberOfImageComponents()) + 7] & 0xFF) / 16; +} + +public int getApproxBitPositionLow() { + return (reference[(2 * getNumberOfImageComponents()) + 7] & 0xFF) % 16; +} + +public int getEndOfSpectralSelection() { + return (reference[(2 * getNumberOfImageComponents()) + 6] & 0xFF); +} + +public int getNumberOfImageComponents() { + return (reference[4] & 0xFF); +} + +public int getStartOfSpectralSelection() { + return (reference[(2 * getNumberOfImageComponents()) + 5] & 0xFF); +} + +/* Used when decoding. */ +void initializeComponentParameters() { + int compCount = getNumberOfImageComponents(); + componentParameters = new int[0][]; + for (int i = 0; i < compCount; i++) { + int ofs = 5 + i * 2; + int cid = reference[ofs] & 0xFF; + int dc = (reference[ofs + 1] & 0xFF) / 16; + int ac = (reference[ofs + 1] & 0xFF) % 16; + if (componentParameters.length < cid) { + int[][] newParams = new int[cid][]; + System.arraycopy(componentParameters, 0, newParams, 0, componentParameters.length); + componentParameters = newParams; + } + componentParameters[cid - 1] = new int[] { dc, ac }; + } +} + +/* Used when encoding. */ +public void initializeContents() { + int compCount = getNumberOfImageComponents(); + int[][] compSpecParams = componentParameters; + if (compCount == 0 || compCount != compSpecParams.length) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + for (int i = 0; i < compCount; i++) { + int ofs = i * 2 + 5; + int[] compParams = compSpecParams[i]; + reference[ofs] = (byte)(i + 1); + reference[ofs + 1] = (byte)(compParams[0] * 16 + compParams[1]); + } +} + +public void setEndOfSpectralSelection(int anInteger) { + reference[(2 * getNumberOfImageComponents()) + 6] = (byte)anInteger; +} + +public void setNumberOfImageComponents(int anInteger) { + reference[4] = (byte)(anInteger & 0xFF); +} + +public void setStartOfSpectralSelection(int anInteger) { + reference[(2 * getNumberOfImageComponents()) + 5] = (byte)anInteger; +} + +public int signature() { + return JPEGFileFormat.SOS; +} + +public boolean verifyProgressiveScan() { + int start = getStartOfSpectralSelection(); + int end = getEndOfSpectralSelection(); + int low = getApproxBitPositionLow(); + int high = getApproxBitPositionHigh(); + int count = getNumberOfImageComponents(); + if ((start == 0 && end == 00) || (start <= end && end <= 63)) { + if (low <= 13 && high <= 13 && (high == 0 || high == low + 1)) { + return start == 0 || (start > 0 && count == 1); + } + } + return false; +} + +public boolean isACProgressiveScan() { + return getStartOfSpectralSelection() != 0 && getEndOfSpectralSelection() != 0; +} + +public boolean isDCProgressiveScan() { + return getStartOfSpectralSelection() == 0 && getEndOfSpectralSelection() == 0; +} + +public boolean isFirstScan() { + return getApproxBitPositionHigh() == 0; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGSegment.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGSegment.java index 49ce0e2084..19a986cf0e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGSegment.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGSegment.java @@ -1,54 +1,54 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-class JPEGSegment {
- public byte[] reference;
-
- JPEGSegment() {
- }
-
- public JPEGSegment(byte[] reference) {
- this.reference = reference;
- }
-
- public int signature() {
- return 0;
- }
-
- public boolean verify() {
- return getSegmentMarker() == signature();
- }
-
- public int getSegmentMarker() {
- return ((reference[0] & 0xFF) << 8 | (reference[1] & 0xFF));
- }
-
- public void setSegmentMarker(int marker) {
- reference[0] = (byte)((marker & 0xFF00) >> 8);
- reference[1] = (byte)(marker & 0xFF);
- }
-
- public int getSegmentLength() {
- return ((reference[2] & 0xFF) << 8 | (reference[3] & 0xFF));
- }
-
- public void setSegmentLength(int length) {
- reference[2] = (byte)((length & 0xFF00) >> 8);
- reference[3] = (byte)(length & 0xFF);
- }
-
- public boolean writeToStream(LEDataOutputStream byteStream) {
- try {
- byteStream.write(reference);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +class JPEGSegment { + public byte[] reference; + + JPEGSegment() { + } + + public JPEGSegment(byte[] reference) { + this.reference = reference; + } + + public int signature() { + return 0; + } + + public boolean verify() { + return getSegmentMarker() == signature(); + } + + public int getSegmentMarker() { + return ((reference[0] & 0xFF) << 8 | (reference[1] & 0xFF)); + } + + public void setSegmentMarker(int marker) { + reference[0] = (byte)((marker & 0xFF00) >> 8); + reference[1] = (byte)(marker & 0xFF); + } + + public int getSegmentLength() { + return ((reference[2] & 0xFF) << 8 | (reference[3] & 0xFF)); + } + + public void setSegmentLength(int length) { + reference[2] = (byte)((length & 0xFF00) >> 8); + reference[3] = (byte)(length & 0xFF); + } + + public boolean writeToStream(LEDataOutputStream byteStream) { + try { + byteStream.write(reference); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGStartOfImage.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGStartOfImage.java index d37e024c90..8ea7052946 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGStartOfImage.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGStartOfImage.java @@ -1,31 +1,31 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class JPEGStartOfImage extends JPEGFixedSizeSegment {
-
- public JPEGStartOfImage() {
- super();
- }
-
- public JPEGStartOfImage(byte[] reference) {
- super(reference);
- }
-
- public JPEGStartOfImage(LEDataInputStream byteStream) {
- super(byteStream);
- }
-
- public int signature() {
- return JPEGFileFormat.SOI;
- }
-
- public int fixedSize() {
- return 2;
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class JPEGStartOfImage extends JPEGFixedSizeSegment { + + public JPEGStartOfImage() { + super(); + } + + public JPEGStartOfImage(byte[] reference) { + super(reference); + } + + public JPEGStartOfImage(LEDataInputStream byteStream) { + super(byteStream); + } + + public int signature() { + return JPEGFileFormat.SOI; + } + + public int fixedSize() { + return 2; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGVariableSizeSegment.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGVariableSizeSegment.java index 458ea134d9..ab43a9fde8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGVariableSizeSegment.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/JPEGVariableSizeSegment.java @@ -1,34 +1,34 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-abstract class JPEGVariableSizeSegment extends JPEGSegment {
-
- public JPEGVariableSizeSegment(byte[] reference) {
- super(reference);
- }
-
- public JPEGVariableSizeSegment(LEDataInputStream byteStream) {
- try {
- byte[] header = new byte[4];
- byteStream.read(header);
- reference = header; // to use getSegmentLength()
- byte[] contents = new byte[getSegmentLength() + 2];
- contents[0] = header[0];
- contents[1] = header[1];
- contents[2] = header[2];
- contents[3] = header[3];
- byteStream.read(contents, 4, contents.length - 4);
- reference = contents;
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +abstract class JPEGVariableSizeSegment extends JPEGSegment { + + public JPEGVariableSizeSegment(byte[] reference) { + super(reference); + } + + public JPEGVariableSizeSegment(LEDataInputStream byteStream) { + try { + byte[] header = new byte[4]; + byteStream.read(header); + reference = header; // to use getSegmentLength() + byte[] contents = new byte[getSegmentLength() + 2]; + contents[0] = header[0]; + contents[1] = header[1]; + contents[2] = header[2]; + contents[3] = header[3]; + byteStream.read(contents, 4, contents.length - 4); + reference = contents; + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataInputStream.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataInputStream.java index 15b7345b9e..d1b2d38393 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataInputStream.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataInputStream.java @@ -1,181 +1,181 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-
-final class LEDataInputStream extends InputStream {
- int position;
- InputStream in;
-
- /**
- * The byte array containing the bytes to read.
- */
- protected byte[] buf;
-
- /**
- * The current position within the byte array <code>buf</code>. A value
- * equal to buf.length indicates no bytes available. A value of
- * 0 indicates the buffer is full.
- */
- protected int pos;
-
-
- public LEDataInputStream(InputStream input) {
- this(input, 512);
- }
-
- public LEDataInputStream(InputStream input, int bufferSize) {
- this.in = input;
- if (bufferSize > 0) {
- buf = new byte[bufferSize];
- pos = bufferSize;
- }
- else throw new IllegalArgumentException();
- }
-
- public void close() throws IOException {
- buf = null;
- if (in != null) {
- in.close();
- in = null;
- }
- }
-
- /**
- * Answer how many bytes were read.
- */
- public int getPosition() {
- return position;
- }
-
- /**
- * Answers how many bytes are available for reading without blocking
- */
- public int available() throws IOException {
- if (buf == null) throw new IOException();
- return (buf.length - pos) + in.available();
- }
-
- /**
- * Answer the next byte of the input stream.
- */
- public int read() throws IOException {
- if (buf == null) throw new IOException();
- position++;
- if (pos < buf.length) return (buf[pos++] & 0xFF);
- return in.read();
- }
-
- /**
- * Don't imitate the JDK behaviour of reading a random number
- * of bytes when you can actually read them all.
- */
- public int read(byte b[], int off, int len) throws IOException {
- int result;
- int left = len;
- result = readData(b, off, len);
- while (true) {
- if (result == -1) return -1;
- position += result;
- if (result == left) return len;
- left -= result;
- off += result;
- result = readData(b, off, left);
- }
- }
-
- /**
- * Reads at most <code>length</code> bytes from this LEDataInputStream and
- * stores them in byte array <code>buffer</code> starting at <code>offset</code>.
- * <p>
- * Answer the number of bytes actually read or -1 if no bytes were read and
- * end of stream was encountered. This implementation reads bytes from
- * the pushback buffer first, then the target stream if more bytes are required
- * to satisfy <code>count</code>.
- * </p>
- * @param buffer the byte array in which to store the read bytes.
- * @param offset the offset in <code>buffer</code> to store the read bytes.
- * @param length the maximum number of bytes to store in <code>buffer</code>.
- *
- * @return int the number of bytes actually read or -1 if end of stream.
- *
- * @exception java.io.IOException if an IOException occurs.
- */
- private int readData(byte[] buffer, int offset, int length) throws IOException {
- if (buf == null) throw new IOException();
- if (offset < 0 || offset > buffer.length ||
- length < 0 || (length > buffer.length - offset)) {
- throw new ArrayIndexOutOfBoundsException();
- }
-
- int cacheCopied = 0;
- int newOffset = offset;
-
- // Are there pushback bytes available?
- int available = buf.length - pos;
- if (available > 0) {
- cacheCopied = (available >= length) ? length : available;
- System.arraycopy(buf, pos, buffer, newOffset, cacheCopied);
- newOffset += cacheCopied;
- pos += cacheCopied;
- }
-
- // Have we copied enough?
- if (cacheCopied == length) return length;
-
- int inCopied = in.read(buffer, newOffset, length - cacheCopied);
-
- if (inCopied > 0) return inCopied + cacheCopied;
- if (cacheCopied == 0) return inCopied;
- return cacheCopied;
- }
-
- /**
- * Answer an integer comprised of the next
- * four bytes of the input stream.
- */
- public int readInt() throws IOException {
- byte[] buf = new byte[4];
- read(buf);
- return ((((((buf[3] & 0xFF) << 8) |
- (buf[2] & 0xFF)) << 8) |
- (buf[1] & 0xFF)) << 8) |
- (buf[0] & 0xFF);
- }
-
- /**
- * Answer a short comprised of the next
- * two bytes of the input stream.
- */
- public short readShort() throws IOException {
- byte[] buf = new byte[2];
- read(buf);
- return (short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF));
- }
-
- /**
- * Push back the entire content of the given buffer <code>b</code>.
- * <p>
- * The bytes are pushed so that they would be read back b[0], b[1], etc.
- * If the push back buffer cannot handle the bytes copied from <code>b</code>,
- * an IOException will be thrown and no byte will be pushed back.
- * </p>
- *
- * @param b the byte array containing bytes to push back into the stream
- *
- * @exception java.io.IOException if the pushback buffer is too small
- */
- public void unread(byte[] b) throws IOException {
- int length = b.length;
- if (length > pos) throw new IOException();
- position -= length;
- pos -= length;
- System.arraycopy(b, 0, buf, pos, length);
- }
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; + +final class LEDataInputStream extends InputStream { + int position; + InputStream in; + + /** + * The byte array containing the bytes to read. + */ + protected byte[] buf; + + /** + * The current position within the byte array <code>buf</code>. A value + * equal to buf.length indicates no bytes available. A value of + * 0 indicates the buffer is full. + */ + protected int pos; + + + public LEDataInputStream(InputStream input) { + this(input, 512); + } + + public LEDataInputStream(InputStream input, int bufferSize) { + this.in = input; + if (bufferSize > 0) { + buf = new byte[bufferSize]; + pos = bufferSize; + } + else throw new IllegalArgumentException(); + } + + public void close() throws IOException { + buf = null; + if (in != null) { + in.close(); + in = null; + } + } + + /** + * Answer how many bytes were read. + */ + public int getPosition() { + return position; + } + + /** + * Answers how many bytes are available for reading without blocking + */ + public int available() throws IOException { + if (buf == null) throw new IOException(); + return (buf.length - pos) + in.available(); + } + + /** + * Answer the next byte of the input stream. + */ + public int read() throws IOException { + if (buf == null) throw new IOException(); + position++; + if (pos < buf.length) return (buf[pos++] & 0xFF); + return in.read(); + } + + /** + * Don't imitate the JDK behaviour of reading a random number + * of bytes when you can actually read them all. + */ + public int read(byte b[], int off, int len) throws IOException { + int result; + int left = len; + result = readData(b, off, len); + while (true) { + if (result == -1) return -1; + position += result; + if (result == left) return len; + left -= result; + off += result; + result = readData(b, off, left); + } + } + + /** + * Reads at most <code>length</code> bytes from this LEDataInputStream and + * stores them in byte array <code>buffer</code> starting at <code>offset</code>. + * <p> + * Answer the number of bytes actually read or -1 if no bytes were read and + * end of stream was encountered. This implementation reads bytes from + * the pushback buffer first, then the target stream if more bytes are required + * to satisfy <code>count</code>. + * </p> + * @param buffer the byte array in which to store the read bytes. + * @param offset the offset in <code>buffer</code> to store the read bytes. + * @param length the maximum number of bytes to store in <code>buffer</code>. + * + * @return int the number of bytes actually read or -1 if end of stream. + * + * @exception java.io.IOException if an IOException occurs. + */ + private int readData(byte[] buffer, int offset, int length) throws IOException { + if (buf == null) throw new IOException(); + if (offset < 0 || offset > buffer.length || + length < 0 || (length > buffer.length - offset)) { + throw new ArrayIndexOutOfBoundsException(); + } + + int cacheCopied = 0; + int newOffset = offset; + + // Are there pushback bytes available? + int available = buf.length - pos; + if (available > 0) { + cacheCopied = (available >= length) ? length : available; + System.arraycopy(buf, pos, buffer, newOffset, cacheCopied); + newOffset += cacheCopied; + pos += cacheCopied; + } + + // Have we copied enough? + if (cacheCopied == length) return length; + + int inCopied = in.read(buffer, newOffset, length - cacheCopied); + + if (inCopied > 0) return inCopied + cacheCopied; + if (cacheCopied == 0) return inCopied; + return cacheCopied; + } + + /** + * Answer an integer comprised of the next + * four bytes of the input stream. + */ + public int readInt() throws IOException { + byte[] buf = new byte[4]; + read(buf); + return ((((((buf[3] & 0xFF) << 8) | + (buf[2] & 0xFF)) << 8) | + (buf[1] & 0xFF)) << 8) | + (buf[0] & 0xFF); + } + + /** + * Answer a short comprised of the next + * two bytes of the input stream. + */ + public short readShort() throws IOException { + byte[] buf = new byte[2]; + read(buf); + return (short)(((buf[1] & 0xFF) << 8) | (buf[0] & 0xFF)); + } + + /** + * Push back the entire content of the given buffer <code>b</code>. + * <p> + * The bytes are pushed so that they would be read back b[0], b[1], etc. + * If the push back buffer cannot handle the bytes copied from <code>b</code>, + * an IOException will be thrown and no byte will be pushed back. + * </p> + * + * @param b the byte array containing bytes to push back into the stream + * + * @exception java.io.IOException if the pushback buffer is too small + */ + public void unread(byte[] b) throws IOException { + int length = b.length; + if (length > pos) throw new IOException(); + position -= length; + pos -= length; + System.arraycopy(b, 0, buf, pos, length); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataOutputStream.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataOutputStream.java index 96847dab59..b8a8359145 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataOutputStream.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LEDataOutputStream.java @@ -1,53 +1,53 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-
-final class LEDataOutputStream extends OutputStream {
- OutputStream out;
-public LEDataOutputStream(OutputStream output) {
- this.out = output;
-}
-public void close() throws IOException {
- out.close();
-}
-public void write(byte b[], int off, int len) throws IOException {
- out.write(b, off, len);
-}
-/**
- * Answer the next byte of the input stream.
- */
-public void write(int b) throws IOException {
- out.write(b);
-}
-/**
- * Answer the next byte of the input stream.
- */
-public void writeByte(byte b) throws IOException {
- out.write(b & 0xFF);
-}
-/**
- * Answer an integer comprised of the next
- * four bytes of the input stream.
- */
-public void writeInt(int theInt) throws IOException {
- out.write(theInt & 0xFF);
- out.write((theInt >> 8) & 0xFF);
- out.write((theInt >> 16) & 0xFF);
- out.write((theInt >> 24) & 0xFF);
-}
-/**
- * Answer an integer comprised of the next
- * two bytes of the input stream.
- */
-public void writeShort(int theShort) throws IOException {
- out.write(theShort & 0xFF);
- out.write((theShort >> 8) & 0xFF);
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; + +final class LEDataOutputStream extends OutputStream { + OutputStream out; +public LEDataOutputStream(OutputStream output) { + this.out = output; +} +public void close() throws IOException { + out.close(); +} +public void write(byte b[], int off, int len) throws IOException { + out.write(b, off, len); +} +/** + * Answer the next byte of the input stream. + */ +public void write(int b) throws IOException { + out.write(b); +} +/** + * Answer the next byte of the input stream. + */ +public void writeByte(byte b) throws IOException { + out.write(b & 0xFF); +} +/** + * Answer an integer comprised of the next + * four bytes of the input stream. + */ +public void writeInt(int theInt) throws IOException { + out.write(theInt & 0xFF); + out.write((theInt >> 8) & 0xFF); + out.write((theInt >> 16) & 0xFF); + out.write((theInt >> 24) & 0xFF); +} +/** + * Answer an integer comprised of the next + * two bytes of the input stream. + */ +public void writeShort(int theShort) throws IOException { + out.write(theShort & 0xFF); + out.write((theShort >> 8) & 0xFF); +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWCodec.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWCodec.java index 42e5a0ef00..51e80f9ce2 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWCodec.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWCodec.java @@ -1,478 +1,478 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-
-final class LZWCodec {
- int bitsPerPixel, blockSize, blockIndex, currentByte, bitsLeft,
- codeSize, clearCode, endCode, newCodes, topSlot, currentSlot,
- imageWidth, imageHeight, imageX, imageY, pass, line, codeMask, buffer;
- byte[] block, lineArray;
- int[] maskTable, stack, suffix, prefix;
- LZWNode[] nodeStack;
- LEDataInputStream inputStream;
- LEDataOutputStream outputStream;
- ImageData image;
- ImageLoader loader;
- boolean interlaced;
-/**
- * Decode the input.
- */
-void decode() {
- int code;
- int oc = 0;
- int fc = 0;
- byte[] buf = new byte[imageWidth];
- int stackIndex = 0;
- int bufIndex = 0;
- int c;
- while ((c = nextCode()) != endCode) {
- if (c == clearCode) {
- codeSize = bitsPerPixel + 1;
- codeMask = maskTable[bitsPerPixel];
- currentSlot = newCodes;
- topSlot = 1 << codeSize;
- while ((c = nextCode()) == clearCode) {};
- if (c != endCode) {
- oc = fc = c;
- buf[bufIndex] = (byte)c;
- bufIndex++;
- if (bufIndex == imageWidth) {
- nextPutPixels(buf);
- bufIndex = 0;
- }
- }
- } else {
- code = c;
- if (code >= currentSlot) {
- if (code > currentSlot)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- code = oc;
- stack[stackIndex] = fc;
- stackIndex++;
- }
- while (code >= newCodes) {
- stack[stackIndex] = suffix[code];
- stackIndex++;
- code = prefix[code];
- }
- stack[stackIndex] = code;
- stackIndex++;
- if (currentSlot < topSlot) {
- fc = code;
- suffix[currentSlot] = fc;
- prefix[currentSlot] = oc;
- currentSlot++;
- oc = c;
- }
- if (currentSlot >= topSlot) {
- if (codeSize < 12) {
- codeMask = maskTable[codeSize];
- codeSize++;
- topSlot = topSlot + topSlot;
- }
- }
- while (stackIndex > 0) {
- stackIndex--;
- buf[bufIndex] = (byte)stack[stackIndex];
- bufIndex++;
- if (bufIndex == imageWidth) {
- nextPutPixels(buf);
- bufIndex = 0;
- }
- }
- }
- }
- if (bufIndex != 0 && line < imageHeight) {
- nextPutPixels(buf);
- }
-}
-/**
- * Decode the LZW-encoded bytes in the given byte stream
- * into the given DeviceIndependentImage.
- */
-public void decode(LEDataInputStream inputStream, ImageLoader loader, ImageData image, boolean interlaced, int depth) {
- this.inputStream = inputStream;
- this.loader = loader;
- this.image = image;
- this.interlaced = interlaced;
- this.bitsPerPixel = depth;
- initializeForDecoding();
- decode();
-}
-/**
- * Encode the image.
- */
-void encode() {
- nextPutCode(clearCode);
- int lastPrefix = encodeLoop();
- nextPutCode(lastPrefix);
- nextPutCode(endCode);
-
- // Write out last partial block
- if (bitsLeft == 8) {
- block[0] = (byte)(blockIndex - 1); // Nothing in last byte
- } else {
- block[0] = (byte)(blockIndex); // Last byte has data
- }
- writeBlock();
-
- // Write out empty block to indicate the end (if needed)
- if (block[0] != 0) {
- block[0] = 0;
- writeBlock();
- }
-}
-/**
- * Encode the bytes into the given byte stream
- * from the given DeviceIndependentImage.
- */
-public void encode(LEDataOutputStream byteStream, ImageData image) {
- this.outputStream = byteStream;
- this.image = image;
- initializeForEncoding();
- encode();
-}
-/**
- * Encoding loop broken out to allow early return.
- */
-int encodeLoop() {
- int pixel = nextPixel();
- boolean found;
- LZWNode node;
- while (true) {
- int currentPrefix = pixel;
- node = nodeStack[currentPrefix];
- found = true;
- pixel = nextPixel();
- if (pixel < 0)
- return currentPrefix;
- while (found && (node.children != null)) {
- node = node.children;
- while (found && (node.suffix != pixel)) {
- if (pixel < node.suffix) {
- if (node.left == null) {
- node.left = new LZWNode();
- found = false;
- }
- node = node.left;
- } else {
- if (node.right == null) {
- node.right = new LZWNode();
- found = false;
- }
- node = node.right;
- }
- }
- if (found) {
- currentPrefix = node.code;
- pixel = nextPixel();
- if (pixel < 0)
- return currentPrefix;
- }
- }
- if (found) {
- node.children = new LZWNode();
- node = node.children;
- }
- node.children = null;
- node.left = null;
- node.right = null;
- node.code = currentSlot;
- node.prefix = currentPrefix;
- node.suffix = pixel;
- nextPutCode(currentPrefix);
- currentSlot++;
- // Off by one?
- if (currentSlot < 4096) {
- if (currentSlot > topSlot) {
- codeSize++;
- codeMask = maskTable[codeSize - 1];
- topSlot *= 2;
- }
- } else {
- nextPutCode(clearCode);
- for (int i = 0; i < nodeStack.length; i++)
- nodeStack[i].children = null;
- codeSize = bitsPerPixel + 1;
- codeMask = maskTable[codeSize - 1];
- currentSlot = newCodes;
- topSlot = 1 << codeSize;
- }
- }
-}
-/**
- * Initialize the receiver for decoding the given
- * byte array.
- */
-void initializeForDecoding() {
- pass = 1;
- line = 0;
- codeSize = bitsPerPixel + 1;
- topSlot = 1 << codeSize;
- clearCode = 1 << bitsPerPixel;
- endCode = clearCode + 1;
- newCodes = currentSlot = endCode + 1;
- currentByte = -1;
- blockSize = bitsLeft = 0;
- blockIndex = 0;
- maskTable = new int[] {
- 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F,
- 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
- };
- codeMask = maskTable[codeSize - 1];
- stack = new int[4096];
- suffix = new int[4096];
- prefix = new int[4096];
- block = new byte[256];
- imageWidth = image.width;
- imageHeight = image.height;
-}
-/**
- * Initialize the receiver for encoding the given
- * byte array.
- */
-void initializeForEncoding() {
- interlaced = false;
- bitsPerPixel = image.depth;
- codeSize = bitsPerPixel + 1;
- topSlot = 1 << codeSize;
- clearCode = 1 << bitsPerPixel;
- endCode = clearCode + 1;
- newCodes = currentSlot = endCode + 1;
- bitsLeft = 8;
- currentByte = 0;
- blockIndex = 1;
- blockSize = 255;
- block = new byte[blockSize];
- block[0] = (byte)(blockSize - 1);
- maskTable = new int[] {
- 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F,
- 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF
- };
- nodeStack = new LZWNode[1 << bitsPerPixel];
- for (int i = 0; i < nodeStack.length; i++) {
- LZWNode node = new LZWNode();
- node.code = i + 1;
- node.prefix = -1;
- node.suffix = i + 1;
- nodeStack[i] = node;
- }
- imageWidth = image.width;
- imageHeight = image.height;
- imageY = -1;
- lineArray = new byte[imageWidth];
- imageX = imageWidth + 1; // Force a read
-}
-/**
- * Answer the next code from the input byte array.
- */
-int nextCode() {
- int code;
- if (bitsLeft == 0) {
- if (blockIndex >= blockSize) {
- blockSize = readBlock();
- blockIndex = 0;
- if (blockSize == 0) return endCode;
- }
- blockIndex++;
- currentByte = block[blockIndex] & 0xFF;
- bitsLeft = 8;
- code = currentByte;
- } else {
- int shift = bitsLeft - 8;
- if (shift < 0)
- code = currentByte >> (0 - shift);
- else
- code = currentByte << shift;
- }
- while (codeSize > bitsLeft) {
- if (blockIndex >= blockSize) {
- blockSize = readBlock();
- blockIndex = 0;
- if (blockSize == 0) return endCode;
- }
- blockIndex++;
- currentByte = block[blockIndex] & 0xFF;
- code += currentByte << bitsLeft;
- bitsLeft += 8;
- }
- bitsLeft -= codeSize;
- return code & codeMask;
-}
-/**
- * Answer the next pixel to encode in the image
- */
-int nextPixel() {
- imageX++;
- if (imageX > imageWidth) {
- imageY++;
- if (imageY >= imageHeight) {
- return -1;
- } else {
- nextPixels(lineArray, imageWidth);
- }
- imageX = 1;
- }
- return this.lineArray[imageX - 1] & 0xFF;
-}
-/**
- * Copy a row of pixel values from the image.
- */
-void nextPixels(byte[] buf, int lineWidth) {
- if (image.depth == 8) {
- System.arraycopy(image.data, imageY * image.bytesPerLine, buf, 0, lineWidth);
- } else {
- image.getPixels(0, imageY, lineWidth, buf, 0);
- }
-}
-/**
- * Output aCode to the output stream.
- */
-void nextPutCode(int aCode) {
- int codeToDo = aCode;
- int codeBitsToDo = codeSize;
- // Fill in the remainder of the current byte with the
- // *high-order* bits of the code.
- int c = codeToDo & maskTable[bitsLeft - 1];
- currentByte = currentByte | (c << (8 - bitsLeft));
- block[blockIndex] = (byte)currentByte;
- codeBitsToDo -= bitsLeft;
- if (codeBitsToDo < 1) {
- // The whole code fit in the first byte, so we are done.
- bitsLeft -= codeSize;
- if (bitsLeft == 0) {
- // We used the whole last byte, so get ready
- // for the next one.
- bitsLeft = 8;
- blockIndex++;
- if (blockIndex >= blockSize) {
- writeBlock();
- blockIndex = 1;
- }
- currentByte = 0;
- }
- return;
- }
- codeToDo = codeToDo >> bitsLeft;
-
- // Fill in any remaining whole bytes (i.e. not the last one!)
- blockIndex++;
- if (blockIndex >= blockSize) {
- writeBlock();
- blockIndex = 1;
- }
- while (codeBitsToDo >= 8) {
- currentByte = codeToDo & 0xFF;
- block[blockIndex] = (byte)currentByte;
- codeToDo = codeToDo >> 8;
- codeBitsToDo -= 8;
- blockIndex++;
- if (blockIndex >= blockSize) {
- writeBlock();
- blockIndex = 1;
- }
- }
- // Fill the *low-order* bits of the last byte with the remainder
- bitsLeft = 8 - codeBitsToDo;
- currentByte = codeToDo;
- block[blockIndex] = (byte)currentByte;
-}
-/**
- * Copy a row of pixel values to the image.
- */
-void nextPutPixels(byte[] buf) {
- if (image.depth == 8) {
- // Slight optimization for depth = 8.
- int start = line * image.bytesPerLine;
- for (int i = 0; i < imageWidth; i++)
- image.data[start + i] = buf[i];
- } else {
- image.setPixels(0, line, imageWidth, buf, 0);
- }
- if (interlaced) {
- if (pass == 1) {
- copyRow(buf, 7);
- line += 8;
- } else if (pass == 2) {
- copyRow(buf, 3);
- line += 8;
- } else if (pass == 3) {
- copyRow(buf, 1);
- line += 4;
- } else if (pass == 4) {
- line += 2;
- } else if (pass == 5) {
- line += 0;
- }
- if (line >= imageHeight) {
- pass++;
- if (pass == 2) line = 4;
- else if (pass == 3) line = 2;
- else if (pass == 4) line = 1;
- else if (pass == 5) line = 0;
- if (pass < 5) {
- if (loader.hasListeners()) {
- ImageData imageCopy = (ImageData) image.clone();
- loader.notifyListeners(
- new ImageLoaderEvent(loader, imageCopy, pass - 2, false));
- }
- }
- }
- if (line >= imageHeight) line = 0;
- } else {
- line++;
- }
-}
-/**
- * Copy duplicate rows of pixel values to the image.
- * This is to fill in rows if the image is interlaced.
- */
-void copyRow(byte[] buf, int copies) {
- for (int i = 1; i <= copies; i++) {
- if (line + i < imageHeight) {
- image.setPixels(0, line + i, imageWidth, buf, 0);
- }
- }
-}
-/**
- * Read a block from the byte stream.
- * Return the number of bytes read.
- * Throw an exception if the block could not be read.
- */
-int readBlock() {
- int size = -1;
- try {
- size = inputStream.read();
- if (size == -1) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- block[0] = (byte)size;
- size = inputStream.read(block, 1, size);
- if (size == -1) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return size;
-}
-/**
- * Write a block to the byte stream.
- * Throw an exception if the block could not be written.
- */
-void writeBlock() {
- try {
- outputStream.write(block, 0, (block[0] & 0xFF) + 1);
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; + +final class LZWCodec { + int bitsPerPixel, blockSize, blockIndex, currentByte, bitsLeft, + codeSize, clearCode, endCode, newCodes, topSlot, currentSlot, + imageWidth, imageHeight, imageX, imageY, pass, line, codeMask, buffer; + byte[] block, lineArray; + int[] maskTable, stack, suffix, prefix; + LZWNode[] nodeStack; + LEDataInputStream inputStream; + LEDataOutputStream outputStream; + ImageData image; + ImageLoader loader; + boolean interlaced; +/** + * Decode the input. + */ +void decode() { + int code; + int oc = 0; + int fc = 0; + byte[] buf = new byte[imageWidth]; + int stackIndex = 0; + int bufIndex = 0; + int c; + while ((c = nextCode()) != endCode) { + if (c == clearCode) { + codeSize = bitsPerPixel + 1; + codeMask = maskTable[bitsPerPixel]; + currentSlot = newCodes; + topSlot = 1 << codeSize; + while ((c = nextCode()) == clearCode) {}; + if (c != endCode) { + oc = fc = c; + buf[bufIndex] = (byte)c; + bufIndex++; + if (bufIndex == imageWidth) { + nextPutPixels(buf); + bufIndex = 0; + } + } + } else { + code = c; + if (code >= currentSlot) { + if (code > currentSlot) + SWT.error(SWT.ERROR_INVALID_IMAGE); + code = oc; + stack[stackIndex] = fc; + stackIndex++; + } + while (code >= newCodes) { + stack[stackIndex] = suffix[code]; + stackIndex++; + code = prefix[code]; + } + stack[stackIndex] = code; + stackIndex++; + if (currentSlot < topSlot) { + fc = code; + suffix[currentSlot] = fc; + prefix[currentSlot] = oc; + currentSlot++; + oc = c; + } + if (currentSlot >= topSlot) { + if (codeSize < 12) { + codeMask = maskTable[codeSize]; + codeSize++; + topSlot = topSlot + topSlot; + } + } + while (stackIndex > 0) { + stackIndex--; + buf[bufIndex] = (byte)stack[stackIndex]; + bufIndex++; + if (bufIndex == imageWidth) { + nextPutPixels(buf); + bufIndex = 0; + } + } + } + } + if (bufIndex != 0 && line < imageHeight) { + nextPutPixels(buf); + } +} +/** + * Decode the LZW-encoded bytes in the given byte stream + * into the given DeviceIndependentImage. + */ +public void decode(LEDataInputStream inputStream, ImageLoader loader, ImageData image, boolean interlaced, int depth) { + this.inputStream = inputStream; + this.loader = loader; + this.image = image; + this.interlaced = interlaced; + this.bitsPerPixel = depth; + initializeForDecoding(); + decode(); +} +/** + * Encode the image. + */ +void encode() { + nextPutCode(clearCode); + int lastPrefix = encodeLoop(); + nextPutCode(lastPrefix); + nextPutCode(endCode); + + // Write out last partial block + if (bitsLeft == 8) { + block[0] = (byte)(blockIndex - 1); // Nothing in last byte + } else { + block[0] = (byte)(blockIndex); // Last byte has data + } + writeBlock(); + + // Write out empty block to indicate the end (if needed) + if (block[0] != 0) { + block[0] = 0; + writeBlock(); + } +} +/** + * Encode the bytes into the given byte stream + * from the given DeviceIndependentImage. + */ +public void encode(LEDataOutputStream byteStream, ImageData image) { + this.outputStream = byteStream; + this.image = image; + initializeForEncoding(); + encode(); +} +/** + * Encoding loop broken out to allow early return. + */ +int encodeLoop() { + int pixel = nextPixel(); + boolean found; + LZWNode node; + while (true) { + int currentPrefix = pixel; + node = nodeStack[currentPrefix]; + found = true; + pixel = nextPixel(); + if (pixel < 0) + return currentPrefix; + while (found && (node.children != null)) { + node = node.children; + while (found && (node.suffix != pixel)) { + if (pixel < node.suffix) { + if (node.left == null) { + node.left = new LZWNode(); + found = false; + } + node = node.left; + } else { + if (node.right == null) { + node.right = new LZWNode(); + found = false; + } + node = node.right; + } + } + if (found) { + currentPrefix = node.code; + pixel = nextPixel(); + if (pixel < 0) + return currentPrefix; + } + } + if (found) { + node.children = new LZWNode(); + node = node.children; + } + node.children = null; + node.left = null; + node.right = null; + node.code = currentSlot; + node.prefix = currentPrefix; + node.suffix = pixel; + nextPutCode(currentPrefix); + currentSlot++; + // Off by one? + if (currentSlot < 4096) { + if (currentSlot > topSlot) { + codeSize++; + codeMask = maskTable[codeSize - 1]; + topSlot *= 2; + } + } else { + nextPutCode(clearCode); + for (int i = 0; i < nodeStack.length; i++) + nodeStack[i].children = null; + codeSize = bitsPerPixel + 1; + codeMask = maskTable[codeSize - 1]; + currentSlot = newCodes; + topSlot = 1 << codeSize; + } + } +} +/** + * Initialize the receiver for decoding the given + * byte array. + */ +void initializeForDecoding() { + pass = 1; + line = 0; + codeSize = bitsPerPixel + 1; + topSlot = 1 << codeSize; + clearCode = 1 << bitsPerPixel; + endCode = clearCode + 1; + newCodes = currentSlot = endCode + 1; + currentByte = -1; + blockSize = bitsLeft = 0; + blockIndex = 0; + maskTable = new int[] { + 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, + 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF + }; + codeMask = maskTable[codeSize - 1]; + stack = new int[4096]; + suffix = new int[4096]; + prefix = new int[4096]; + block = new byte[256]; + imageWidth = image.width; + imageHeight = image.height; +} +/** + * Initialize the receiver for encoding the given + * byte array. + */ +void initializeForEncoding() { + interlaced = false; + bitsPerPixel = image.depth; + codeSize = bitsPerPixel + 1; + topSlot = 1 << codeSize; + clearCode = 1 << bitsPerPixel; + endCode = clearCode + 1; + newCodes = currentSlot = endCode + 1; + bitsLeft = 8; + currentByte = 0; + blockIndex = 1; + blockSize = 255; + block = new byte[blockSize]; + block[0] = (byte)(blockSize - 1); + maskTable = new int[] { + 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, + 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF + }; + nodeStack = new LZWNode[1 << bitsPerPixel]; + for (int i = 0; i < nodeStack.length; i++) { + LZWNode node = new LZWNode(); + node.code = i + 1; + node.prefix = -1; + node.suffix = i + 1; + nodeStack[i] = node; + } + imageWidth = image.width; + imageHeight = image.height; + imageY = -1; + lineArray = new byte[imageWidth]; + imageX = imageWidth + 1; // Force a read +} +/** + * Answer the next code from the input byte array. + */ +int nextCode() { + int code; + if (bitsLeft == 0) { + if (blockIndex >= blockSize) { + blockSize = readBlock(); + blockIndex = 0; + if (blockSize == 0) return endCode; + } + blockIndex++; + currentByte = block[blockIndex] & 0xFF; + bitsLeft = 8; + code = currentByte; + } else { + int shift = bitsLeft - 8; + if (shift < 0) + code = currentByte >> (0 - shift); + else + code = currentByte << shift; + } + while (codeSize > bitsLeft) { + if (blockIndex >= blockSize) { + blockSize = readBlock(); + blockIndex = 0; + if (blockSize == 0) return endCode; + } + blockIndex++; + currentByte = block[blockIndex] & 0xFF; + code += currentByte << bitsLeft; + bitsLeft += 8; + } + bitsLeft -= codeSize; + return code & codeMask; +} +/** + * Answer the next pixel to encode in the image + */ +int nextPixel() { + imageX++; + if (imageX > imageWidth) { + imageY++; + if (imageY >= imageHeight) { + return -1; + } else { + nextPixels(lineArray, imageWidth); + } + imageX = 1; + } + return this.lineArray[imageX - 1] & 0xFF; +} +/** + * Copy a row of pixel values from the image. + */ +void nextPixels(byte[] buf, int lineWidth) { + if (image.depth == 8) { + System.arraycopy(image.data, imageY * image.bytesPerLine, buf, 0, lineWidth); + } else { + image.getPixels(0, imageY, lineWidth, buf, 0); + } +} +/** + * Output aCode to the output stream. + */ +void nextPutCode(int aCode) { + int codeToDo = aCode; + int codeBitsToDo = codeSize; + // Fill in the remainder of the current byte with the + // *high-order* bits of the code. + int c = codeToDo & maskTable[bitsLeft - 1]; + currentByte = currentByte | (c << (8 - bitsLeft)); + block[blockIndex] = (byte)currentByte; + codeBitsToDo -= bitsLeft; + if (codeBitsToDo < 1) { + // The whole code fit in the first byte, so we are done. + bitsLeft -= codeSize; + if (bitsLeft == 0) { + // We used the whole last byte, so get ready + // for the next one. + bitsLeft = 8; + blockIndex++; + if (blockIndex >= blockSize) { + writeBlock(); + blockIndex = 1; + } + currentByte = 0; + } + return; + } + codeToDo = codeToDo >> bitsLeft; + + // Fill in any remaining whole bytes (i.e. not the last one!) + blockIndex++; + if (blockIndex >= blockSize) { + writeBlock(); + blockIndex = 1; + } + while (codeBitsToDo >= 8) { + currentByte = codeToDo & 0xFF; + block[blockIndex] = (byte)currentByte; + codeToDo = codeToDo >> 8; + codeBitsToDo -= 8; + blockIndex++; + if (blockIndex >= blockSize) { + writeBlock(); + blockIndex = 1; + } + } + // Fill the *low-order* bits of the last byte with the remainder + bitsLeft = 8 - codeBitsToDo; + currentByte = codeToDo; + block[blockIndex] = (byte)currentByte; +} +/** + * Copy a row of pixel values to the image. + */ +void nextPutPixels(byte[] buf) { + if (image.depth == 8) { + // Slight optimization for depth = 8. + int start = line * image.bytesPerLine; + for (int i = 0; i < imageWidth; i++) + image.data[start + i] = buf[i]; + } else { + image.setPixels(0, line, imageWidth, buf, 0); + } + if (interlaced) { + if (pass == 1) { + copyRow(buf, 7); + line += 8; + } else if (pass == 2) { + copyRow(buf, 3); + line += 8; + } else if (pass == 3) { + copyRow(buf, 1); + line += 4; + } else if (pass == 4) { + line += 2; + } else if (pass == 5) { + line += 0; + } + if (line >= imageHeight) { + pass++; + if (pass == 2) line = 4; + else if (pass == 3) line = 2; + else if (pass == 4) line = 1; + else if (pass == 5) line = 0; + if (pass < 5) { + if (loader.hasListeners()) { + ImageData imageCopy = (ImageData) image.clone(); + loader.notifyListeners( + new ImageLoaderEvent(loader, imageCopy, pass - 2, false)); + } + } + } + if (line >= imageHeight) line = 0; + } else { + line++; + } +} +/** + * Copy duplicate rows of pixel values to the image. + * This is to fill in rows if the image is interlaced. + */ +void copyRow(byte[] buf, int copies) { + for (int i = 1; i <= copies; i++) { + if (line + i < imageHeight) { + image.setPixels(0, line + i, imageWidth, buf, 0); + } + } +} +/** + * Read a block from the byte stream. + * Return the number of bytes read. + * Throw an exception if the block could not be read. + */ +int readBlock() { + int size = -1; + try { + size = inputStream.read(); + if (size == -1) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + block[0] = (byte)size; + size = inputStream.read(block, 1, size); + if (size == -1) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } + return size; +} +/** + * Write a block to the byte stream. + * Throw an exception if the block could not be written. + */ +void writeBlock() { + try { + outputStream.write(block, 0, (block[0] & 0xFF) + 1); + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWNode.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWNode.java index b53e45cf8e..0a0eb64344 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWNode.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/LZWNode.java @@ -1,13 +1,13 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-final class LZWNode {
- public LZWNode left, right, children;
- public int code, prefix, suffix;
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +final class LZWNode { + public LZWNode left, right, children; + public int code, prefix, suffix; +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PNGFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PNGFileFormat.java index f1ab0ec561..af955def8a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PNGFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PNGFileFormat.java @@ -1,534 +1,534 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.*;
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-
-public class PNGFileFormat extends FileFormat {
- static final int SIGNATURE_LENGTH = 8;
- PngDecodingDataStream decodingStream;
- PngIhdrChunk headerChunk;
- PngPlteChunk paletteChunk;
- PngTrnsChunk trnsChunk;
- ImageData imageData;
- byte[] data;
- byte[] alphaPalette;
-
-/**
- * Skip over signature data. This has already been
- * verified in isPNGFile().
- */
-void readSignature() throws IOException {
- byte[] signature = new byte[SIGNATURE_LENGTH];
- inputStream.read(signature);
-}
-/**
- * Load the PNG image from the byte stream.
- */
-ImageData[] loadFromByteStream() {
- try {
- readSignature();
- PngChunkReader chunkReader = new PngChunkReader(inputStream);
- headerChunk = chunkReader.getIhdrChunk();
- int imageSize = getAlignedBytesPerRow() * headerChunk.getHeight();
- data = new byte[imageSize];
- imageData = ImageData.internal_new(
- headerChunk.getWidth(),
- headerChunk.getHeight(),
- headerChunk.getSwtBitsPerPixel(),
- new PaletteData(0, 0, 0),
- 4,
- data,
- 0,
- null,
- null,
- -1,
- -1,
- SWT.IMAGE_PNG,
- 0,
- 0,
- 0,
- 0);
-
- if (headerChunk.usesDirectColor()) {
- imageData.palette = headerChunk.getPaletteData();
- };
-
- // Read and process chunks until the IEND chunk is encountered.
- while (chunkReader.hasMoreChunks()) {
- readNextChunk(chunkReader);
- }
-
- return new ImageData[] {imageData};
- } catch (IOException e) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return null;
- }
-}
-/**
- * Read and handle the next chunk of data from the
- * PNG file.
- */
-void readNextChunk(PngChunkReader chunkReader) {
- PngChunk chunk = chunkReader.readNextChunk();
- switch (chunk.getChunkType()) {
- case PngChunk.CHUNK_IEND:
- break;
- case PngChunk.CHUNK_PLTE:
- if (!headerChunk.usesDirectColor()) {
- paletteChunk = (PngPlteChunk) chunk;
- imageData.palette = paletteChunk.getPaletteData();
- };
- break;
- case PngChunk.CHUNK_tRNS:
- PngTrnsChunk trnsChunk = (PngTrnsChunk) chunk;
- if (trnsChunk.getTransparencyType(headerChunk) ==
- PngTrnsChunk.TRANSPARENCY_TYPE_PIXEL)
- {
- imageData.transparentPixel =
- trnsChunk.getSwtTransparentPixel(headerChunk);
- } else {
- alphaPalette = trnsChunk.getAlphaValues(headerChunk, paletteChunk);
- }
- break;
- case PngChunk.CHUNK_IDAT:
- if (chunkReader.readPixelData()) {
- // All IDAT chunks in an image file must be
- // sequential. If the pixel data has already
- // been read and another IDAT block is encountered,
- // then this is an invalid image.
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- // Read in the pixel data for the image. This should
- // go through all the image's IDAT chunks.
- PngIdatChunk dataChunk = (PngIdatChunk) chunk;
- readPixelData(dataChunk, chunkReader);
- }
- break;
- default:
- if (chunk.isCritical()) {
- // All critical chunks must be supported.
- SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
- }
- }
-}
-void unloadIntoByteStream(ImageData p1) {
- SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
-}
-boolean isFileFormat(LEDataInputStream stream) {
- try {
- byte[] signature = new byte[SIGNATURE_LENGTH];
- stream.read(signature);
- stream.unread(signature);
- if ((signature[0] & 0xFF) != 137) return false; //137
- if ((signature[1] & 0xFF) != 80) return false; //P
- if ((signature[2] & 0xFF) != 78) return false; //N
- if ((signature[3] & 0xFF) != 71) return false; //G
- if ((signature[4] & 0xFF) != 13) return false; //<RETURN>
- if ((signature[5] & 0xFF) != 10) return false; //<LINEFEED>
- if ((signature[6] & 0xFF) != 26) return false; //<CTRL/Z>
- if ((signature[7] & 0xFF) != 10) return false; //<LINEFEED>
- return true;
- } catch (Exception e) {
- return false;
- }
-}
-/**
- * SWT does not support 16-bit depths. If this image uses
- * 16-bit depths, convert the data to an 8-bit depth.
- */
-byte[] validateBitDepth(byte[] data) {
- if (headerChunk.getBitDepth() > 8) {
- byte[] result = new byte[data.length / 2];
- compress16BitDepthTo8BitDepth(data, 0, result, 0, result.length);
- return result;
- } else {
- return data;
- }
-}
-/**
- * SWT does not support greyscale as a color type. For
- * plain grayscale, we create a palette. For Grayscale
- * with Alpha, however, we need to convert the pixels
- * to use RGB values.
- * Note: This method assumes that the bit depth of the
- * data has already been restricted to 8 or less.
- */
-void setPixelData(byte[] data, ImageData imageData) {
- switch (headerChunk.getColorType()) {
- case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- {
- int width = imageData.width;
- int height = imageData.height;
- int destBytesPerLine = imageData.bytesPerLine;
- /*
- * If the image uses 16-bit depth, it is converted
- * to an 8-bit depth image.
- */
- int srcBytesPerLine = getAlignedBytesPerRow();
- if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2;
-
- byte[] rgbData = new byte[destBytesPerLine * height];
- byte[] alphaData = new byte[width * height];
- for (int y = 0; y < height; y++) {
- int srcIndex = srcBytesPerLine * y;
- int destIndex = destBytesPerLine * y;
- int destAlphaIndex = width * y;
- for (int x = 0; x < width; x++) {
- byte grey = data[srcIndex];
- byte alpha = data[srcIndex + 1];
- rgbData[destIndex + 0] = grey;
- rgbData[destIndex + 1] = grey;
- rgbData[destIndex + 2] = grey;
- alphaData[destAlphaIndex] = alpha;
- srcIndex += 2;
- destIndex += 3;
- destAlphaIndex++;
- }
- }
- imageData.data = rgbData;
- imageData.alphaData = alphaData;
- break;
- }
- case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
- {
- int width = imageData.width;
- int height = imageData.height;
- int destBytesPerLine = imageData.bytesPerLine;
- int srcBytesPerLine = getAlignedBytesPerRow();
- /*
- * If the image uses 16-bit depth, it is converted
- * to an 8-bit depth image.
- */
- if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2;
-
- byte[] rgbData = new byte[destBytesPerLine * height];
- byte[] alphaData = new byte[width * height];
- for (int y = 0; y < height; y++) {
- int srcIndex = srcBytesPerLine * y;
- int destIndex = destBytesPerLine * y;
- int destAlphaIndex = width * y;
- for (int x = 0; x < width; x++) {
- rgbData[destIndex + 0] = data[srcIndex + 0];
- rgbData[destIndex + 1] = data[srcIndex + 1];
- rgbData[destIndex + 2] = data[srcIndex + 2];
- alphaData[destAlphaIndex] = data[srcIndex + 3];
- srcIndex += 4;
- destIndex += 3;
- destAlphaIndex++;
- }
- }
- imageData.data = rgbData;
- imageData.alphaData = alphaData;
- break;
- }
- case PngIhdrChunk.COLOR_TYPE_RGB:
- imageData.data = data;
- break;
- case PngIhdrChunk.COLOR_TYPE_PALETTE:
- imageData.data = data;
- if (alphaPalette != null) {
- int size = imageData.width * imageData.height;
- byte[] alphaData = new byte[size];
- byte[] pixelData = new byte[size];
- imageData.getPixels(0, 0, size, pixelData, 0);
- for (int i = 0; i < pixelData.length; i++) {
- alphaData[i] = alphaPalette[pixelData[i] & 0xFF];
- }
- imageData.alphaData = alphaData;
- }
- break;
- default:
- imageData.data = data;
- break;
- }
-}
-/**
- * PNG supports some color types and bit depths that are
- * unsupported by SWT. If the image uses an unsupported
- * color type (either of the gray scale types) or bit
- * depth (16), convert the data to an SWT-supported
- * format. Then assign the data into the ImageData given.
- */
-void setImageDataValues(byte[] data, ImageData imageData) {
- byte[] result = validateBitDepth(data);
- setPixelData(result, imageData);
-}
-/**
- * Read the image data from the data stream. This must handle
- * decoding the data, filtering, and interlacing.
- */
-void readPixelData(PngIdatChunk chunk, PngChunkReader chunkReader) {
- decodingStream = new PngDecodingDataStream(chunk, chunkReader);
- int interlaceMethod = headerChunk.getInterlaceMethod();
- if (interlaceMethod == PngIhdrChunk.INTERLACE_METHOD_NONE) {
- readNonInterlacedImage();
- } else {
- readInterlacedImage();
- }
- decodingStream.assertImageDataAtEnd();
- decodingStream.checkAdler();
-}
-/**
- * Answer the number of bytes in a word-aligned row of pixel data.
- */
-int getAlignedBytesPerRow() {
- return ((getBytesPerRow(headerChunk.getWidth()) + 3) / 4) * 4;
-}
-/**
- * Answer the number of bytes in each row of the image
- * data. Each PNG row is byte-aligned, so images with bit
- * depths less than a byte may have unused bits at the
- * end of each row. The value of these bits is undefined.
- */
-int getBytesPerRow() {
- return getBytesPerRow(headerChunk.getWidth());
-}
-/**
- * Answer the number of bytes needed to represent a pixel.
- * This value depends on the image's color type and bit
- * depth.
- * Note that this method rounds up if an image's pixel size
- * isn't byte-aligned.
- */
-int getBytesPerPixel() {
- int bitsPerPixel = headerChunk.getBitsPerPixel();
- return (bitsPerPixel + 7) / 8;
-}
-/**
- * Answer the number of bytes in a row of the given pixel
- * width. Each row is byte-aligned, so images with bit
- * depths less than a byte may have unused bits at the
- * end of each row. The value of these bits is undefined.
- */
-int getBytesPerRow(int rowWidthInPixels) {
- int bitsPerPixel = headerChunk.getBitsPerPixel();
- int bitsPerRow = bitsPerPixel * rowWidthInPixels;
- int bitsPerByte = 8;
- return (bitsPerRow + (bitsPerByte - 1)) / bitsPerByte;
-}
-/**
- * 1. Read one of the seven frames of interlaced data.
- * 2. Update the imageData.
- * 3. Notify the image loader's listeners of the frame load.
- */
-void readInterlaceFrame(
- int rowInterval,
- int columnInterval,
- int startRow,
- int startColumn,
- int frameCount)
-{
- int width = headerChunk.getWidth();
- int alignedBytesPerRow = getAlignedBytesPerRow();
- int height = headerChunk.getHeight();
- if (startRow >= height || startColumn >= width) return;
-
- int pixelsPerRow = (width - startColumn + columnInterval - 1) / columnInterval;
- int bytesPerRow = getBytesPerRow(pixelsPerRow);
- byte[] row1 = new byte[bytesPerRow];
- byte[] row2 = new byte[bytesPerRow];
- byte[] currentRow = row1;
- byte[] lastRow = row2;
- for (int row = startRow; row < height; row += rowInterval) {
- byte filterType = decodingStream.getNextDecodedByte();
- for (int col = 0; col < bytesPerRow; col++) {
- currentRow[col] = decodingStream.getNextDecodedByte();
- }
- filterRow(currentRow, lastRow, filterType);
- if (headerChunk.getBitDepth() >= 8) {
- int bytesPerPixel = getBytesPerPixel();
- int dataOffset = (row * alignedBytesPerRow) + (startColumn * bytesPerPixel);
- for (int rowOffset = 0; rowOffset < currentRow.length; rowOffset += bytesPerPixel) {
- for (int byteOffset = 0; byteOffset < bytesPerPixel; byteOffset++) {
- data[dataOffset + byteOffset] = currentRow[rowOffset + byteOffset];
- }
- dataOffset += (columnInterval * bytesPerPixel);
- }
- } else {
- int bitsPerPixel = headerChunk.getBitDepth();
- int pixelsPerByte = 8 / bitsPerPixel;
- int column = startColumn;
- int rowBase = row * alignedBytesPerRow;
- int valueMask = 0;
- for (int i = 0; i < bitsPerPixel; i++) {
- valueMask <<= 1;
- valueMask |= 1;
- }
- int maxShift = 8 - bitsPerPixel;
- for (int byteOffset = 0; byteOffset < currentRow.length; byteOffset++) {
- for (int bitOffset = maxShift; bitOffset >= 0; bitOffset -= bitsPerPixel) {
- if (column < width) {
- int dataOffset = rowBase + (column * bitsPerPixel / 8);
- int value = (currentRow[byteOffset] >> bitOffset) & valueMask;
- int dataShift = maxShift - (bitsPerPixel * (column % pixelsPerByte));
- data[dataOffset] |= value << dataShift;
- }
- column += columnInterval;
- }
- }
- }
- currentRow = (currentRow == row1) ? row2 : row1;
- lastRow = (lastRow == row1) ? row2 : row1;
- }
- setImageDataValues(data, imageData);
- fireInterlacedFrameEvent(frameCount);
-}
-/**
- * Read the pixel data for an interlaced image from the
- * data stream.
- */
-void readInterlacedImage() {
- readInterlaceFrame(8, 8, 0, 0, 0);
- readInterlaceFrame(8, 8, 0, 4, 1);
- readInterlaceFrame(8, 4, 4, 0, 2);
- readInterlaceFrame(4, 4, 0, 2, 3);
- readInterlaceFrame(4, 2, 2, 0, 4);
- readInterlaceFrame(2, 2, 0, 1, 5);
- readInterlaceFrame(2, 1, 1, 0, 6);
-}
-/**
- * Fire an event to let listeners know that an interlaced
- * frame has been loaded.
- * finalFrame should be true if the image has finished
- * loading, false if there are more frames to come.
- */
-void fireInterlacedFrameEvent(int frameCount) {
- if (loader.hasListeners()) {
- ImageData image = (ImageData) imageData.clone();
- boolean finalFrame = frameCount == 6;
- loader.notifyListeners(new ImageLoaderEvent(loader, image, frameCount, finalFrame));
- }
-}
-/**
- * Read the pixel data for a non-interlaced image from the
- * data stream.
- * Update the imageData to reflect the new data.
- */
-void readNonInterlacedImage() {
- int dataOffset = 0;
- int alignedBytesPerRow = getAlignedBytesPerRow();
- int bytesPerRow = getBytesPerRow();
- byte[] row1 = new byte[bytesPerRow];
- byte[] row2 = new byte[bytesPerRow];
- byte[] currentRow = row1;
- byte[] lastRow = row2;
- for (int row = 0; row < headerChunk.getHeight(); row++) {
- byte filterType = decodingStream.getNextDecodedByte();
- for (int col = 0; col < bytesPerRow; col++) {
- currentRow[col] = decodingStream.getNextDecodedByte();
- }
- filterRow(currentRow, lastRow, filterType);
- System.arraycopy(currentRow, 0, data, dataOffset, bytesPerRow);
- dataOffset += alignedBytesPerRow;
- currentRow = (currentRow == row1) ? row2 : row1;
- lastRow = (lastRow == row1) ? row2 : row1;
- }
- setImageDataValues(data, imageData);
-}
-/**
- * SWT does not support 16-bit depth color formats.
- * Convert the 16-bit data to 8-bit data.
- * The correct way to do this is to multiply each
- * 16 bit value by the value:
- * (2^8 - 1) / (2^16 - 1).
- * The fast way to do this is just to drop the low
- * byte of the 16-bit value.
- */
-static void compress16BitDepthTo8BitDepth(
- byte[] source,
- int sourceOffset,
- byte[] destination,
- int destinationOffset,
- int numberOfValues)
-{
- //double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1);
- for (int i = 0; i < numberOfValues; i++) {
- int sourceIndex = sourceOffset + (2 * i);
- int destinationIndex = destinationOffset + i;
- //int value = (source[sourceIndex] << 8) | source[sourceIndex + 1];
- //byte compressedValue = (byte)(value * multiplier);
- byte compressedValue = source[sourceIndex];
- destination[destinationIndex] = compressedValue;
- }
-}
-/**
- * SWT does not support 16-bit depth color formats.
- * Convert the 16-bit data to 8-bit data.
- * The correct way to do this is to multiply each
- * 16 bit value by the value:
- * (2^8 - 1) / (2^16 - 1).
- * The fast way to do this is just to drop the low
- * byte of the 16-bit value.
- */
-static int compress16BitDepthTo8BitDepth(int value) {
- //double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1);
- //byte compressedValue = (byte)(value * multiplier);
- return value >> 8;
-}
-/**
- * PNG supports four filtering types. These types are applied
- * per row of image data. This method unfilters the given row
- * based on the filterType.
- */
-void filterRow(byte[] row, byte[] previousRow, int filterType) {
- int byteOffset = headerChunk.getFilterByteOffset();
- switch (filterType) {
- case PngIhdrChunk.FILTER_NONE:
- break;
- case PngIhdrChunk.FILTER_SUB:
- for (int i = byteOffset; i < row.length; i++) {
- int current = row[i] & 0xFF;
- int left = row[i - byteOffset] & 0xFF;
- row[i] = (byte)((current + left) & 0xFF);
- }
- break;
- case PngIhdrChunk.FILTER_UP:
- for (int i = 0; i < row.length; i++) {
- int current = row[i] & 0xFF;
- int above = previousRow[i] & 0xFF;
- row[i] = (byte)((current + above) & 0xFF);
- }
- break;
- case PngIhdrChunk.FILTER_AVERAGE:
- for (int i = 0; i < row.length; i++) {
- int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF;
- int above = previousRow[i] & 0xFF;
- int current = row[i] & 0xFF;
- row[i] = (byte)((current + ((left + above) / 2)) & 0xFF);
- }
- break;
- case PngIhdrChunk.FILTER_PAETH:
- for (int i = 0; i < row.length; i++) {
- int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF;
- int aboveLeft = (i < byteOffset) ? 0 : previousRow[i - byteOffset] & 0xFF;
- int above = previousRow[i] & 0xFF;
-
- int a = Math.abs(above - aboveLeft);
- int b = Math.abs(left - aboveLeft);
- int c = Math.abs(left - aboveLeft + above - aboveLeft);
-
- int preductor = 0;
- if (a <= b && a <= c) {
- preductor = left;
- } else if (b <= c) {
- preductor = above;
- } else {
- preductor = aboveLeft;
- }
-
- int currentValue = row[i] & 0xFF;
- row[i] = (byte) ((currentValue + preductor) & 0xFF);
- }
- break;
- }
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import java.io.*; +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; + +public class PNGFileFormat extends FileFormat { + static final int SIGNATURE_LENGTH = 8; + PngDecodingDataStream decodingStream; + PngIhdrChunk headerChunk; + PngPlteChunk paletteChunk; + PngTrnsChunk trnsChunk; + ImageData imageData; + byte[] data; + byte[] alphaPalette; + +/** + * Skip over signature data. This has already been + * verified in isPNGFile(). + */ +void readSignature() throws IOException { + byte[] signature = new byte[SIGNATURE_LENGTH]; + inputStream.read(signature); +} +/** + * Load the PNG image from the byte stream. + */ +ImageData[] loadFromByteStream() { + try { + readSignature(); + PngChunkReader chunkReader = new PngChunkReader(inputStream); + headerChunk = chunkReader.getIhdrChunk(); + int imageSize = getAlignedBytesPerRow() * headerChunk.getHeight(); + data = new byte[imageSize]; + imageData = ImageData.internal_new( + headerChunk.getWidth(), + headerChunk.getHeight(), + headerChunk.getSwtBitsPerPixel(), + new PaletteData(0, 0, 0), + 4, + data, + 0, + null, + null, + -1, + -1, + SWT.IMAGE_PNG, + 0, + 0, + 0, + 0); + + if (headerChunk.usesDirectColor()) { + imageData.palette = headerChunk.getPaletteData(); + }; + + // Read and process chunks until the IEND chunk is encountered. + while (chunkReader.hasMoreChunks()) { + readNextChunk(chunkReader); + } + + return new ImageData[] {imageData}; + } catch (IOException e) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + return null; + } +} +/** + * Read and handle the next chunk of data from the + * PNG file. + */ +void readNextChunk(PngChunkReader chunkReader) { + PngChunk chunk = chunkReader.readNextChunk(); + switch (chunk.getChunkType()) { + case PngChunk.CHUNK_IEND: + break; + case PngChunk.CHUNK_PLTE: + if (!headerChunk.usesDirectColor()) { + paletteChunk = (PngPlteChunk) chunk; + imageData.palette = paletteChunk.getPaletteData(); + }; + break; + case PngChunk.CHUNK_tRNS: + PngTrnsChunk trnsChunk = (PngTrnsChunk) chunk; + if (trnsChunk.getTransparencyType(headerChunk) == + PngTrnsChunk.TRANSPARENCY_TYPE_PIXEL) + { + imageData.transparentPixel = + trnsChunk.getSwtTransparentPixel(headerChunk); + } else { + alphaPalette = trnsChunk.getAlphaValues(headerChunk, paletteChunk); + } + break; + case PngChunk.CHUNK_IDAT: + if (chunkReader.readPixelData()) { + // All IDAT chunks in an image file must be + // sequential. If the pixel data has already + // been read and another IDAT block is encountered, + // then this is an invalid image. + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + // Read in the pixel data for the image. This should + // go through all the image's IDAT chunks. + PngIdatChunk dataChunk = (PngIdatChunk) chunk; + readPixelData(dataChunk, chunkReader); + } + break; + default: + if (chunk.isCritical()) { + // All critical chunks must be supported. + SWT.error(SWT.ERROR_NOT_IMPLEMENTED); + } + } +} +void unloadIntoByteStream(ImageData p1) { + SWT.error(SWT.ERROR_NOT_IMPLEMENTED); +} +boolean isFileFormat(LEDataInputStream stream) { + try { + byte[] signature = new byte[SIGNATURE_LENGTH]; + stream.read(signature); + stream.unread(signature); + if ((signature[0] & 0xFF) != 137) return false; //137 + if ((signature[1] & 0xFF) != 80) return false; //P + if ((signature[2] & 0xFF) != 78) return false; //N + if ((signature[3] & 0xFF) != 71) return false; //G + if ((signature[4] & 0xFF) != 13) return false; //<RETURN> + if ((signature[5] & 0xFF) != 10) return false; //<LINEFEED> + if ((signature[6] & 0xFF) != 26) return false; //<CTRL/Z> + if ((signature[7] & 0xFF) != 10) return false; //<LINEFEED> + return true; + } catch (Exception e) { + return false; + } +} +/** + * SWT does not support 16-bit depths. If this image uses + * 16-bit depths, convert the data to an 8-bit depth. + */ +byte[] validateBitDepth(byte[] data) { + if (headerChunk.getBitDepth() > 8) { + byte[] result = new byte[data.length / 2]; + compress16BitDepthTo8BitDepth(data, 0, result, 0, result.length); + return result; + } else { + return data; + } +} +/** + * SWT does not support greyscale as a color type. For + * plain grayscale, we create a palette. For Grayscale + * with Alpha, however, we need to convert the pixels + * to use RGB values. + * Note: This method assumes that the bit depth of the + * data has already been restricted to 8 or less. + */ +void setPixelData(byte[] data, ImageData imageData) { + switch (headerChunk.getColorType()) { + case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + { + int width = imageData.width; + int height = imageData.height; + int destBytesPerLine = imageData.bytesPerLine; + /* + * If the image uses 16-bit depth, it is converted + * to an 8-bit depth image. + */ + int srcBytesPerLine = getAlignedBytesPerRow(); + if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2; + + byte[] rgbData = new byte[destBytesPerLine * height]; + byte[] alphaData = new byte[width * height]; + for (int y = 0; y < height; y++) { + int srcIndex = srcBytesPerLine * y; + int destIndex = destBytesPerLine * y; + int destAlphaIndex = width * y; + for (int x = 0; x < width; x++) { + byte grey = data[srcIndex]; + byte alpha = data[srcIndex + 1]; + rgbData[destIndex + 0] = grey; + rgbData[destIndex + 1] = grey; + rgbData[destIndex + 2] = grey; + alphaData[destAlphaIndex] = alpha; + srcIndex += 2; + destIndex += 3; + destAlphaIndex++; + } + } + imageData.data = rgbData; + imageData.alphaData = alphaData; + break; + } + case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA: + { + int width = imageData.width; + int height = imageData.height; + int destBytesPerLine = imageData.bytesPerLine; + int srcBytesPerLine = getAlignedBytesPerRow(); + /* + * If the image uses 16-bit depth, it is converted + * to an 8-bit depth image. + */ + if (headerChunk.getBitDepth() > 8) srcBytesPerLine /= 2; + + byte[] rgbData = new byte[destBytesPerLine * height]; + byte[] alphaData = new byte[width * height]; + for (int y = 0; y < height; y++) { + int srcIndex = srcBytesPerLine * y; + int destIndex = destBytesPerLine * y; + int destAlphaIndex = width * y; + for (int x = 0; x < width; x++) { + rgbData[destIndex + 0] = data[srcIndex + 0]; + rgbData[destIndex + 1] = data[srcIndex + 1]; + rgbData[destIndex + 2] = data[srcIndex + 2]; + alphaData[destAlphaIndex] = data[srcIndex + 3]; + srcIndex += 4; + destIndex += 3; + destAlphaIndex++; + } + } + imageData.data = rgbData; + imageData.alphaData = alphaData; + break; + } + case PngIhdrChunk.COLOR_TYPE_RGB: + imageData.data = data; + break; + case PngIhdrChunk.COLOR_TYPE_PALETTE: + imageData.data = data; + if (alphaPalette != null) { + int size = imageData.width * imageData.height; + byte[] alphaData = new byte[size]; + byte[] pixelData = new byte[size]; + imageData.getPixels(0, 0, size, pixelData, 0); + for (int i = 0; i < pixelData.length; i++) { + alphaData[i] = alphaPalette[pixelData[i] & 0xFF]; + } + imageData.alphaData = alphaData; + } + break; + default: + imageData.data = data; + break; + } +} +/** + * PNG supports some color types and bit depths that are + * unsupported by SWT. If the image uses an unsupported + * color type (either of the gray scale types) or bit + * depth (16), convert the data to an SWT-supported + * format. Then assign the data into the ImageData given. + */ +void setImageDataValues(byte[] data, ImageData imageData) { + byte[] result = validateBitDepth(data); + setPixelData(result, imageData); +} +/** + * Read the image data from the data stream. This must handle + * decoding the data, filtering, and interlacing. + */ +void readPixelData(PngIdatChunk chunk, PngChunkReader chunkReader) { + decodingStream = new PngDecodingDataStream(chunk, chunkReader); + int interlaceMethod = headerChunk.getInterlaceMethod(); + if (interlaceMethod == PngIhdrChunk.INTERLACE_METHOD_NONE) { + readNonInterlacedImage(); + } else { + readInterlacedImage(); + } + decodingStream.assertImageDataAtEnd(); + decodingStream.checkAdler(); +} +/** + * Answer the number of bytes in a word-aligned row of pixel data. + */ +int getAlignedBytesPerRow() { + return ((getBytesPerRow(headerChunk.getWidth()) + 3) / 4) * 4; +} +/** + * Answer the number of bytes in each row of the image + * data. Each PNG row is byte-aligned, so images with bit + * depths less than a byte may have unused bits at the + * end of each row. The value of these bits is undefined. + */ +int getBytesPerRow() { + return getBytesPerRow(headerChunk.getWidth()); +} +/** + * Answer the number of bytes needed to represent a pixel. + * This value depends on the image's color type and bit + * depth. + * Note that this method rounds up if an image's pixel size + * isn't byte-aligned. + */ +int getBytesPerPixel() { + int bitsPerPixel = headerChunk.getBitsPerPixel(); + return (bitsPerPixel + 7) / 8; +} +/** + * Answer the number of bytes in a row of the given pixel + * width. Each row is byte-aligned, so images with bit + * depths less than a byte may have unused bits at the + * end of each row. The value of these bits is undefined. + */ +int getBytesPerRow(int rowWidthInPixels) { + int bitsPerPixel = headerChunk.getBitsPerPixel(); + int bitsPerRow = bitsPerPixel * rowWidthInPixels; + int bitsPerByte = 8; + return (bitsPerRow + (bitsPerByte - 1)) / bitsPerByte; +} +/** + * 1. Read one of the seven frames of interlaced data. + * 2. Update the imageData. + * 3. Notify the image loader's listeners of the frame load. + */ +void readInterlaceFrame( + int rowInterval, + int columnInterval, + int startRow, + int startColumn, + int frameCount) +{ + int width = headerChunk.getWidth(); + int alignedBytesPerRow = getAlignedBytesPerRow(); + int height = headerChunk.getHeight(); + if (startRow >= height || startColumn >= width) return; + + int pixelsPerRow = (width - startColumn + columnInterval - 1) / columnInterval; + int bytesPerRow = getBytesPerRow(pixelsPerRow); + byte[] row1 = new byte[bytesPerRow]; + byte[] row2 = new byte[bytesPerRow]; + byte[] currentRow = row1; + byte[] lastRow = row2; + for (int row = startRow; row < height; row += rowInterval) { + byte filterType = decodingStream.getNextDecodedByte(); + for (int col = 0; col < bytesPerRow; col++) { + currentRow[col] = decodingStream.getNextDecodedByte(); + } + filterRow(currentRow, lastRow, filterType); + if (headerChunk.getBitDepth() >= 8) { + int bytesPerPixel = getBytesPerPixel(); + int dataOffset = (row * alignedBytesPerRow) + (startColumn * bytesPerPixel); + for (int rowOffset = 0; rowOffset < currentRow.length; rowOffset += bytesPerPixel) { + for (int byteOffset = 0; byteOffset < bytesPerPixel; byteOffset++) { + data[dataOffset + byteOffset] = currentRow[rowOffset + byteOffset]; + } + dataOffset += (columnInterval * bytesPerPixel); + } + } else { + int bitsPerPixel = headerChunk.getBitDepth(); + int pixelsPerByte = 8 / bitsPerPixel; + int column = startColumn; + int rowBase = row * alignedBytesPerRow; + int valueMask = 0; + for (int i = 0; i < bitsPerPixel; i++) { + valueMask <<= 1; + valueMask |= 1; + } + int maxShift = 8 - bitsPerPixel; + for (int byteOffset = 0; byteOffset < currentRow.length; byteOffset++) { + for (int bitOffset = maxShift; bitOffset >= 0; bitOffset -= bitsPerPixel) { + if (column < width) { + int dataOffset = rowBase + (column * bitsPerPixel / 8); + int value = (currentRow[byteOffset] >> bitOffset) & valueMask; + int dataShift = maxShift - (bitsPerPixel * (column % pixelsPerByte)); + data[dataOffset] |= value << dataShift; + } + column += columnInterval; + } + } + } + currentRow = (currentRow == row1) ? row2 : row1; + lastRow = (lastRow == row1) ? row2 : row1; + } + setImageDataValues(data, imageData); + fireInterlacedFrameEvent(frameCount); +} +/** + * Read the pixel data for an interlaced image from the + * data stream. + */ +void readInterlacedImage() { + readInterlaceFrame(8, 8, 0, 0, 0); + readInterlaceFrame(8, 8, 0, 4, 1); + readInterlaceFrame(8, 4, 4, 0, 2); + readInterlaceFrame(4, 4, 0, 2, 3); + readInterlaceFrame(4, 2, 2, 0, 4); + readInterlaceFrame(2, 2, 0, 1, 5); + readInterlaceFrame(2, 1, 1, 0, 6); +} +/** + * Fire an event to let listeners know that an interlaced + * frame has been loaded. + * finalFrame should be true if the image has finished + * loading, false if there are more frames to come. + */ +void fireInterlacedFrameEvent(int frameCount) { + if (loader.hasListeners()) { + ImageData image = (ImageData) imageData.clone(); + boolean finalFrame = frameCount == 6; + loader.notifyListeners(new ImageLoaderEvent(loader, image, frameCount, finalFrame)); + } +} +/** + * Read the pixel data for a non-interlaced image from the + * data stream. + * Update the imageData to reflect the new data. + */ +void readNonInterlacedImage() { + int dataOffset = 0; + int alignedBytesPerRow = getAlignedBytesPerRow(); + int bytesPerRow = getBytesPerRow(); + byte[] row1 = new byte[bytesPerRow]; + byte[] row2 = new byte[bytesPerRow]; + byte[] currentRow = row1; + byte[] lastRow = row2; + for (int row = 0; row < headerChunk.getHeight(); row++) { + byte filterType = decodingStream.getNextDecodedByte(); + for (int col = 0; col < bytesPerRow; col++) { + currentRow[col] = decodingStream.getNextDecodedByte(); + } + filterRow(currentRow, lastRow, filterType); + System.arraycopy(currentRow, 0, data, dataOffset, bytesPerRow); + dataOffset += alignedBytesPerRow; + currentRow = (currentRow == row1) ? row2 : row1; + lastRow = (lastRow == row1) ? row2 : row1; + } + setImageDataValues(data, imageData); +} +/** + * SWT does not support 16-bit depth color formats. + * Convert the 16-bit data to 8-bit data. + * The correct way to do this is to multiply each + * 16 bit value by the value: + * (2^8 - 1) / (2^16 - 1). + * The fast way to do this is just to drop the low + * byte of the 16-bit value. + */ +static void compress16BitDepthTo8BitDepth( + byte[] source, + int sourceOffset, + byte[] destination, + int destinationOffset, + int numberOfValues) +{ + //double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1); + for (int i = 0; i < numberOfValues; i++) { + int sourceIndex = sourceOffset + (2 * i); + int destinationIndex = destinationOffset + i; + //int value = (source[sourceIndex] << 8) | source[sourceIndex + 1]; + //byte compressedValue = (byte)(value * multiplier); + byte compressedValue = source[sourceIndex]; + destination[destinationIndex] = compressedValue; + } +} +/** + * SWT does not support 16-bit depth color formats. + * Convert the 16-bit data to 8-bit data. + * The correct way to do this is to multiply each + * 16 bit value by the value: + * (2^8 - 1) / (2^16 - 1). + * The fast way to do this is just to drop the low + * byte of the 16-bit value. + */ +static int compress16BitDepthTo8BitDepth(int value) { + //double multiplier = (Compatibility.pow2(8) - 1) / (Compatibility.pow2(16) - 1); + //byte compressedValue = (byte)(value * multiplier); + return value >> 8; +} +/** + * PNG supports four filtering types. These types are applied + * per row of image data. This method unfilters the given row + * based on the filterType. + */ +void filterRow(byte[] row, byte[] previousRow, int filterType) { + int byteOffset = headerChunk.getFilterByteOffset(); + switch (filterType) { + case PngIhdrChunk.FILTER_NONE: + break; + case PngIhdrChunk.FILTER_SUB: + for (int i = byteOffset; i < row.length; i++) { + int current = row[i] & 0xFF; + int left = row[i - byteOffset] & 0xFF; + row[i] = (byte)((current + left) & 0xFF); + } + break; + case PngIhdrChunk.FILTER_UP: + for (int i = 0; i < row.length; i++) { + int current = row[i] & 0xFF; + int above = previousRow[i] & 0xFF; + row[i] = (byte)((current + above) & 0xFF); + } + break; + case PngIhdrChunk.FILTER_AVERAGE: + for (int i = 0; i < row.length; i++) { + int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF; + int above = previousRow[i] & 0xFF; + int current = row[i] & 0xFF; + row[i] = (byte)((current + ((left + above) / 2)) & 0xFF); + } + break; + case PngIhdrChunk.FILTER_PAETH: + for (int i = 0; i < row.length; i++) { + int left = (i < byteOffset) ? 0 : row[i - byteOffset] & 0xFF; + int aboveLeft = (i < byteOffset) ? 0 : previousRow[i - byteOffset] & 0xFF; + int above = previousRow[i] & 0xFF; + + int a = Math.abs(above - aboveLeft); + int b = Math.abs(left - aboveLeft); + int c = Math.abs(left - aboveLeft + above - aboveLeft); + + int preductor = 0; + if (a <= b && a <= c) { + preductor = left; + } else if (b <= c) { + preductor = above; + } else { + preductor = aboveLeft; + } + + int currentValue = row[i] & 0xFF; + row[i] = (byte) ((currentValue + preductor) & 0xFF); + } + break; + } +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunk.java index 534e333671..a74f3d9d18 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunk.java @@ -1,336 +1,336 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.internal.Compatibility;
-import java.io.*;
-
-class PngChunk extends Object {
- byte[] reference;
-
- static final int LENGTH_OFFSET = 0;
- static final int TYPE_OFFSET = 4;
- static final int DATA_OFFSET = 8;
-
- static final int TYPE_FIELD_LENGTH = 4;
- static final int LENGTH_FIELD_LENGTH = 4;
- static final int MIN_LENGTH = 12;
-
- static final int CHUNK_UNKNOWN = -1;
- // Critical chunks.
- static final int CHUNK_IHDR = 0;
- static final int CHUNK_PLTE = 1;
- static final int CHUNK_IDAT = 2;
- static final int CHUNK_IEND = 3;
- // Non-critical chunks.
- static final int CHUNK_tRNS = 5;
-
- static final byte[] TYPE_IHDR = {(byte) 'I', (byte) 'H', (byte) 'D', (byte) 'R'};
- static final byte[] TYPE_PLTE = {(byte) 'P', (byte) 'L', (byte) 'T', (byte) 'E'};
- static final byte[] TYPE_IDAT = {(byte) 'I', (byte) 'D', (byte) 'A', (byte) 'T'};
- static final byte[] TYPE_IEND = {(byte) 'I', (byte) 'E', (byte) 'N', (byte) 'D'};
- static final byte[] TYPE_tRNS = {(byte) 't', (byte) 'R', (byte) 'N', (byte) 'S'};
-
- static final int[] CRC_TABLE;
- static {
- CRC_TABLE = new int[256];
- for (int i = 0; i < 256; i++) {
- CRC_TABLE[i] = i;
- for (int j = 0; j < 8; j++) {
- if ((CRC_TABLE[i] & 0x1) == 0) {
- CRC_TABLE[i] = (CRC_TABLE[i] >> 1) & 0x7FFFFFFF;
- } else {
- CRC_TABLE[i] = 0xEDB88320 ^ ((CRC_TABLE[i] >> 1) & 0x7FFFFFFF);
- }
- }
- }
- }
-
-/**
- * Construct a PngChunk using the reference bytes
- * given.
- */
-PngChunk(byte[] reference) {
- super();
- setReference(reference);
-}
-
-/**
- * Get the PngChunk's reference byteArray;
- */
-byte[] getReference() {
- return reference;
-}
-
-/**
- * Set the PngChunk's reference byteArray;
- */
-void setReference(byte[] reference) {
- this.reference = reference;
-}
-
-/**
- * Get the 32-bit integer from the reference byte
- * array at the given offset.
- */
-int getInt32(int offset) {
- int answer = 0;
- answer |= (reference[offset] & 0xFF) << 24;
- answer |= (reference[offset + 1] & 0xFF) << 16;
- answer |= (reference[offset + 2] & 0xFF) << 8;
- answer |= (reference[offset + 3] & 0xFF);
- return answer;
-}
-
-/**
- * Set the 32-bit integer in the reference byte
- * array at the given offset.
- */
-void setInt32(int offset, int value) {
- reference[offset] = (byte) ((value >> 24) & 0xFF);
- reference[offset + 1] = (byte) ((value >> 16) & 0xFF);
- reference[offset + 2] = (byte) ((value >> 8) & 0xFF);
- reference[offset + 3] = (byte) (value & 0xFF);
-}
-
-/**
- * Get the length of the data component of this chunk.
- * This is not the length of the entire chunk.
- */
-int getLength() {
- return getInt32(LENGTH_OFFSET);
-}
-
-/**
- * Set the length of the data component of this chunk.
- * This is not the length of the entire chunk.
- */
-void setLength(int value) {
- setInt32(LENGTH_OFFSET, value);
-}
-
-/**
- * Get the chunk type. This is a four byte value.
- * Each byte should be an ASCII character.
- * The first byte is upper case if the chunk is critical.
- * The second byte is upper case if the chunk is publicly defined.
- * The third byte must be upper case.
- * The fourth byte is upper case if the chunk is unsafe to copy.
- * Public chunk types are defined by the PNG Development Group.
- */
-byte[] getTypeBytes() {
- byte[] type = new byte[4];
- System.arraycopy(reference, TYPE_OFFSET, type, 0, TYPE_FIELD_LENGTH);
- return type;
-}
-
-/**
- * Set the chunk type. This is a four byte value.
- * Each byte should be an ASCII character.
- * The first byte is upper case if the chunk is critical.
- * The second byte is upper case if the chunk is publicly defined.
- * The third byte must be upper case.
- * The fourth byte is upper case if the chunk is unsafe to copy.
- * Public chunk types are defined by the PNG Development Group.
- */
-void setType(byte[] value) {
- if (value.length != TYPE_FIELD_LENGTH) {
- SWT.error (SWT.ERROR_INVALID_ARGUMENT);
- }
- System.arraycopy(value, 0, reference, TYPE_OFFSET, TYPE_FIELD_LENGTH);
-}
-
-/**
- * Get the chunk's data.
- */
-byte[] getData() {
- int dataLength = getLength();
- if (reference.length < MIN_LENGTH + dataLength) {
- SWT.error (SWT.ERROR_INVALID_RANGE);
- }
- byte[] data = new byte[dataLength];
- System.arraycopy(reference, DATA_OFFSET, data, 0, dataLength);
- return data;
-}
-
-/**
- * Set the chunk's data.
- * This method has two side-effects.
- * 1. It will set the length field to be the length
- * of the data array given.
- * 2. It will set the CRC field to the computed CRC
- * value of the data array given.
- */
-void setData(byte[] data) {
- setLength(data.length);
- System.arraycopy(data, 0, reference, DATA_OFFSET, data.length);
- setCRC(computeCRC());
-}
-
-/**
- * Get the CRC value for the chunk's data.
- * Ensure that the length field has a good
- * value before making this call.
- */
-int getCRC() {
- int crcOffset = DATA_OFFSET + getLength();
- return getInt32(crcOffset);
-}
-
-/**
- * Set the CRC value for the chunk's data.
- * Ensure that the length field has a good
- * value before making this call.
- */
-void setCRC(int value) {
- int crcOffset = DATA_OFFSET + getLength();
- setInt32(crcOffset, value);
-}
-
-/**
- * Get the chunk's total size including the length, type, and crc fields.
- */
-int getSize() {
- return MIN_LENGTH + getLength();
-}
-
-/**
- * Compute the CRC value for the chunk's data. Answer
- * whether this value matches the value stored in the
- * chunk.
- */
-boolean checkCRC() {
- int crc = computeCRC();
- int storedCRC = getCRC();
- return crc == storedCRC;
-}
-
-/**
- * Answer the CRC value of chunk's data.
- */
-int computeCRC() {
- int crc = 0xFFFFFFFF;
- int start = TYPE_OFFSET;
- int stop = DATA_OFFSET + getLength();
- for (int i = start; i < stop; i++) {
- int index = (crc ^ reference[i]) & 0xFF;
- crc = CRC_TABLE[index] ^ ((crc >> 8) & 0x00FFFFFF);
- }
- return ~crc;
-}
-
-boolean typeMatchesArray(byte[] array) {
- for (int i = 0; i < TYPE_FIELD_LENGTH; i++) {
- if (reference[TYPE_OFFSET + i] != array[i]){
- return false;
- }
- }
- return true;
-}
-
-boolean isCritical() {
- return Character.isUpperCase((char) getTypeBytes()[0]);
-}
-
-int getChunkType() {
- if (typeMatchesArray(TYPE_IHDR)) return CHUNK_IHDR;
- if (typeMatchesArray(TYPE_PLTE)) return CHUNK_PLTE;
- if (typeMatchesArray(TYPE_IDAT)) return CHUNK_IDAT;
- if (typeMatchesArray(TYPE_IEND)) return CHUNK_IEND;
- if (typeMatchesArray(TYPE_tRNS)) return CHUNK_tRNS;
- return CHUNK_UNKNOWN;
-}
-
-
-
-
-/**
- * Read the next PNG chunk from the input stream given.
- * If unable to read a chunk, return null.
- */
-static PngChunk readNextFromStream(LEDataInputStream stream) {
- try {
- int headerLength = LENGTH_FIELD_LENGTH + TYPE_FIELD_LENGTH;
- byte[] headerBytes = new byte[headerLength];
- int result = stream.read(headerBytes, 0, headerLength);
- stream.unread(headerBytes);
- if (result != headerLength) return null;
-
- PngChunk tempChunk = new PngChunk(headerBytes);
-
- int chunkLength = tempChunk.getSize();
- byte[] chunk = new byte[chunkLength];
- result = stream.read(chunk, 0, chunkLength);
- if (result != chunkLength) return null;
-
- switch (tempChunk.getChunkType()) {
- case CHUNK_IHDR:
- return new PngIhdrChunk(chunk);
- case CHUNK_PLTE:
- return new PngPlteChunk(chunk);
- case CHUNK_IDAT:
- return new PngIdatChunk(chunk);
- case CHUNK_IEND:
- return new PngIendChunk(chunk);
- case CHUNK_tRNS:
- return new PngTrnsChunk(chunk);
- default:
- return new PngChunk(chunk);
- }
- } catch (IOException e) {
- return null;
- }
-}
-
-/**
- * Answer whether the chunk is a valid PNG chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
- if (reference.length < MIN_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- byte[] type = getTypeBytes();
-
- // The third character MUST be upper case.
- if (!Character.isUpperCase((char) type[2])) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- // All characters must be letters.
- for (int i = 0; i < TYPE_FIELD_LENGTH; i++) {
- if (!Compatibility.isLetter((char) type[i])) SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-
- // The stored CRC must match the data's computed CRC.
- if (!checkCRC()) SWT.error(SWT.ERROR_INVALID_IMAGE);
-}
-
-/**
- * Provided so that subclasses can override and add
- * data to the toString() call.
- */
-void contributeToString(StringBuffer buffer) {}
-
-public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append("{");
- buffer.append("\n\tLength: ");
- buffer.append(getLength());
- buffer.append("\n\tType: ");
- byte[] type = getTypeBytes();
- for(int i = 0; i < type.length; i++) {
- buffer.append((char) type[i]);
- }
-
- contributeToString(buffer);
-
- buffer.append("\n\tCRC: ");
- buffer.append(Integer.toHexString(getCRC()));
- buffer.append("\n}");
- return buffer.toString();
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.internal.Compatibility; +import java.io.*; + +class PngChunk extends Object { + byte[] reference; + + static final int LENGTH_OFFSET = 0; + static final int TYPE_OFFSET = 4; + static final int DATA_OFFSET = 8; + + static final int TYPE_FIELD_LENGTH = 4; + static final int LENGTH_FIELD_LENGTH = 4; + static final int MIN_LENGTH = 12; + + static final int CHUNK_UNKNOWN = -1; + // Critical chunks. + static final int CHUNK_IHDR = 0; + static final int CHUNK_PLTE = 1; + static final int CHUNK_IDAT = 2; + static final int CHUNK_IEND = 3; + // Non-critical chunks. + static final int CHUNK_tRNS = 5; + + static final byte[] TYPE_IHDR = {(byte) 'I', (byte) 'H', (byte) 'D', (byte) 'R'}; + static final byte[] TYPE_PLTE = {(byte) 'P', (byte) 'L', (byte) 'T', (byte) 'E'}; + static final byte[] TYPE_IDAT = {(byte) 'I', (byte) 'D', (byte) 'A', (byte) 'T'}; + static final byte[] TYPE_IEND = {(byte) 'I', (byte) 'E', (byte) 'N', (byte) 'D'}; + static final byte[] TYPE_tRNS = {(byte) 't', (byte) 'R', (byte) 'N', (byte) 'S'}; + + static final int[] CRC_TABLE; + static { + CRC_TABLE = new int[256]; + for (int i = 0; i < 256; i++) { + CRC_TABLE[i] = i; + for (int j = 0; j < 8; j++) { + if ((CRC_TABLE[i] & 0x1) == 0) { + CRC_TABLE[i] = (CRC_TABLE[i] >> 1) & 0x7FFFFFFF; + } else { + CRC_TABLE[i] = 0xEDB88320 ^ ((CRC_TABLE[i] >> 1) & 0x7FFFFFFF); + } + } + } + } + +/** + * Construct a PngChunk using the reference bytes + * given. + */ +PngChunk(byte[] reference) { + super(); + setReference(reference); +} + +/** + * Get the PngChunk's reference byteArray; + */ +byte[] getReference() { + return reference; +} + +/** + * Set the PngChunk's reference byteArray; + */ +void setReference(byte[] reference) { + this.reference = reference; +} + +/** + * Get the 32-bit integer from the reference byte + * array at the given offset. + */ +int getInt32(int offset) { + int answer = 0; + answer |= (reference[offset] & 0xFF) << 24; + answer |= (reference[offset + 1] & 0xFF) << 16; + answer |= (reference[offset + 2] & 0xFF) << 8; + answer |= (reference[offset + 3] & 0xFF); + return answer; +} + +/** + * Set the 32-bit integer in the reference byte + * array at the given offset. + */ +void setInt32(int offset, int value) { + reference[offset] = (byte) ((value >> 24) & 0xFF); + reference[offset + 1] = (byte) ((value >> 16) & 0xFF); + reference[offset + 2] = (byte) ((value >> 8) & 0xFF); + reference[offset + 3] = (byte) (value & 0xFF); +} + +/** + * Get the length of the data component of this chunk. + * This is not the length of the entire chunk. + */ +int getLength() { + return getInt32(LENGTH_OFFSET); +} + +/** + * Set the length of the data component of this chunk. + * This is not the length of the entire chunk. + */ +void setLength(int value) { + setInt32(LENGTH_OFFSET, value); +} + +/** + * Get the chunk type. This is a four byte value. + * Each byte should be an ASCII character. + * The first byte is upper case if the chunk is critical. + * The second byte is upper case if the chunk is publicly defined. + * The third byte must be upper case. + * The fourth byte is upper case if the chunk is unsafe to copy. + * Public chunk types are defined by the PNG Development Group. + */ +byte[] getTypeBytes() { + byte[] type = new byte[4]; + System.arraycopy(reference, TYPE_OFFSET, type, 0, TYPE_FIELD_LENGTH); + return type; +} + +/** + * Set the chunk type. This is a four byte value. + * Each byte should be an ASCII character. + * The first byte is upper case if the chunk is critical. + * The second byte is upper case if the chunk is publicly defined. + * The third byte must be upper case. + * The fourth byte is upper case if the chunk is unsafe to copy. + * Public chunk types are defined by the PNG Development Group. + */ +void setType(byte[] value) { + if (value.length != TYPE_FIELD_LENGTH) { + SWT.error (SWT.ERROR_INVALID_ARGUMENT); + } + System.arraycopy(value, 0, reference, TYPE_OFFSET, TYPE_FIELD_LENGTH); +} + +/** + * Get the chunk's data. + */ +byte[] getData() { + int dataLength = getLength(); + if (reference.length < MIN_LENGTH + dataLength) { + SWT.error (SWT.ERROR_INVALID_RANGE); + } + byte[] data = new byte[dataLength]; + System.arraycopy(reference, DATA_OFFSET, data, 0, dataLength); + return data; +} + +/** + * Set the chunk's data. + * This method has two side-effects. + * 1. It will set the length field to be the length + * of the data array given. + * 2. It will set the CRC field to the computed CRC + * value of the data array given. + */ +void setData(byte[] data) { + setLength(data.length); + System.arraycopy(data, 0, reference, DATA_OFFSET, data.length); + setCRC(computeCRC()); +} + +/** + * Get the CRC value for the chunk's data. + * Ensure that the length field has a good + * value before making this call. + */ +int getCRC() { + int crcOffset = DATA_OFFSET + getLength(); + return getInt32(crcOffset); +} + +/** + * Set the CRC value for the chunk's data. + * Ensure that the length field has a good + * value before making this call. + */ +void setCRC(int value) { + int crcOffset = DATA_OFFSET + getLength(); + setInt32(crcOffset, value); +} + +/** + * Get the chunk's total size including the length, type, and crc fields. + */ +int getSize() { + return MIN_LENGTH + getLength(); +} + +/** + * Compute the CRC value for the chunk's data. Answer + * whether this value matches the value stored in the + * chunk. + */ +boolean checkCRC() { + int crc = computeCRC(); + int storedCRC = getCRC(); + return crc == storedCRC; +} + +/** + * Answer the CRC value of chunk's data. + */ +int computeCRC() { + int crc = 0xFFFFFFFF; + int start = TYPE_OFFSET; + int stop = DATA_OFFSET + getLength(); + for (int i = start; i < stop; i++) { + int index = (crc ^ reference[i]) & 0xFF; + crc = CRC_TABLE[index] ^ ((crc >> 8) & 0x00FFFFFF); + } + return ~crc; +} + +boolean typeMatchesArray(byte[] array) { + for (int i = 0; i < TYPE_FIELD_LENGTH; i++) { + if (reference[TYPE_OFFSET + i] != array[i]){ + return false; + } + } + return true; +} + +boolean isCritical() { + return Character.isUpperCase((char) getTypeBytes()[0]); +} + +int getChunkType() { + if (typeMatchesArray(TYPE_IHDR)) return CHUNK_IHDR; + if (typeMatchesArray(TYPE_PLTE)) return CHUNK_PLTE; + if (typeMatchesArray(TYPE_IDAT)) return CHUNK_IDAT; + if (typeMatchesArray(TYPE_IEND)) return CHUNK_IEND; + if (typeMatchesArray(TYPE_tRNS)) return CHUNK_tRNS; + return CHUNK_UNKNOWN; +} + + + + +/** + * Read the next PNG chunk from the input stream given. + * If unable to read a chunk, return null. + */ +static PngChunk readNextFromStream(LEDataInputStream stream) { + try { + int headerLength = LENGTH_FIELD_LENGTH + TYPE_FIELD_LENGTH; + byte[] headerBytes = new byte[headerLength]; + int result = stream.read(headerBytes, 0, headerLength); + stream.unread(headerBytes); + if (result != headerLength) return null; + + PngChunk tempChunk = new PngChunk(headerBytes); + + int chunkLength = tempChunk.getSize(); + byte[] chunk = new byte[chunkLength]; + result = stream.read(chunk, 0, chunkLength); + if (result != chunkLength) return null; + + switch (tempChunk.getChunkType()) { + case CHUNK_IHDR: + return new PngIhdrChunk(chunk); + case CHUNK_PLTE: + return new PngPlteChunk(chunk); + case CHUNK_IDAT: + return new PngIdatChunk(chunk); + case CHUNK_IEND: + return new PngIendChunk(chunk); + case CHUNK_tRNS: + return new PngTrnsChunk(chunk); + default: + return new PngChunk(chunk); + } + } catch (IOException e) { + return null; + } +} + +/** + * Answer whether the chunk is a valid PNG chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk) { + if (reference.length < MIN_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE); + + byte[] type = getTypeBytes(); + + // The third character MUST be upper case. + if (!Character.isUpperCase((char) type[2])) SWT.error(SWT.ERROR_INVALID_IMAGE); + + // All characters must be letters. + for (int i = 0; i < TYPE_FIELD_LENGTH; i++) { + if (!Compatibility.isLetter((char) type[i])) SWT.error(SWT.ERROR_INVALID_IMAGE); + } + + // The stored CRC must match the data's computed CRC. + if (!checkCRC()) SWT.error(SWT.ERROR_INVALID_IMAGE); +} + +/** + * Provided so that subclasses can override and add + * data to the toString() call. + */ +void contributeToString(StringBuffer buffer) {} + +public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("{"); + buffer.append("\n\tLength: "); + buffer.append(getLength()); + buffer.append("\n\tType: "); + byte[] type = getTypeBytes(); + for(int i = 0; i < type.length; i++) { + buffer.append((char) type[i]); + } + + contributeToString(buffer); + + buffer.append("\n\tCRC: "); + buffer.append(Integer.toHexString(getCRC())); + buffer.append("\n}"); + return buffer.toString(); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunkReader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunkReader.java index 86bf69275c..febd9148e8 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunkReader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngChunkReader.java @@ -1,66 +1,66 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-public class PngChunkReader {
- LEDataInputStream inputStream;
- PngFileReadState readState;
- PngIhdrChunk headerChunk;
- PngPlteChunk paletteChunk;
-
-PngChunkReader(LEDataInputStream inputStream) {
- this.inputStream = inputStream;
- readState = new PngFileReadState();
- headerChunk = null;
-}
-
-PngIhdrChunk getIhdrChunk() {
- if (headerChunk == null) {
- try {
- PngChunk chunk = PngChunk.readNextFromStream(inputStream);
- headerChunk = (PngIhdrChunk) chunk;
- headerChunk.validate(readState, null);
- } catch (ClassCastException e) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- }
- return headerChunk;
-}
-
-PngChunk readNextChunk() {
- if (headerChunk == null) return getIhdrChunk();
-
- PngChunk chunk = PngChunk.readNextFromStream(inputStream);
- switch (chunk.getChunkType()) {
- case PngChunk.CHUNK_tRNS:
- ((PngTrnsChunk) chunk).validate(readState, headerChunk, paletteChunk);
- break;
- case PngChunk.CHUNK_PLTE:
- chunk.validate(readState, headerChunk);
- paletteChunk = (PngPlteChunk) chunk;
- break;
- default:
- chunk.validate(readState, headerChunk);
- }
- if (readState.readIDAT && !(chunk.getChunkType() == PngChunk.CHUNK_IDAT)) {
- readState.readPixelData = true;
- }
- return chunk;
-}
-
-boolean readPixelData() {
- return readState.readPixelData;
-}
-
-boolean hasMoreChunks() {
- return !readState.readIEND;
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +public class PngChunkReader { + LEDataInputStream inputStream; + PngFileReadState readState; + PngIhdrChunk headerChunk; + PngPlteChunk paletteChunk; + +PngChunkReader(LEDataInputStream inputStream) { + this.inputStream = inputStream; + readState = new PngFileReadState(); + headerChunk = null; +} + +PngIhdrChunk getIhdrChunk() { + if (headerChunk == null) { + try { + PngChunk chunk = PngChunk.readNextFromStream(inputStream); + headerChunk = (PngIhdrChunk) chunk; + headerChunk.validate(readState, null); + } catch (ClassCastException e) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + } + return headerChunk; +} + +PngChunk readNextChunk() { + if (headerChunk == null) return getIhdrChunk(); + + PngChunk chunk = PngChunk.readNextFromStream(inputStream); + switch (chunk.getChunkType()) { + case PngChunk.CHUNK_tRNS: + ((PngTrnsChunk) chunk).validate(readState, headerChunk, paletteChunk); + break; + case PngChunk.CHUNK_PLTE: + chunk.validate(readState, headerChunk); + paletteChunk = (PngPlteChunk) chunk; + break; + default: + chunk.validate(readState, headerChunk); + } + if (readState.readIDAT && !(chunk.getChunkType() == PngChunk.CHUNK_IDAT)) { + readState.readPixelData = true; + } + return chunk; +} + +boolean readPixelData() { + return readState.readPixelData; +} + +boolean hasMoreChunks() { + return !readState.readIEND; +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngDecodingDataStream.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngDecodingDataStream.java index 350b3f6f0e..b17e342e10 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngDecodingDataStream.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngDecodingDataStream.java @@ -1,132 +1,132 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-public class PngDecodingDataStream {
- PngIdatChunk currentChunk;
- PngChunkReader chunkReader;
- byte currentByte;
- int nextByteIndex;
- int nextBitIndex;
-
- PngLzBlockReader lzBlockReader;
- int adlerValue;
-
- static final int PRIME = 65521;
- static final int MAX_BIT = 7;
-
-PngDecodingDataStream(PngIdatChunk idatChunk, PngChunkReader chunkReader) {
- super();
- this.currentChunk = idatChunk;
- this.chunkReader = chunkReader;
- nextByteIndex = 0;
- nextBitIndex = MAX_BIT + 1;
- adlerValue = 1;
- lzBlockReader = new PngLzBlockReader(this);
- readCompressedDataHeader();
- lzBlockReader.readNextBlockHeader();
-}
-
-/**
- * This method should be called when the image decoder thinks
- * that all of the compressed image data has been read. This
- * method will ensure that the next data value is an end of
- * block marker. If there are more blocks after this one,
- * the method will read them and ensure that they are empty.
- */
-void assertImageDataAtEnd() {
- lzBlockReader.assertCompressedDataAtEnd();
-}
-
-int getNextIdatBits(int length) {
- int value = 0;
- for (int i = 0; i < length; i++) {
- value |= (getNextIdatBit() << i);
- }
- return value;
-}
-
-byte getNextIdatBit() {
- if (nextBitIndex > MAX_BIT) {
- currentByte = getNextIdatByte();
- nextBitIndex = 0;
- }
- int mask = 1 << nextBitIndex;
- nextBitIndex++;
- return ((currentByte & mask) > 0) ? (byte) 1 : (byte) 0;
-}
-
-private PngIdatChunk getNextChunk() {
- PngChunk chunk = chunkReader.readNextChunk();
- if (chunk == null) error();
- if (chunk.getChunkType() != PngChunk.CHUNK_IDAT) error();
- return (PngIdatChunk) chunk;
-}
-
-byte getNextIdatByte() {
- if (nextByteIndex > currentChunk.getLength() - 1) {
- currentChunk = getNextChunk();
- nextByteIndex = 0;
- }
- byte nextByte = currentChunk.getDataByteAtOffset(nextByteIndex);
- nextByteIndex++;
- nextBitIndex = MAX_BIT + 1;
- return nextByte;
-}
-
-private void updateAdler(byte value) {
- int low = adlerValue & 0xFFFF;
- int high = (adlerValue >> 16) & 0xFFFF;
- int valueInt = value & 0xFF;
- low = (low + valueInt) % PRIME;
- high = (low + high) % PRIME;
- adlerValue = (high << 16) | low;
-}
-
-byte getNextDecodedByte() {
- byte nextDecodedByte = lzBlockReader.getNextByte();
- updateAdler(nextDecodedByte);
- return nextDecodedByte;
-}
-
-void error() {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
-}
-
-private void readCompressedDataHeader() {
- byte headerByte1 = getNextIdatByte();
- byte headerByte2 = getNextIdatByte();
-
- int number = ((headerByte1 & 0xFF) << 8) | (headerByte2 & 0xFF);
- if (number % 31 != 0) error();
-
- int compressionMethod = headerByte1 & 0x0F;
- if (compressionMethod != 8) error();
-
- int windowSizeHint = (headerByte1 & 0xF0) >> 4;
- if (windowSizeHint > 7) error();
- int windowSize = (1 << (windowSizeHint + 8));
- lzBlockReader.setWindowSize(windowSize);
-
- int dictionary = (headerByte2 & (1 << 5));
- if (dictionary != 0) error();
-
-// int compressionLevel = (headerByte2 & 0xC0) >> 6;
-}
-
-void checkAdler() {
- int storedAdler = ((getNextIdatByte() & 0xFF) << 24)
- | ((getNextIdatByte() & 0xFF) << 16)
- | ((getNextIdatByte() & 0xFF) << 8)
- | (getNextIdatByte() & 0xFF);
- if (storedAdler != adlerValue) error();
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +public class PngDecodingDataStream { + PngIdatChunk currentChunk; + PngChunkReader chunkReader; + byte currentByte; + int nextByteIndex; + int nextBitIndex; + + PngLzBlockReader lzBlockReader; + int adlerValue; + + static final int PRIME = 65521; + static final int MAX_BIT = 7; + +PngDecodingDataStream(PngIdatChunk idatChunk, PngChunkReader chunkReader) { + super(); + this.currentChunk = idatChunk; + this.chunkReader = chunkReader; + nextByteIndex = 0; + nextBitIndex = MAX_BIT + 1; + adlerValue = 1; + lzBlockReader = new PngLzBlockReader(this); + readCompressedDataHeader(); + lzBlockReader.readNextBlockHeader(); +} + +/** + * This method should be called when the image decoder thinks + * that all of the compressed image data has been read. This + * method will ensure that the next data value is an end of + * block marker. If there are more blocks after this one, + * the method will read them and ensure that they are empty. + */ +void assertImageDataAtEnd() { + lzBlockReader.assertCompressedDataAtEnd(); +} + +int getNextIdatBits(int length) { + int value = 0; + for (int i = 0; i < length; i++) { + value |= (getNextIdatBit() << i); + } + return value; +} + +byte getNextIdatBit() { + if (nextBitIndex > MAX_BIT) { + currentByte = getNextIdatByte(); + nextBitIndex = 0; + } + int mask = 1 << nextBitIndex; + nextBitIndex++; + return ((currentByte & mask) > 0) ? (byte) 1 : (byte) 0; +} + +private PngIdatChunk getNextChunk() { + PngChunk chunk = chunkReader.readNextChunk(); + if (chunk == null) error(); + if (chunk.getChunkType() != PngChunk.CHUNK_IDAT) error(); + return (PngIdatChunk) chunk; +} + +byte getNextIdatByte() { + if (nextByteIndex > currentChunk.getLength() - 1) { + currentChunk = getNextChunk(); + nextByteIndex = 0; + } + byte nextByte = currentChunk.getDataByteAtOffset(nextByteIndex); + nextByteIndex++; + nextBitIndex = MAX_BIT + 1; + return nextByte; +} + +private void updateAdler(byte value) { + int low = adlerValue & 0xFFFF; + int high = (adlerValue >> 16) & 0xFFFF; + int valueInt = value & 0xFF; + low = (low + valueInt) % PRIME; + high = (low + high) % PRIME; + adlerValue = (high << 16) | low; +} + +byte getNextDecodedByte() { + byte nextDecodedByte = lzBlockReader.getNextByte(); + updateAdler(nextDecodedByte); + return nextDecodedByte; +} + +void error() { + SWT.error(SWT.ERROR_INVALID_IMAGE); +} + +private void readCompressedDataHeader() { + byte headerByte1 = getNextIdatByte(); + byte headerByte2 = getNextIdatByte(); + + int number = ((headerByte1 & 0xFF) << 8) | (headerByte2 & 0xFF); + if (number % 31 != 0) error(); + + int compressionMethod = headerByte1 & 0x0F; + if (compressionMethod != 8) error(); + + int windowSizeHint = (headerByte1 & 0xF0) >> 4; + if (windowSizeHint > 7) error(); + int windowSize = (1 << (windowSizeHint + 8)); + lzBlockReader.setWindowSize(windowSize); + + int dictionary = (headerByte2 & (1 << 5)); + if (dictionary != 0) error(); + +// int compressionLevel = (headerByte2 & 0xC0) >> 6; +} + +void checkAdler() { + int storedAdler = ((getNextIdatByte() & 0xFF) << 24) + | ((getNextIdatByte() & 0xFF) << 16) + | ((getNextIdatByte() & 0xFF) << 8) + | (getNextIdatByte() & 0xFF); + if (storedAdler != adlerValue) error(); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngFileReadState.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngFileReadState.java index 0a7103f844..fc4c4e5a0e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngFileReadState.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngFileReadState.java @@ -1,22 +1,22 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-class PngFileReadState extends Object {
- boolean readIHDR;
- boolean readPLTE;
- boolean readIDAT;
- boolean readIEND;
-
- // Non - critical chunks
- boolean readBKGD;
- boolean readTRNS;
-
- // Set to true after IDATs have been read.
- boolean readPixelData;
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +class PngFileReadState extends Object { + boolean readIHDR; + boolean readPLTE; + boolean readIDAT; + boolean readIEND; + + // Non - critical chunks + boolean readBKGD; + boolean readTRNS; + + // Set to true after IDATs have been read. + boolean readPixelData; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTable.java index 483c1672ed..1d5602d236 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTable.java @@ -1,124 +1,124 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-public class PngHuffmanTable {
- CodeLengthInfo[] codeLengthInfo;
- int[] codeValues;
-
- static final int MAX_CODE_LENGTH = 15;
- static final int BAD_CODE = 0xFFFFFFF;
-
-PngHuffmanTable (int[] lengths) {
- super();
- initialize(lengths);
- generateTable(lengths);
-}
-
-private void initialize(int[] lengths) {
- codeValues = new int[lengths.length];
- for (int i = 0; i < codeValues.length; i++) {
- codeValues[i] = i;
- }
-
- // minCodesByLength[n] : The smallest Huffman code of length n + 1.
- // maxCodesByLength[n] : The largest Huffman code of length n + 1.
- // indexesByLength[n] : Index into the values array. First value with a code of length n + 1.
- codeLengthInfo = new CodeLengthInfo[MAX_CODE_LENGTH];
- for (int i = 0; i < MAX_CODE_LENGTH; i++) {
- codeLengthInfo[i] = new CodeLengthInfo();
- codeLengthInfo[i].length = i;
- codeLengthInfo[i].baseIndex = 0;
- codeLengthInfo[i].min = BAD_CODE;
- codeLengthInfo[i].max = -1;
- }
-}
-
-private void generateTable(int[] lengths) {
- // Sort the values. Primary key is code size. Secondary key is value.
- for (int i = 0; i < lengths.length - 1; i++) {
- for (int j = i + 1; j < lengths.length; j++) {
- if (lengths[j] < lengths[i]
- || (lengths[j] == lengths[i]
- && codeValues[j] < codeValues[i]))
- {
- int tmp;
- tmp = lengths[j];
- lengths[j] = lengths[i];
- lengths[i] = tmp;
- tmp = codeValues[j];
- codeValues[j] = codeValues[i];
- codeValues[i] = tmp;
- }
- }
- }
-
- // These values in these arrays correspond to the elements of the
- // "values" array. The Huffman code for codeValues[N] is codes[N]
- // and the length of the code is lengths[N].
- int[] codes = new int[lengths.length];
- int lastLength = 0;
- int code = 0;
- for (int i = 0; i < lengths.length; i++) {
- while (lastLength != lengths[i]) {
- lastLength++;
- code <<= 1;
- }
- if (lastLength != 0) {
- codes[i] = code;
- code++;
- }
- }
-
- int last = 0;
- for (int i = 0; i < lengths.length; i++) {
- if (last != lengths[i]) {
- last = lengths[i];
- codeLengthInfo[last - 1].baseIndex = i;
- codeLengthInfo[last - 1].min = codes[i];
- }
- if (last != 0) codeLengthInfo[last - 1].max = codes[i];
- }
-}
-
-int getNextValue(PngDecodingDataStream stream) {
- int code = stream.getNextIdatBit();
- int codelength = 0;
-
- // Here we are taking advantage of the fact that 1 bits are used as
- // a prefix to the longer codeValues.
- while (code > codeLengthInfo[codelength].max && codelength < MAX_CODE_LENGTH) {
- code = ((code << 1) | stream.getNextIdatBit());
- codelength++;
- }
- if (codelength >= MAX_CODE_LENGTH) stream.error();
-
- // Now we have a Huffman code of length (codelength + 1) that
- // is somewhere in the range
- // minCodesByLength[codelength]..maxCodesByLength[codelength].
- // This code is the (offset + 1)'th code of (codelength + 1);
- int offset = code - codeLengthInfo[codelength].min;
-
- // indexesByLength[codelength] is the first code of length (codelength + 1)
- // so now we can look up the value for the Huffman code in the table.
- int index = codeLengthInfo[codelength].baseIndex + offset;
- return codeValues[index];
-}
-
-class CodeValuePair {
- int value;
- int code;
-}
-class CodeLengthInfo {
- int length;
- int max;
- int min;
- int baseIndex;
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +public class PngHuffmanTable { + CodeLengthInfo[] codeLengthInfo; + int[] codeValues; + + static final int MAX_CODE_LENGTH = 15; + static final int BAD_CODE = 0xFFFFFFF; + +PngHuffmanTable (int[] lengths) { + super(); + initialize(lengths); + generateTable(lengths); +} + +private void initialize(int[] lengths) { + codeValues = new int[lengths.length]; + for (int i = 0; i < codeValues.length; i++) { + codeValues[i] = i; + } + + // minCodesByLength[n] : The smallest Huffman code of length n + 1. + // maxCodesByLength[n] : The largest Huffman code of length n + 1. + // indexesByLength[n] : Index into the values array. First value with a code of length n + 1. + codeLengthInfo = new CodeLengthInfo[MAX_CODE_LENGTH]; + for (int i = 0; i < MAX_CODE_LENGTH; i++) { + codeLengthInfo[i] = new CodeLengthInfo(); + codeLengthInfo[i].length = i; + codeLengthInfo[i].baseIndex = 0; + codeLengthInfo[i].min = BAD_CODE; + codeLengthInfo[i].max = -1; + } +} + +private void generateTable(int[] lengths) { + // Sort the values. Primary key is code size. Secondary key is value. + for (int i = 0; i < lengths.length - 1; i++) { + for (int j = i + 1; j < lengths.length; j++) { + if (lengths[j] < lengths[i] + || (lengths[j] == lengths[i] + && codeValues[j] < codeValues[i])) + { + int tmp; + tmp = lengths[j]; + lengths[j] = lengths[i]; + lengths[i] = tmp; + tmp = codeValues[j]; + codeValues[j] = codeValues[i]; + codeValues[i] = tmp; + } + } + } + + // These values in these arrays correspond to the elements of the + // "values" array. The Huffman code for codeValues[N] is codes[N] + // and the length of the code is lengths[N]. + int[] codes = new int[lengths.length]; + int lastLength = 0; + int code = 0; + for (int i = 0; i < lengths.length; i++) { + while (lastLength != lengths[i]) { + lastLength++; + code <<= 1; + } + if (lastLength != 0) { + codes[i] = code; + code++; + } + } + + int last = 0; + for (int i = 0; i < lengths.length; i++) { + if (last != lengths[i]) { + last = lengths[i]; + codeLengthInfo[last - 1].baseIndex = i; + codeLengthInfo[last - 1].min = codes[i]; + } + if (last != 0) codeLengthInfo[last - 1].max = codes[i]; + } +} + +int getNextValue(PngDecodingDataStream stream) { + int code = stream.getNextIdatBit(); + int codelength = 0; + + // Here we are taking advantage of the fact that 1 bits are used as + // a prefix to the longer codeValues. + while (code > codeLengthInfo[codelength].max && codelength < MAX_CODE_LENGTH) { + code = ((code << 1) | stream.getNextIdatBit()); + codelength++; + } + if (codelength >= MAX_CODE_LENGTH) stream.error(); + + // Now we have a Huffman code of length (codelength + 1) that + // is somewhere in the range + // minCodesByLength[codelength]..maxCodesByLength[codelength]. + // This code is the (offset + 1)'th code of (codelength + 1); + int offset = code - codeLengthInfo[codelength].min; + + // indexesByLength[codelength] is the first code of length (codelength + 1) + // so now we can look up the value for the Huffman code in the table. + int index = codeLengthInfo[codelength].baseIndex + offset; + return codeValues[index]; +} + +class CodeValuePair { + int value; + int code; +} +class CodeLengthInfo { + int length; + int max; + int min; + int baseIndex; +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTables.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTables.java index 5d0dcde249..c88a983a01 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTables.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngHuffmanTables.java @@ -1,158 +1,158 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-public class PngHuffmanTables {
- PngHuffmanTable literalTable;
- PngHuffmanTable distanceTable;
-
- static PngHuffmanTable FixedLiteralTable;
- static PngHuffmanTable FixedDistanceTable;
-
- static final int LiteralTableSize = 288;
- static final int[] FixedLiteralLengths = {
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
- };
-
- static final int DistanceTableSize = 32;
- static final int[] FixedDistanceLengths = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- };
-
- static final int LengthCodeTableSize = 19;
- static final int[] LengthCodeOrder = {
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
- 11, 4, 12, 3, 13, 2, 14, 1, 15
- };
-
-static PngHuffmanTables getDynamicTables(PngDecodingDataStream stream){
- return new PngHuffmanTables(stream);
-}
-static PngHuffmanTables getFixedTables() {
- return new PngHuffmanTables();
-}
-
-private PngHuffmanTable getFixedLiteralTable() {
- if (FixedLiteralTable == null) {
- FixedLiteralTable = new PngHuffmanTable(FixedLiteralLengths);
- }
- return FixedLiteralTable;
-}
-
-private PngHuffmanTable getFixedDistanceTable() {
- if (FixedDistanceTable == null) {
- FixedDistanceTable = new PngHuffmanTable(FixedDistanceLengths);
- }
- return FixedDistanceTable;
-}
-
-private PngHuffmanTables () {
- super();
- literalTable = getFixedLiteralTable();
- distanceTable = getFixedDistanceTable();
-}
-
-private PngHuffmanTables (PngDecodingDataStream stream) {
- super();
-
- int literals = PngLzBlockReader.FIRST_LENGTH_CODE
- + stream.getNextIdatBits(5);
- int distances = PngLzBlockReader.FIRST_DISTANCE_CODE
- + stream.getNextIdatBits(5);
- int codeLengthCodes = PngLzBlockReader.FIRST_CODE_LENGTH_CODE
- + stream.getNextIdatBits(4);
-
- if (codeLengthCodes > PngLzBlockReader.LAST_CODE_LENGTH_CODE) {
- stream.error();
- }
-
- /* Tricky, tricky, tricky. The length codes are stored in
- * a very odd order. (For the order, see the definition of
- * the static field lengthCodeOrder.) Also, the data may
- * not contain values for all the codes. It may just contain
- * values for the first X number of codes. The table should
- * be of size <LengthCodeTableSize> regardless of the number
- * of values actually given in the table.
- */
- int[] lengthCodes = new int[LengthCodeTableSize];
- for (int i = 0; i < codeLengthCodes; i++) {
- lengthCodes[LengthCodeOrder[i]] = stream.getNextIdatBits(3);
- }
- PngHuffmanTable codeLengthsTable = new PngHuffmanTable(lengthCodes);
-
- int[] literalLengths = readLengths(
- stream, literals, codeLengthsTable, LiteralTableSize);
- int[] distanceLengths = readLengths(
- stream, distances, codeLengthsTable, DistanceTableSize);
-
- literalTable = new PngHuffmanTable(literalLengths);
- distanceTable = new PngHuffmanTable(distanceLengths);
-}
-
-private int [] readLengths (PngDecodingDataStream stream,
- int numLengths,
- PngHuffmanTable lengthsTable,
- int tableSize)
-{
- int[] lengths = new int[tableSize];
-
- for (int index = 0; index < numLengths;) {
- int value = lengthsTable.getNextValue(stream);
- if (value < 16) {
- // Literal value
- lengths[index] = value;
- index++;
- } else if (value == 16) {
- // Repeat the previous code 3-6 times.
- int count = stream.getNextIdatBits(2) + 3;
- for (int i = 0; i < count; i++) {
- lengths[index] = lengths [index - 1];
- index++;
- }
- } else if (value == 17) {
- // Repeat 0 3-10 times.
- int count = stream.getNextIdatBits(3) + 3;
- for (int i = 0; i < count; i++) {
- lengths[index] = 0;
- index++;
- }
- } else if (value == 18) {
- // Repeat 0 11-138 times.
- int count = stream.getNextIdatBits(7) + 11;
- for (int i = 0; i < count; i++) {
- lengths[index] = 0;
- index++;
- }
- } else {
- stream.error();
- }
- }
- return lengths;
-}
-
-int getNextLiteralValue(PngDecodingDataStream stream) {
- return literalTable.getNextValue(stream);
-}
-
-int getNextDistanceValue(PngDecodingDataStream stream) {
- return distanceTable.getNextValue(stream);
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +public class PngHuffmanTables { + PngHuffmanTable literalTable; + PngHuffmanTable distanceTable; + + static PngHuffmanTable FixedLiteralTable; + static PngHuffmanTable FixedDistanceTable; + + static final int LiteralTableSize = 288; + static final int[] FixedLiteralLengths = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, + }; + + static final int DistanceTableSize = 32; + static final int[] FixedDistanceLengths = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + }; + + static final int LengthCodeTableSize = 19; + static final int[] LengthCodeOrder = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, + 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + +static PngHuffmanTables getDynamicTables(PngDecodingDataStream stream){ + return new PngHuffmanTables(stream); +} +static PngHuffmanTables getFixedTables() { + return new PngHuffmanTables(); +} + +private PngHuffmanTable getFixedLiteralTable() { + if (FixedLiteralTable == null) { + FixedLiteralTable = new PngHuffmanTable(FixedLiteralLengths); + } + return FixedLiteralTable; +} + +private PngHuffmanTable getFixedDistanceTable() { + if (FixedDistanceTable == null) { + FixedDistanceTable = new PngHuffmanTable(FixedDistanceLengths); + } + return FixedDistanceTable; +} + +private PngHuffmanTables () { + super(); + literalTable = getFixedLiteralTable(); + distanceTable = getFixedDistanceTable(); +} + +private PngHuffmanTables (PngDecodingDataStream stream) { + super(); + + int literals = PngLzBlockReader.FIRST_LENGTH_CODE + + stream.getNextIdatBits(5); + int distances = PngLzBlockReader.FIRST_DISTANCE_CODE + + stream.getNextIdatBits(5); + int codeLengthCodes = PngLzBlockReader.FIRST_CODE_LENGTH_CODE + + stream.getNextIdatBits(4); + + if (codeLengthCodes > PngLzBlockReader.LAST_CODE_LENGTH_CODE) { + stream.error(); + } + + /* Tricky, tricky, tricky. The length codes are stored in + * a very odd order. (For the order, see the definition of + * the static field lengthCodeOrder.) Also, the data may + * not contain values for all the codes. It may just contain + * values for the first X number of codes. The table should + * be of size <LengthCodeTableSize> regardless of the number + * of values actually given in the table. + */ + int[] lengthCodes = new int[LengthCodeTableSize]; + for (int i = 0; i < codeLengthCodes; i++) { + lengthCodes[LengthCodeOrder[i]] = stream.getNextIdatBits(3); + } + PngHuffmanTable codeLengthsTable = new PngHuffmanTable(lengthCodes); + + int[] literalLengths = readLengths( + stream, literals, codeLengthsTable, LiteralTableSize); + int[] distanceLengths = readLengths( + stream, distances, codeLengthsTable, DistanceTableSize); + + literalTable = new PngHuffmanTable(literalLengths); + distanceTable = new PngHuffmanTable(distanceLengths); +} + +private int [] readLengths (PngDecodingDataStream stream, + int numLengths, + PngHuffmanTable lengthsTable, + int tableSize) +{ + int[] lengths = new int[tableSize]; + + for (int index = 0; index < numLengths;) { + int value = lengthsTable.getNextValue(stream); + if (value < 16) { + // Literal value + lengths[index] = value; + index++; + } else if (value == 16) { + // Repeat the previous code 3-6 times. + int count = stream.getNextIdatBits(2) + 3; + for (int i = 0; i < count; i++) { + lengths[index] = lengths [index - 1]; + index++; + } + } else if (value == 17) { + // Repeat 0 3-10 times. + int count = stream.getNextIdatBits(3) + 3; + for (int i = 0; i < count; i++) { + lengths[index] = 0; + index++; + } + } else if (value == 18) { + // Repeat 0 11-138 times. + int count = stream.getNextIdatBits(7) + 11; + for (int i = 0; i < count; i++) { + lengths[index] = 0; + index++; + } + } else { + stream.error(); + } + } + return lengths; +} + +int getNextLiteralValue(PngDecodingDataStream stream) { + return literalTable.getNextValue(stream); +} + +int getNextDistanceValue(PngDecodingDataStream stream) { + return distanceTable.getNextValue(stream); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIdatChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIdatChunk.java index 744c0d3765..8dbb505539 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIdatChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIdatChunk.java @@ -1,38 +1,38 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-class PngIdatChunk extends PngChunk {
-
-PngIdatChunk(byte[] reference){
- super(reference);
-}
-
-/**
- * Answer whether the chunk is a valid IDAT chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
- if (!readState.readIHDR
- || (headerChunk.getMustHavePalette() && !readState.readPLTE)
- || readState.readIEND)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- readState.readIDAT = true;
- }
-
- super.validate(readState, headerChunk);
-}
-
-byte getDataByteAtOffset(int offset) {
- return reference[DATA_OFFSET + offset];
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +class PngIdatChunk extends PngChunk { + +PngIdatChunk(byte[] reference){ + super(reference); +} + +/** + * Answer whether the chunk is a valid IDAT chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk) { + if (!readState.readIHDR + || (headerChunk.getMustHavePalette() && !readState.readPLTE) + || readState.readIEND) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + readState.readIDAT = true; + } + + super.validate(readState, headerChunk); +} + +byte getDataByteAtOffset(int offset) { + return reference[DATA_OFFSET + offset]; +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIendChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIendChunk.java index 914fad1e02..57fa44c7c2 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIendChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIendChunk.java @@ -1,41 +1,41 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-class PngIendChunk extends PngChunk {
-
-PngIendChunk(byte[] reference){
- super(reference);
-}
-
-/**
- * Answer whether the chunk is a valid IEND chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
- // An IEND chunk is invalid if no IHDR has been read.
- // Or if a palette is required and has not been read.
- // Or if no IDAT chunk has been read.
- if (!readState.readIHDR
- || (headerChunk.getMustHavePalette() && !readState.readPLTE)
- || !readState.readIDAT
- || readState.readIEND)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- readState.readIEND = true;
- }
-
- super.validate(readState, headerChunk);
-
- // IEND chunks are not allowed to have any data.
- if (getLength() > 0) SWT.error(SWT.ERROR_INVALID_IMAGE);
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +class PngIendChunk extends PngChunk { + +PngIendChunk(byte[] reference){ + super(reference); +} + +/** + * Answer whether the chunk is a valid IEND chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk) { + // An IEND chunk is invalid if no IHDR has been read. + // Or if a palette is required and has not been read. + // Or if no IDAT chunk has been read. + if (!readState.readIHDR + || (headerChunk.getMustHavePalette() && !readState.readPLTE) + || !readState.readIDAT + || readState.readIEND) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + readState.readIEND = true; + } + + super.validate(readState, headerChunk); + + // IEND chunks are not allowed to have any data. + if (getLength() > 0) SWT.error(SWT.ERROR_INVALID_IMAGE); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIhdrChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIhdrChunk.java index 780e6051e5..4c2a60182e 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIhdrChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngIhdrChunk.java @@ -1,375 +1,375 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.internal.Compatibility;
-
-class PngIhdrChunk extends PngChunk {
- static final int EXPECTED_DATA_LENGTH = 13;
-
- static final int WIDTH_DATA_OFFSET = DATA_OFFSET + 0;
- static final int HEIGHT_DATA_OFFSET = DATA_OFFSET + 4;
- static final int BIT_DEPTH_OFFSET = DATA_OFFSET + 8;
- static final int COLOR_TYPE_OFFSET = DATA_OFFSET + 9;
- static final int COMPRESSION_METHOD_OFFSET = DATA_OFFSET + 10;
- static final int FILTER_METHOD_OFFSET = DATA_OFFSET + 11;
- static final int INTERLACE_METHOD_OFFSET = DATA_OFFSET + 12;
-
- static final int COLOR_TYPE_GRAYSCALE = 0;
- static final int COLOR_TYPE_RGB = 2;
- static final int COLOR_TYPE_PALETTE = 3;
- static final int COLOR_TYPE_GRAYSCALE_WITH_ALPHA = 4;
- static final int COLOR_TYPE_RGB_WITH_ALPHA = 6;
-
- static final int INTERLACE_METHOD_NONE = 0;
- static final int INTERLACE_METHOD_ADAM7 = 1;
-
- static final int FILTER_NONE = 0;
- static final int FILTER_SUB = 1;
- static final int FILTER_UP = 2;
- static final int FILTER_AVERAGE = 3;
- static final int FILTER_PAETH = 4;
-
- static final byte[] ValidBitDepths = {1, 2, 4, 8, 16};
- static final byte[] ValidColorTypes = {0, 2, 3, 4, 6};
-
-/**
- * Construct a PNGChunk using the reference bytes
- * given.
- */
-PngIhdrChunk(byte[] reference) {
- super(reference);
-}
-
-/**
- * Get the image's width in pixels.
- */
-int getWidth() {
- return getInt32(WIDTH_DATA_OFFSET);
-}
-
-/**
- * Set the image's width in pixels.
- */
-void setWidth(int value) {
- setInt32(WIDTH_DATA_OFFSET, value);
-}
-
-/**
- * Get the image's height in pixels.
- */
-int getHeight() {
- return getInt32(HEIGHT_DATA_OFFSET);
-}
-
-/**
- * Set the image's height in pixels.
- */
-void setHeight(int value) {
- setInt32(HEIGHT_DATA_OFFSET, value);
-}
-
-/**
- * Get the image's bit depth.
- * This is limited to the values 1, 2, 4, 8, or 16.
- */
-byte getBitDepth() {
- return reference[BIT_DEPTH_OFFSET];
-}
-
-/**
- * Set the image's bit depth.
- * This is limited to the values 1, 2, 4, 8, or 16.
- */
-void setBitDepth(byte value) {
- reference[BIT_DEPTH_OFFSET] = value;
-}
-
-/**
- * Get the image's color type.
- * This is limited to the values:
- * 0 - Grayscale image.
- * 2 - RGB triple.
- * 3 - Palette.
- * 4 - Grayscale with Alpha channel.
- * 6 - RGB with Alpha channel.
- */
-byte getColorType() {
- return reference[COLOR_TYPE_OFFSET];
-}
-
-/**
- * Set the image's color type.
- * This is limited to the values:
- * 0 - Grayscale image.
- * 2 - RGB triple.
- * 3 - Palette.
- * 4 - Grayscale with Alpha channel.
- * 6 - RGB with Alpha channel.
- */
-void setColorType(byte value) {
- reference[COLOR_TYPE_OFFSET] = value;
-}
-
-/**
- * Get the image's compression method.
- * This value must be 0.
- */
-byte getCompressionMethod() {
- return reference[COMPRESSION_METHOD_OFFSET];
-}
-
-/**
- * Set the image's compression method.
- * This value must be 0.
- */
-void setCompressionMethod(byte value) {
- reference[COMPRESSION_METHOD_OFFSET] = value;
-}
-
-/**
- * Get the image's filter method.
- * This value must be 0.
- */
-byte getFilterMethod() {
- return reference[FILTER_METHOD_OFFSET];
-}
-
-/**
- * Set the image's filter method.
- * This value must be 0.
- */
-void setFilterMethod(byte value) {
- reference[FILTER_METHOD_OFFSET] = value;
-}
-
-/**
- * Get the image's interlace method.
- * This value is limited to:
- * 0 - No interlacing used.
- * 1 - Adam7 interlacing used.
- */
-byte getInterlaceMethod() {
- return reference[INTERLACE_METHOD_OFFSET];
-}
-
-/**
- * Set the image's interlace method.
- * This value is limited to:
- * 0 - No interlacing used.
- * 1 - Adam7 interlacing used.
- */
-void setInterlaceMethod(byte value) {
- reference[INTERLACE_METHOD_OFFSET] = value;
-}
-
-/**
- * Answer whether the chunk is a valid IHDR chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
- // An IHDR chunk is invalid if any other chunk has
- // been read.
- if (readState.readIHDR
- || readState.readPLTE
- || readState.readIDAT
- || readState.readIEND)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- readState.readIHDR = true;
- }
-
- super.validate(readState, headerChunk);
-
- if (getLength() != EXPECTED_DATA_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE);
- if (getCompressionMethod() != 0) SWT.error(SWT.ERROR_INVALID_IMAGE);
- if (getInterlaceMethod() != INTERLACE_METHOD_NONE &&
- getInterlaceMethod() != INTERLACE_METHOD_ADAM7) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-
- boolean colorTypeIsValid = false;
- byte colorType = getColorType();
- for (int i = 0; i < ValidColorTypes.length; i++) {
- if (ValidColorTypes[i] == colorType) {
- colorTypeIsValid = true;
- break;
- }
- }
- if (!colorTypeIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE);;
-
- boolean bitDepthIsValid = false;
- byte bitDepth = getBitDepth();
- for (int i = 0; i < ValidBitDepths.length; i++) {
- if (ValidBitDepths[i] == bitDepth) {
- bitDepthIsValid = true;
- break;
- }
- }
- if (!bitDepthIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- if ((colorType == COLOR_TYPE_RGB
- || colorType == COLOR_TYPE_RGB_WITH_ALPHA
- || colorType == COLOR_TYPE_GRAYSCALE_WITH_ALPHA)
- && bitDepth < 8)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-
- if (colorType == COLOR_TYPE_PALETTE && bitDepth > 8) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-}
-
-String getColorTypeString() {
- switch (getColorType()) {
- case COLOR_TYPE_GRAYSCALE: return "Grayscale";
- case COLOR_TYPE_RGB: return "RGB";
- case COLOR_TYPE_PALETTE: return "Palette";
- case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: return "Grayscale with Alpha";
- case COLOR_TYPE_RGB_WITH_ALPHA: return "RGB with Alpha";
- default: return "Unknown - " + getColorType();
- }
-}
-
-String getFilterMethodString() {
- switch (getFilterMethod()) {
- case FILTER_NONE: return "None";
- case FILTER_SUB: return "Sub";
- case FILTER_UP: return "Up";
- case FILTER_AVERAGE: return "Average";
- case FILTER_PAETH: return "Paeth";
- default: return "Unknown";
- }
-}
-
-String getInterlaceMethodString() {
- switch (getInterlaceMethod()) {
- case INTERLACE_METHOD_NONE: return "Not Interlaced";
- case INTERLACE_METHOD_ADAM7: return "Interlaced - ADAM7";
- default: return "Unknown";
- }
-}
-
-void contributeToString(StringBuffer buffer) {
- buffer.append("\n\tWidth: ");
- buffer.append(getWidth());
- buffer.append("\n\tHeight: ");
- buffer.append(getHeight());
- buffer.append("\n\tBit Depth: ");
- buffer.append(getBitDepth());
- buffer.append("\n\tColor Type: ");
- buffer.append(getColorTypeString());
- buffer.append("\n\tCompression Method: ");
- buffer.append(getCompressionMethod());
- buffer.append("\n\tFilter Method: ");
- buffer.append(getFilterMethodString());
- buffer.append("\n\tInterlace Method: ");
- buffer.append(getInterlaceMethodString());
-}
-
-boolean getMustHavePalette() {
- return getColorType() == COLOR_TYPE_PALETTE;
-}
-
-boolean getCanHavePalette() {
- int colorType = getColorType();
- return colorType != COLOR_TYPE_GRAYSCALE &&
- colorType != COLOR_TYPE_GRAYSCALE_WITH_ALPHA;
-}
-
-/**
- * Answer the pixel size in bits based on the color type
- * and bit depth.
- */
-int getBitsPerPixel() {
- int bitDepth = getBitDepth();
- switch (getColorType()) {
- case COLOR_TYPE_RGB_WITH_ALPHA:
- return 4 * bitDepth;
- case COLOR_TYPE_RGB:
- return 3 * bitDepth;
- case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- return 2 * bitDepth;
- case COLOR_TYPE_GRAYSCALE:
- case COLOR_TYPE_PALETTE:
- return bitDepth;
- default:
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return 0;
- }
-}
-
-/**
- * Answer the pixel size in bits based on the color type
- * and bit depth.
- */
-int getSwtBitsPerPixel() {
- int bitDepth = getBitDepth();
- switch (getColorType()) {
- case COLOR_TYPE_RGB_WITH_ALPHA:
- case COLOR_TYPE_RGB:
- case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- return 24;
- case COLOR_TYPE_GRAYSCALE:
- case COLOR_TYPE_PALETTE:
- return Math.min(bitDepth, 8);
- default:
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return 0;
- }
-}
-
-int getFilterByteOffset() {
- if (getBitDepth() < 8) return 1;
- return getBitsPerPixel() / 8;
-}
-
-boolean usesDirectColor() {
- switch (getColorType()) {
- case COLOR_TYPE_GRAYSCALE:
- case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- case COLOR_TYPE_RGB:
- case COLOR_TYPE_RGB_WITH_ALPHA:
- return true;
- default:
- return false;
- }
-}
-
-PaletteData createGrayscalePalette() {
- int bitDepth = Math.min(getBitDepth(), 8);
- int max = Compatibility.pow2(bitDepth) - 1;
- int delta = 255 / max;
- int gray = 0;
- RGB[] rgbs = new RGB[max + 1];
- for (int i = 0; i <= max; i++) {
- rgbs[i] = new RGB(gray, gray, gray);
- gray += delta;
- }
- return new PaletteData(rgbs);
-}
-
-PaletteData getPaletteData() {
- switch (getColorType()) {
- case COLOR_TYPE_GRAYSCALE:
- return createGrayscalePalette();
- case COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- case COLOR_TYPE_RGB:
- case COLOR_TYPE_RGB_WITH_ALPHA:
- return new PaletteData(0xFF0000, 0xFF00, 0xFF);
- default:
- return null;
- }
-}
-
-
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.Compatibility; + +class PngIhdrChunk extends PngChunk { + static final int EXPECTED_DATA_LENGTH = 13; + + static final int WIDTH_DATA_OFFSET = DATA_OFFSET + 0; + static final int HEIGHT_DATA_OFFSET = DATA_OFFSET + 4; + static final int BIT_DEPTH_OFFSET = DATA_OFFSET + 8; + static final int COLOR_TYPE_OFFSET = DATA_OFFSET + 9; + static final int COMPRESSION_METHOD_OFFSET = DATA_OFFSET + 10; + static final int FILTER_METHOD_OFFSET = DATA_OFFSET + 11; + static final int INTERLACE_METHOD_OFFSET = DATA_OFFSET + 12; + + static final int COLOR_TYPE_GRAYSCALE = 0; + static final int COLOR_TYPE_RGB = 2; + static final int COLOR_TYPE_PALETTE = 3; + static final int COLOR_TYPE_GRAYSCALE_WITH_ALPHA = 4; + static final int COLOR_TYPE_RGB_WITH_ALPHA = 6; + + static final int INTERLACE_METHOD_NONE = 0; + static final int INTERLACE_METHOD_ADAM7 = 1; + + static final int FILTER_NONE = 0; + static final int FILTER_SUB = 1; + static final int FILTER_UP = 2; + static final int FILTER_AVERAGE = 3; + static final int FILTER_PAETH = 4; + + static final byte[] ValidBitDepths = {1, 2, 4, 8, 16}; + static final byte[] ValidColorTypes = {0, 2, 3, 4, 6}; + +/** + * Construct a PNGChunk using the reference bytes + * given. + */ +PngIhdrChunk(byte[] reference) { + super(reference); +} + +/** + * Get the image's width in pixels. + */ +int getWidth() { + return getInt32(WIDTH_DATA_OFFSET); +} + +/** + * Set the image's width in pixels. + */ +void setWidth(int value) { + setInt32(WIDTH_DATA_OFFSET, value); +} + +/** + * Get the image's height in pixels. + */ +int getHeight() { + return getInt32(HEIGHT_DATA_OFFSET); +} + +/** + * Set the image's height in pixels. + */ +void setHeight(int value) { + setInt32(HEIGHT_DATA_OFFSET, value); +} + +/** + * Get the image's bit depth. + * This is limited to the values 1, 2, 4, 8, or 16. + */ +byte getBitDepth() { + return reference[BIT_DEPTH_OFFSET]; +} + +/** + * Set the image's bit depth. + * This is limited to the values 1, 2, 4, 8, or 16. + */ +void setBitDepth(byte value) { + reference[BIT_DEPTH_OFFSET] = value; +} + +/** + * Get the image's color type. + * This is limited to the values: + * 0 - Grayscale image. + * 2 - RGB triple. + * 3 - Palette. + * 4 - Grayscale with Alpha channel. + * 6 - RGB with Alpha channel. + */ +byte getColorType() { + return reference[COLOR_TYPE_OFFSET]; +} + +/** + * Set the image's color type. + * This is limited to the values: + * 0 - Grayscale image. + * 2 - RGB triple. + * 3 - Palette. + * 4 - Grayscale with Alpha channel. + * 6 - RGB with Alpha channel. + */ +void setColorType(byte value) { + reference[COLOR_TYPE_OFFSET] = value; +} + +/** + * Get the image's compression method. + * This value must be 0. + */ +byte getCompressionMethod() { + return reference[COMPRESSION_METHOD_OFFSET]; +} + +/** + * Set the image's compression method. + * This value must be 0. + */ +void setCompressionMethod(byte value) { + reference[COMPRESSION_METHOD_OFFSET] = value; +} + +/** + * Get the image's filter method. + * This value must be 0. + */ +byte getFilterMethod() { + return reference[FILTER_METHOD_OFFSET]; +} + +/** + * Set the image's filter method. + * This value must be 0. + */ +void setFilterMethod(byte value) { + reference[FILTER_METHOD_OFFSET] = value; +} + +/** + * Get the image's interlace method. + * This value is limited to: + * 0 - No interlacing used. + * 1 - Adam7 interlacing used. + */ +byte getInterlaceMethod() { + return reference[INTERLACE_METHOD_OFFSET]; +} + +/** + * Set the image's interlace method. + * This value is limited to: + * 0 - No interlacing used. + * 1 - Adam7 interlacing used. + */ +void setInterlaceMethod(byte value) { + reference[INTERLACE_METHOD_OFFSET] = value; +} + +/** + * Answer whether the chunk is a valid IHDR chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk) { + // An IHDR chunk is invalid if any other chunk has + // been read. + if (readState.readIHDR + || readState.readPLTE + || readState.readIDAT + || readState.readIEND) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + readState.readIHDR = true; + } + + super.validate(readState, headerChunk); + + if (getLength() != EXPECTED_DATA_LENGTH) SWT.error(SWT.ERROR_INVALID_IMAGE); + if (getCompressionMethod() != 0) SWT.error(SWT.ERROR_INVALID_IMAGE); + if (getInterlaceMethod() != INTERLACE_METHOD_NONE && + getInterlaceMethod() != INTERLACE_METHOD_ADAM7) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + + boolean colorTypeIsValid = false; + byte colorType = getColorType(); + for (int i = 0; i < ValidColorTypes.length; i++) { + if (ValidColorTypes[i] == colorType) { + colorTypeIsValid = true; + break; + } + } + if (!colorTypeIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE);; + + boolean bitDepthIsValid = false; + byte bitDepth = getBitDepth(); + for (int i = 0; i < ValidBitDepths.length; i++) { + if (ValidBitDepths[i] == bitDepth) { + bitDepthIsValid = true; + break; + } + } + if (!bitDepthIsValid) SWT.error(SWT.ERROR_INVALID_IMAGE); + + if ((colorType == COLOR_TYPE_RGB + || colorType == COLOR_TYPE_RGB_WITH_ALPHA + || colorType == COLOR_TYPE_GRAYSCALE_WITH_ALPHA) + && bitDepth < 8) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + + if (colorType == COLOR_TYPE_PALETTE && bitDepth > 8) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } +} + +String getColorTypeString() { + switch (getColorType()) { + case COLOR_TYPE_GRAYSCALE: return "Grayscale"; + case COLOR_TYPE_RGB: return "RGB"; + case COLOR_TYPE_PALETTE: return "Palette"; + case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: return "Grayscale with Alpha"; + case COLOR_TYPE_RGB_WITH_ALPHA: return "RGB with Alpha"; + default: return "Unknown - " + getColorType(); + } +} + +String getFilterMethodString() { + switch (getFilterMethod()) { + case FILTER_NONE: return "None"; + case FILTER_SUB: return "Sub"; + case FILTER_UP: return "Up"; + case FILTER_AVERAGE: return "Average"; + case FILTER_PAETH: return "Paeth"; + default: return "Unknown"; + } +} + +String getInterlaceMethodString() { + switch (getInterlaceMethod()) { + case INTERLACE_METHOD_NONE: return "Not Interlaced"; + case INTERLACE_METHOD_ADAM7: return "Interlaced - ADAM7"; + default: return "Unknown"; + } +} + +void contributeToString(StringBuffer buffer) { + buffer.append("\n\tWidth: "); + buffer.append(getWidth()); + buffer.append("\n\tHeight: "); + buffer.append(getHeight()); + buffer.append("\n\tBit Depth: "); + buffer.append(getBitDepth()); + buffer.append("\n\tColor Type: "); + buffer.append(getColorTypeString()); + buffer.append("\n\tCompression Method: "); + buffer.append(getCompressionMethod()); + buffer.append("\n\tFilter Method: "); + buffer.append(getFilterMethodString()); + buffer.append("\n\tInterlace Method: "); + buffer.append(getInterlaceMethodString()); +} + +boolean getMustHavePalette() { + return getColorType() == COLOR_TYPE_PALETTE; +} + +boolean getCanHavePalette() { + int colorType = getColorType(); + return colorType != COLOR_TYPE_GRAYSCALE && + colorType != COLOR_TYPE_GRAYSCALE_WITH_ALPHA; +} + +/** + * Answer the pixel size in bits based on the color type + * and bit depth. + */ +int getBitsPerPixel() { + int bitDepth = getBitDepth(); + switch (getColorType()) { + case COLOR_TYPE_RGB_WITH_ALPHA: + return 4 * bitDepth; + case COLOR_TYPE_RGB: + return 3 * bitDepth; + case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + return 2 * bitDepth; + case COLOR_TYPE_GRAYSCALE: + case COLOR_TYPE_PALETTE: + return bitDepth; + default: + SWT.error(SWT.ERROR_INVALID_IMAGE); + return 0; + } +} + +/** + * Answer the pixel size in bits based on the color type + * and bit depth. + */ +int getSwtBitsPerPixel() { + int bitDepth = getBitDepth(); + switch (getColorType()) { + case COLOR_TYPE_RGB_WITH_ALPHA: + case COLOR_TYPE_RGB: + case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + return 24; + case COLOR_TYPE_GRAYSCALE: + case COLOR_TYPE_PALETTE: + return Math.min(bitDepth, 8); + default: + SWT.error(SWT.ERROR_INVALID_IMAGE); + return 0; + } +} + +int getFilterByteOffset() { + if (getBitDepth() < 8) return 1; + return getBitsPerPixel() / 8; +} + +boolean usesDirectColor() { + switch (getColorType()) { + case COLOR_TYPE_GRAYSCALE: + case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + case COLOR_TYPE_RGB: + case COLOR_TYPE_RGB_WITH_ALPHA: + return true; + default: + return false; + } +} + +PaletteData createGrayscalePalette() { + int bitDepth = Math.min(getBitDepth(), 8); + int max = Compatibility.pow2(bitDepth) - 1; + int delta = 255 / max; + int gray = 0; + RGB[] rgbs = new RGB[max + 1]; + for (int i = 0; i <= max; i++) { + rgbs[i] = new RGB(gray, gray, gray); + gray += delta; + } + return new PaletteData(rgbs); +} + +PaletteData getPaletteData() { + switch (getColorType()) { + case COLOR_TYPE_GRAYSCALE: + return createGrayscalePalette(); + case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + case COLOR_TYPE_RGB: + case COLOR_TYPE_RGB_WITH_ALPHA: + return new PaletteData(0xFF0000, 0xFF00, 0xFF); + default: + return null; + } +} + + + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngLzBlockReader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngLzBlockReader.java index 4f3fd815e4..95a3651fc6 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngLzBlockReader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngLzBlockReader.java @@ -1,169 +1,169 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-public class PngLzBlockReader {
- boolean readHeader;
- boolean isLastBlock;
- byte compressionType;
- int uncompressedBytesRemaining;
- PngDecodingDataStream stream;
- PngHuffmanTables huffmanTables;
-
- byte[] window;
- int windowIndex;
- int copyIndex;
- int copyBytesRemaining;
-
- static final int UNCOMPRESSED = 0;
- static final int COMPRESSED_FIXED = 1;
- static final int COMPRESSED_DYNAMIC = 2;
-
- static final int END_OF_COMPRESSED_BLOCK = 256;
- static final int FIRST_LENGTH_CODE = 257;
- static final int LAST_LENGTH_CODE = 285;
- static final int FIRST_DISTANCE_CODE = 1;
- static final int LAST_DISTANCE_CODE = 29;
- static final int FIRST_CODE_LENGTH_CODE = 4;
- static final int LAST_CODE_LENGTH_CODE = 19;
-
- static final int[] lengthBases = {
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
- 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
- } ;
- static final int[] extraLengthBits = {
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,
- };
- static final int[] distanceBases = {
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129,
- 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097,
- 6145, 8193, 12289, 16385, 24577,
- };
- static final int[] extraDistanceBits = {
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
- 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
- };
-
-
-PngLzBlockReader(PngDecodingDataStream stream) {
- this.stream = stream;
- readHeader = false;
- isLastBlock = false;
-}
-
-void setWindowSize(int windowSize) {
- window = new byte[windowSize];
-}
-
-void readNextBlockHeader() {
- isLastBlock = stream.getNextIdatBit() != 0;
- compressionType = (byte)(stream.getNextIdatBits(2) & 0xFF);
- if (compressionType > 2) stream.error();
-
- if (compressionType == UNCOMPRESSED) {
- byte b1 = stream.getNextIdatByte();
- byte b2 = stream.getNextIdatByte();
- byte b3 = stream.getNextIdatByte();
- byte b4 = stream.getNextIdatByte();
- if (b1 != ~b3 || b2 != ~b4) stream.error();
- uncompressedBytesRemaining = (b1 & 0xFF) | ((b2 & 0xFF) << 8);
- } else if (compressionType == COMPRESSED_DYNAMIC) {
- huffmanTables = PngHuffmanTables.getDynamicTables(stream);
- } else {
- huffmanTables = PngHuffmanTables.getFixedTables();
- }
-}
-
-byte getNextByte() {
- if (compressionType == UNCOMPRESSED) {
- if (uncompressedBytesRemaining == 0) {
- readNextBlockHeader();
- return getNextByte();
- }
- uncompressedBytesRemaining--;
- return stream.getNextIdatByte();
- } else {
- byte value = getNextCompressedByte();
- if (value == END_OF_COMPRESSED_BLOCK) {
- if (isLastBlock) stream.error();
- readNextBlockHeader();
- return getNextByte();
- } else {
- return value;
- }
- }
-}
-
-private void assertBlockAtEnd() {
- if (compressionType == UNCOMPRESSED) {
- if (uncompressedBytesRemaining > 0) stream.error();
- } else if (copyBytesRemaining > 0 ||
- (huffmanTables.getNextLiteralValue(stream) != END_OF_COMPRESSED_BLOCK))
- {
- stream.error();
- }
-}
-void assertCompressedDataAtEnd() {
- assertBlockAtEnd();
- while (!isLastBlock) {
- readNextBlockHeader();
- assertBlockAtEnd();
- }
-}
-
-private byte getNextCompressedByte() {
- if (copyBytesRemaining > 0) {
- byte value = window[copyIndex];
- window[windowIndex] = value;
- copyBytesRemaining--;
-
- copyIndex++;
- windowIndex++;
- if (copyIndex == window.length) copyIndex = 0;
- if (windowIndex == window.length) windowIndex = 0;
-
- return value;
- }
-
- int value = huffmanTables.getNextLiteralValue(stream);
- if (value < END_OF_COMPRESSED_BLOCK) {
- window[windowIndex] = (byte) (value & 0xFF);
- windowIndex++;
- if (windowIndex >= window.length) windowIndex = 0;
- return (byte) (value & 0xFF);
- } else if (value == END_OF_COMPRESSED_BLOCK) {
- readNextBlockHeader();
- return getNextCompressedByte();
- } else if (value <= LAST_LENGTH_CODE) {
- int extraBits = extraLengthBits[value - FIRST_LENGTH_CODE];
- int length = lengthBases[value - FIRST_LENGTH_CODE];
- if (extraBits > 0) {
- length += stream.getNextIdatBits(extraBits);
- }
-
- value = huffmanTables.getNextDistanceValue(stream);
- if (value > LAST_DISTANCE_CODE) stream.error();
- extraBits = extraDistanceBits[value];
- int distance = distanceBases[value];
- if (extraBits > 0) {
- distance += stream.getNextIdatBits(extraBits);
- }
-
- copyIndex = windowIndex - distance;
- if (copyIndex < 0) copyIndex += window.length;
-
- copyBytesRemaining = length;
- return getNextCompressedByte();
- } else {
- stream.error();
- return 0;
- }
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +public class PngLzBlockReader { + boolean readHeader; + boolean isLastBlock; + byte compressionType; + int uncompressedBytesRemaining; + PngDecodingDataStream stream; + PngHuffmanTables huffmanTables; + + byte[] window; + int windowIndex; + int copyIndex; + int copyBytesRemaining; + + static final int UNCOMPRESSED = 0; + static final int COMPRESSED_FIXED = 1; + static final int COMPRESSED_DYNAMIC = 2; + + static final int END_OF_COMPRESSED_BLOCK = 256; + static final int FIRST_LENGTH_CODE = 257; + static final int LAST_LENGTH_CODE = 285; + static final int FIRST_DISTANCE_CODE = 1; + static final int LAST_DISTANCE_CODE = 29; + static final int FIRST_CODE_LENGTH_CODE = 4; + static final int LAST_CODE_LENGTH_CODE = 19; + + static final int[] lengthBases = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, + 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 + } ; + static final int[] extraLengthBits = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, + }; + static final int[] distanceBases = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, + 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, + 6145, 8193, 12289, 16385, 24577, + }; + static final int[] extraDistanceBits = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, + }; + + +PngLzBlockReader(PngDecodingDataStream stream) { + this.stream = stream; + readHeader = false; + isLastBlock = false; +} + +void setWindowSize(int windowSize) { + window = new byte[windowSize]; +} + +void readNextBlockHeader() { + isLastBlock = stream.getNextIdatBit() != 0; + compressionType = (byte)(stream.getNextIdatBits(2) & 0xFF); + if (compressionType > 2) stream.error(); + + if (compressionType == UNCOMPRESSED) { + byte b1 = stream.getNextIdatByte(); + byte b2 = stream.getNextIdatByte(); + byte b3 = stream.getNextIdatByte(); + byte b4 = stream.getNextIdatByte(); + if (b1 != ~b3 || b2 != ~b4) stream.error(); + uncompressedBytesRemaining = (b1 & 0xFF) | ((b2 & 0xFF) << 8); + } else if (compressionType == COMPRESSED_DYNAMIC) { + huffmanTables = PngHuffmanTables.getDynamicTables(stream); + } else { + huffmanTables = PngHuffmanTables.getFixedTables(); + } +} + +byte getNextByte() { + if (compressionType == UNCOMPRESSED) { + if (uncompressedBytesRemaining == 0) { + readNextBlockHeader(); + return getNextByte(); + } + uncompressedBytesRemaining--; + return stream.getNextIdatByte(); + } else { + byte value = getNextCompressedByte(); + if (value == END_OF_COMPRESSED_BLOCK) { + if (isLastBlock) stream.error(); + readNextBlockHeader(); + return getNextByte(); + } else { + return value; + } + } +} + +private void assertBlockAtEnd() { + if (compressionType == UNCOMPRESSED) { + if (uncompressedBytesRemaining > 0) stream.error(); + } else if (copyBytesRemaining > 0 || + (huffmanTables.getNextLiteralValue(stream) != END_OF_COMPRESSED_BLOCK)) + { + stream.error(); + } +} +void assertCompressedDataAtEnd() { + assertBlockAtEnd(); + while (!isLastBlock) { + readNextBlockHeader(); + assertBlockAtEnd(); + } +} + +private byte getNextCompressedByte() { + if (copyBytesRemaining > 0) { + byte value = window[copyIndex]; + window[windowIndex] = value; + copyBytesRemaining--; + + copyIndex++; + windowIndex++; + if (copyIndex == window.length) copyIndex = 0; + if (windowIndex == window.length) windowIndex = 0; + + return value; + } + + int value = huffmanTables.getNextLiteralValue(stream); + if (value < END_OF_COMPRESSED_BLOCK) { + window[windowIndex] = (byte) (value & 0xFF); + windowIndex++; + if (windowIndex >= window.length) windowIndex = 0; + return (byte) (value & 0xFF); + } else if (value == END_OF_COMPRESSED_BLOCK) { + readNextBlockHeader(); + return getNextCompressedByte(); + } else if (value <= LAST_LENGTH_CODE) { + int extraBits = extraLengthBits[value - FIRST_LENGTH_CODE]; + int length = lengthBases[value - FIRST_LENGTH_CODE]; + if (extraBits > 0) { + length += stream.getNextIdatBits(extraBits); + } + + value = huffmanTables.getNextDistanceValue(stream); + if (value > LAST_DISTANCE_CODE) stream.error(); + extraBits = extraDistanceBits[value]; + int distance = distanceBases[value]; + if (extraBits > 0) { + distance += stream.getNextIdatBits(extraBits); + } + + copyIndex = windowIndex - distance; + if (copyIndex < 0) copyIndex += window.length; + + copyBytesRemaining = length; + return getNextCompressedByte(); + } else { + stream.error(); + return 0; + } +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngPlteChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngPlteChunk.java index 752a39a076..c78f96c05c 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngPlteChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngPlteChunk.java @@ -1,90 +1,90 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.internal.Compatibility;
-
-class PngPlteChunk extends PngChunk {
-
-PngPlteChunk(byte[] reference){
- super(reference);
-}
-
-/**
- * Get the number of colors in this palette.
- */
-int getPaletteSize() {
- return getLength() / 3;
-}
-
-/**
- * Get a PaletteData object representing the colors
- * stored in this PLTE chunk.
- * The result should be cached as the PLTE chunk
- * does not store the palette data created.
- */
-PaletteData getPaletteData() {
- RGB[] rgbs = new RGB[getPaletteSize()];
-// int start = DATA_OFFSET;
-// int end = DATA_OFFSET + getLength();
- for (int i = 0; i < rgbs.length; i++) {
- int offset = DATA_OFFSET + (i * 3);
- int red = reference[offset] & 0xFF;
- int green = reference[offset + 1] & 0xFF;
- int blue = reference[offset + 2] & 0xFF;
- rgbs[i] = new RGB(red, green, blue);
- }
- return new PaletteData(rgbs);
-}
-
-/**
- * Answer whether the chunk is a valid PLTE chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
- // A PLTE chunk is invalid if no IHDR has been read or if any PLTE,
- // IDAT, or IEND chunk has been read.
- if (!readState.readIHDR
- || readState.readPLTE
- || readState.readTRNS
- || readState.readBKGD
- || readState.readIDAT
- || readState.readIEND)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- readState.readPLTE = true;
- }
-
- super.validate(readState, headerChunk);
-
- // Palettes cannot be included in grayscale images.
- if (!headerChunk.getCanHavePalette()) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- // Palette chunks' data fields must be event multiples
- // of 3. Each 3-byte group represents an RGB value.
- if (getLength() % 3 != 0) SWT.error(SWT.ERROR_INVALID_IMAGE);
-
- // Palettes cannot have more entries than 2^bitDepth
- // where bitDepth is the bit depth of the image given
- // in the IHDR chunk.
- if (Compatibility.pow2(headerChunk.getBitDepth()) < getPaletteSize()) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-
- // Palettes cannot have more than 256 entries.
- if (256 < getPaletteSize()) SWT.error(SWT.ERROR_INVALID_IMAGE);
-}
-
-void contributeToString(StringBuffer buffer) {
- buffer.append("\n\tPalette size:");
- buffer.append(getPaletteSize());
-}
-
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.Compatibility; + +class PngPlteChunk extends PngChunk { + +PngPlteChunk(byte[] reference){ + super(reference); +} + +/** + * Get the number of colors in this palette. + */ +int getPaletteSize() { + return getLength() / 3; +} + +/** + * Get a PaletteData object representing the colors + * stored in this PLTE chunk. + * The result should be cached as the PLTE chunk + * does not store the palette data created. + */ +PaletteData getPaletteData() { + RGB[] rgbs = new RGB[getPaletteSize()]; +// int start = DATA_OFFSET; +// int end = DATA_OFFSET + getLength(); + for (int i = 0; i < rgbs.length; i++) { + int offset = DATA_OFFSET + (i * 3); + int red = reference[offset] & 0xFF; + int green = reference[offset + 1] & 0xFF; + int blue = reference[offset + 2] & 0xFF; + rgbs[i] = new RGB(red, green, blue); + } + return new PaletteData(rgbs); +} + +/** + * Answer whether the chunk is a valid PLTE chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk) { + // A PLTE chunk is invalid if no IHDR has been read or if any PLTE, + // IDAT, or IEND chunk has been read. + if (!readState.readIHDR + || readState.readPLTE + || readState.readTRNS + || readState.readBKGD + || readState.readIDAT + || readState.readIEND) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + readState.readPLTE = true; + } + + super.validate(readState, headerChunk); + + // Palettes cannot be included in grayscale images. + if (!headerChunk.getCanHavePalette()) SWT.error(SWT.ERROR_INVALID_IMAGE); + + // Palette chunks' data fields must be event multiples + // of 3. Each 3-byte group represents an RGB value. + if (getLength() % 3 != 0) SWT.error(SWT.ERROR_INVALID_IMAGE); + + // Palettes cannot have more entries than 2^bitDepth + // where bitDepth is the bit depth of the image given + // in the IHDR chunk. + if (Compatibility.pow2(headerChunk.getBitDepth()) < getPaletteSize()) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + + // Palettes cannot have more than 256 entries. + if (256 < getPaletteSize()) SWT.error(SWT.ERROR_INVALID_IMAGE); +} + +void contributeToString(StringBuffer buffer) { + buffer.append("\n\tPalette size:"); + buffer.append(getPaletteSize()); +} + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngTrnsChunk.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngTrnsChunk.java index aeb8ca330f..560368ebd1 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngTrnsChunk.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/PngTrnsChunk.java @@ -1,135 +1,135 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-public class PngTrnsChunk extends PngChunk {
- static final int TRANSPARENCY_TYPE_PIXEL = 0;
- static final int TRANSPARENCY_TYPE_ALPHAS = 1;
-
-PngTrnsChunk(byte[] reference){
- super(reference);
-}
-
-void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
- boolean valid;
- switch (header.getColorType()) {
- case PngIhdrChunk.COLOR_TYPE_RGB:
- // Three 2-byte values (RGB)
- valid = getLength() == 6;
- break;
- case PngIhdrChunk.COLOR_TYPE_PALETTE:
- // Three 2-byte values (RGB)
- valid = getLength() <= paletteChunk.getLength();
- break;
- case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
- // One 2-byte value
- valid = getLength() == 2;
- break;
- // Cannot use both Alpha and tRNS
- case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
- case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
- default:
- valid = false;
- }
- if (!valid) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
-}
-
-/**
- * Answer whether the chunk is a valid tRNS chunk.
- */
-void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) {
- if (!readState.readIHDR
- || (headerChunk.getMustHavePalette() && !readState.readPLTE)
- || readState.readIDAT
- || readState.readIEND)
- {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } else {
- readState.readTRNS = true;
- }
-
- validateLength(headerChunk, paletteChunk);
-
- super.validate(readState, headerChunk);
-}
-
-
-int getTransparencyType(PngIhdrChunk header) {
- if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) {
- return TRANSPARENCY_TYPE_ALPHAS;
- }
- return TRANSPARENCY_TYPE_PIXEL;
-}
-
-/**
- * Answer the transparent pixel RGB value.
- * This is not valid for palette color types.
- * This is not valid for alpha color types.
- * This will convert a grayscale value into
- * a palette index.
- * It will compress a 6 byte RGB into a 3 byte
- * RGB.
- */
-int getSwtTransparentPixel(PngIhdrChunk header) {
- switch (header.getColorType()) {
- case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
- int gray = ((reference[DATA_OFFSET] & 0xFF) << 8)
- + (reference[DATA_OFFSET + 1] & 0xFF);
- if (header.getBitDepth() > 8) {
- return PNGFileFormat.compress16BitDepthTo8BitDepth(gray);
- }
- return gray & 0xFF;
- case PngIhdrChunk.COLOR_TYPE_RGB:
- int red = ((reference[DATA_OFFSET] & 0xFF) << 8)
- | (reference[DATA_OFFSET + 1] & 0xFF);
- int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8)
- | (reference[DATA_OFFSET + 3] & 0xFF);
- int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8)
- | (reference[DATA_OFFSET + 5] & 0xFF);
- if (header.getBitDepth() > 8) {
- red = PNGFileFormat.compress16BitDepthTo8BitDepth(red);
- green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
- blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue);
- }
- return (red << 16) | (green << 8) | blue;
- default:
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return -1;
- }
-}
-
-/**
- * Answer an array of Alpha values that correspond to the
- * colors in the palette.
- * This is only valid for the COLOR_TYPE_PALETTE color type.
- */
-byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
- if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) {
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- }
- byte[] alphas = new byte[paletteChunk.getPaletteSize()];
- int dataLength = getLength();
- int i = 0;
- for (i = 0; i < dataLength; i++) {
- alphas[i] = reference[DATA_OFFSET + i];
- }
- /**
- * Any palette entries which do not have a corresponding
- * alpha value in the tRNS chunk are spec'd to have an
- * alpha of 255.
- */
- for (int j = i; j < alphas.length; j++) {
- alphas[j] = (byte) 255;
- }
- return alphas;
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +public class PngTrnsChunk extends PngChunk { + static final int TRANSPARENCY_TYPE_PIXEL = 0; + static final int TRANSPARENCY_TYPE_ALPHAS = 1; + +PngTrnsChunk(byte[] reference){ + super(reference); +} + +void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) { + boolean valid; + switch (header.getColorType()) { + case PngIhdrChunk.COLOR_TYPE_RGB: + // Three 2-byte values (RGB) + valid = getLength() == 6; + break; + case PngIhdrChunk.COLOR_TYPE_PALETTE: + // Three 2-byte values (RGB) + valid = getLength() <= paletteChunk.getLength(); + break; + case PngIhdrChunk.COLOR_TYPE_GRAYSCALE: + // One 2-byte value + valid = getLength() == 2; + break; + // Cannot use both Alpha and tRNS + case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA: + case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA: + default: + valid = false; + } + if (!valid) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } +} + +/** + * Answer whether the chunk is a valid tRNS chunk. + */ +void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) { + if (!readState.readIHDR + || (headerChunk.getMustHavePalette() && !readState.readPLTE) + || readState.readIDAT + || readState.readIEND) + { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } else { + readState.readTRNS = true; + } + + validateLength(headerChunk, paletteChunk); + + super.validate(readState, headerChunk); +} + + +int getTransparencyType(PngIhdrChunk header) { + if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) { + return TRANSPARENCY_TYPE_ALPHAS; + } + return TRANSPARENCY_TYPE_PIXEL; +} + +/** + * Answer the transparent pixel RGB value. + * This is not valid for palette color types. + * This is not valid for alpha color types. + * This will convert a grayscale value into + * a palette index. + * It will compress a 6 byte RGB into a 3 byte + * RGB. + */ +int getSwtTransparentPixel(PngIhdrChunk header) { + switch (header.getColorType()) { + case PngIhdrChunk.COLOR_TYPE_GRAYSCALE: + int gray = ((reference[DATA_OFFSET] & 0xFF) << 8) + + (reference[DATA_OFFSET + 1] & 0xFF); + if (header.getBitDepth() > 8) { + return PNGFileFormat.compress16BitDepthTo8BitDepth(gray); + } + return gray & 0xFF; + case PngIhdrChunk.COLOR_TYPE_RGB: + int red = ((reference[DATA_OFFSET] & 0xFF) << 8) + | (reference[DATA_OFFSET + 1] & 0xFF); + int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8) + | (reference[DATA_OFFSET + 3] & 0xFF); + int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8) + | (reference[DATA_OFFSET + 5] & 0xFF); + if (header.getBitDepth() > 8) { + red = PNGFileFormat.compress16BitDepthTo8BitDepth(red); + green = PNGFileFormat.compress16BitDepthTo8BitDepth(green); + blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue); + } + return (red << 16) | (green << 8) | blue; + default: + SWT.error(SWT.ERROR_INVALID_IMAGE); + return -1; + } +} + +/** + * Answer an array of Alpha values that correspond to the + * colors in the palette. + * This is only valid for the COLOR_TYPE_PALETTE color type. + */ +byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) { + if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + byte[] alphas = new byte[paletteChunk.getPaletteSize()]; + int dataLength = getLength(); + int i = 0; + for (i = 0; i < dataLength; i++) { + alphas[i] = reference[DATA_OFFSET + i]; + } + /** + * Any palette entries which do not have a corresponding + * alpha value in the tRNS chunk are spec'd to have an + * alpha of 255. + */ + for (int j = i; j < alphas.length; j++) { + alphas[j] = (byte) 255; + } + return alphas; +} } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinBMPFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinBMPFileFormat.java index e03ad73744..205cdd0fd3 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinBMPFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinBMPFileFormat.java @@ -1,665 +1,665 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import java.io.*;
-
-final class WinBMPFileFormat extends FileFormat {
- int importantColors;
- Point pelsPerMeter = new Point(0, 0);
- public static final int BMPHeaderFixedSize = 40;
-
-/**
- * Compress numBytes bytes of image data from src, storing in dest
- * (starting at 0), using the technique specified by comp.
- * If last is true, this indicates the last line of the image.
- * Answer the size of the compressed data.
- */
-int compress(int comp, byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) {
- if (comp == 1) { // BMP_RLE8_COMPRESSION
- return compressRLE8Data(src, srcOffset, numBytes, dest, last);
- }
- if (comp == 2) { // BMP_RLE4_COMPRESSION
- return compressRLE4Data(src, srcOffset, numBytes, dest, last);
- }
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return 0;
-}
-int compressRLE4Data(byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) {
- int sp = srcOffset, end = srcOffset + numBytes, dp = 0;
- int size = 0, left, i, n;
- byte theByte;
- while (sp < end) {
- /* find two consecutive bytes that are the same in the next 128 */
- left = end - sp - 1;
- if (left > 127)
- left = 127;
- for (n = 0; n < left; n++) {
- if (src[sp + n] == src[sp + n + 1])
- break;
- }
- /* if there is only one more byte in the scan line, include it */
- if (n < 127 && n == left)
- n++;
- /* store the intervening data */
- switch (n) {
- case 0:
- break;
- case 1: /* handled separately because 0,2 is a command */
- dest[dp] = 2; dp++; /* 1 byte == 2 pixels */
- dest[dp] = src[sp];
- dp++; sp++;
- size += 2;
- break;
- default:
- dest[dp] = 0; dp++;
- dest[dp] = (byte)(n + n); dp++; /* n bytes = n*2 pixels */
- for (i = n; i > 0; i--) {
- dest[dp] = src[sp];
- dp++; sp++;
- }
- size += 2 + n;
- if ((n & 1) != 0) { /* pad to word */
- dest[dp] = 0;
- dp++;
- size++;
- }
- break;
- }
- /* find the length of the next run (up to 127) and store it */
- left = end - sp;
- if (left > 0) {
- if (left > 127)
- left = 127;
- theByte = src[sp];
- for (n = 1; n < left; n++) {
- if (src[sp + n] != theByte)
- break;
- }
- dest[dp] = (byte)(n + n); dp++; /* n bytes = n*2 pixels */
- dest[dp] = theByte; dp++;
- sp += n;
- size += 2;
- }
- }
-
- /* store the end of line or end of bitmap codes */
- dest[dp] = 0; dp++;
- if (last) {
- dest[dp] = 1; dp++;
- } else {
- dest[dp] = 0; dp++;
- }
- size += 2;
-
- return size;
-}
-int compressRLE8Data(byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) {
- int sp = srcOffset, end = srcOffset + numBytes, dp = 0;
- int size = 0, left, i, n;
- byte theByte;
- while (sp < end) {
- /* find two consecutive bytes that are the same in the next 256 */
- left = end - sp - 1;
- if (left > 254)
- left = 254;
- for (n = 0; n < left; n++) {
- if (src[sp + n] == src[sp + n + 1])
- break;
- }
- /* if there is only one more byte in the scan line, include it */
- if (n == left)
- n++;
- /* store the intervening data */
- switch (n) {
- case 0:
- break;
- case 2: /* handled separately because 0,2 is a command */
- dest[dp] = 1; dp++;
- dest[dp] = src[sp];
- dp++; sp++;
- size += 2;
- /* don't break, fall through */
- case 1: /* handled separately because 0,1 is a command */
- dest[dp] = 1; dp++;
- dest[dp] = src[sp];
- dp++; sp++;
- size += 2;
- break;
- default:
- dest[dp] = 0; dp++;
- dest[dp] = (byte)n; dp++;
- for (i = n; i > 0; i--) {
- dest[dp] = src[sp];
- dp++; sp++;
- }
- size += 2 + n;
- if ((n & 1) != 0) { /* pad to word */
- dest[dp] = 0;
- dp++;
- size++;
- }
- break;
- }
- /* find the length of the next run (up to 255) and store it */
- left = end - sp;
- if (left > 0) {
- if (left > 255)
- left = 255;
- theByte = src[sp];
- for (n = 1; n < left; n++) {
- if (src[sp + n] != theByte)
- break;
- }
- dest[dp] = (byte)n; dp++;
- dest[dp] = theByte; dp++;
- sp += n;
- size += 2;
- }
- }
-
- /* store the end of line or end of bitmap codes */
- dest[dp] = 0; dp++;
- if (last) {
- dest[dp] = 1; dp++;
- } else {
- dest[dp] = 0; dp++;
- }
- size += 2;
-
- return size;
-}
-void decompressData(byte[] src, byte[] dest, int stride, int cmp) {
- if (cmp == 1) { // BMP_RLE8_COMPRESSION
- if (decompressRLE8Data(src, src.length, stride, dest, dest.length) <= 0)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return;
- }
- if (cmp == 2) { // BMP_RLE4_COMPRESSION
- if (decompressRLE4Data(src, src.length, stride, dest, dest.length) <= 0)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return;
- }
- SWT.error(SWT.ERROR_INVALID_IMAGE);
-}
-int decompressRLE4Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) {
- int sp = 0;
- int se = numBytes;
- int dp = 0;
- int de = destSize;
- int x = 0, y = 0;
- while (sp < se) {
- int len = src[sp] & 0xFF;
- sp++;
- if (len == 0) {
- len = src[sp] & 0xFF;
- sp++;
- switch (len) {
- case 0: /* end of line */
- y++;
- x = 0;
- dp = y * stride;
- if (dp >= de)
- return -1;
- break;
- case 1: /* end of bitmap */
- return 1;
- case 2: /* delta */
- x += src[sp] & 0xFF;
- sp++;
- y += src[sp] & 0xFF;
- sp++;
- dp = y * stride + x / 2;
- if (dp >= de)
- return -1;
- break;
- default: /* absolute mode run */
- if ((len & 1) != 0) /* odd run lengths not currently supported */
- return -1;
- x += len;
- len = len / 2;
- if (len > (se - sp))
- return -1;
- if (len > (de - dp))
- return -1;
- for (int i = 0; i < len; i++) {
- dest[dp] = src[sp];
- dp++;
- sp++;
- }
- if ((sp & 1) != 0)
- sp++; /* word align sp? */
- break;
- }
- } else {
- if ((len & 1) != 0)
- return -1;
- x += len;
- len = len / 2;
- byte theByte = src[sp];
- sp++;
- if (len > (de - dp))
- return -1;
- for (int i = 0; i < len; i++) {
- dest[dp] = theByte;
- dp++;
- }
- }
- }
- return 1;
-}
-int decompressRLE8Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) {
- int sp = 0;
- int se = numBytes;
- int dp = 0;
- int de = destSize;
- int x = 0, y = 0;
- while (sp < se) {
- int len = src[sp] & 0xFF;
- sp++;
- if (len == 0) {
- len = src[sp] & 0xFF;
- sp++;
- switch (len) {
- case 0: /* end of line */
- y++;
- x = 0;
- dp = y * stride;
- if (dp >= de)
- return -1;
- break;
- case 1: /* end of bitmap */
- return 1;
- case 2: /* delta */
- x += src[sp] & 0xFF;
- sp++;
- y += src[sp] & 0xFF;
- sp++;
- dp = y * stride + x;
- if (dp >= de)
- return -1;
- break;
- default: /* absolute mode run */
- if (len > (se - sp))
- return -1;
- if (len > (de - dp))
- return -1;
- for (int i = 0; i < len; i++) {
- dest[dp] = src[sp];
- dp++;
- sp++;
- }
- if ((sp & 1) != 0)
- sp++; /* word align sp? */
- x += len;
- break;
- }
- } else {
- byte theByte = src[sp];
- sp++;
- if (len > (de - dp))
- return -1;
- for (int i = 0; i < len; i++) {
- dest[dp] = theByte;
- dp++;
- }
- x += len;
- }
- }
- return 1;
-}
-boolean isFileFormat(LEDataInputStream stream) {
- try {
- byte[] header = new byte[2];
- stream.read(header);
- stream.unread(header);
- return header[0] == 0x42 && header[1] == 0x4D;
- } catch (Exception e) {
- return false;
- }
-}
-byte[] loadData(byte[] infoHeader) {
- int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
- int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
- int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
- int stride = (width * bitCount + 7) / 8;
- stride = (stride + 3) / 4 * 4; // Round up to 4 byte multiple
- byte[] data = loadData(infoHeader, stride);
- flipScanLines(data, stride, height);
- return data;
-}
-byte[] loadData(byte[] infoHeader, int stride) {
- int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
- int dataSize = height * stride;
- byte[] data = new byte[dataSize];
- int cmp = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24);
- if (cmp == 0) { // BMP_NO_COMPRESSION
- try {
- if (inputStream.read(data) != dataSize)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- } else {
- int compressedSize = (infoHeader[20] & 0xFF) | ((infoHeader[21] & 0xFF) << 8) | ((infoHeader[22] & 0xFF) << 16) | ((infoHeader[23] & 0xFF) << 24);
- byte[] compressed = new byte[compressedSize];
- try {
- if (inputStream.read(compressed) != compressedSize)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- decompressData(compressed, data, stride, cmp);
- }
- return data;
-}
-int[] loadFileHeader() {
- int[] header = new int[5];
- try {
- header[0] = inputStream.readShort();
- header[1] = inputStream.readInt();
- header[2] = inputStream.readShort();
- header[3] = inputStream.readShort();
- header[4] = inputStream.readInt();
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- if (header[0] != 0x4D42)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return header;
-}
-ImageData[] loadFromByteStream() {
- int[] fileHeader = loadFileHeader();
- byte[] infoHeader = new byte[BMPHeaderFixedSize];
- try {
- inputStream.read(infoHeader);
- } catch (Exception e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- PaletteData palette = loadPalette(infoHeader);
- if (inputStream.getPosition() < fileHeader[4]) {
- // Seek to the specified offset
- try {
- inputStream.skip(fileHeader[4] - inputStream.getPosition());
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
- byte[] data = loadData(infoHeader);
- this.compression = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24);
- this.importantColors = (infoHeader[36] & 0xFF) | ((infoHeader[37] & 0xFF) << 8) | ((infoHeader[38] & 0xFF) << 16) | ((infoHeader[39] & 0xFF) << 24);
- int xPelsPerMeter = (infoHeader[24] & 0xFF) | ((infoHeader[25] & 0xFF) << 8) | ((infoHeader[26] & 0xFF) << 16) | ((infoHeader[27] & 0xFF) << 24);
- int yPelsPerMeter = (infoHeader[28] & 0xFF) | ((infoHeader[29] & 0xFF) << 8) | ((infoHeader[30] & 0xFF) << 16) | ((infoHeader[31] & 0xFF) << 24);
- this.pelsPerMeter = new Point(xPelsPerMeter, yPelsPerMeter);
- int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
- int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
- int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
- int type = (this.compression == 1 /*BMP_RLE8_COMPRESSION*/) || (this.compression == 2 /*BMP_RLE4_COMPRESSION*/) ? SWT.IMAGE_BMP_RLE : SWT.IMAGE_BMP;
- return new ImageData[] {
- ImageData.internal_new(
- width,
- height,
- bitCount,
- palette,
- 4,
- data,
- 0,
- null,
- null,
- -1,
- -1,
- type,
- 0,
- 0,
- 0,
- 0)
- };
-}
-PaletteData loadPalette(byte[] infoHeader) {
- int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
- if (depth <= 8) {
- int numColors = (infoHeader[32] & 0xFF) | ((infoHeader[33] & 0xFF) << 8) | ((infoHeader[34] & 0xFF) << 16) | ((infoHeader[35] & 0xFF) << 24);
- if (numColors == 0) {
- numColors = 1 << ((infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8));
- } else {
- if (numColors > 256)
- numColors = 256;
- }
- byte[] buf = new byte[numColors * 4];
- try {
- if (inputStream.read(buf) != buf.length)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return paletteFromBytes(buf, numColors);
- }
- if (depth == 16) return new PaletteData(0x7C00, 0x3E0, 0x1F);
- if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000);
- return new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
-}
-PaletteData paletteFromBytes(byte[] bytes, int numColors) {
- int bytesOffset = 0;
- RGB[] colors = new RGB[numColors];
- for (int i = 0; i < numColors; i++) {
- colors[i] = new RGB(bytes[bytesOffset + 2] & 0xFF,
- bytes[bytesOffset + 1] & 0xFF,
- bytes[bytesOffset] & 0xFF);
- bytesOffset += 4;
- }
- return new PaletteData(colors);
-}
-/**
- * Answer a byte array containing the BMP representation of
- * the given device independent palette.
- */
-byte[] paletteToBytes(PaletteData pal) {
- int n = (pal.colors.length < 256) ? pal.colors.length : 256;
- byte[] bytes = new byte[n * 4];
- int offset = 0;
- for (int i = 0; i < n; i++) {
- RGB col = pal.colors[i];
- bytes[offset] = (byte)col.blue;
- bytes[offset + 1] = (byte)col.green;
- bytes[offset + 2] = (byte)col.red;
- offset += 4;
- }
- return bytes;
-}
-/**
- * Unload the given image's data into the given byte stream
- * using the given compression strategy.
- * Answer the number of bytes written.
- */
-int unloadData(ImageData image, OutputStream out, int comp) {
- int totalSize = 0;
- try {
- if (comp == 0)
- return unloadDataNoCompression(image, out);
- int bpl = (image.width * image.depth + 7) / 8;
- int bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes
- int imageBpl = image.bytesPerLine;
- // Compression can actually take twice as much space, in worst case
- byte[] buf = new byte[bmpBpl * 2];
- int srcOffset = imageBpl * (image.height - 1); // Start at last line
- byte[] data = image.data;
- totalSize = 0;
- byte[] buf2 = new byte[32768];
- int buf2Offset = 0;
- for (int y = image.height - 1; y >= 0; y--) {
- int lineSize = compress(comp, data, srcOffset, bpl, buf, y == 0);
- if (buf2Offset + lineSize > buf2.length) {
- out.write(buf2, 0, buf2Offset);
- buf2Offset = 0;
- }
- System.arraycopy(buf, 0, buf2, buf2Offset, lineSize);
- buf2Offset += lineSize;
- totalSize += lineSize;
- srcOffset -= imageBpl;
- }
- if (buf2Offset > 0)
- out.write(buf2, 0, buf2Offset);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return totalSize;
-}
-/**
- * Prepare the given image's data for unloading into a byte stream
- * using no compression strategy.
- * Answer the number of bytes written.
- */
-int unloadDataNoCompression(ImageData image, OutputStream out) {
- int bmpBpl = 0;
- try {
- int bpl = (image.width * image.depth + 7) / 8;
- bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes
- int linesPerBuf = 32678 / bmpBpl;
- byte[] buf = new byte[linesPerBuf * bmpBpl];
- byte[] data = image.data;
- int imageBpl = image.bytesPerLine;
- int dataIndex = imageBpl * (image.height - 1); // Start at last line
- if (image.depth == 16) {
- for (int y = 0; y < image.height; y += linesPerBuf) {
- int count = image.height - y;
- if (linesPerBuf < count) count = linesPerBuf;
- int bufOffset = 0;
- for (int i = 0; i < count; i++) {
- for (int wIndex = 0; wIndex < bpl; wIndex += 2) {
- buf[bufOffset + wIndex + 1] = data[dataIndex + wIndex + 1];
- buf[bufOffset + wIndex] = data[dataIndex + wIndex];
- }
- bufOffset += bmpBpl;
- dataIndex -= imageBpl;
- }
- out.write(buf, 0, bufOffset);
- }
- } else {
- for (int y = 0; y < image.height; y += linesPerBuf) {
- int tmp = image.height - y;
- int count = tmp < linesPerBuf ? tmp : linesPerBuf;
- int bufOffset = 0;
- for (int i = 0; i < count; i++) {
- System.arraycopy(data, dataIndex, buf, bufOffset, bpl);
- bufOffset += bmpBpl;
- dataIndex -= imageBpl;
- }
- out.write(buf, 0, bufOffset);
- }
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return bmpBpl * image.height;
-}
-/**
- * Unload a DeviceIndependentImage using Windows .BMP format into the given
- * byte stream.
- */
-void unloadIntoByteStream(ImageData image) {
- byte[] rgbs;
- int numCols;
- if (!((image.depth == 1) || (image.depth == 4) || (image.depth == 8) ||
- (image.depth == 16) || (image.depth == 24) || (image.depth == 32)))
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
- int comp = this.compression;
- if (!((comp == 0) || ((comp == 1) && (image.depth == 8)) ||
- ((comp == 2) && (image.depth == 4))))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- PaletteData pal = image.palette;
- if ((image.depth == 16) || (image.depth == 24) || (image.depth == 32)) {
- if (!pal.isDirect)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- numCols = 0;
- rgbs = null;
- } else {
- if (pal.isDirect)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- numCols = pal.colors.length;
- rgbs = paletteToBytes(pal);
- }
- // Fill in file header, except for bfsize, which is done later.
- int headersSize = 54;
- int[] fileHeader = new int[5];
- fileHeader[0] = 0x4D42; // Signature
- fileHeader[1] = 0; // File size - filled in later
- fileHeader[2] = 0; // Reserved 1
- fileHeader[3] = 0; // Reserved 2
- fileHeader[4] = headersSize; // Offset to data
- if (rgbs != null) {
- fileHeader[4] += rgbs.length;
- }
-
- // Prepare data. This is done first so we don't have to try to rewind
- // the stream and fill in the details later.
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- unloadData(image, out, comp);
- byte[] compressedData = out.toByteArray();
-
- // Calculate file size
- fileHeader[1] = fileHeader[4] + compressedData.length;
-
- // Write the headers
- try {
- outputStream.writeShort(fileHeader[0]);
- outputStream.writeInt(fileHeader[1]);
- outputStream.writeShort(fileHeader[2]);
- outputStream.writeShort(fileHeader[3]);
- outputStream.writeInt(fileHeader[4]);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- try {
- outputStream.writeInt(WinBMPFileFormat.BMPHeaderFixedSize);
- outputStream.writeInt(image.width);
- outputStream.writeInt(image.height);
- outputStream.writeShort(1);
- outputStream.writeShort((short)image.depth);
- outputStream.writeInt(comp);
- outputStream.writeInt(compressedData.length);
- outputStream.writeInt(pelsPerMeter.x);
- outputStream.writeInt(pelsPerMeter.y);
- outputStream.writeInt(numCols);
- outputStream.writeInt(importantColors);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-
- // Unload palette
- if (numCols > 0) {
- try {
- outputStream.write(rgbs);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- }
-
- // Unload the data
- try {
- outputStream.write(compressedData);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-void flipScanLines(byte[] data, int stride, int height) {
- int i1 = 0;
- int i2 = (height - 1) * stride;
- for (int i = 0; i < height / 2; i++) {
- for (int index = 0; index < stride; index++) {
- byte b = data[index + i1];
- data[index + i1] = data[index + i2];
- data[index + i2] = b;
- }
- i1 += stride;
- i2 -= stride;
- }
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import java.io.*; + +final class WinBMPFileFormat extends FileFormat { + int importantColors; + Point pelsPerMeter = new Point(0, 0); + public static final int BMPHeaderFixedSize = 40; + +/** + * Compress numBytes bytes of image data from src, storing in dest + * (starting at 0), using the technique specified by comp. + * If last is true, this indicates the last line of the image. + * Answer the size of the compressed data. + */ +int compress(int comp, byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) { + if (comp == 1) { // BMP_RLE8_COMPRESSION + return compressRLE8Data(src, srcOffset, numBytes, dest, last); + } + if (comp == 2) { // BMP_RLE4_COMPRESSION + return compressRLE4Data(src, srcOffset, numBytes, dest, last); + } + SWT.error(SWT.ERROR_INVALID_IMAGE); + return 0; +} +int compressRLE4Data(byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) { + int sp = srcOffset, end = srcOffset + numBytes, dp = 0; + int size = 0, left, i, n; + byte theByte; + while (sp < end) { + /* find two consecutive bytes that are the same in the next 128 */ + left = end - sp - 1; + if (left > 127) + left = 127; + for (n = 0; n < left; n++) { + if (src[sp + n] == src[sp + n + 1]) + break; + } + /* if there is only one more byte in the scan line, include it */ + if (n < 127 && n == left) + n++; + /* store the intervening data */ + switch (n) { + case 0: + break; + case 1: /* handled separately because 0,2 is a command */ + dest[dp] = 2; dp++; /* 1 byte == 2 pixels */ + dest[dp] = src[sp]; + dp++; sp++; + size += 2; + break; + default: + dest[dp] = 0; dp++; + dest[dp] = (byte)(n + n); dp++; /* n bytes = n*2 pixels */ + for (i = n; i > 0; i--) { + dest[dp] = src[sp]; + dp++; sp++; + } + size += 2 + n; + if ((n & 1) != 0) { /* pad to word */ + dest[dp] = 0; + dp++; + size++; + } + break; + } + /* find the length of the next run (up to 127) and store it */ + left = end - sp; + if (left > 0) { + if (left > 127) + left = 127; + theByte = src[sp]; + for (n = 1; n < left; n++) { + if (src[sp + n] != theByte) + break; + } + dest[dp] = (byte)(n + n); dp++; /* n bytes = n*2 pixels */ + dest[dp] = theByte; dp++; + sp += n; + size += 2; + } + } + + /* store the end of line or end of bitmap codes */ + dest[dp] = 0; dp++; + if (last) { + dest[dp] = 1; dp++; + } else { + dest[dp] = 0; dp++; + } + size += 2; + + return size; +} +int compressRLE8Data(byte[] src, int srcOffset, int numBytes, byte[] dest, boolean last) { + int sp = srcOffset, end = srcOffset + numBytes, dp = 0; + int size = 0, left, i, n; + byte theByte; + while (sp < end) { + /* find two consecutive bytes that are the same in the next 256 */ + left = end - sp - 1; + if (left > 254) + left = 254; + for (n = 0; n < left; n++) { + if (src[sp + n] == src[sp + n + 1]) + break; + } + /* if there is only one more byte in the scan line, include it */ + if (n == left) + n++; + /* store the intervening data */ + switch (n) { + case 0: + break; + case 2: /* handled separately because 0,2 is a command */ + dest[dp] = 1; dp++; + dest[dp] = src[sp]; + dp++; sp++; + size += 2; + /* don't break, fall through */ + case 1: /* handled separately because 0,1 is a command */ + dest[dp] = 1; dp++; + dest[dp] = src[sp]; + dp++; sp++; + size += 2; + break; + default: + dest[dp] = 0; dp++; + dest[dp] = (byte)n; dp++; + for (i = n; i > 0; i--) { + dest[dp] = src[sp]; + dp++; sp++; + } + size += 2 + n; + if ((n & 1) != 0) { /* pad to word */ + dest[dp] = 0; + dp++; + size++; + } + break; + } + /* find the length of the next run (up to 255) and store it */ + left = end - sp; + if (left > 0) { + if (left > 255) + left = 255; + theByte = src[sp]; + for (n = 1; n < left; n++) { + if (src[sp + n] != theByte) + break; + } + dest[dp] = (byte)n; dp++; + dest[dp] = theByte; dp++; + sp += n; + size += 2; + } + } + + /* store the end of line or end of bitmap codes */ + dest[dp] = 0; dp++; + if (last) { + dest[dp] = 1; dp++; + } else { + dest[dp] = 0; dp++; + } + size += 2; + + return size; +} +void decompressData(byte[] src, byte[] dest, int stride, int cmp) { + if (cmp == 1) { // BMP_RLE8_COMPRESSION + if (decompressRLE8Data(src, src.length, stride, dest, dest.length) <= 0) + SWT.error(SWT.ERROR_INVALID_IMAGE); + return; + } + if (cmp == 2) { // BMP_RLE4_COMPRESSION + if (decompressRLE4Data(src, src.length, stride, dest, dest.length) <= 0) + SWT.error(SWT.ERROR_INVALID_IMAGE); + return; + } + SWT.error(SWT.ERROR_INVALID_IMAGE); +} +int decompressRLE4Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) { + int sp = 0; + int se = numBytes; + int dp = 0; + int de = destSize; + int x = 0, y = 0; + while (sp < se) { + int len = src[sp] & 0xFF; + sp++; + if (len == 0) { + len = src[sp] & 0xFF; + sp++; + switch (len) { + case 0: /* end of line */ + y++; + x = 0; + dp = y * stride; + if (dp >= de) + return -1; + break; + case 1: /* end of bitmap */ + return 1; + case 2: /* delta */ + x += src[sp] & 0xFF; + sp++; + y += src[sp] & 0xFF; + sp++; + dp = y * stride + x / 2; + if (dp >= de) + return -1; + break; + default: /* absolute mode run */ + if ((len & 1) != 0) /* odd run lengths not currently supported */ + return -1; + x += len; + len = len / 2; + if (len > (se - sp)) + return -1; + if (len > (de - dp)) + return -1; + for (int i = 0; i < len; i++) { + dest[dp] = src[sp]; + dp++; + sp++; + } + if ((sp & 1) != 0) + sp++; /* word align sp? */ + break; + } + } else { + if ((len & 1) != 0) + return -1; + x += len; + len = len / 2; + byte theByte = src[sp]; + sp++; + if (len > (de - dp)) + return -1; + for (int i = 0; i < len; i++) { + dest[dp] = theByte; + dp++; + } + } + } + return 1; +} +int decompressRLE8Data(byte[] src, int numBytes, int stride, byte[] dest, int destSize) { + int sp = 0; + int se = numBytes; + int dp = 0; + int de = destSize; + int x = 0, y = 0; + while (sp < se) { + int len = src[sp] & 0xFF; + sp++; + if (len == 0) { + len = src[sp] & 0xFF; + sp++; + switch (len) { + case 0: /* end of line */ + y++; + x = 0; + dp = y * stride; + if (dp >= de) + return -1; + break; + case 1: /* end of bitmap */ + return 1; + case 2: /* delta */ + x += src[sp] & 0xFF; + sp++; + y += src[sp] & 0xFF; + sp++; + dp = y * stride + x; + if (dp >= de) + return -1; + break; + default: /* absolute mode run */ + if (len > (se - sp)) + return -1; + if (len > (de - dp)) + return -1; + for (int i = 0; i < len; i++) { + dest[dp] = src[sp]; + dp++; + sp++; + } + if ((sp & 1) != 0) + sp++; /* word align sp? */ + x += len; + break; + } + } else { + byte theByte = src[sp]; + sp++; + if (len > (de - dp)) + return -1; + for (int i = 0; i < len; i++) { + dest[dp] = theByte; + dp++; + } + x += len; + } + } + return 1; +} +boolean isFileFormat(LEDataInputStream stream) { + try { + byte[] header = new byte[2]; + stream.read(header); + stream.unread(header); + return header[0] == 0x42 && header[1] == 0x4D; + } catch (Exception e) { + return false; + } +} +byte[] loadData(byte[] infoHeader) { + int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24); + int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24); + int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8); + int stride = (width * bitCount + 7) / 8; + stride = (stride + 3) / 4 * 4; // Round up to 4 byte multiple + byte[] data = loadData(infoHeader, stride); + flipScanLines(data, stride, height); + return data; +} +byte[] loadData(byte[] infoHeader, int stride) { + int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24); + int dataSize = height * stride; + byte[] data = new byte[dataSize]; + int cmp = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24); + if (cmp == 0) { // BMP_NO_COMPRESSION + try { + if (inputStream.read(data) != dataSize) + SWT.error(SWT.ERROR_INVALID_IMAGE); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } else { + int compressedSize = (infoHeader[20] & 0xFF) | ((infoHeader[21] & 0xFF) << 8) | ((infoHeader[22] & 0xFF) << 16) | ((infoHeader[23] & 0xFF) << 24); + byte[] compressed = new byte[compressedSize]; + try { + if (inputStream.read(compressed) != compressedSize) + SWT.error(SWT.ERROR_INVALID_IMAGE); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + decompressData(compressed, data, stride, cmp); + } + return data; +} +int[] loadFileHeader() { + int[] header = new int[5]; + try { + header[0] = inputStream.readShort(); + header[1] = inputStream.readInt(); + header[2] = inputStream.readShort(); + header[3] = inputStream.readShort(); + header[4] = inputStream.readInt(); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + if (header[0] != 0x4D42) + SWT.error(SWT.ERROR_INVALID_IMAGE); + return header; +} +ImageData[] loadFromByteStream() { + int[] fileHeader = loadFileHeader(); + byte[] infoHeader = new byte[BMPHeaderFixedSize]; + try { + inputStream.read(infoHeader); + } catch (Exception e) { + SWT.error(SWT.ERROR_IO, e); + } + PaletteData palette = loadPalette(infoHeader); + if (inputStream.getPosition() < fileHeader[4]) { + // Seek to the specified offset + try { + inputStream.skip(fileHeader[4] - inputStream.getPosition()); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + byte[] data = loadData(infoHeader); + this.compression = (infoHeader[16] & 0xFF) | ((infoHeader[17] & 0xFF) << 8) | ((infoHeader[18] & 0xFF) << 16) | ((infoHeader[19] & 0xFF) << 24); + this.importantColors = (infoHeader[36] & 0xFF) | ((infoHeader[37] & 0xFF) << 8) | ((infoHeader[38] & 0xFF) << 16) | ((infoHeader[39] & 0xFF) << 24); + int xPelsPerMeter = (infoHeader[24] & 0xFF) | ((infoHeader[25] & 0xFF) << 8) | ((infoHeader[26] & 0xFF) << 16) | ((infoHeader[27] & 0xFF) << 24); + int yPelsPerMeter = (infoHeader[28] & 0xFF) | ((infoHeader[29] & 0xFF) << 8) | ((infoHeader[30] & 0xFF) << 16) | ((infoHeader[31] & 0xFF) << 24); + this.pelsPerMeter = new Point(xPelsPerMeter, yPelsPerMeter); + int width = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24); + int height = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24); + int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8); + int type = (this.compression == 1 /*BMP_RLE8_COMPRESSION*/) || (this.compression == 2 /*BMP_RLE4_COMPRESSION*/) ? SWT.IMAGE_BMP_RLE : SWT.IMAGE_BMP; + return new ImageData[] { + ImageData.internal_new( + width, + height, + bitCount, + palette, + 4, + data, + 0, + null, + null, + -1, + -1, + type, + 0, + 0, + 0, + 0) + }; +} +PaletteData loadPalette(byte[] infoHeader) { + int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8); + if (depth <= 8) { + int numColors = (infoHeader[32] & 0xFF) | ((infoHeader[33] & 0xFF) << 8) | ((infoHeader[34] & 0xFF) << 16) | ((infoHeader[35] & 0xFF) << 24); + if (numColors == 0) { + numColors = 1 << ((infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8)); + } else { + if (numColors > 256) + numColors = 256; + } + byte[] buf = new byte[numColors * 4]; + try { + if (inputStream.read(buf) != buf.length) + SWT.error(SWT.ERROR_INVALID_IMAGE); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return paletteFromBytes(buf, numColors); + } + if (depth == 16) return new PaletteData(0x7C00, 0x3E0, 0x1F); + if (depth == 24) return new PaletteData(0xFF, 0xFF00, 0xFF0000); + return new PaletteData(0xFF00, 0xFF0000, 0xFF000000); +} +PaletteData paletteFromBytes(byte[] bytes, int numColors) { + int bytesOffset = 0; + RGB[] colors = new RGB[numColors]; + for (int i = 0; i < numColors; i++) { + colors[i] = new RGB(bytes[bytesOffset + 2] & 0xFF, + bytes[bytesOffset + 1] & 0xFF, + bytes[bytesOffset] & 0xFF); + bytesOffset += 4; + } + return new PaletteData(colors); +} +/** + * Answer a byte array containing the BMP representation of + * the given device independent palette. + */ +byte[] paletteToBytes(PaletteData pal) { + int n = (pal.colors.length < 256) ? pal.colors.length : 256; + byte[] bytes = new byte[n * 4]; + int offset = 0; + for (int i = 0; i < n; i++) { + RGB col = pal.colors[i]; + bytes[offset] = (byte)col.blue; + bytes[offset + 1] = (byte)col.green; + bytes[offset + 2] = (byte)col.red; + offset += 4; + } + return bytes; +} +/** + * Unload the given image's data into the given byte stream + * using the given compression strategy. + * Answer the number of bytes written. + */ +int unloadData(ImageData image, OutputStream out, int comp) { + int totalSize = 0; + try { + if (comp == 0) + return unloadDataNoCompression(image, out); + int bpl = (image.width * image.depth + 7) / 8; + int bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes + int imageBpl = image.bytesPerLine; + // Compression can actually take twice as much space, in worst case + byte[] buf = new byte[bmpBpl * 2]; + int srcOffset = imageBpl * (image.height - 1); // Start at last line + byte[] data = image.data; + totalSize = 0; + byte[] buf2 = new byte[32768]; + int buf2Offset = 0; + for (int y = image.height - 1; y >= 0; y--) { + int lineSize = compress(comp, data, srcOffset, bpl, buf, y == 0); + if (buf2Offset + lineSize > buf2.length) { + out.write(buf2, 0, buf2Offset); + buf2Offset = 0; + } + System.arraycopy(buf, 0, buf2, buf2Offset, lineSize); + buf2Offset += lineSize; + totalSize += lineSize; + srcOffset -= imageBpl; + } + if (buf2Offset > 0) + out.write(buf2, 0, buf2Offset); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return totalSize; +} +/** + * Prepare the given image's data for unloading into a byte stream + * using no compression strategy. + * Answer the number of bytes written. + */ +int unloadDataNoCompression(ImageData image, OutputStream out) { + int bmpBpl = 0; + try { + int bpl = (image.width * image.depth + 7) / 8; + bmpBpl = (bpl + 3) / 4 * 4; // BMP pads scanlines to multiples of 4 bytes + int linesPerBuf = 32678 / bmpBpl; + byte[] buf = new byte[linesPerBuf * bmpBpl]; + byte[] data = image.data; + int imageBpl = image.bytesPerLine; + int dataIndex = imageBpl * (image.height - 1); // Start at last line + if (image.depth == 16) { + for (int y = 0; y < image.height; y += linesPerBuf) { + int count = image.height - y; + if (linesPerBuf < count) count = linesPerBuf; + int bufOffset = 0; + for (int i = 0; i < count; i++) { + for (int wIndex = 0; wIndex < bpl; wIndex += 2) { + buf[bufOffset + wIndex + 1] = data[dataIndex + wIndex + 1]; + buf[bufOffset + wIndex] = data[dataIndex + wIndex]; + } + bufOffset += bmpBpl; + dataIndex -= imageBpl; + } + out.write(buf, 0, bufOffset); + } + } else { + for (int y = 0; y < image.height; y += linesPerBuf) { + int tmp = image.height - y; + int count = tmp < linesPerBuf ? tmp : linesPerBuf; + int bufOffset = 0; + for (int i = 0; i < count; i++) { + System.arraycopy(data, dataIndex, buf, bufOffset, bpl); + bufOffset += bmpBpl; + dataIndex -= imageBpl; + } + out.write(buf, 0, bufOffset); + } + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return bmpBpl * image.height; +} +/** + * Unload a DeviceIndependentImage using Windows .BMP format into the given + * byte stream. + */ +void unloadIntoByteStream(ImageData image) { + byte[] rgbs; + int numCols; + if (!((image.depth == 1) || (image.depth == 4) || (image.depth == 8) || + (image.depth == 16) || (image.depth == 24) || (image.depth == 32))) + SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); + int comp = this.compression; + if (!((comp == 0) || ((comp == 1) && (image.depth == 8)) || + ((comp == 2) && (image.depth == 4)))) + SWT.error(SWT.ERROR_INVALID_IMAGE); + PaletteData pal = image.palette; + if ((image.depth == 16) || (image.depth == 24) || (image.depth == 32)) { + if (!pal.isDirect) + SWT.error(SWT.ERROR_INVALID_IMAGE); + numCols = 0; + rgbs = null; + } else { + if (pal.isDirect) + SWT.error(SWT.ERROR_INVALID_IMAGE); + numCols = pal.colors.length; + rgbs = paletteToBytes(pal); + } + // Fill in file header, except for bfsize, which is done later. + int headersSize = 54; + int[] fileHeader = new int[5]; + fileHeader[0] = 0x4D42; // Signature + fileHeader[1] = 0; // File size - filled in later + fileHeader[2] = 0; // Reserved 1 + fileHeader[3] = 0; // Reserved 2 + fileHeader[4] = headersSize; // Offset to data + if (rgbs != null) { + fileHeader[4] += rgbs.length; + } + + // Prepare data. This is done first so we don't have to try to rewind + // the stream and fill in the details later. + ByteArrayOutputStream out = new ByteArrayOutputStream(); + unloadData(image, out, comp); + byte[] compressedData = out.toByteArray(); + + // Calculate file size + fileHeader[1] = fileHeader[4] + compressedData.length; + + // Write the headers + try { + outputStream.writeShort(fileHeader[0]); + outputStream.writeInt(fileHeader[1]); + outputStream.writeShort(fileHeader[2]); + outputStream.writeShort(fileHeader[3]); + outputStream.writeInt(fileHeader[4]); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + try { + outputStream.writeInt(WinBMPFileFormat.BMPHeaderFixedSize); + outputStream.writeInt(image.width); + outputStream.writeInt(image.height); + outputStream.writeShort(1); + outputStream.writeShort((short)image.depth); + outputStream.writeInt(comp); + outputStream.writeInt(compressedData.length); + outputStream.writeInt(pelsPerMeter.x); + outputStream.writeInt(pelsPerMeter.y); + outputStream.writeInt(numCols); + outputStream.writeInt(importantColors); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + + // Unload palette + if (numCols > 0) { + try { + outputStream.write(rgbs); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + } + + // Unload the data + try { + outputStream.write(compressedData); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } +} +void flipScanLines(byte[] data, int stride, int height) { + int i1 = 0; + int i2 = (height - 1) * stride; + for (int i = 0; i < height / 2; i++) { + for (int index = 0; index < stride; index++) { + byte b = data[index + i1]; + data[index + i1] = data[index + i2]; + data[index + i2] = b; + } + i1 += stride; + i2 -= stride; + } +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java index ebac34ad41..1da16ed8d2 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/WinICOFileFormat.java @@ -1,284 +1,284 @@ -package org.eclipse.swt.internal.image;
-
-/*
+package org.eclipse.swt.internal.image; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import java.io.*;
-
-final class WinICOFileFormat extends FileFormat {
-/**
- * Answer the size in bytes of the file representation of the given
- * icon
- */
-int iconSize(ImageData i) {
- int shapeDataStride = (i.width * i.depth + 31) / 32 * 4;
- int maskDataStride = (i.width + 31) / 32 * 4;
- int dataSize = (shapeDataStride + maskDataStride) * i.height;
- return WinBMPFileFormat.BMPHeaderFixedSize + (i.palette.colors.length * 4) + dataSize;
-}
-boolean isFileFormat(LEDataInputStream stream) {
- try {
- byte[] header = new byte[4];
- stream.read(header);
- stream.unread(header);
- return header[0] == 0 && header[1] == 0 && header[2] == 1 && header[3] == 0;
- } catch (Exception e) {
- return false;
- }
-}
-boolean isValidIcon(ImageData i) {
- if (!((i.depth == 1) || (i.depth == 4) || (i.depth == 8)))
- return false;
- int size = i.palette.colors.length;
- return ((size == 2) || (size == 16) || (size == 32) || (size == 256));
-}
-int loadFileHeader(LEDataInputStream byteStream) {
- int[] fileHeader = new int[3];
- try {
- fileHeader[0] = byteStream.readShort();
- fileHeader[1] = byteStream.readShort();
- fileHeader[2] = byteStream.readShort();
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- if ((fileHeader[0] != 0) || (fileHeader[1] != 1))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- int numIcons = fileHeader[2];
- if (numIcons <= 0)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return numIcons;
-}
-int loadFileHeader(LEDataInputStream byteStream, boolean hasHeader) {
- int[] fileHeader = new int[3];
- try {
- if (hasHeader) {
- fileHeader[0] = byteStream.readShort();
- fileHeader[1] = byteStream.readShort();
- } else {
- fileHeader[0] = 0;
- fileHeader[1] = 1;
- }
- fileHeader[2] = byteStream.readShort();
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- if ((fileHeader[0] != 0) || (fileHeader[1] != 1))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- int numIcons = fileHeader[2];
- if (numIcons <= 0)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- return numIcons;
-}
-ImageData[] loadFromByteStream() {
- int numIcons = loadFileHeader(inputStream);
- int[][] headers = loadIconHeaders(numIcons);
- ImageData[] icons = new ImageData[headers.length];
- for (int i = 0; i < icons.length; i++) {
- icons[i] = loadIcon(headers[i]);
- }
- return icons;
-}
-/**
- * Load one icon from the byte stream.
- */
-ImageData loadIcon(int[] iconHeader) {
- byte[] infoHeader = loadInfoHeader(iconHeader);
- WinBMPFileFormat bmpFormat = new WinBMPFileFormat();
- bmpFormat.inputStream = inputStream;
- PaletteData palette = bmpFormat.loadPalette(infoHeader);
- byte[] shapeData = bmpFormat.loadData(infoHeader);
- int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
- infoHeader[14] = 1;
- infoHeader[15] = 0;
- byte[] maskData = bmpFormat.loadData(infoHeader);
- bitInvertData(maskData, 0, maskData.length);
- int infoWidth = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
- int infoHeight = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
- return ImageData.internal_new(
- infoWidth,
- infoHeight,
- depth,
- palette,
- 4,
- shapeData,
-// 4,
- 2,
- maskData,
- null,
- -1,
- -1,
- SWT.IMAGE_ICO,
- 0,
- 0,
- 0,
- 0);
-}
-int[][] loadIconHeaders(int numIcons) {
- int[][] headers = new int[numIcons][7];
- try {
- for (int i = 0; i < numIcons; i++) {
- headers[i][0] = inputStream.read();
- headers[i][1] = inputStream.read();
- headers[i][2] = inputStream.readShort();
- headers[i][3] = inputStream.readShort();
- headers[i][4] = inputStream.readShort();
- headers[i][5] = inputStream.readInt();
- headers[i][6] = inputStream.readInt();
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- return headers;
-}
-byte[] loadInfoHeader(int[] iconHeader) {
- int width = iconHeader[0];
- int height = iconHeader[1];
- int numColors = iconHeader[2]; // the number of colors is in the low byte, but the high byte must be 0
- if (numColors == 0) numColors = 256; // this is specified: '00' represents '256' (0x100) colors
- if ((numColors != 2) && (numColors != 8) && (numColors != 16) &&
- (numColors != 32) && (numColors != 256))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- if (inputStream.getPosition() < iconHeader[6]) {
- // Seek to the specified offset
- try {
- inputStream.skip(iconHeader[6] - inputStream.getPosition());
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- return null;
- }
- }
- byte[] infoHeader = new byte[WinBMPFileFormat.BMPHeaderFixedSize];
- try {
- inputStream.read(infoHeader);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- if (((infoHeader[12] & 0xFF) | ((infoHeader[13] & 0xFF) << 8)) != 1)
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- int infoWidth = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24);
- int infoHeight = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24);
- int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8);
- if (height == infoHeight && bitCount == 1) height /= 2;
- if (!((width == infoWidth) && (height * 2 == infoHeight) &&
- ((bitCount == 1) || (bitCount == 4) || (bitCount == 8))))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- infoHeader[8] = (byte)(height & 0xFF);
- infoHeader[9] = (byte)((height >> 8) & 0xFF);
- infoHeader[10] = (byte)((height >> 16) & 0xFF);
- infoHeader[11] = (byte)((height >> 24) & 0xFF);
- return infoHeader;
-}
-/**
- * Unload a single icon
- */
-void unloadIcon(ImageData icon) {
- int sizeImage = (((icon.width * icon.depth + 31) / 32 * 4) +
- ((icon.width + 31) / 32 * 4)) * icon.height;
- try {
- outputStream.writeInt(WinBMPFileFormat.BMPHeaderFixedSize);
- outputStream.writeInt(icon.width);
- outputStream.writeInt(icon.height * 2);
- outputStream.writeShort(1);
- outputStream.writeShort((short)icon.depth);
- outputStream.writeInt(0);
- outputStream.writeInt(sizeImage);
- outputStream.writeInt(0);
- outputStream.writeInt(0);
- outputStream.writeInt(icon.palette.colors.length);
- outputStream.writeInt(0);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-
- byte[] rgbs = new WinBMPFileFormat().paletteToBytes(icon.palette);
- try {
- outputStream.write(rgbs);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- unloadShapeData(icon);
- unloadMaskData(icon);
-}
-/**
- * Unload the icon header for the given icon, calculating the offset.
- */
-void unloadIconHeader(ImageData i) {
- int headerSize = 16;
- int offset = headerSize + 6;
- int iconSize = iconSize(i);
- try {
- outputStream.writeByte((byte)i.width);
- outputStream.writeByte((byte)i.height);
- outputStream.writeShort(i.palette.colors.length);
- outputStream.writeShort(0);
- outputStream.writeShort(0);
- outputStream.writeInt(iconSize);
- outputStream.writeInt(offset);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-void unloadIntoByteStream(ImageData image) {
- if (!isValidIcon(image))
- SWT.error(SWT.ERROR_INVALID_IMAGE);
- try {
- outputStream.writeShort(0);
- outputStream.writeShort(1);
- outputStream.writeShort(1);
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
- unloadIconHeader(image);
- unloadIcon(image);
-}
-/**
- * Unload the mask data for an icon. The data is flipped vertically
- * and inverted.
- */
-void unloadMaskData(ImageData icon) {
- int bpl = (icon.width + 7) / 8;
- int pad = 4;
- int srcBpl = (bpl + pad - 1) / pad * pad;
- int destBpl = (bpl + 3) / 4 * 4;
- byte[] buf = new byte[destBpl];
- int offset = (icon.height - 1) * srcBpl;
- byte[] data = icon.getTransparencyMask().data;
- try {
- for (int i = 0; i < icon.height; i++) {
- System.arraycopy(data, offset, buf, 0, bpl);
- bitInvertData(buf, 0, bpl);
- outputStream.write(buf, 0, destBpl);
- offset -= srcBpl;
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-/**
- * Unload the shape data for an icon. The data is flipped vertically.
- */
-void unloadShapeData(ImageData icon) {
- int bpl = (icon.width * icon.depth + 7) / 8;
- int pad = 4;
- int srcBpl = (bpl + pad - 1) / pad * pad;
- int destBpl = (bpl + 3) / 4 * 4;
- byte[] buf = new byte[destBpl];
- int offset = (icon.height - 1) * srcBpl;
- byte[] data = icon.data;
- try {
- for (int i = 0; i < icon.height; i++) {
- System.arraycopy(data, offset, buf, 0, bpl);
- outputStream.write(buf, 0, destBpl);
- offset -= srcBpl;
- }
- } catch (IOException e) {
- SWT.error(SWT.ERROR_IO, e);
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import java.io.*; + +final class WinICOFileFormat extends FileFormat { +/** + * Answer the size in bytes of the file representation of the given + * icon + */ +int iconSize(ImageData i) { + int shapeDataStride = (i.width * i.depth + 31) / 32 * 4; + int maskDataStride = (i.width + 31) / 32 * 4; + int dataSize = (shapeDataStride + maskDataStride) * i.height; + return WinBMPFileFormat.BMPHeaderFixedSize + (i.palette.colors.length * 4) + dataSize; +} +boolean isFileFormat(LEDataInputStream stream) { + try { + byte[] header = new byte[4]; + stream.read(header); + stream.unread(header); + return header[0] == 0 && header[1] == 0 && header[2] == 1 && header[3] == 0; + } catch (Exception e) { + return false; + } +} +boolean isValidIcon(ImageData i) { + if (!((i.depth == 1) || (i.depth == 4) || (i.depth == 8))) + return false; + int size = i.palette.colors.length; + return ((size == 2) || (size == 16) || (size == 32) || (size == 256)); +} +int loadFileHeader(LEDataInputStream byteStream) { + int[] fileHeader = new int[3]; + try { + fileHeader[0] = byteStream.readShort(); + fileHeader[1] = byteStream.readShort(); + fileHeader[2] = byteStream.readShort(); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + if ((fileHeader[0] != 0) || (fileHeader[1] != 1)) + SWT.error(SWT.ERROR_INVALID_IMAGE); + int numIcons = fileHeader[2]; + if (numIcons <= 0) + SWT.error(SWT.ERROR_INVALID_IMAGE); + return numIcons; +} +int loadFileHeader(LEDataInputStream byteStream, boolean hasHeader) { + int[] fileHeader = new int[3]; + try { + if (hasHeader) { + fileHeader[0] = byteStream.readShort(); + fileHeader[1] = byteStream.readShort(); + } else { + fileHeader[0] = 0; + fileHeader[1] = 1; + } + fileHeader[2] = byteStream.readShort(); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + if ((fileHeader[0] != 0) || (fileHeader[1] != 1)) + SWT.error(SWT.ERROR_INVALID_IMAGE); + int numIcons = fileHeader[2]; + if (numIcons <= 0) + SWT.error(SWT.ERROR_INVALID_IMAGE); + return numIcons; +} +ImageData[] loadFromByteStream() { + int numIcons = loadFileHeader(inputStream); + int[][] headers = loadIconHeaders(numIcons); + ImageData[] icons = new ImageData[headers.length]; + for (int i = 0; i < icons.length; i++) { + icons[i] = loadIcon(headers[i]); + } + return icons; +} +/** + * Load one icon from the byte stream. + */ +ImageData loadIcon(int[] iconHeader) { + byte[] infoHeader = loadInfoHeader(iconHeader); + WinBMPFileFormat bmpFormat = new WinBMPFileFormat(); + bmpFormat.inputStream = inputStream; + PaletteData palette = bmpFormat.loadPalette(infoHeader); + byte[] shapeData = bmpFormat.loadData(infoHeader); + int depth = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8); + infoHeader[14] = 1; + infoHeader[15] = 0; + byte[] maskData = bmpFormat.loadData(infoHeader); + bitInvertData(maskData, 0, maskData.length); + int infoWidth = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24); + int infoHeight = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24); + return ImageData.internal_new( + infoWidth, + infoHeight, + depth, + palette, + 4, + shapeData, +// 4, + 2, + maskData, + null, + -1, + -1, + SWT.IMAGE_ICO, + 0, + 0, + 0, + 0); +} +int[][] loadIconHeaders(int numIcons) { + int[][] headers = new int[numIcons][7]; + try { + for (int i = 0; i < numIcons; i++) { + headers[i][0] = inputStream.read(); + headers[i][1] = inputStream.read(); + headers[i][2] = inputStream.readShort(); + headers[i][3] = inputStream.readShort(); + headers[i][4] = inputStream.readShort(); + headers[i][5] = inputStream.readInt(); + headers[i][6] = inputStream.readInt(); + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return headers; +} +byte[] loadInfoHeader(int[] iconHeader) { + int width = iconHeader[0]; + int height = iconHeader[1]; + int numColors = iconHeader[2]; // the number of colors is in the low byte, but the high byte must be 0 + if (numColors == 0) numColors = 256; // this is specified: '00' represents '256' (0x100) colors + if ((numColors != 2) && (numColors != 8) && (numColors != 16) && + (numColors != 32) && (numColors != 256)) + SWT.error(SWT.ERROR_INVALID_IMAGE); + if (inputStream.getPosition() < iconHeader[6]) { + // Seek to the specified offset + try { + inputStream.skip(iconHeader[6] - inputStream.getPosition()); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + return null; + } + } + byte[] infoHeader = new byte[WinBMPFileFormat.BMPHeaderFixedSize]; + try { + inputStream.read(infoHeader); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + if (((infoHeader[12] & 0xFF) | ((infoHeader[13] & 0xFF) << 8)) != 1) + SWT.error(SWT.ERROR_INVALID_IMAGE); + int infoWidth = (infoHeader[4] & 0xFF) | ((infoHeader[5] & 0xFF) << 8) | ((infoHeader[6] & 0xFF) << 16) | ((infoHeader[7] & 0xFF) << 24); + int infoHeight = (infoHeader[8] & 0xFF) | ((infoHeader[9] & 0xFF) << 8) | ((infoHeader[10] & 0xFF) << 16) | ((infoHeader[11] & 0xFF) << 24); + int bitCount = (infoHeader[14] & 0xFF) | ((infoHeader[15] & 0xFF) << 8); + if (height == infoHeight && bitCount == 1) height /= 2; + if (!((width == infoWidth) && (height * 2 == infoHeight) && + ((bitCount == 1) || (bitCount == 4) || (bitCount == 8)))) + SWT.error(SWT.ERROR_INVALID_IMAGE); + infoHeader[8] = (byte)(height & 0xFF); + infoHeader[9] = (byte)((height >> 8) & 0xFF); + infoHeader[10] = (byte)((height >> 16) & 0xFF); + infoHeader[11] = (byte)((height >> 24) & 0xFF); + return infoHeader; +} +/** + * Unload a single icon + */ +void unloadIcon(ImageData icon) { + int sizeImage = (((icon.width * icon.depth + 31) / 32 * 4) + + ((icon.width + 31) / 32 * 4)) * icon.height; + try { + outputStream.writeInt(WinBMPFileFormat.BMPHeaderFixedSize); + outputStream.writeInt(icon.width); + outputStream.writeInt(icon.height * 2); + outputStream.writeShort(1); + outputStream.writeShort((short)icon.depth); + outputStream.writeInt(0); + outputStream.writeInt(sizeImage); + outputStream.writeInt(0); + outputStream.writeInt(0); + outputStream.writeInt(icon.palette.colors.length); + outputStream.writeInt(0); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + + byte[] rgbs = new WinBMPFileFormat().paletteToBytes(icon.palette); + try { + outputStream.write(rgbs); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + unloadShapeData(icon); + unloadMaskData(icon); +} +/** + * Unload the icon header for the given icon, calculating the offset. + */ +void unloadIconHeader(ImageData i) { + int headerSize = 16; + int offset = headerSize + 6; + int iconSize = iconSize(i); + try { + outputStream.writeByte((byte)i.width); + outputStream.writeByte((byte)i.height); + outputStream.writeShort(i.palette.colors.length); + outputStream.writeShort(0); + outputStream.writeShort(0); + outputStream.writeInt(iconSize); + outputStream.writeInt(offset); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } +} +void unloadIntoByteStream(ImageData image) { + if (!isValidIcon(image)) + SWT.error(SWT.ERROR_INVALID_IMAGE); + try { + outputStream.writeShort(0); + outputStream.writeShort(1); + outputStream.writeShort(1); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + unloadIconHeader(image); + unloadIcon(image); +} +/** + * Unload the mask data for an icon. The data is flipped vertically + * and inverted. + */ +void unloadMaskData(ImageData icon) { + int bpl = (icon.width + 7) / 8; + int pad = 4; + int srcBpl = (bpl + pad - 1) / pad * pad; + int destBpl = (bpl + 3) / 4 * 4; + byte[] buf = new byte[destBpl]; + int offset = (icon.height - 1) * srcBpl; + byte[] data = icon.getTransparencyMask().data; + try { + for (int i = 0; i < icon.height; i++) { + System.arraycopy(data, offset, buf, 0, bpl); + bitInvertData(buf, 0, bpl); + outputStream.write(buf, 0, destBpl); + offset -= srcBpl; + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } +} +/** + * Unload the shape data for an icon. The data is flipped vertically. + */ +void unloadShapeData(ImageData icon) { + int bpl = (icon.width * icon.depth + 7) / 8; + int pad = 4; + int srcBpl = (bpl + pad - 1) / pad * pad; + int destBpl = (bpl + 3) / 4 * 4; + byte[] buf = new byte[destBpl]; + int offset = (icon.height - 1) * srcBpl; + byte[] data = icon.data; + try { + for (int i = 0; i < icon.height; i++) { + System.arraycopy(data, offset, buf, 0, bpl); + outputStream.write(buf, 0, destBpl); + offset -= srcBpl; + } + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FillLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FillLayout.java index fd82c6a586..1b27a2774d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FillLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FillLayout.java @@ -1,111 +1,111 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * <code>FillLayout</code> is the simplest layout class. It lays out
- * controls in a single row or column, forcing them to be the same size.
- * <p>
- * Initially, the controls will all be as tall as the tallest control,
- * and as wide as the widest. <code>FillLayout</code> does not wrap,
- * and you cannot specify margins or spacing. You might use it to
- * lay out buttons in a task bar or tool bar, or to stack checkboxes
- * in a <code>Group</code>. <code>FillLayout</code> can also be used
- * when a <code>Composite</code> only has one child. For example,
- * if a <code>Shell</code> has a single <code>Group</code> child,
- * <code>FillLayout</code> will cause the <code>Group</code> to
- * completely fill the <code>Shell</code>.
- * </p>
- * <p>
- * Example code: first a <code>FillLayout</code> is created and
- * its type field is set, and then the layout is set into the
- * <code>Composite</code>. Note that in a <code>FillLayout</code>,
- * children are always the same size, and they fill all available space.
- * <pre>
- * FillLayout fillLayout = new FillLayout();
- * fillLayout.type = SWT.VERTICAL;
- * shell.setLayout(fillLayout);
- * </pre>
- * </p>
- */
-public final class FillLayout extends Layout {
- /**
- * type specifies how controls will be positioned
- * within the layout.
- *
- * The default value is HORIZONTAL.
- *
- * Possible values are:
- *
- * HORIZONTAL: Position the controls horizontally from left to right
- * VERTICAL: Position the controls vertically from top to bottom
- */
- public int type = SWT.HORIZONTAL;
-
-/**
- * Constructs a new instance of this class.
- */
-public FillLayout () {
-}
-
-/**
- * Constructs a new instance of this class given the type.
- *
- * @param type the type of fill layout
- *
- * @since 2.0
- */
-public FillLayout (int type) {
- this.type = type;
-}
-
-protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) {
- Control [] children = composite.getChildren ();
- int count = children.length;
- int maxWidth = 0, maxHeight = 0;
- for (int i=0; i<count; i++) {
- Control child = children [i];
- Point pt = child.computeSize (SWT.DEFAULT, SWT.DEFAULT, flushCache);
- maxWidth = Math.max (maxWidth, pt.x);
- maxHeight = Math.max (maxHeight, pt.y);
- }
- if (type == SWT.HORIZONTAL) {
- return new Point (count * maxWidth, maxHeight);
- }
- return new Point (maxWidth, count * maxHeight);
-}
-
-protected void layout (Composite composite, boolean flushCache) {
- Rectangle rect = composite.getClientArea ();
- Control [] children = composite.getChildren ();
- int count = children.length;
- if (count == 0) return;
- if (type == SWT.HORIZONTAL) {
- int x = rect.x + ((rect.width % count) / 2);
- int width = rect.width / count;
- int y = rect.y, height = rect.height;
- for (int i=0; i<count; i++) {
- Control child = children [i];
- child.setBounds (x, y, width, height);
- x += width;
- }
- return;
- }
- int x = rect.x, width = rect.width;
- int y = rect.y + ((rect.height % count) / 2);
- int height = rect.height / count;
- for (int i=0; i<count; i++) {
- Control child = children [i];
- child.setBounds (x, y, width, height);
- y += height;
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +/** + * <code>FillLayout</code> is the simplest layout class. It lays out + * controls in a single row or column, forcing them to be the same size. + * <p> + * Initially, the controls will all be as tall as the tallest control, + * and as wide as the widest. <code>FillLayout</code> does not wrap, + * and you cannot specify margins or spacing. You might use it to + * lay out buttons in a task bar or tool bar, or to stack checkboxes + * in a <code>Group</code>. <code>FillLayout</code> can also be used + * when a <code>Composite</code> only has one child. For example, + * if a <code>Shell</code> has a single <code>Group</code> child, + * <code>FillLayout</code> will cause the <code>Group</code> to + * completely fill the <code>Shell</code>. + * </p> + * <p> + * Example code: first a <code>FillLayout</code> is created and + * its type field is set, and then the layout is set into the + * <code>Composite</code>. Note that in a <code>FillLayout</code>, + * children are always the same size, and they fill all available space. + * <pre> + * FillLayout fillLayout = new FillLayout(); + * fillLayout.type = SWT.VERTICAL; + * shell.setLayout(fillLayout); + * </pre> + * </p> + */ +public final class FillLayout extends Layout { + /** + * type specifies how controls will be positioned + * within the layout. + * + * The default value is HORIZONTAL. + * + * Possible values are: + * + * HORIZONTAL: Position the controls horizontally from left to right + * VERTICAL: Position the controls vertically from top to bottom + */ + public int type = SWT.HORIZONTAL; + +/** + * Constructs a new instance of this class. + */ +public FillLayout () { +} + +/** + * Constructs a new instance of this class given the type. + * + * @param type the type of fill layout + * + * @since 2.0 + */ +public FillLayout (int type) { + this.type = type; +} + +protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) { + Control [] children = composite.getChildren (); + int count = children.length; + int maxWidth = 0, maxHeight = 0; + for (int i=0; i<count; i++) { + Control child = children [i]; + Point pt = child.computeSize (SWT.DEFAULT, SWT.DEFAULT, flushCache); + maxWidth = Math.max (maxWidth, pt.x); + maxHeight = Math.max (maxHeight, pt.y); + } + if (type == SWT.HORIZONTAL) { + return new Point (count * maxWidth, maxHeight); + } + return new Point (maxWidth, count * maxHeight); +} + +protected void layout (Composite composite, boolean flushCache) { + Rectangle rect = composite.getClientArea (); + Control [] children = composite.getChildren (); + int count = children.length; + if (count == 0) return; + if (type == SWT.HORIZONTAL) { + int x = rect.x + ((rect.width % count) / 2); + int width = rect.width / count; + int y = rect.y, height = rect.height; + for (int i=0; i<count; i++) { + Control child = children [i]; + child.setBounds (x, y, width, height); + x += width; + } + return; + } + int x = rect.x, width = rect.width; + int y = rect.y + ((rect.height % count) / 2); + int height = rect.height / count; + for (int i=0; i<count; i++) { + Control child = children [i]; + child.setBounds (x, y, width, height); + y += height; + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormAttachment.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormAttachment.java index 109a78a30c..e9fafdb6ff 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormAttachment.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormAttachment.java @@ -1,261 +1,261 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Instances of this class are used to define the edges of a control
- * within a <code>FormLayout</code>.
- * <p>
- * <code>FormAttachments</code> are set into the top, bottom, left,
- * and right fields of the <code>FormData</code> for a control.
- * For example:
- * <pre>
- * FormData data = new FormData();
- * data.top = new FormAttachment(0,5);
- * data.bottom = new FormAttachment(100,-5);
- * data.left = new FormAttachment(0,5);
- * data.right = new FormAttachment(100,-5);
- * button.setLayoutData(data);
- * </pre>
- * </p>
- * <p>
- * A <code>FormAttachment</code> defines where to attach the side of
- * a control by using the equation, y = ax + b. The "a" term represents
- * a fraction of the parent composite's width (from the left) or height
- * (from the top). It can be defined using a numerator and denominator,
- * or just a percentage value. If a percentage is used, the denominator
- * is set to 100. The "b" term in the equation represents an offset, in
- * pixels, from the attachment position. For example:
- * <pre>
- * FormAttachment attach = new FormAttachment (20, -5);
- * </pre>
- * specifies that the side to which the <code>FormAttachment</code>
- * object belongs will lie at 20% of the parent composite, minus 5 pixels.
- * </p>
- * <p>
- * Control sides can also be attached to another control.
- * For example:
- * <pre>
- * FormAttachment attach = new FormAttachment (button, 10);
- * </pre>
- * specifies that the side to which the <code>FormAttachment</code>
- * object belongs will lie in the same position as the adjacent side of
- * the <code>button</code> control, plus 10 pixels. The control side can
- * also be attached to the opposite side of the specified control.
- * For example:
- * <pre>
- * FormData data = new FormData ();
- * data.left = new FormAttachment (button, 0, SWT.LEFT);
- * </pre>
- * specifies that the left side of the control will lie in the same position
- * as the left side of the <code>button</code> control. The control can also
- * be attached in a position that will center the control on the specified
- * control. For example:
- * <pre>
- * data.left = new FormAttachment (button, 0, SWT.CENTER);
- * </pre>
- * specifies that the left side of the control will be positioned so that it is
- * centered between the left and right sides of the <code>button</code> control.
- * If the alignment is not specified, the default is to attach to the adjacent side.
- * </p>
- *
- * @see FormLayout
- * @see FormData
- *
- * @since 2.0
- */
-public final class FormAttachment {
- /**
- * numerator specifies the numerator of the "a" term in the
- * equation, y = ax + b, which defines the attachment.
- */
- public int numerator;
- /**
- * denominator specifies the denominator of the "a" term in the
- * equation, y = ax + b, which defines the attachment.
- *
- * The default value is 100.
- */
- public int denominator = 100;
- /**
- * offset specifies the offset, in pixels, of the control side
- * from the attachment position.
- * If the offset is positive, then the control side is offset
- * to the right of or below the attachment position. If it is
- * negative, then the control side is offset to the left of or
- * above the attachment position.
- *
- * This is equivalent to the "b" term in the equation y = ax + b.
- * The default value is 0.
- */
- public int offset;
- /**
- * control specifies the control to which the control side is
- * attached.
- */
- public Control control;
- /**
- * alignment specifies the alignment of the control side that is
- * attached to a control.
- * For top and bottom attachments, TOP, BOTTOM and CENTER are used. For left
- * and right attachments, LEFT, RIGHT and CENTER are used. If any other case
- * occurs, the default will be used instead.
- *
- * Possible values are:
- *
- * TOP: Attach the side to the top side of the specified control.
- * BOTTOM : Attach the side to the bottom side of the specified control.
- * LEFT: Attach the side to the left side of the specified control.
- * RIGHT: Attach the side to the right side of the specified control.
- * CENTER: Attach the side at a position which will center the control on
- * the specified control.
- * DEFAULT: Attach the side to the adjacent side of the specified control.
- */
- public int alignment;
-
-FormAttachment () {
-}
-
-/**
- * Constructs a new instance of this class given a numerator
- * and denominator and an offset. The position of the side is
- * given by the fraction of the form defined by the numerator
- * and denominator.
- *
- * @param numerator the numerator of the position
- * @param denominator the denominator of the position
- * @param offset the offset of the side from the position
- */
-public FormAttachment (int numerator, int denominator, int offset) {
- if (denominator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO);
- this.numerator = numerator;
- this.denominator = denominator;
- this.offset = offset;
-}
-
-/**
- * Constructs a new instance of this class given a numerator
- * and an offset. Since no denominator is specified, the default
- * is to read the numerator as a percentage of the form, with a
- * denominator of 100.
- *
- * @param numerator the percentage of the position
- * @param offset the offset of the side from the position
- */
-public FormAttachment (int numerator, int offset) {
- this (numerator, 100, offset);
-}
-
-/**
- * Constructs a new instance of this class given a control,
- * an offset and an alignment.
- *
- * @param control the control the side is attached to
- * @param offset the offset of the side from the control
- * @param alignment the alignment of the side to the control it is attached to
- */
-public FormAttachment (Control control, int offset, int alignment) {
- this.control = control;
- this.offset = offset;
- this.alignment = alignment;
-}
-
-/**
- * Constructs a new instance of this class given a control
- * and an offset. Since no alignment is specified, the default
- * alignment is to attach the side to the adjacent side of the
- * specified control.
- *
- * @param control the control the side is attached to
- * @param offset the offset of the side from the control
- */
-public FormAttachment (Control control, int offset) {
- this (control, offset, SWT.DEFAULT);
-}
-
-/**
- * Constructs a new instance of this class given a control.
- * Since no alignment is specified, the default alignment is
- * to attach the side to the adjacent side of the specified
- * control. Since no offset is specified, an offset of 0 is
- * used.
- *
- * @param control the control the side is attached to
- */
-public FormAttachment (Control control) {
- this (control, 0, SWT.DEFAULT);
-}
-
-FormAttachment divide (int value) {
- return new FormAttachment (numerator, denominator * value, offset / value);
-}
-
-int gcd (int m, int n) {
- int temp;
- m = Math.abs (m); n = Math.abs (n);
- if (m < n) {
- temp = m;
- m = n;
- n = temp;
- }
- while (n != 0){
- temp = m;
- m = n;
- n = temp % n;
- }
- return m;
-}
-
-FormAttachment minus (FormAttachment attachment) {
- FormAttachment solution = new FormAttachment ();
- solution.numerator = numerator * attachment.denominator - denominator * attachment.numerator;
- solution.denominator = denominator * attachment.denominator;
- int gcd = gcd (solution.denominator, solution.numerator);
- solution.numerator = solution.numerator / gcd;
- solution.denominator = solution.denominator / gcd;
- solution.offset = offset - attachment.offset;
- return solution;
-}
-
-FormAttachment minus (int value) {
- return new FormAttachment (numerator, denominator, offset - value);
-}
-
-FormAttachment plus (FormAttachment attachment) {
- FormAttachment solution = new FormAttachment ();
- solution.numerator = numerator * attachment.denominator + denominator * attachment.numerator;
- solution.denominator = denominator * attachment.denominator;
- int gcd = gcd (solution.denominator, solution.numerator);
- solution.numerator = solution.numerator / gcd;
- solution.denominator = solution.denominator / gcd;
- solution.offset = offset + attachment.offset;
- return solution;
-}
-
-FormAttachment plus (int value) {
- return new FormAttachment (numerator, denominator, offset + value);
-}
-
-int solveX (int value) {
- if (denominator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO);
- return ((numerator * value) / denominator) + offset;
-}
-
-int solveY (int value) {
- if (numerator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO);
- return (value - offset) * denominator / numerator;
-}
-
-public String toString () {
- String string = control != null ? control.toString () : numerator + "/" + denominator;
- return "y = (" + string + (offset >= 0 ? ")x + " + offset: ")x - " + (-offset));
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; +import org.eclipse.swt.widgets.*; + +/** + * Instances of this class are used to define the edges of a control + * within a <code>FormLayout</code>. + * <p> + * <code>FormAttachments</code> are set into the top, bottom, left, + * and right fields of the <code>FormData</code> for a control. + * For example: + * <pre> + * FormData data = new FormData(); + * data.top = new FormAttachment(0,5); + * data.bottom = new FormAttachment(100,-5); + * data.left = new FormAttachment(0,5); + * data.right = new FormAttachment(100,-5); + * button.setLayoutData(data); + * </pre> + * </p> + * <p> + * A <code>FormAttachment</code> defines where to attach the side of + * a control by using the equation, y = ax + b. The "a" term represents + * a fraction of the parent composite's width (from the left) or height + * (from the top). It can be defined using a numerator and denominator, + * or just a percentage value. If a percentage is used, the denominator + * is set to 100. The "b" term in the equation represents an offset, in + * pixels, from the attachment position. For example: + * <pre> + * FormAttachment attach = new FormAttachment (20, -5); + * </pre> + * specifies that the side to which the <code>FormAttachment</code> + * object belongs will lie at 20% of the parent composite, minus 5 pixels. + * </p> + * <p> + * Control sides can also be attached to another control. + * For example: + * <pre> + * FormAttachment attach = new FormAttachment (button, 10); + * </pre> + * specifies that the side to which the <code>FormAttachment</code> + * object belongs will lie in the same position as the adjacent side of + * the <code>button</code> control, plus 10 pixels. The control side can + * also be attached to the opposite side of the specified control. + * For example: + * <pre> + * FormData data = new FormData (); + * data.left = new FormAttachment (button, 0, SWT.LEFT); + * </pre> + * specifies that the left side of the control will lie in the same position + * as the left side of the <code>button</code> control. The control can also + * be attached in a position that will center the control on the specified + * control. For example: + * <pre> + * data.left = new FormAttachment (button, 0, SWT.CENTER); + * </pre> + * specifies that the left side of the control will be positioned so that it is + * centered between the left and right sides of the <code>button</code> control. + * If the alignment is not specified, the default is to attach to the adjacent side. + * </p> + * + * @see FormLayout + * @see FormData + * + * @since 2.0 + */ +public final class FormAttachment { + /** + * numerator specifies the numerator of the "a" term in the + * equation, y = ax + b, which defines the attachment. + */ + public int numerator; + /** + * denominator specifies the denominator of the "a" term in the + * equation, y = ax + b, which defines the attachment. + * + * The default value is 100. + */ + public int denominator = 100; + /** + * offset specifies the offset, in pixels, of the control side + * from the attachment position. + * If the offset is positive, then the control side is offset + * to the right of or below the attachment position. If it is + * negative, then the control side is offset to the left of or + * above the attachment position. + * + * This is equivalent to the "b" term in the equation y = ax + b. + * The default value is 0. + */ + public int offset; + /** + * control specifies the control to which the control side is + * attached. + */ + public Control control; + /** + * alignment specifies the alignment of the control side that is + * attached to a control. + * For top and bottom attachments, TOP, BOTTOM and CENTER are used. For left + * and right attachments, LEFT, RIGHT and CENTER are used. If any other case + * occurs, the default will be used instead. + * + * Possible values are: + * + * TOP: Attach the side to the top side of the specified control. + * BOTTOM : Attach the side to the bottom side of the specified control. + * LEFT: Attach the side to the left side of the specified control. + * RIGHT: Attach the side to the right side of the specified control. + * CENTER: Attach the side at a position which will center the control on + * the specified control. + * DEFAULT: Attach the side to the adjacent side of the specified control. + */ + public int alignment; + +FormAttachment () { +} + +/** + * Constructs a new instance of this class given a numerator + * and denominator and an offset. The position of the side is + * given by the fraction of the form defined by the numerator + * and denominator. + * + * @param numerator the numerator of the position + * @param denominator the denominator of the position + * @param offset the offset of the side from the position + */ +public FormAttachment (int numerator, int denominator, int offset) { + if (denominator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO); + this.numerator = numerator; + this.denominator = denominator; + this.offset = offset; +} + +/** + * Constructs a new instance of this class given a numerator + * and an offset. Since no denominator is specified, the default + * is to read the numerator as a percentage of the form, with a + * denominator of 100. + * + * @param numerator the percentage of the position + * @param offset the offset of the side from the position + */ +public FormAttachment (int numerator, int offset) { + this (numerator, 100, offset); +} + +/** + * Constructs a new instance of this class given a control, + * an offset and an alignment. + * + * @param control the control the side is attached to + * @param offset the offset of the side from the control + * @param alignment the alignment of the side to the control it is attached to + */ +public FormAttachment (Control control, int offset, int alignment) { + this.control = control; + this.offset = offset; + this.alignment = alignment; +} + +/** + * Constructs a new instance of this class given a control + * and an offset. Since no alignment is specified, the default + * alignment is to attach the side to the adjacent side of the + * specified control. + * + * @param control the control the side is attached to + * @param offset the offset of the side from the control + */ +public FormAttachment (Control control, int offset) { + this (control, offset, SWT.DEFAULT); +} + +/** + * Constructs a new instance of this class given a control. + * Since no alignment is specified, the default alignment is + * to attach the side to the adjacent side of the specified + * control. Since no offset is specified, an offset of 0 is + * used. + * + * @param control the control the side is attached to + */ +public FormAttachment (Control control) { + this (control, 0, SWT.DEFAULT); +} + +FormAttachment divide (int value) { + return new FormAttachment (numerator, denominator * value, offset / value); +} + +int gcd (int m, int n) { + int temp; + m = Math.abs (m); n = Math.abs (n); + if (m < n) { + temp = m; + m = n; + n = temp; + } + while (n != 0){ + temp = m; + m = n; + n = temp % n; + } + return m; +} + +FormAttachment minus (FormAttachment attachment) { + FormAttachment solution = new FormAttachment (); + solution.numerator = numerator * attachment.denominator - denominator * attachment.numerator; + solution.denominator = denominator * attachment.denominator; + int gcd = gcd (solution.denominator, solution.numerator); + solution.numerator = solution.numerator / gcd; + solution.denominator = solution.denominator / gcd; + solution.offset = offset - attachment.offset; + return solution; +} + +FormAttachment minus (int value) { + return new FormAttachment (numerator, denominator, offset - value); +} + +FormAttachment plus (FormAttachment attachment) { + FormAttachment solution = new FormAttachment (); + solution.numerator = numerator * attachment.denominator + denominator * attachment.numerator; + solution.denominator = denominator * attachment.denominator; + int gcd = gcd (solution.denominator, solution.numerator); + solution.numerator = solution.numerator / gcd; + solution.denominator = solution.denominator / gcd; + solution.offset = offset + attachment.offset; + return solution; +} + +FormAttachment plus (int value) { + return new FormAttachment (numerator, denominator, offset + value); +} + +int solveX (int value) { + if (denominator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO); + return ((numerator * value) / denominator) + offset; +} + +int solveY (int value) { + if (numerator == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO); + return (value - offset) * denominator / numerator; +} + +public String toString () { + String string = control != null ? control.toString () : numerator + "/" + denominator; + return "y = (" + string + (offset >= 0 ? ")x + " + offset: ")x - " + (-offset)); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormLayout.java index 50b1e09c9b..393d0f0907 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/FormLayout.java @@ -10,8 +10,8 @@ package org.eclipse.swt.layout; import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; -
-/**
+ +/** * Instances of this class control the position and size of the * children of a composite control by using <code>FormAttachments</code> * to optionally configure the left, top, right and bottom edge of @@ -80,7 +80,7 @@ import org.eclipse.swt.widgets.*; * * @since 2.0 * - */
+ */ public final class FormLayout extends Layout { /** * marginWidth specifies the number of pixels of horizontal margin @@ -253,5 +253,5 @@ Point layout (Composite composite, boolean move, int x, int y, int width, int he } return move ? null : new Point (width, height); } -
-}
+ +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridData.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridData.java index 184320e044..646d50ff8d 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridData.java @@ -1,195 +1,195 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-
-/**
- * <code>GridData</code> is the layout data object associated with
- * <code>GridLayout</code>. To set a <code>GridData</code> object into a
- * control, you use the <code>setLayoutData ()</code> method.
- * <p>
- * There are two ways to create a <code>GridData</code> object with certain
- * fields set. The first is to set the fields directly, like this:
- * <pre>
- * GridData gridData = new GridData();
- * gridData.horizontalAlignment = GridData.FILL;
- * gridData.grabExcessHorizontalSpace = true;
- * button1.setLayoutData(gridData);
- * </pre>
- * The second is to take advantage of convenience style bits defined
- * by <code>GridData</code>:
- * <pre>
- * button1.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
- * </pre>
- * </p>
- * <p>
- * NOTE: Do not reuse <code>GridData</code> objects. Every control in a
- * <code>Composite</code> that is managed by a <code>GridLayout</code>
- * must have a unique <code>GridData</code> object. If the layout data
- * for a control in a <code>GridLayout</code> is null at layout time,
- * a unique <code>GridData</code> object is created for it.
- * </p>
- *
- * @see GridLayout
- */
-public final class GridData {
- /**
- * verticalAlignment specifies how controls will be positioned
- * vertically within a cell.
- *
- * The default value is CENTER.
- *
- * Possible values are:
- *
- * BEGINNING: Position the control at the top of the cell
- * CENTER: Position the control in the vertical center of the cell
- * END: Position the control at the bottom of the cell
- * FILL: Resize the control to fill the cell vertically
- */
- public int verticalAlignment = CENTER;
- /**
- * horizontalAlignment specifies how controls will be positioned
- * horizontally within a cell.
- *
- * The default value is BEGINNING.
- *
- * Possible values are:
- *
- * BEGINNING: Position the control at the left of the cell
- * CENTER: Position the control in the horizontal center of the cell
- * END: Position the control at the right of the cell
- * FILL: Resize the control to fill the cell horizontally
- */
- public int horizontalAlignment = BEGINNING;
- /**
- * widthHint specifies a minimum width for the column. A value of
- * SWT.DEFAULT indicates that no minimum width is specified.
- *
- * The default value is SWT.DEFAULT.
- */
- public int widthHint = SWT.DEFAULT;
- /**
- * heightHint specifies a minimum height for the row. A value of
- * SWT.DEFAULT indicates that no minimum height is specified.
- *
- * The default value is SWT.DEFAULT.
- */
- public int heightHint = SWT.DEFAULT;
- /**
- * horizontalIndent specifies the number of pixels of indentation
- * that will be placed along the left side of the cell.
- *
- * The default value is 0.
- */
- public int horizontalIndent = 0;
- /**
- * horizontalSpan specifies the number of column cells that the control
- * will take up.
- *
- * The default value is 1.
- */
- public int horizontalSpan = 1;
- /**
- * verticalSpan specifies the number of row cells that the control
- * will take up.
- *
- * The default value is 1.
- */
- public int verticalSpan = 1;
- /**
- * grabExcessHorizontalSpace specifies whether the cell will be made
- * wide enough to fit the remaining horizontal space.
- *
- * The default value is false.
- */
- public boolean grabExcessHorizontalSpace = false;
- /**
- * grabExcessVerticalSpace specifies whether the cell will be made
- * tall enough to fit the remaining vertical space.
- *
- * The default value is false.
- */
- public boolean grabExcessVerticalSpace = false;
-
- // Alignment constants.
- public static final int BEGINNING = 1;
- public static final int CENTER = 2;
- public static final int END = 3;
- public static final int FILL = 4;
-
- // Style constants
- public static final int VERTICAL_ALIGN_BEGINNING = 1 << 1;
- public static final int VERTICAL_ALIGN_CENTER = 1 << 2;
- public static final int VERTICAL_ALIGN_END = 1 << 3;
- public static final int VERTICAL_ALIGN_FILL = 1 << 4;
- public static final int HORIZONTAL_ALIGN_BEGINNING = 1 << 5;
- public static final int HORIZONTAL_ALIGN_CENTER = 1 << 6;
- public static final int HORIZONTAL_ALIGN_END = 1 << 7;
- public static final int HORIZONTAL_ALIGN_FILL = 1 << 8;
- public static final int GRAB_HORIZONTAL = 1 << 9;
- public static final int GRAB_VERTICAL = 1 << 10;
-
- // Style convenience constants
- /**
- * FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL
- */
- public static final int FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL;
- /**
- * FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL
- */
- public static final int FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL;
- /**
- * FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL
- */
- public static final int FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL;
-
- // Private
- int childIndex;
- boolean isItemData = true;
- int hSpan;
-public GridData() {
- super();
-}
-public GridData(int style) {
- super();
-
- if ((style & VERTICAL_ALIGN_BEGINNING) != 0)
- verticalAlignment = BEGINNING;
- if ((style & VERTICAL_ALIGN_CENTER) != 0)
- verticalAlignment = CENTER;
- if ((style & VERTICAL_ALIGN_FILL) != 0)
- verticalAlignment = FILL;
- if ((style & VERTICAL_ALIGN_END) != 0)
- verticalAlignment = END;
-
- if ((style & HORIZONTAL_ALIGN_BEGINNING) != 0)
- horizontalAlignment = BEGINNING;
- if ((style & HORIZONTAL_ALIGN_CENTER) != 0)
- horizontalAlignment = CENTER;
- if ((style & HORIZONTAL_ALIGN_FILL) != 0)
- horizontalAlignment = FILL;
- if ((style & HORIZONTAL_ALIGN_END) != 0)
- horizontalAlignment = END;
-
- if ((style & GRAB_HORIZONTAL) != 0)
- grabExcessHorizontalSpace = true;
- else
- grabExcessHorizontalSpace = false;
- if ((style & GRAB_VERTICAL) != 0)
- grabExcessVerticalSpace = true;
- else
- grabExcessVerticalSpace = false;
-
-}
-boolean isItemData() {
- return isItemData;
-}
-boolean isSpacerData() {
- return !isItemData;
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; + +/** + * <code>GridData</code> is the layout data object associated with + * <code>GridLayout</code>. To set a <code>GridData</code> object into a + * control, you use the <code>setLayoutData ()</code> method. + * <p> + * There are two ways to create a <code>GridData</code> object with certain + * fields set. The first is to set the fields directly, like this: + * <pre> + * GridData gridData = new GridData(); + * gridData.horizontalAlignment = GridData.FILL; + * gridData.grabExcessHorizontalSpace = true; + * button1.setLayoutData(gridData); + * </pre> + * The second is to take advantage of convenience style bits defined + * by <code>GridData</code>: + * <pre> + * button1.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); + * </pre> + * </p> + * <p> + * NOTE: Do not reuse <code>GridData</code> objects. Every control in a + * <code>Composite</code> that is managed by a <code>GridLayout</code> + * must have a unique <code>GridData</code> object. If the layout data + * for a control in a <code>GridLayout</code> is null at layout time, + * a unique <code>GridData</code> object is created for it. + * </p> + * + * @see GridLayout + */ +public final class GridData { + /** + * verticalAlignment specifies how controls will be positioned + * vertically within a cell. + * + * The default value is CENTER. + * + * Possible values are: + * + * BEGINNING: Position the control at the top of the cell + * CENTER: Position the control in the vertical center of the cell + * END: Position the control at the bottom of the cell + * FILL: Resize the control to fill the cell vertically + */ + public int verticalAlignment = CENTER; + /** + * horizontalAlignment specifies how controls will be positioned + * horizontally within a cell. + * + * The default value is BEGINNING. + * + * Possible values are: + * + * BEGINNING: Position the control at the left of the cell + * CENTER: Position the control in the horizontal center of the cell + * END: Position the control at the right of the cell + * FILL: Resize the control to fill the cell horizontally + */ + public int horizontalAlignment = BEGINNING; + /** + * widthHint specifies a minimum width for the column. A value of + * SWT.DEFAULT indicates that no minimum width is specified. + * + * The default value is SWT.DEFAULT. + */ + public int widthHint = SWT.DEFAULT; + /** + * heightHint specifies a minimum height for the row. A value of + * SWT.DEFAULT indicates that no minimum height is specified. + * + * The default value is SWT.DEFAULT. + */ + public int heightHint = SWT.DEFAULT; + /** + * horizontalIndent specifies the number of pixels of indentation + * that will be placed along the left side of the cell. + * + * The default value is 0. + */ + public int horizontalIndent = 0; + /** + * horizontalSpan specifies the number of column cells that the control + * will take up. + * + * The default value is 1. + */ + public int horizontalSpan = 1; + /** + * verticalSpan specifies the number of row cells that the control + * will take up. + * + * The default value is 1. + */ + public int verticalSpan = 1; + /** + * grabExcessHorizontalSpace specifies whether the cell will be made + * wide enough to fit the remaining horizontal space. + * + * The default value is false. + */ + public boolean grabExcessHorizontalSpace = false; + /** + * grabExcessVerticalSpace specifies whether the cell will be made + * tall enough to fit the remaining vertical space. + * + * The default value is false. + */ + public boolean grabExcessVerticalSpace = false; + + // Alignment constants. + public static final int BEGINNING = 1; + public static final int CENTER = 2; + public static final int END = 3; + public static final int FILL = 4; + + // Style constants + public static final int VERTICAL_ALIGN_BEGINNING = 1 << 1; + public static final int VERTICAL_ALIGN_CENTER = 1 << 2; + public static final int VERTICAL_ALIGN_END = 1 << 3; + public static final int VERTICAL_ALIGN_FILL = 1 << 4; + public static final int HORIZONTAL_ALIGN_BEGINNING = 1 << 5; + public static final int HORIZONTAL_ALIGN_CENTER = 1 << 6; + public static final int HORIZONTAL_ALIGN_END = 1 << 7; + public static final int HORIZONTAL_ALIGN_FILL = 1 << 8; + public static final int GRAB_HORIZONTAL = 1 << 9; + public static final int GRAB_VERTICAL = 1 << 10; + + // Style convenience constants + /** + * FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL + */ + public static final int FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL; + /** + * FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL + */ + public static final int FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL; + /** + * FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL + */ + public static final int FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL; + + // Private + int childIndex; + boolean isItemData = true; + int hSpan; +public GridData() { + super(); +} +public GridData(int style) { + super(); + + if ((style & VERTICAL_ALIGN_BEGINNING) != 0) + verticalAlignment = BEGINNING; + if ((style & VERTICAL_ALIGN_CENTER) != 0) + verticalAlignment = CENTER; + if ((style & VERTICAL_ALIGN_FILL) != 0) + verticalAlignment = FILL; + if ((style & VERTICAL_ALIGN_END) != 0) + verticalAlignment = END; + + if ((style & HORIZONTAL_ALIGN_BEGINNING) != 0) + horizontalAlignment = BEGINNING; + if ((style & HORIZONTAL_ALIGN_CENTER) != 0) + horizontalAlignment = CENTER; + if ((style & HORIZONTAL_ALIGN_FILL) != 0) + horizontalAlignment = FILL; + if ((style & HORIZONTAL_ALIGN_END) != 0) + horizontalAlignment = END; + + if ((style & GRAB_HORIZONTAL) != 0) + grabExcessHorizontalSpace = true; + else + grabExcessHorizontalSpace = false; + if ((style & GRAB_VERTICAL) != 0) + grabExcessVerticalSpace = true; + else + grabExcessVerticalSpace = false; + +} +boolean isItemData() { + return isItemData; +} +boolean isSpacerData() { + return !isItemData; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridLayout.java index a6c5e55583..fdc5914afe 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/GridLayout.java @@ -1,691 +1,691 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.graphics.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-/**
- * Instances of this class lay out the control children of a
- * <code>Composite</code> in a grid.
- * <p>
- * <code>GridLayout</code> has a number of configuration fields, and the
- * controls it lays out can have an associated layout data object, called
- * <code>GridData</code>. The power of <code>GridLayout</code> lies in the
- * ability to configure <code>GridData</code> for each control in the layout.
- * </p>
- * <p>
- * The following code creates a shell managed by a <code>GridLayout</code>
- * with 3 columns:
- * <pre>
- * Display display = new Display();
- * Shell shell = new Shell(display);
- * GridLayout gridLayout = new GridLayout();
- * gridLayout.numColumns = 3;
- * shell.setLayout(gridLayout);
- * </pre>
- * The <code>numColumns</code> field is the most important field in a
- * <code>GridLayout</code>. Widgets are laid out in columns from left
- * to right, and a new row is created when <code>numColumns</code> + 1
- * controls are added to the <code>Composite<code>.
- * </p>
- *
- * @see GridData
- */
-public final class GridLayout extends Layout {
- /**
- * marginWidth specifies the number of pixels of horizontal margin
- * that will be placed along the left and right edges of the layout.
- *
- * The default value is 5.
- */
- public int marginWidth = 5;
- /**
- * marginHeight specifies the number of pixels of vertical margin
- * that will be placed along the top and bottom edges of the layout.
- *
- * The default value is 5.
- */
- public int marginHeight = 5;
- /**
- * numColumns specifies the number of cell columns in the layout.
- *
- * The default value is 1.
- */
- public int numColumns = 1;
- /**
- * makeColumnsEqualWidth specifies whether all columns in the layout
- * will be forced to have the same width.
- *
- * The default value is false.
- */
- public boolean makeColumnsEqualWidth = false;
- /**
- * horizontalSpacing specifies the number of pixels between the right
- * edge of one cell and the left edge of its neighbouring cell to
- * the right.
- *
- * The default value is 5.
- */
- public int horizontalSpacing = 5;
- /**
- * verticalSpacing specifies the number of pixels between the bottom
- * edge of one cell and the top edge of its neighbouring cell underneath.
- *
- * The default value is 5.
- */
- public int verticalSpacing = 5;
-
- // Private variables. Cached values used to cut down on grid calculations.
- Vector grid = new Vector();
- int [] pixelColumnWidths;
- int [] pixelRowHeights;
- int [] expandableColumns;
- int [] expandableRows;
-
-/**
- * Constructs a new instance of this class.
- */
-public GridLayout() {
-}
-
-/**
- * Constructs a new instance of this class given the
- * number of columns, and whether or not the columns
- * should be forced to have the same width.
- *
- * @param numColumns the number of columns in the grid
- * @param makeColumnsEqualWidth whether or not the columns will have equal width
- *
- * @since 2.0
- */
-public GridLayout(int numColumns, boolean makeColumnsEqualWidth) {
- this.numColumns = numColumns;
- this.makeColumnsEqualWidth = makeColumnsEqualWidth;
-}
-
-void adjustGridDimensions(Composite composite, boolean flushCache) {
- // Ensure that controls that span more than one row or column have enough space.
- for (int row = 0; row < grid.size(); row++) {
- for (int column = 0; column < numColumns; column++) {
- GridData spec = ((GridData[]) grid.elementAt(row))[column];
- if (spec.isItemData()) {
- // Widgets spanning columns.
- if (spec.hSpan > 1) {
- Control child = composite.getChildren()[spec.childIndex];
- Point extent = child.computeSize(spec.widthHint, spec.heightHint, flushCache);
-
- // Calculate the size of the control's spanned columns.
- int lastSpanIndex = column + spec.hSpan;
- int spannedSize = 0;
- for (int c = column; c < lastSpanIndex; c++) {
- spannedSize = spannedSize + pixelColumnWidths[c] + horizontalSpacing;
- }
- spannedSize = spannedSize - horizontalSpacing;
-
- // If the spanned columns are not large enough to display the control, adjust the column
- // sizes to account for the extra space that is needed.
- if (extent.x + spec.horizontalIndent > spannedSize) {
- int extraSpaceNeeded = extent.x + spec.horizontalIndent - spannedSize;
- int lastColumn = column + spec.hSpan - 1;
- int colWidth;
- if (makeColumnsEqualWidth) {
- // Evenly distribute the extra space amongst all of the columns.
- int columnExtra = extraSpaceNeeded / numColumns;
- int columnRemainder = extraSpaceNeeded % numColumns;
- for (int i = 0; i < pixelColumnWidths.length; i++) {
- colWidth = pixelColumnWidths[i] + columnExtra;
- pixelColumnWidths[i] = colWidth;
- }
- colWidth = pixelColumnWidths[lastColumn] + columnRemainder;
- pixelColumnWidths[lastColumn] = colWidth;
- } else {
- Vector localExpandableColumns = new Vector();
- for (int i = column; i <= lastColumn; i++) {
- for (int j = 0; j < expandableColumns.length; j++) {
- if (expandableColumns[j] == i) {
- localExpandableColumns.addElement(new Integer(i));
- }
- }
- }
- if (localExpandableColumns.size() > 0) {
- // If any of the control's columns grab excess space, allocate the space amongst those columns.
- int columnExtra = extraSpaceNeeded / localExpandableColumns.size();
- int columnRemainder = extraSpaceNeeded % localExpandableColumns.size();
- for (int i = 0; i < localExpandableColumns.size(); i++) {
- int expandableCol = ((Integer) localExpandableColumns.elementAt(i)).intValue();
- colWidth = pixelColumnWidths[expandableCol] + columnExtra;
- pixelColumnWidths[expandableCol] = colWidth;
- }
- colWidth = pixelColumnWidths[lastColumn] + columnRemainder;
- pixelColumnWidths[lastColumn] = colWidth;
- } else {
- // Add the extra space to the control's last column if none of its columns grab excess space.
- colWidth = pixelColumnWidths[lastColumn] + extraSpaceNeeded;
- pixelColumnWidths[lastColumn] = colWidth;
- }
- }
- }
- }
-
- // Widgets spanning rows.
- if (spec.verticalSpan > 1) {
- Control child = composite.getChildren()[spec.childIndex];
- Point extent = child.computeSize(spec.widthHint, spec.heightHint, flushCache);
-
- // Calculate the size of the control's spanned rows.
- int lastSpanIndex = row + spec.verticalSpan;
- int spannedSize = 0;
- for (int r = row; r < lastSpanIndex; r++) {
- spannedSize = spannedSize + pixelRowHeights[r] + verticalSpacing;
- }
- spannedSize = spannedSize - verticalSpacing;
- // If the spanned rows are not large enough to display the control, adjust the row
- // sizes to account for the extra space that is needed.
- if (extent.y > spannedSize) {
- int extraSpaceNeeded = extent.y - spannedSize;
- int lastRow = row + spec.verticalSpan - 1;
- int rowHeight;
- Vector localExpandableRows = new Vector();
- for (int i = row; i <= lastRow; i++) {
- for (int j = 0; j < expandableRows.length; j++) {
- if (expandableRows[j] == i) {
- localExpandableRows.addElement(new Integer(i));
- }
- }
- }
- if (localExpandableRows.size() > 0) {
- // If any of the control's rows grab excess space, allocate the space amongst those rows.
- int rowExtra = extraSpaceNeeded / localExpandableRows.size();
- int rowRemainder = extraSpaceNeeded % localExpandableRows.size();
- for (int i = 0; i < localExpandableRows.size(); i++) {
- int expandableRow = ((Integer) localExpandableRows.elementAt(i)).intValue();
- rowHeight = pixelRowHeights[expandableRow] + rowExtra;
- pixelRowHeights[expandableRow] = rowHeight;
- }
- rowHeight = pixelRowHeights[lastRow] + rowRemainder;
- pixelRowHeights[lastRow] = rowHeight;
- } else {
- // Add the extra space to the control's last row if no rows grab excess space.
- rowHeight = pixelRowHeights[lastRow] + extraSpaceNeeded;
- pixelRowHeights[lastRow] = rowHeight;
- }
- }
- }
- }
- }
- }
-}
-void calculateGridDimensions(Composite composite, boolean flushCache) {
- int maxWidth, childWidth, maxHeight, childHeight;
-
- //
- Control[] children = composite.getChildren();
- Point[] childSizes = new Point[children.length];
- pixelColumnWidths = new int[numColumns];
- pixelRowHeights = new int[grid.size()];
-
- // Loop through the grid by column to get the width that each column needs to be.
- // Each column will be as wide as its widest control.
- for (int column = 0; column < numColumns; column++) {
- maxWidth = 0;
- for (int row = 0; row < grid.size(); row++) {
- GridData spec = ((GridData[]) grid.elementAt(row))[column];
- if (spec.isItemData()) {
- Control child = children[spec.childIndex];
- childSizes[spec.childIndex] = child.computeSize(spec.widthHint, spec.heightHint, flushCache);
- childWidth = childSizes[spec.childIndex].x + spec.horizontalIndent;
- if (spec.hSpan == 1) {
- maxWidth = Math.max(maxWidth, childWidth);
- }
- }
- }
- // Cache the values for later use.
- pixelColumnWidths[column] = maxWidth;
- }
-
- //
- if (makeColumnsEqualWidth) {
- maxWidth = 0;
- // Find the largest column size that is necessary and make each column that size.
- for (int i = 0; i < numColumns; i++) {
- maxWidth = Math.max(maxWidth, pixelColumnWidths[i]);
- }
- for (int i = 0; i < numColumns; i++) {
- pixelColumnWidths[i] = maxWidth;
- }
- }
-
- // Loop through the grid by row to get the height that each row needs to be.
- // Each row will be as high as its tallest control.
- for (int row = 0; row < grid.size(); row++) {
- maxHeight = 0;
- for (int column = 0; column < numColumns; column++) {
- GridData spec = ((GridData[]) grid.elementAt(row))[column];
- if (spec.isItemData()) {
- childHeight = childSizes[spec.childIndex].y;
- if (spec.verticalSpan == 1) {
- maxHeight = Math.max(maxHeight, childHeight);
- }
- }
- }
- // Cache the values for later use.
- pixelRowHeights[row] = maxHeight;
- }
-}
-void computeExpandableCells() {
- // If a control grabs excess horizontal space, the last column that the control spans
- // will be expandable. Similarly, if a control grabs excess vertical space, the
- // last row that the control spans will be expandable.
- Hashtable growColumns = new Hashtable();
- Hashtable growRows = new Hashtable();
- for (int col = 0; col < numColumns; col++) {
- for (int row = 0; row < grid.size(); row++) {
- GridData spec = ((GridData[]) grid.elementAt(row))[col];
- if (spec.grabExcessHorizontalSpace) {
- growColumns.put(new Integer(col + spec.hSpan - 1), new Object());
- }
- if (spec.grabExcessVerticalSpace) {
- growRows.put(new Integer(row + spec.verticalSpan - 1), new Object());
- }
- }
- }
-
- // Cache the values. These values are used later during children layout.
- int i = 0;
- Enumeration enum = growColumns.keys();
- expandableColumns = new int[growColumns.size()];
- while (enum.hasMoreElements()) {
- expandableColumns[i] = ((Integer)enum.nextElement()).intValue();
- i = i + 1;
- }
- i = 0;
- enum = growRows.keys();
- expandableRows = new int[growRows.size()];
- while (enum.hasMoreElements()) {
- expandableRows[i] = ((Integer)enum.nextElement()).intValue();
- i = i + 1;
- }
-}
-Point computeLayoutSize(Composite composite, int wHint, int hHint, boolean flushCache) {
- int totalMarginHeight, totalMarginWidth;
- int totalWidth, totalHeight;
- int cols, rows;
-
- // Initialize the grid and other cached information that help with the grid layout.
- if (grid.size() == 0) {
- createGrid(composite);
- calculateGridDimensions(composite, flushCache);
- computeExpandableCells();
- adjustGridDimensions(composite, flushCache);
- }
-
- //
- cols = numColumns;
- rows = grid.size();
- totalMarginHeight = marginHeight;
- totalMarginWidth = marginWidth;
-
- // The total width is the margin plus border width plus space between each column,
- // plus the width of each column.
- totalWidth = (totalMarginWidth * 2) + ((cols - 1) * horizontalSpacing);
-
- //Add up the width of each column.
- for (int i = 0; i < pixelColumnWidths.length; i++) {
- totalWidth = totalWidth + pixelColumnWidths[i];
- }
-
- // The total height is the margin plus border height, plus space between each row,
- // plus the height of the tallest child in each row.
- totalHeight = (totalMarginHeight * 2) + ((rows - 1) * verticalSpacing);
-
- //Add up the height of each row.
- for (int i = 0; i < pixelRowHeights.length; i++) {
- totalHeight = totalHeight + pixelRowHeights[i];
- }
-
- if (wHint != SWT.DEFAULT) {
- totalWidth = wHint;};
- if (hHint != SWT.DEFAULT) {
- totalHeight = hHint;};
- // The preferred extent is the width and height that will accomodate the grid's controls.
- return new Point(totalWidth, totalHeight);
-}
-protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
- Control[] children = composite.getChildren();
- int numChildren = children.length;
-
- if (numChildren == 0) return new Point(0,0);
-
- if (flushCache) {
- // Cause the grid and its related information to be calculated
- // again.
- grid.removeAllElements();
- }
- return computeLayoutSize(composite, wHint, hHint, flushCache);
-}
-Point getFirstEmptyCell(int row, int column) {
- GridData[] rowData = (GridData[]) grid.elementAt(row);
- while (column < numColumns && rowData[column] != null) {
- column++;
- }
- if (column == numColumns) {
- row++;
- column = 0;
- if (row == grid.size()) {
- grid.addElement(emptyRow());
- }
- return getFirstEmptyCell(row, column);
- }
- return new Point(row, column);
-}
-Point getLastEmptyCell(int row, int column) {
- GridData[] rowData = (GridData[])grid.elementAt(row);
- while (column < numColumns && rowData[column] == null ) {
- column++;
- }
- return new Point(row, column - 1);
-}
-Point getCell(int row, int column, int width, int height) {
- Point start = getFirstEmptyCell(row, column);
- Point end = getLastEmptyCell(start.x, start.y);
- if (end.y + 1 - start.y >= width) return start;
- GridData[] rowData = (GridData[]) grid.elementAt(start.x);
- for (int j = start.y; j < end.y + 1; j++) {
- GridData spacerSpec = new GridData();
- spacerSpec.isItemData = false;
- rowData[j] = spacerSpec;
- }
- return getCell(end.x, end.y, width, height);
-}
-void createGrid(Composite composite) {
- int row, column, rowFill, columnFill;
- Control[] children;
- GridData spacerSpec;
-
- //
- children = composite.getChildren();
-
- //
- grid.addElement(emptyRow());
- row = 0;
- column = 0;
-
- // Loop through the children and place their associated layout specs in the
- // grid. Placement occurs left to right, top to bottom (i.e., by row).
- for (int i = 0; i < children.length; i++) {
- // Find the first available spot in the grid.
- Control child = children[i];
- GridData spec = (GridData) child.getLayoutData();
- if (spec == null) {
- spec = new GridData();
- child.setLayoutData(spec);
- }
- spec.hSpan = Math.min(spec.horizontalSpan, numColumns);
- Point p = getCell(row, column, spec.hSpan, spec.verticalSpan);
- row = p.x; column = p.y;
-
- // The vertical span for the item will be at least 1. If it is > 1,
- // add other rows to the grid.
- for (int j = 2; j <= spec.verticalSpan; j++) {
- if (row + j > grid.size()) {
- grid.addElement(emptyRow());
- }
- }
-
- // Store the layout spec. Also cache the childIndex. NOTE: That we assume the children of a
- // composite are maintained in the order in which they are created and added to the composite.
- ((GridData[]) grid.elementAt(row))[column] = spec;
- spec.childIndex = i;
-
- // Put spacers in the grid to account for the item's vertical and horizontal
- // span.
- rowFill = spec.verticalSpan - 1;
- columnFill = spec.hSpan - 1;
- for (int r = 1; r <= rowFill; r++) {
- for (int c = 0; c < spec.hSpan; c++) {
- spacerSpec = new GridData();
- spacerSpec.isItemData = false;
- ((GridData[]) grid.elementAt(row + r))[column + c] = spacerSpec;
- }
- }
- for (int c = 1; c <= columnFill; c++) {
- for (int r = 0; r < spec.verticalSpan; r++) {
- spacerSpec = new GridData();
- spacerSpec.isItemData = false;
- ((GridData[]) grid.elementAt(row + r))[column + c] = spacerSpec;
- }
- }
- column = column + spec.hSpan - 1;
- }
-
- // Fill out empty grid cells with spacers.
- for (int r = row; r < grid.size(); r++) {
- GridData[] rowData = (GridData[]) grid.elementAt(r);
- for (int c = 0; c < numColumns; c++) {
- if (rowData[c] == null) {
- spacerSpec = new GridData();
- spacerSpec.isItemData = false;
- rowData[c] = spacerSpec;
- }
- }
- }
-}
-GridData[] emptyRow() {
- GridData[] row = new GridData[numColumns];
- for (int i = 0; i < numColumns; i++) {
- row[i] = null;}
- return row;
-}
-protected void layout(Composite composite, boolean flushCache) {
- int[] columnWidths;
- int[] rowHeights;
- int rowSize, rowY, columnX;
- int compositeWidth, compositeHeight;
- int excessHorizontal, excessVertical;
- Control[] children;
- if (flushCache) {
- // Cause the grid and its related information to be calculated
- // again.
- grid.removeAllElements();
- }
- children = composite.getChildren();
- if (children.length == 0)
- return;
-
- //
- Point extent = computeSize(composite, SWT.DEFAULT, SWT.DEFAULT, flushCache);
- columnWidths = new int[numColumns];
- for (int i = 0; i < pixelColumnWidths.length; i++) {
- columnWidths[i] = pixelColumnWidths[i];
- }
- rowHeights = new int[grid.size()];
- for (int i = 0; i < pixelRowHeights.length; i++) {
- rowHeights[i] = pixelRowHeights[i];
- }
- int columnWidth = 0;
- rowSize = Math.max(1, grid.size());
-
- //
- compositeWidth = extent.x;
- compositeHeight = extent.y;
-
- // Calculate whether or not there is any extra space or not enough space due to a resize
- // operation. Then allocate/deallocate the space to columns and rows that are expandable.
- // If a control grabs excess space, its last column or row will be expandable.
- excessHorizontal = composite.getClientArea().width - compositeWidth;
- excessVertical = composite.getClientArea().height - compositeHeight;
-
- // Allocate/deallocate horizontal space.
- if (expandableColumns.length != 0) {
- int excess, remainder, last;
- int colWidth;
- excess = excessHorizontal / expandableColumns.length;
- remainder = excessHorizontal % expandableColumns.length;
- last = 0;
- for (int i = 0; i < expandableColumns.length; i++) {
- int expandableCol = expandableColumns[i];
- colWidth = columnWidths[expandableCol];
- colWidth = colWidth + excess;
- columnWidths[expandableCol] = colWidth;
- last = Math.max(last, expandableCol);
- }
- colWidth = columnWidths[last];
- colWidth = colWidth + remainder;
- columnWidths[last] = colWidth;
- }
-
- // Go through all specs in each expandable column and get the maximum specified
- // widthHint. Use this as the minimumWidth for the column.
- for (int i = 0; i < expandableColumns.length; i++) {
- int expandableCol = expandableColumns[i];
- int colWidth = columnWidths[expandableCol];
- int minWidth = 0;
- for (int j = 0; j < grid.size(); j++) {
- GridData[] row = (GridData[]) grid.elementAt(j);
- GridData spec = row[expandableCol];
- if (spec.hSpan == 1) {
- minWidth = Math.max(minWidth, spec.widthHint);
- }
- }
- columnWidths[expandableCol] = Math.max(colWidth, minWidth);
- }
- // Allocate/deallocate vertical space.
- if (expandableRows.length != 0) {
- int excess, remainder, last;
- int rowHeight;
- excess = excessVertical / expandableRows.length;
- remainder = excessVertical % expandableRows.length;
- last = 0;
- for (int i = 0; i < expandableRows.length; i++) {
- int expandableRow = expandableRows[i];
- rowHeight = rowHeights[expandableRow];
- rowHeight = rowHeight + excess;
- rowHeights[expandableRow] = rowHeight;
- last = Math.max(last, expandableRow);
- }
- rowHeight = rowHeights[last];
- rowHeight = rowHeight + remainder;
- rowHeights[last] = rowHeight;
- }
- // Go through all specs in each expandable row and get the maximum specified
- // heightHint. Use this as the minimumHeight for the row.
- for (int i = 0; i < expandableRows.length; i++) {
- int expandableRow = expandableRows[i];
- int rowHeight = rowHeights[expandableRow];
- int minHeight = 0;
- GridData[] row = (GridData[]) grid.elementAt(expandableRow);
- for (int j = 0; j < numColumns; j++) {
- GridData spec = row[j];
- if (spec.verticalSpan == 1) {
- minHeight = Math.max(minHeight, spec.heightHint);
- }
- }
- rowHeights[expandableRow] = Math.max(rowHeight, minHeight);
- }
-
- // Get the starting x and y.
- columnX = marginWidth + composite.getClientArea().x;
- rowY = marginHeight + composite.getClientArea().y;
-
- // Layout the control left to right, top to bottom.
- for (int r = 0; r < rowSize; r++) {
- int rowHeight = rowHeights[r];
- GridData[] row = (GridData[]) grid.elementAt(r);
-
- //
- for (int c = 0; c < row.length; c++) {
- int spannedWidth = 0, spannedHeight = 0;
- int hAlign = 0, vAlign = 0;
- int widgetX = 0, widgetY = 0;
- int widgetW = 0, widgetH = 0;
-
- //
- GridData spec = (GridData) row[c];
- if (makeColumnsEqualWidth) {
- columnWidth = composite.getClientArea().width - 2 * (marginWidth) - ((numColumns - 1) * horizontalSpacing);
- columnWidth = columnWidth / numColumns;
- for (int i = 0; i < columnWidths.length; i++) {
- columnWidths[i] = columnWidth;
- }
- } else {
- columnWidth = columnWidths[c];
- }
-
- //
- spannedWidth = columnWidth;
- for (int k = 1; k < spec.hSpan; k++) {
- if ((c + k) <= numColumns) {
- if (!makeColumnsEqualWidth) {
- columnWidth = columnWidths[c + k];
- }
- spannedWidth = spannedWidth + columnWidth + horizontalSpacing;
- }
- }
-
- //
- spannedHeight = rowHeight;
- for (int k = 1; k < spec.verticalSpan; k++) {
- if ((r + k) <= grid.size()) {
- spannedHeight = spannedHeight + rowHeights[r + k] + verticalSpacing;
- }
- }
-
- //
- if (spec.isItemData()) {
- Control child = children[spec.childIndex];
- Point childExtent = child.computeSize(spec.widthHint, spec.heightHint, flushCache);
- hAlign = spec.horizontalAlignment;
- widgetX = columnX;
-
- // Calculate the x and width values for the control.
- if (hAlign == GridData.CENTER) {
- widgetX = widgetX + (spannedWidth / 2) - (childExtent.x / 2);
- } else
- if (hAlign == GridData.END) {
- widgetX = widgetX + spannedWidth - childExtent.x - spec.horizontalIndent;
- } else {
- widgetX = widgetX + spec.horizontalIndent;
- }
- if (hAlign == GridData.FILL) {
- widgetW = spannedWidth - spec.horizontalIndent;
- widgetX = columnX + spec.horizontalIndent;
- } else {
- widgetW = childExtent.x;
- }
-
- // Calculate the y and height values for the control.
- vAlign = spec.verticalAlignment;
- widgetY = rowY;
- if (vAlign == GridData.CENTER) {
- widgetY = widgetY + (spannedHeight / 2) - (childExtent.y / 2);
- } else
- if (vAlign == GridData.END) {
- widgetY = widgetY + spannedHeight - childExtent.y;
- }
- if (vAlign == GridData.FILL) {
- widgetH = spannedHeight;
- widgetY = rowY;
- } else {
- widgetH = childExtent.y;
- }
- // Place the control.
- child.setBounds(widgetX, widgetY, widgetW, widgetH);
- }
- // Update the starting x value.
- columnX = columnX + columnWidths[c] + horizontalSpacing;
- }
- // Update the starting y value and since we're starting a new row, reset the starting x value.
- rowY = rowY + rowHeights[r] + verticalSpacing;
- columnX = marginWidth + composite.getClientArea().x;
- }
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; +import org.eclipse.swt.widgets.*; +import org.eclipse.swt.graphics.*; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + * Instances of this class lay out the control children of a + * <code>Composite</code> in a grid. + * <p> + * <code>GridLayout</code> has a number of configuration fields, and the + * controls it lays out can have an associated layout data object, called + * <code>GridData</code>. The power of <code>GridLayout</code> lies in the + * ability to configure <code>GridData</code> for each control in the layout. + * </p> + * <p> + * The following code creates a shell managed by a <code>GridLayout</code> + * with 3 columns: + * <pre> + * Display display = new Display(); + * Shell shell = new Shell(display); + * GridLayout gridLayout = new GridLayout(); + * gridLayout.numColumns = 3; + * shell.setLayout(gridLayout); + * </pre> + * The <code>numColumns</code> field is the most important field in a + * <code>GridLayout</code>. Widgets are laid out in columns from left + * to right, and a new row is created when <code>numColumns</code> + 1 + * controls are added to the <code>Composite<code>. + * </p> + * + * @see GridData + */ +public final class GridLayout extends Layout { + /** + * marginWidth specifies the number of pixels of horizontal margin + * that will be placed along the left and right edges of the layout. + * + * The default value is 5. + */ + public int marginWidth = 5; + /** + * marginHeight specifies the number of pixels of vertical margin + * that will be placed along the top and bottom edges of the layout. + * + * The default value is 5. + */ + public int marginHeight = 5; + /** + * numColumns specifies the number of cell columns in the layout. + * + * The default value is 1. + */ + public int numColumns = 1; + /** + * makeColumnsEqualWidth specifies whether all columns in the layout + * will be forced to have the same width. + * + * The default value is false. + */ + public boolean makeColumnsEqualWidth = false; + /** + * horizontalSpacing specifies the number of pixels between the right + * edge of one cell and the left edge of its neighbouring cell to + * the right. + * + * The default value is 5. + */ + public int horizontalSpacing = 5; + /** + * verticalSpacing specifies the number of pixels between the bottom + * edge of one cell and the top edge of its neighbouring cell underneath. + * + * The default value is 5. + */ + public int verticalSpacing = 5; + + // Private variables. Cached values used to cut down on grid calculations. + Vector grid = new Vector(); + int [] pixelColumnWidths; + int [] pixelRowHeights; + int [] expandableColumns; + int [] expandableRows; + +/** + * Constructs a new instance of this class. + */ +public GridLayout() { +} + +/** + * Constructs a new instance of this class given the + * number of columns, and whether or not the columns + * should be forced to have the same width. + * + * @param numColumns the number of columns in the grid + * @param makeColumnsEqualWidth whether or not the columns will have equal width + * + * @since 2.0 + */ +public GridLayout(int numColumns, boolean makeColumnsEqualWidth) { + this.numColumns = numColumns; + this.makeColumnsEqualWidth = makeColumnsEqualWidth; +} + +void adjustGridDimensions(Composite composite, boolean flushCache) { + // Ensure that controls that span more than one row or column have enough space. + for (int row = 0; row < grid.size(); row++) { + for (int column = 0; column < numColumns; column++) { + GridData spec = ((GridData[]) grid.elementAt(row))[column]; + if (spec.isItemData()) { + // Widgets spanning columns. + if (spec.hSpan > 1) { + Control child = composite.getChildren()[spec.childIndex]; + Point extent = child.computeSize(spec.widthHint, spec.heightHint, flushCache); + + // Calculate the size of the control's spanned columns. + int lastSpanIndex = column + spec.hSpan; + int spannedSize = 0; + for (int c = column; c < lastSpanIndex; c++) { + spannedSize = spannedSize + pixelColumnWidths[c] + horizontalSpacing; + } + spannedSize = spannedSize - horizontalSpacing; + + // If the spanned columns are not large enough to display the control, adjust the column + // sizes to account for the extra space that is needed. + if (extent.x + spec.horizontalIndent > spannedSize) { + int extraSpaceNeeded = extent.x + spec.horizontalIndent - spannedSize; + int lastColumn = column + spec.hSpan - 1; + int colWidth; + if (makeColumnsEqualWidth) { + // Evenly distribute the extra space amongst all of the columns. + int columnExtra = extraSpaceNeeded / numColumns; + int columnRemainder = extraSpaceNeeded % numColumns; + for (int i = 0; i < pixelColumnWidths.length; i++) { + colWidth = pixelColumnWidths[i] + columnExtra; + pixelColumnWidths[i] = colWidth; + } + colWidth = pixelColumnWidths[lastColumn] + columnRemainder; + pixelColumnWidths[lastColumn] = colWidth; + } else { + Vector localExpandableColumns = new Vector(); + for (int i = column; i <= lastColumn; i++) { + for (int j = 0; j < expandableColumns.length; j++) { + if (expandableColumns[j] == i) { + localExpandableColumns.addElement(new Integer(i)); + } + } + } + if (localExpandableColumns.size() > 0) { + // If any of the control's columns grab excess space, allocate the space amongst those columns. + int columnExtra = extraSpaceNeeded / localExpandableColumns.size(); + int columnRemainder = extraSpaceNeeded % localExpandableColumns.size(); + for (int i = 0; i < localExpandableColumns.size(); i++) { + int expandableCol = ((Integer) localExpandableColumns.elementAt(i)).intValue(); + colWidth = pixelColumnWidths[expandableCol] + columnExtra; + pixelColumnWidths[expandableCol] = colWidth; + } + colWidth = pixelColumnWidths[lastColumn] + columnRemainder; + pixelColumnWidths[lastColumn] = colWidth; + } else { + // Add the extra space to the control's last column if none of its columns grab excess space. + colWidth = pixelColumnWidths[lastColumn] + extraSpaceNeeded; + pixelColumnWidths[lastColumn] = colWidth; + } + } + } + } + + // Widgets spanning rows. + if (spec.verticalSpan > 1) { + Control child = composite.getChildren()[spec.childIndex]; + Point extent = child.computeSize(spec.widthHint, spec.heightHint, flushCache); + + // Calculate the size of the control's spanned rows. + int lastSpanIndex = row + spec.verticalSpan; + int spannedSize = 0; + for (int r = row; r < lastSpanIndex; r++) { + spannedSize = spannedSize + pixelRowHeights[r] + verticalSpacing; + } + spannedSize = spannedSize - verticalSpacing; + // If the spanned rows are not large enough to display the control, adjust the row + // sizes to account for the extra space that is needed. + if (extent.y > spannedSize) { + int extraSpaceNeeded = extent.y - spannedSize; + int lastRow = row + spec.verticalSpan - 1; + int rowHeight; + Vector localExpandableRows = new Vector(); + for (int i = row; i <= lastRow; i++) { + for (int j = 0; j < expandableRows.length; j++) { + if (expandableRows[j] == i) { + localExpandableRows.addElement(new Integer(i)); + } + } + } + if (localExpandableRows.size() > 0) { + // If any of the control's rows grab excess space, allocate the space amongst those rows. + int rowExtra = extraSpaceNeeded / localExpandableRows.size(); + int rowRemainder = extraSpaceNeeded % localExpandableRows.size(); + for (int i = 0; i < localExpandableRows.size(); i++) { + int expandableRow = ((Integer) localExpandableRows.elementAt(i)).intValue(); + rowHeight = pixelRowHeights[expandableRow] + rowExtra; + pixelRowHeights[expandableRow] = rowHeight; + } + rowHeight = pixelRowHeights[lastRow] + rowRemainder; + pixelRowHeights[lastRow] = rowHeight; + } else { + // Add the extra space to the control's last row if no rows grab excess space. + rowHeight = pixelRowHeights[lastRow] + extraSpaceNeeded; + pixelRowHeights[lastRow] = rowHeight; + } + } + } + } + } + } +} +void calculateGridDimensions(Composite composite, boolean flushCache) { + int maxWidth, childWidth, maxHeight, childHeight; + + // + Control[] children = composite.getChildren(); + Point[] childSizes = new Point[children.length]; + pixelColumnWidths = new int[numColumns]; + pixelRowHeights = new int[grid.size()]; + + // Loop through the grid by column to get the width that each column needs to be. + // Each column will be as wide as its widest control. + for (int column = 0; column < numColumns; column++) { + maxWidth = 0; + for (int row = 0; row < grid.size(); row++) { + GridData spec = ((GridData[]) grid.elementAt(row))[column]; + if (spec.isItemData()) { + Control child = children[spec.childIndex]; + childSizes[spec.childIndex] = child.computeSize(spec.widthHint, spec.heightHint, flushCache); + childWidth = childSizes[spec.childIndex].x + spec.horizontalIndent; + if (spec.hSpan == 1) { + maxWidth = Math.max(maxWidth, childWidth); + } + } + } + // Cache the values for later use. + pixelColumnWidths[column] = maxWidth; + } + + // + if (makeColumnsEqualWidth) { + maxWidth = 0; + // Find the largest column size that is necessary and make each column that size. + for (int i = 0; i < numColumns; i++) { + maxWidth = Math.max(maxWidth, pixelColumnWidths[i]); + } + for (int i = 0; i < numColumns; i++) { + pixelColumnWidths[i] = maxWidth; + } + } + + // Loop through the grid by row to get the height that each row needs to be. + // Each row will be as high as its tallest control. + for (int row = 0; row < grid.size(); row++) { + maxHeight = 0; + for (int column = 0; column < numColumns; column++) { + GridData spec = ((GridData[]) grid.elementAt(row))[column]; + if (spec.isItemData()) { + childHeight = childSizes[spec.childIndex].y; + if (spec.verticalSpan == 1) { + maxHeight = Math.max(maxHeight, childHeight); + } + } + } + // Cache the values for later use. + pixelRowHeights[row] = maxHeight; + } +} +void computeExpandableCells() { + // If a control grabs excess horizontal space, the last column that the control spans + // will be expandable. Similarly, if a control grabs excess vertical space, the + // last row that the control spans will be expandable. + Hashtable growColumns = new Hashtable(); + Hashtable growRows = new Hashtable(); + for (int col = 0; col < numColumns; col++) { + for (int row = 0; row < grid.size(); row++) { + GridData spec = ((GridData[]) grid.elementAt(row))[col]; + if (spec.grabExcessHorizontalSpace) { + growColumns.put(new Integer(col + spec.hSpan - 1), new Object()); + } + if (spec.grabExcessVerticalSpace) { + growRows.put(new Integer(row + spec.verticalSpan - 1), new Object()); + } + } + } + + // Cache the values. These values are used later during children layout. + int i = 0; + Enumeration enum = growColumns.keys(); + expandableColumns = new int[growColumns.size()]; + while (enum.hasMoreElements()) { + expandableColumns[i] = ((Integer)enum.nextElement()).intValue(); + i = i + 1; + } + i = 0; + enum = growRows.keys(); + expandableRows = new int[growRows.size()]; + while (enum.hasMoreElements()) { + expandableRows[i] = ((Integer)enum.nextElement()).intValue(); + i = i + 1; + } +} +Point computeLayoutSize(Composite composite, int wHint, int hHint, boolean flushCache) { + int totalMarginHeight, totalMarginWidth; + int totalWidth, totalHeight; + int cols, rows; + + // Initialize the grid and other cached information that help with the grid layout. + if (grid.size() == 0) { + createGrid(composite); + calculateGridDimensions(composite, flushCache); + computeExpandableCells(); + adjustGridDimensions(composite, flushCache); + } + + // + cols = numColumns; + rows = grid.size(); + totalMarginHeight = marginHeight; + totalMarginWidth = marginWidth; + + // The total width is the margin plus border width plus space between each column, + // plus the width of each column. + totalWidth = (totalMarginWidth * 2) + ((cols - 1) * horizontalSpacing); + + //Add up the width of each column. + for (int i = 0; i < pixelColumnWidths.length; i++) { + totalWidth = totalWidth + pixelColumnWidths[i]; + } + + // The total height is the margin plus border height, plus space between each row, + // plus the height of the tallest child in each row. + totalHeight = (totalMarginHeight * 2) + ((rows - 1) * verticalSpacing); + + //Add up the height of each row. + for (int i = 0; i < pixelRowHeights.length; i++) { + totalHeight = totalHeight + pixelRowHeights[i]; + } + + if (wHint != SWT.DEFAULT) { + totalWidth = wHint;}; + if (hHint != SWT.DEFAULT) { + totalHeight = hHint;}; + // The preferred extent is the width and height that will accomodate the grid's controls. + return new Point(totalWidth, totalHeight); +} +protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { + Control[] children = composite.getChildren(); + int numChildren = children.length; + + if (numChildren == 0) return new Point(0,0); + + if (flushCache) { + // Cause the grid and its related information to be calculated + // again. + grid.removeAllElements(); + } + return computeLayoutSize(composite, wHint, hHint, flushCache); +} +Point getFirstEmptyCell(int row, int column) { + GridData[] rowData = (GridData[]) grid.elementAt(row); + while (column < numColumns && rowData[column] != null) { + column++; + } + if (column == numColumns) { + row++; + column = 0; + if (row == grid.size()) { + grid.addElement(emptyRow()); + } + return getFirstEmptyCell(row, column); + } + return new Point(row, column); +} +Point getLastEmptyCell(int row, int column) { + GridData[] rowData = (GridData[])grid.elementAt(row); + while (column < numColumns && rowData[column] == null ) { + column++; + } + return new Point(row, column - 1); +} +Point getCell(int row, int column, int width, int height) { + Point start = getFirstEmptyCell(row, column); + Point end = getLastEmptyCell(start.x, start.y); + if (end.y + 1 - start.y >= width) return start; + GridData[] rowData = (GridData[]) grid.elementAt(start.x); + for (int j = start.y; j < end.y + 1; j++) { + GridData spacerSpec = new GridData(); + spacerSpec.isItemData = false; + rowData[j] = spacerSpec; + } + return getCell(end.x, end.y, width, height); +} +void createGrid(Composite composite) { + int row, column, rowFill, columnFill; + Control[] children; + GridData spacerSpec; + + // + children = composite.getChildren(); + + // + grid.addElement(emptyRow()); + row = 0; + column = 0; + + // Loop through the children and place their associated layout specs in the + // grid. Placement occurs left to right, top to bottom (i.e., by row). + for (int i = 0; i < children.length; i++) { + // Find the first available spot in the grid. + Control child = children[i]; + GridData spec = (GridData) child.getLayoutData(); + if (spec == null) { + spec = new GridData(); + child.setLayoutData(spec); + } + spec.hSpan = Math.min(spec.horizontalSpan, numColumns); + Point p = getCell(row, column, spec.hSpan, spec.verticalSpan); + row = p.x; column = p.y; + + // The vertical span for the item will be at least 1. If it is > 1, + // add other rows to the grid. + for (int j = 2; j <= spec.verticalSpan; j++) { + if (row + j > grid.size()) { + grid.addElement(emptyRow()); + } + } + + // Store the layout spec. Also cache the childIndex. NOTE: That we assume the children of a + // composite are maintained in the order in which they are created and added to the composite. + ((GridData[]) grid.elementAt(row))[column] = spec; + spec.childIndex = i; + + // Put spacers in the grid to account for the item's vertical and horizontal + // span. + rowFill = spec.verticalSpan - 1; + columnFill = spec.hSpan - 1; + for (int r = 1; r <= rowFill; r++) { + for (int c = 0; c < spec.hSpan; c++) { + spacerSpec = new GridData(); + spacerSpec.isItemData = false; + ((GridData[]) grid.elementAt(row + r))[column + c] = spacerSpec; + } + } + for (int c = 1; c <= columnFill; c++) { + for (int r = 0; r < spec.verticalSpan; r++) { + spacerSpec = new GridData(); + spacerSpec.isItemData = false; + ((GridData[]) grid.elementAt(row + r))[column + c] = spacerSpec; + } + } + column = column + spec.hSpan - 1; + } + + // Fill out empty grid cells with spacers. + for (int r = row; r < grid.size(); r++) { + GridData[] rowData = (GridData[]) grid.elementAt(r); + for (int c = 0; c < numColumns; c++) { + if (rowData[c] == null) { + spacerSpec = new GridData(); + spacerSpec.isItemData = false; + rowData[c] = spacerSpec; + } + } + } +} +GridData[] emptyRow() { + GridData[] row = new GridData[numColumns]; + for (int i = 0; i < numColumns; i++) { + row[i] = null;} + return row; +} +protected void layout(Composite composite, boolean flushCache) { + int[] columnWidths; + int[] rowHeights; + int rowSize, rowY, columnX; + int compositeWidth, compositeHeight; + int excessHorizontal, excessVertical; + Control[] children; + if (flushCache) { + // Cause the grid and its related information to be calculated + // again. + grid.removeAllElements(); + } + children = composite.getChildren(); + if (children.length == 0) + return; + + // + Point extent = computeSize(composite, SWT.DEFAULT, SWT.DEFAULT, flushCache); + columnWidths = new int[numColumns]; + for (int i = 0; i < pixelColumnWidths.length; i++) { + columnWidths[i] = pixelColumnWidths[i]; + } + rowHeights = new int[grid.size()]; + for (int i = 0; i < pixelRowHeights.length; i++) { + rowHeights[i] = pixelRowHeights[i]; + } + int columnWidth = 0; + rowSize = Math.max(1, grid.size()); + + // + compositeWidth = extent.x; + compositeHeight = extent.y; + + // Calculate whether or not there is any extra space or not enough space due to a resize + // operation. Then allocate/deallocate the space to columns and rows that are expandable. + // If a control grabs excess space, its last column or row will be expandable. + excessHorizontal = composite.getClientArea().width - compositeWidth; + excessVertical = composite.getClientArea().height - compositeHeight; + + // Allocate/deallocate horizontal space. + if (expandableColumns.length != 0) { + int excess, remainder, last; + int colWidth; + excess = excessHorizontal / expandableColumns.length; + remainder = excessHorizontal % expandableColumns.length; + last = 0; + for (int i = 0; i < expandableColumns.length; i++) { + int expandableCol = expandableColumns[i]; + colWidth = columnWidths[expandableCol]; + colWidth = colWidth + excess; + columnWidths[expandableCol] = colWidth; + last = Math.max(last, expandableCol); + } + colWidth = columnWidths[last]; + colWidth = colWidth + remainder; + columnWidths[last] = colWidth; + } + + // Go through all specs in each expandable column and get the maximum specified + // widthHint. Use this as the minimumWidth for the column. + for (int i = 0; i < expandableColumns.length; i++) { + int expandableCol = expandableColumns[i]; + int colWidth = columnWidths[expandableCol]; + int minWidth = 0; + for (int j = 0; j < grid.size(); j++) { + GridData[] row = (GridData[]) grid.elementAt(j); + GridData spec = row[expandableCol]; + if (spec.hSpan == 1) { + minWidth = Math.max(minWidth, spec.widthHint); + } + } + columnWidths[expandableCol] = Math.max(colWidth, minWidth); + } + // Allocate/deallocate vertical space. + if (expandableRows.length != 0) { + int excess, remainder, last; + int rowHeight; + excess = excessVertical / expandableRows.length; + remainder = excessVertical % expandableRows.length; + last = 0; + for (int i = 0; i < expandableRows.length; i++) { + int expandableRow = expandableRows[i]; + rowHeight = rowHeights[expandableRow]; + rowHeight = rowHeight + excess; + rowHeights[expandableRow] = rowHeight; + last = Math.max(last, expandableRow); + } + rowHeight = rowHeights[last]; + rowHeight = rowHeight + remainder; + rowHeights[last] = rowHeight; + } + // Go through all specs in each expandable row and get the maximum specified + // heightHint. Use this as the minimumHeight for the row. + for (int i = 0; i < expandableRows.length; i++) { + int expandableRow = expandableRows[i]; + int rowHeight = rowHeights[expandableRow]; + int minHeight = 0; + GridData[] row = (GridData[]) grid.elementAt(expandableRow); + for (int j = 0; j < numColumns; j++) { + GridData spec = row[j]; + if (spec.verticalSpan == 1) { + minHeight = Math.max(minHeight, spec.heightHint); + } + } + rowHeights[expandableRow] = Math.max(rowHeight, minHeight); + } + + // Get the starting x and y. + columnX = marginWidth + composite.getClientArea().x; + rowY = marginHeight + composite.getClientArea().y; + + // Layout the control left to right, top to bottom. + for (int r = 0; r < rowSize; r++) { + int rowHeight = rowHeights[r]; + GridData[] row = (GridData[]) grid.elementAt(r); + + // + for (int c = 0; c < row.length; c++) { + int spannedWidth = 0, spannedHeight = 0; + int hAlign = 0, vAlign = 0; + int widgetX = 0, widgetY = 0; + int widgetW = 0, widgetH = 0; + + // + GridData spec = (GridData) row[c]; + if (makeColumnsEqualWidth) { + columnWidth = composite.getClientArea().width - 2 * (marginWidth) - ((numColumns - 1) * horizontalSpacing); + columnWidth = columnWidth / numColumns; + for (int i = 0; i < columnWidths.length; i++) { + columnWidths[i] = columnWidth; + } + } else { + columnWidth = columnWidths[c]; + } + + // + spannedWidth = columnWidth; + for (int k = 1; k < spec.hSpan; k++) { + if ((c + k) <= numColumns) { + if (!makeColumnsEqualWidth) { + columnWidth = columnWidths[c + k]; + } + spannedWidth = spannedWidth + columnWidth + horizontalSpacing; + } + } + + // + spannedHeight = rowHeight; + for (int k = 1; k < spec.verticalSpan; k++) { + if ((r + k) <= grid.size()) { + spannedHeight = spannedHeight + rowHeights[r + k] + verticalSpacing; + } + } + + // + if (spec.isItemData()) { + Control child = children[spec.childIndex]; + Point childExtent = child.computeSize(spec.widthHint, spec.heightHint, flushCache); + hAlign = spec.horizontalAlignment; + widgetX = columnX; + + // Calculate the x and width values for the control. + if (hAlign == GridData.CENTER) { + widgetX = widgetX + (spannedWidth / 2) - (childExtent.x / 2); + } else + if (hAlign == GridData.END) { + widgetX = widgetX + spannedWidth - childExtent.x - spec.horizontalIndent; + } else { + widgetX = widgetX + spec.horizontalIndent; + } + if (hAlign == GridData.FILL) { + widgetW = spannedWidth - spec.horizontalIndent; + widgetX = columnX + spec.horizontalIndent; + } else { + widgetW = childExtent.x; + } + + // Calculate the y and height values for the control. + vAlign = spec.verticalAlignment; + widgetY = rowY; + if (vAlign == GridData.CENTER) { + widgetY = widgetY + (spannedHeight / 2) - (childExtent.y / 2); + } else + if (vAlign == GridData.END) { + widgetY = widgetY + spannedHeight - childExtent.y; + } + if (vAlign == GridData.FILL) { + widgetH = spannedHeight; + widgetY = rowY; + } else { + widgetH = childExtent.y; + } + // Place the control. + child.setBounds(widgetX, widgetY, widgetW, widgetH); + } + // Update the starting x value. + columnX = columnX + columnWidths[c] + horizontalSpacing; + } + // Update the starting y value and since we're starting a new row, reset the starting x value. + rowY = rowY + rowHeights[r] + verticalSpacing; + columnX = marginWidth + composite.getClientArea().x; + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowData.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowData.java index 05d4019e35..9f44d42b2f 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowData.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowData.java @@ -1,53 +1,53 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-
-/**
- * Each control controlled by a <code>RowLayout</code> can have its initial
- * width and height specified by setting a <code>RowData</code> object
- * into the control.
- * <p>
- * The following code uses a <code>RowData</code> object to change the initial
- * size of a <code>Button</code> in a <code>Shell</code>:
- * <pre>
- * Display display = new Display();
- * Shell shell = new Shell(display);
- * shell.setLayout(new RowLayout());
- * Button button1 = new Button(shell, SWT.PUSH);
- * button1.setText("Button 1");
- * button1.setLayoutData(new RowData(50, 40));
- * </pre>
- * </p>
- *
- * @see RowLayout
- */
-public final class RowData {
- /**
- * width specifies the width of the cell in pixels.
- */
- public int width;
- /**
- * height specifies the height of the cell in pixels.
- */
- public int height;
-
-public RowData () {
- this (SWT.DEFAULT, SWT.DEFAULT);
-}
-
-public RowData (int width, int height) {
- this.width = width;
- this.height = height;
-}
-
-public RowData (Point point) {
- this (point.x, point.y);
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; + +/** + * Each control controlled by a <code>RowLayout</code> can have its initial + * width and height specified by setting a <code>RowData</code> object + * into the control. + * <p> + * The following code uses a <code>RowData</code> object to change the initial + * size of a <code>Button</code> in a <code>Shell</code>: + * <pre> + * Display display = new Display(); + * Shell shell = new Shell(display); + * shell.setLayout(new RowLayout()); + * Button button1 = new Button(shell, SWT.PUSH); + * button1.setText("Button 1"); + * button1.setLayoutData(new RowData(50, 40)); + * </pre> + * </p> + * + * @see RowLayout + */ +public final class RowData { + /** + * width specifies the width of the cell in pixels. + */ + public int width; + /** + * height specifies the height of the cell in pixels. + */ + public int height; + +public RowData () { + this (SWT.DEFAULT, SWT.DEFAULT); +} + +public RowData (int width, int height) { + this.width = width; + this.height = height; +} + +public RowData (Point point) { + this (point.x, point.y); +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowLayout.java index d99d0c1a57..f6463fa49b 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/RowLayout.java @@ -1,297 +1,297 @@ -package org.eclipse.swt.layout;
-
-/*
+package org.eclipse.swt.layout; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Instances of this class determine the size and position of the
- * children of a <code>Composite</code> by placing them either in
- * horizontal rows or vertical columns within the parent <code>Composite</code>.
- * <p>
- * <code>RowLayout</code> aligns all controls in one row if the
- * <code>type</code> is set to horizontal, and one column if it is
- * set to vertical. It has the ability to wrap, and provides configurable
- * margins and spacing. <code>RowLayout</code> has a number of configuration
- * fields. In addition, the height and width of each control in a
- * <code>RowLayout</code> can be specified by setting a <code>RowData</code>
- * object into the control using <code>setLayoutData ()</code>.
- * </p>
- * <p>
- * The following example code creates a <code>RowLayout</code>, sets all
- * of its fields to non-default values, and then sets it into a
- * <code>Shell</code>.
- * <pre>
- * RowLayout rowLayout = new RowLayout();
- * rowLayout.wrap = false;
- * rowLayout.pack = false;
- * rowLayout.justify = true;
- * rowLayout.type = SWT.VERTICAL;
- * rowLayout.marginLeft = 5;
- * rowLayout.marginTop = 5;
- * rowLayout.marginRight = 5;
- * rowLayout.marginBottom = 5;
- * rowLayout.spacing = 0;
- * shell.setLayout(rowLayout);
- * </pre>
- * If you are using the default field values, you only need one line of code:
- * <pre>
- * shell.setLayout(new RowLayout());
- * </pre>
- * </p>
- *
- * @see RowData
- */
-public final class RowLayout extends Layout {
- /**
- * type specifies whether the layout places controls in rows or
- * columns.
- *
- * The default value is HORIZONTAL.
- *
- * Possible values are:
- *
- * HORIZONTAL: Position the controls horizontally from left to right
- * VERTICAL: Position the controls vertically from top to bottom
- *
- * @since 2.0
- */
- public int type = SWT.HORIZONTAL;
- /**
- * wrap specifies whether a control will be wrapped to the next
- * row if there is insufficient space on the current row.
- *
- * The default value is true.
- */
- public boolean wrap = true;
- /**
- * pack specifies whether all controls in the layout take
- * their preferred size. If pack is false, all controls will
- * have the same size which is the size required to accommodate the
- * largest preferred height and the largest preferred width of all
- * the controls in the layout.
- *
- * The default value is true.
- */
- public boolean pack = true;
- /**
- * justify specifies whether the controls in a row should be
- * fully justified, with any extra space placed between the controls.
- *
- * The default value is false.
- */
- public boolean justify = false;
- /**
- * spacing specifies the number of pixels between the edge of one cell
- * and the edge of its neighbouring cell.
- *
- * The default value is 3.
- */
- public int spacing = 3;
- /**
- * marginLeft specifies the number of pixels of horizontal margin
- * that will be placed along the left edge of the layout.
- *
- * The default value is 3.
- */
- public int marginLeft = 3;
- /**
- * marginTop specifies the number of pixels of vertical margin
- * that will be placed along the top edge of the layout.
- *
- * The default value is 3.
- */
- public int marginTop = 3;
- /**
- * marginRight specifies the number of pixels of horizontal margin
- * that will be placed along the right edge of the layout.
- *
- * The default value is 3.
- */
- public int marginRight = 3;
- /**
- * marginBottom specifies the number of pixels of vertical margin
- * that will be placed along the bottom edge of the layout.
- *
- * The default value is 3.
- */
- public int marginBottom = 3;
-
-/**
- * Constructs a new instance of this class.
- */
-public RowLayout () {
-}
-
-/**
- * Constructs a new instance of this class given the type.
- *
- * @param type the type of row layout
- *
- * @since 2.0
- */
-public RowLayout (int type) {
- this.type = type;
-}
-
-protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) {
- Point extent;
- if (type == SWT.HORIZONTAL) {
- extent = layoutHorizontal (composite, false, (wHint != SWT.DEFAULT) && wrap, wHint, flushCache);
- } else {
- extent = layoutVertical (composite, false, (hHint != SWT.DEFAULT) && wrap, hHint, flushCache);
- }
- if (wHint != SWT.DEFAULT) extent.x = wHint;
- if (hHint != SWT.DEFAULT) extent.y = hHint;
- return extent;
-}
-
-Point getSize (Control control, boolean flushCache) {
- int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT;
- RowData data = (RowData) control.getLayoutData ();
- if (data != null) {
- wHint = data.width;
- hHint = data.height;
- }
- return control.computeSize (wHint, hHint, flushCache);
-}
-
-protected void layout (Composite composite, boolean flushCache) {
- Rectangle clientArea = composite.getClientArea ();
- if (type == SWT.HORIZONTAL) {
- layoutHorizontal (composite, true, wrap, clientArea.width, flushCache);
- } else {
- layoutVertical (composite, true, wrap, clientArea.height, flushCache);
- }
-}
-
-Point layoutHorizontal (Composite composite, boolean move, boolean wrap, int width, boolean flushCache) {
- Control [] children = composite.getChildren ();
- int count = children.length;
- int childWidth = 0, childHeight = 0, maxHeight = 0;
- if (!pack) {
- for (int i=0; i<count; i++) {
- Control child = children [i];
- Point pt = getSize (child, flushCache);
- childWidth = Math.max (childWidth, pt.x);
- childHeight = Math.max (childHeight, pt.y);
- }
- maxHeight = childHeight;
- }
- int clientX = 0, clientY = 0;
- if (move) {
- Rectangle rect = composite.getClientArea ();
- clientX = rect.x; clientY = rect.y;
- }
- boolean wrapped = false;
- Rectangle [] bounds = null;
- if (move && justify) bounds = new Rectangle [count];
- int maxX = 0, x = marginLeft, y = marginTop;
- for (int i=0; i<count; i++) {
- Control child = children [i];
- if (pack) {
- Point pt = getSize (child, flushCache);
- childWidth = pt.x; childHeight = pt.y;
- }
- if (wrap && (i != 0) && (x + childWidth > width)) {
- wrapped = true;
- x = marginLeft; y += spacing + maxHeight;
- }
- if (pack) {
- maxHeight = Math.max (maxHeight, childHeight);
- }
- if (move) {
- int childX = x + clientX, childY = y + clientY;
- if (justify) {
- bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
- } else {
- child.setBounds (childX, childY, childWidth, childHeight);
- }
- }
- x += spacing + childWidth;
- maxX = Math.max (maxX, x);
- }
- if (!wrap) maxX = x + marginRight;
- if (move && justify) {
- int space = 0, margin = 0;
- if (!wrapped) {
- space = Math.max (0, (width - maxX) / (count + 1));
- margin = Math.max (0, ((width - maxX) % (count + 1)) / 2);
- }
- for (int i=0; i<count; i++) {
- Control child = children [i];
- bounds [i].x += (space * (i + 1)) + margin;
- child.setBounds (bounds [i]);
- }
- }
- return new Point (maxX, y + maxHeight + marginBottom);
-}
-
-Point layoutVertical (Composite composite, boolean move, boolean wrap, int height, boolean flushCache) {
- Control [] children = composite.getChildren ();
- int count = children.length;
- int childWidth = 0, childHeight = 0, maxWidth = 0;
- if (!pack) {
- for (int i=0; i<count; i++) {
- Control child = children [i];
- Point pt = getSize (child, flushCache);
- childWidth = Math.max (childWidth, pt.x);
- childHeight = Math.max (childHeight, pt.y);
- }
- maxWidth = childWidth;
- }
- int clientX = 0, clientY = 0;
- if (move) {
- Rectangle rect = composite.getClientArea ();
- clientX = rect.x; clientY = rect.y;
- }
- boolean wrapped = false;
- Rectangle [] bounds = null;
- if (move && justify) bounds = new Rectangle [count];
- int maxY = 0, x = marginLeft, y = marginTop;
- for (int i=0; i<count; i++) {
- Control child = children [i];
- if (pack) {
- Point pt = getSize (child, flushCache);
- childWidth = pt.x; childHeight = pt.y;
- }
- if (wrap && (i != 0) && (y + childHeight > height)) {
- wrapped = true;
- x += spacing + maxWidth; y = marginTop;
- }
- if (pack) {
- maxWidth = Math.max (maxWidth, childWidth);
- }
- if (move) {
- int childX = x + clientX, childY = y + clientY;
- if (justify) {
- bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
- } else {
- child.setBounds (childX, childY, childWidth, childHeight);
- }
- }
- y += spacing + childHeight;
- maxY = Math.max (maxY, y);
- }
- if (!wrap) maxY = y + marginBottom;
- if (move && justify) {
- int space = 0, margin = 0;
- if (!wrapped) {
- space = Math.max (0, (height - maxY) / (count + 1));
- margin = Math.max (0, ((height - maxY) % (count + 1)) / 2);
- }
- for (int i=0; i<count; i++) {
- Control child = children [i];
- bounds [i].y += (space * (i + 1)) + margin;
- child.setBounds (bounds [i]);
- }
- }
- return new Point (x + maxWidth + marginRight, maxY);
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.widgets.*; + +/** + * Instances of this class determine the size and position of the + * children of a <code>Composite</code> by placing them either in + * horizontal rows or vertical columns within the parent <code>Composite</code>. + * <p> + * <code>RowLayout</code> aligns all controls in one row if the + * <code>type</code> is set to horizontal, and one column if it is + * set to vertical. It has the ability to wrap, and provides configurable + * margins and spacing. <code>RowLayout</code> has a number of configuration + * fields. In addition, the height and width of each control in a + * <code>RowLayout</code> can be specified by setting a <code>RowData</code> + * object into the control using <code>setLayoutData ()</code>. + * </p> + * <p> + * The following example code creates a <code>RowLayout</code>, sets all + * of its fields to non-default values, and then sets it into a + * <code>Shell</code>. + * <pre> + * RowLayout rowLayout = new RowLayout(); + * rowLayout.wrap = false; + * rowLayout.pack = false; + * rowLayout.justify = true; + * rowLayout.type = SWT.VERTICAL; + * rowLayout.marginLeft = 5; + * rowLayout.marginTop = 5; + * rowLayout.marginRight = 5; + * rowLayout.marginBottom = 5; + * rowLayout.spacing = 0; + * shell.setLayout(rowLayout); + * </pre> + * If you are using the default field values, you only need one line of code: + * <pre> + * shell.setLayout(new RowLayout()); + * </pre> + * </p> + * + * @see RowData + */ +public final class RowLayout extends Layout { + /** + * type specifies whether the layout places controls in rows or + * columns. + * + * The default value is HORIZONTAL. + * + * Possible values are: + * + * HORIZONTAL: Position the controls horizontally from left to right + * VERTICAL: Position the controls vertically from top to bottom + * + * @since 2.0 + */ + public int type = SWT.HORIZONTAL; + /** + * wrap specifies whether a control will be wrapped to the next + * row if there is insufficient space on the current row. + * + * The default value is true. + */ + public boolean wrap = true; + /** + * pack specifies whether all controls in the layout take + * their preferred size. If pack is false, all controls will + * have the same size which is the size required to accommodate the + * largest preferred height and the largest preferred width of all + * the controls in the layout. + * + * The default value is true. + */ + public boolean pack = true; + /** + * justify specifies whether the controls in a row should be + * fully justified, with any extra space placed between the controls. + * + * The default value is false. + */ + public boolean justify = false; + /** + * spacing specifies the number of pixels between the edge of one cell + * and the edge of its neighbouring cell. + * + * The default value is 3. + */ + public int spacing = 3; + /** + * marginLeft specifies the number of pixels of horizontal margin + * that will be placed along the left edge of the layout. + * + * The default value is 3. + */ + public int marginLeft = 3; + /** + * marginTop specifies the number of pixels of vertical margin + * that will be placed along the top edge of the layout. + * + * The default value is 3. + */ + public int marginTop = 3; + /** + * marginRight specifies the number of pixels of horizontal margin + * that will be placed along the right edge of the layout. + * + * The default value is 3. + */ + public int marginRight = 3; + /** + * marginBottom specifies the number of pixels of vertical margin + * that will be placed along the bottom edge of the layout. + * + * The default value is 3. + */ + public int marginBottom = 3; + +/** + * Constructs a new instance of this class. + */ +public RowLayout () { +} + +/** + * Constructs a new instance of this class given the type. + * + * @param type the type of row layout + * + * @since 2.0 + */ +public RowLayout (int type) { + this.type = type; +} + +protected Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache) { + Point extent; + if (type == SWT.HORIZONTAL) { + extent = layoutHorizontal (composite, false, (wHint != SWT.DEFAULT) && wrap, wHint, flushCache); + } else { + extent = layoutVertical (composite, false, (hHint != SWT.DEFAULT) && wrap, hHint, flushCache); + } + if (wHint != SWT.DEFAULT) extent.x = wHint; + if (hHint != SWT.DEFAULT) extent.y = hHint; + return extent; +} + +Point getSize (Control control, boolean flushCache) { + int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT; + RowData data = (RowData) control.getLayoutData (); + if (data != null) { + wHint = data.width; + hHint = data.height; + } + return control.computeSize (wHint, hHint, flushCache); +} + +protected void layout (Composite composite, boolean flushCache) { + Rectangle clientArea = composite.getClientArea (); + if (type == SWT.HORIZONTAL) { + layoutHorizontal (composite, true, wrap, clientArea.width, flushCache); + } else { + layoutVertical (composite, true, wrap, clientArea.height, flushCache); + } +} + +Point layoutHorizontal (Composite composite, boolean move, boolean wrap, int width, boolean flushCache) { + Control [] children = composite.getChildren (); + int count = children.length; + int childWidth = 0, childHeight = 0, maxHeight = 0; + if (!pack) { + for (int i=0; i<count; i++) { + Control child = children [i]; + Point pt = getSize (child, flushCache); + childWidth = Math.max (childWidth, pt.x); + childHeight = Math.max (childHeight, pt.y); + } + maxHeight = childHeight; + } + int clientX = 0, clientY = 0; + if (move) { + Rectangle rect = composite.getClientArea (); + clientX = rect.x; clientY = rect.y; + } + boolean wrapped = false; + Rectangle [] bounds = null; + if (move && justify) bounds = new Rectangle [count]; + int maxX = 0, x = marginLeft, y = marginTop; + for (int i=0; i<count; i++) { + Control child = children [i]; + if (pack) { + Point pt = getSize (child, flushCache); + childWidth = pt.x; childHeight = pt.y; + } + if (wrap && (i != 0) && (x + childWidth > width)) { + wrapped = true; + x = marginLeft; y += spacing + maxHeight; + } + if (pack) { + maxHeight = Math.max (maxHeight, childHeight); + } + if (move) { + int childX = x + clientX, childY = y + clientY; + if (justify) { + bounds [i] = new Rectangle (childX, childY, childWidth, childHeight); + } else { + child.setBounds (childX, childY, childWidth, childHeight); + } + } + x += spacing + childWidth; + maxX = Math.max (maxX, x); + } + if (!wrap) maxX = x + marginRight; + if (move && justify) { + int space = 0, margin = 0; + if (!wrapped) { + space = Math.max (0, (width - maxX) / (count + 1)); + margin = Math.max (0, ((width - maxX) % (count + 1)) / 2); + } + for (int i=0; i<count; i++) { + Control child = children [i]; + bounds [i].x += (space * (i + 1)) + margin; + child.setBounds (bounds [i]); + } + } + return new Point (maxX, y + maxHeight + marginBottom); +} + +Point layoutVertical (Composite composite, boolean move, boolean wrap, int height, boolean flushCache) { + Control [] children = composite.getChildren (); + int count = children.length; + int childWidth = 0, childHeight = 0, maxWidth = 0; + if (!pack) { + for (int i=0; i<count; i++) { + Control child = children [i]; + Point pt = getSize (child, flushCache); + childWidth = Math.max (childWidth, pt.x); + childHeight = Math.max (childHeight, pt.y); + } + maxWidth = childWidth; + } + int clientX = 0, clientY = 0; + if (move) { + Rectangle rect = composite.getClientArea (); + clientX = rect.x; clientY = rect.y; + } + boolean wrapped = false; + Rectangle [] bounds = null; + if (move && justify) bounds = new Rectangle [count]; + int maxY = 0, x = marginLeft, y = marginTop; + for (int i=0; i<count; i++) { + Control child = children [i]; + if (pack) { + Point pt = getSize (child, flushCache); + childWidth = pt.x; childHeight = pt.y; + } + if (wrap && (i != 0) && (y + childHeight > height)) { + wrapped = true; + x += spacing + maxWidth; y = marginTop; + } + if (pack) { + maxWidth = Math.max (maxWidth, childWidth); + } + if (move) { + int childX = x + clientX, childY = y + clientY; + if (justify) { + bounds [i] = new Rectangle (childX, childY, childWidth, childHeight); + } else { + child.setBounds (childX, childY, childWidth, childHeight); + } + } + y += spacing + childHeight; + maxY = Math.max (maxY, y); + } + if (!wrap) maxY = y + marginBottom; + if (move && justify) { + int space = 0, margin = 0; + if (!wrapped) { + space = Math.max (0, (height - maxY) / (count + 1)); + margin = Math.max (0, ((height - maxY) % (count + 1)) / 2); + } + for (int i=0; i<count; i++) { + Control child = children [i]; + bounds [i].y += (space * (i + 1)) + margin; + child.setBounds (bounds [i]); + } + } + return new Point (x + maxWidth + marginRight, maxY); +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Dialog.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Dialog.java index cfdfa57a1c..a45ffc96a5 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Dialog.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Dialog.java @@ -1,253 +1,253 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-
-/**
- * This class is the abstract superclass of the classes
- * that represent the built in platform dialogs.
- * A <code>Dialog</code> typically contains other widgets
- * that are not accessible. A <code>Dialog</code> is not
- * a <code>Widget</code>.
- * <p>
- * This class can also be used as the abstract superclass
- * for user-designed dialogs. Such dialogs usually consist
- * of a Shell with child widgets. The basic template for a
- * user-defined dialog typically looks something like this:
- * <code>
- * public class MyDialog extends Dialog {
- * Object result;
- *
- * public MyDialog (Shell parent, int style) {
- * super (parent, style);
- * }
- * public MyDialog (Shell parent) {
- * this (parent, 0); // your default style bits go here (not the Shell's style bits)
- * }
- * public Object open () {
- * Shell parent = getParent();
- * Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
- * shell.setText(getText());
- * // Your code goes here (widget creation, set result, etc).
- * shell.open();
- * Display display = parent.getDisplay();
- * while (!shell.isDisposed()) {
- * if (!display.readAndDispatch()) display.sleep();
- * }
- * return result;
- * }
- * }
- * </code>
- * <p>
- * Note: The <em>modality</em> styles supported by this class
- * must be treated as <em>HINT</em>s, because not all are
- * supported by every subclass on every platform. If a modality style
- * is not supported, it is "upgraded" to a more restrictive modality
- * style that is supported. For example, if <code>PRIMARY_MODAL</code>
- * is not supported by a particular dialog, it would be upgraded to
- * <code>APPLICATION_MODAL</code>. In addition, as is the case
- * for shells, the window manager for the desktop on which the
- * instance is visible has ultimate control over the appearance
- * and behavior of the instance, including its modality.
- * <dl>
- * <dt><b>Styles:</b></dt>
- * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd>
- * <dt><b>Events:</b></dt>
- * <dd>(none)</dd>
- * </dl>
- *
- * @see Shell
- */
-
-public abstract class Dialog {
- int style;
- Shell parent;
- String title;
-
-/**
- * Constructs a new instance of this class given only its
- * parent.
- * <p>
- * Note: Currently, null can be passed in for the parent.
- * This has the effect of creating the dialog on the currently active
- * display if there is one. If there is no current display, the
- * dialog is created on a "default" display. <b>Passing in null as
- * the parent is not considered to be good coding style,
- * and may not be supported in a future release of SWT.</b>
- * </p>
- *
- * @param parent a shell which will be the parent of the new instance
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
- * </ul>
- */
-public Dialog (Shell parent) {
- this (parent, 0);
-}
-
-/**
- * Constructs a new instance of this class given its parent
- * and a style value describing its behavior and appearance.
- * <p>
- * The style value is either one of the style constants defined in
- * class <code>SWT</code> which is applicable to instances of this
- * class, or must be built by <em>bitwise OR</em>'ing together
- * (that is, using the <code>int</code> "|" operator) two or more
- * of those <code>SWT</code> style constants. The class description
- * lists the style constants that are applicable to the class.
- * Style bits are also inherited from superclasses.
- * </p>
- * Note: Currently, null can be passed in for the parent.
- * This has the effect of creating the dialog on the currently active
- * display if there is one. If there is no current display, the
- * dialog is created on a "default" display. <b>Passing in null as
- * the parent is not considered to be good coding style,
- * and may not be supported in a future release of SWT.</b>
- * </p>
- *
- * @param parent a shell which will be the parent of the new instance
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
- * </ul>
- */
-public Dialog (Shell parent, int style) {
- checkParent (parent);
- this.parent = parent;
- this.style = style;
- title = "";
-}
-
-/**
- * Checks that this class can be subclassed.
- * <p>
- * IMPORTANT: See the comment in <code>Widget.checkSubclass()</code>.
- * </p>
- *
- * @exception SWTException <ul>
- * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
- * </ul>
- *
- * @see Widget#checkSubclass
- */
-protected void checkSubclass () {
- if (!Display.isValidClass (getClass ())) {
- error (SWT.ERROR_INVALID_SUBCLASS);
- }
-}
-
-/**
- * Throws an exception if the specified widget can not be
- * used as a parent for the receiver.
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
- * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
- * </ul>
- */
-void checkParent (Shell parent) {
- if (parent == null) error (SWT.ERROR_NULL_ARGUMENT);
- if (!parent.isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS);
- if (parent.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT);
-}
-
-/**
- * Does whatever dialog specific cleanup is required, and then
- * uses the code in <code>SWTError.error</code> to handle the error.
- *
- * @param code the descriptive error code
- *
- * @see SWTError#error
- */
-void error (int code) {
- SWT.error(code);
-}
-
-/**
- * Returns the receiver's parent, which must be a <code>Shell</code>
- * or null.
- *
- * @return the receiver's parent
- *
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public Shell getParent () {
- return parent;
-}
-
-/**
- * Returns the receiver's style information.
- * <p>
- * Note that, the value which is returned by this method <em>may
- * not match</em> the value which was provided to the constructor
- * when the receiver was created.
- * </p>
- *
- * @return the style bits
- *
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public int getStyle () {
- return style;
-}
-
-/**
- * Returns the receiver's text, which is the string that the
- * window manager will typically display as the receiver's
- * <em>title</em>. If the text has not previously been set,
- * returns an empty string.
- *
- * @return the text
- *
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public String getText () {
- return title;
-}
-
-/**
- * Sets the receiver's text, which is the string that the
- * window manager will typically display as the receiver's
- * <em>title</em>, to the argument, which must not be null.
- *
- * @param text the new text
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public void setText (String string) {
- if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
- title = string;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; + +/** + * This class is the abstract superclass of the classes + * that represent the built in platform dialogs. + * A <code>Dialog</code> typically contains other widgets + * that are not accessible. A <code>Dialog</code> is not + * a <code>Widget</code>. + * <p> + * This class can also be used as the abstract superclass + * for user-designed dialogs. Such dialogs usually consist + * of a Shell with child widgets. The basic template for a + * user-defined dialog typically looks something like this: + * <code> + * public class MyDialog extends Dialog { + * Object result; + * + * public MyDialog (Shell parent, int style) { + * super (parent, style); + * } + * public MyDialog (Shell parent) { + * this (parent, 0); // your default style bits go here (not the Shell's style bits) + * } + * public Object open () { + * Shell parent = getParent(); + * Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + * shell.setText(getText()); + * // Your code goes here (widget creation, set result, etc). + * shell.open(); + * Display display = parent.getDisplay(); + * while (!shell.isDisposed()) { + * if (!display.readAndDispatch()) display.sleep(); + * } + * return result; + * } + * } + * </code> + * <p> + * Note: The <em>modality</em> styles supported by this class + * must be treated as <em>HINT</em>s, because not all are + * supported by every subclass on every platform. If a modality style + * is not supported, it is "upgraded" to a more restrictive modality + * style that is supported. For example, if <code>PRIMARY_MODAL</code> + * is not supported by a particular dialog, it would be upgraded to + * <code>APPLICATION_MODAL</code>. In addition, as is the case + * for shells, the window manager for the desktop on which the + * instance is visible has ultimate control over the appearance + * and behavior of the instance, including its modality. + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>APPLICATION_MODAL, MODELESS, PRIMARY_MODAL, SYSTEM_MODAL</dd> + * <dt><b>Events:</b></dt> + * <dd>(none)</dd> + * </dl> + * + * @see Shell + */ + +public abstract class Dialog { + int style; + Shell parent; + String title; + +/** + * Constructs a new instance of this class given only its + * parent. + * <p> + * Note: Currently, null can be passed in for the parent. + * This has the effect of creating the dialog on the currently active + * display if there is one. If there is no current display, the + * dialog is created on a "default" display. <b>Passing in null as + * the parent is not considered to be good coding style, + * and may not be supported in a future release of SWT.</b> + * </p> + * + * @param parent a shell which will be the parent of the new instance + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + */ +public Dialog (Shell parent) { + this (parent, 0); +} + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * Note: Currently, null can be passed in for the parent. + * This has the effect of creating the dialog on the currently active + * display if there is one. If there is no current display, the + * dialog is created on a "default" display. <b>Passing in null as + * the parent is not considered to be good coding style, + * and may not be supported in a future release of SWT.</b> + * </p> + * + * @param parent a shell which will be the parent of the new instance + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + */ +public Dialog (Shell parent, int style) { + checkParent (parent); + this.parent = parent; + this.style = style; + title = ""; +} + +/** + * Checks that this class can be subclassed. + * <p> + * IMPORTANT: See the comment in <code>Widget.checkSubclass()</code>. + * </p> + * + * @exception SWTException <ul> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + * + * @see Widget#checkSubclass + */ +protected void checkSubclass () { + if (!Display.isValidClass (getClass ())) { + error (SWT.ERROR_INVALID_SUBCLASS); + } +} + +/** + * Throws an exception if the specified widget can not be + * used as a parent for the receiver. + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * <li>ERROR_INVALID_ARGUMENT - if the parent is disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + */ +void checkParent (Shell parent) { + if (parent == null) error (SWT.ERROR_NULL_ARGUMENT); + if (!parent.isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS); + if (parent.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); +} + +/** + * Does whatever dialog specific cleanup is required, and then + * uses the code in <code>SWTError.error</code> to handle the error. + * + * @param code the descriptive error code + * + * @see SWTError#error + */ +void error (int code) { + SWT.error(code); +} + +/** + * Returns the receiver's parent, which must be a <code>Shell</code> + * or null. + * + * @return the receiver's parent + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public Shell getParent () { + return parent; +} + +/** + * Returns the receiver's style information. + * <p> + * Note that, the value which is returned by this method <em>may + * not match</em> the value which was provided to the constructor + * when the receiver was created. + * </p> + * + * @return the style bits + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public int getStyle () { + return style; +} + +/** + * Returns the receiver's text, which is the string that the + * window manager will typically display as the receiver's + * <em>title</em>. If the text has not previously been set, + * returns an empty string. + * + * @return the text + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public String getText () { + return title; +} + +/** + * Sets the receiver's text, which is the string that the + * window manager will typically display as the receiver's + * <em>title</em>, to the argument, which must not be null. + * + * @param text the new text + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the text is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public void setText (String string) { + if (string == null) error (SWT.ERROR_NULL_ARGUMENT); + title = string; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java index 2bc9da03a9..6ae5cc2ef6 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Event.java @@ -1,208 +1,208 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.graphics.*;
-
-/**
- * Instances of this class provide a description of a particular
- * event which occurred within SWT. The SWT <em>untyped listener</em>
- * API uses these instances for all event dispatching.
- * <p>
- * Note: For a given event, only the fields which are appropriate
- * will be filled in. The contents of the fields which are not used
- * by the event are unspecified.
- * </p>
- *
- * @see Listener
- * @see org.eclipse.swt.events.TypedEvent
- */
-
-public class Event {
-
- /**
- * the display where the event occurred
- *
- * @since 2.0
- */
- public Display display;
-
- /**
- * the widget that issued the event
- */
- public Widget widget;
-
- /**
- * the type of event, as defined by the event type constants
- * in class <code>SWT</code>
- *
- * @see SWT
- */
- public int type;
-
- /**
- * the event specific detail field, as defined by the detail constants
- * in class <code>SWT</code>
- *
- * @see SWT
- */
- public int detail;
-
- /**
- * the item that the event occurred in (can be null)
- */
- public Widget item;
-
- /**
- * the graphics context to use when painting
- * that is configured to use the colors, font and
- * damaged region of the control. It is valid
- * only during the paint and must not be disposed
- */
- public GC gc;
-
- /**
- * depending on the event type, the x offset of the bounding
- * rectangle of the region that requires painting or the
- * widget-relative, x coordinate of the pointer at the
- * time the mouse button was pressed or released
- */
- public int x;
-
- /**
- * depending on the event type, the y offset of the bounding
- * rectangle of the region that requires painting or the
- * widget-relative, y coordinate of the pointer at the
- * time the mouse button was pressed or released
- */
- public int y;
-
- /**
- * the width of the bounding rectangle of the
- * region that requires painting
- */
- public int width;
-
- /**
- * the height of the bounding rectangle of the
- * region that requires painting
- */
- public int height;
-
- /**
- * the number of following paint events which
- * are pending which may always be zero on
- * some platforms
- */
- public int count;
-
- /**
- * the time that the event occurred.
- *
- * NOTE: This field is an unsigned integer and should
- * be AND'ed with 0xFFFFFFFFL so that it can be treated
- * as a signed long.
- */
- public int time;
-
- /**
- * the button that was pressed or released; 1 for the
- * first button, 2 for the second button, and 3 for the
- * third button, etc.
- */
- public int button;
-
- /**
- * depending on the event, the character represented by the key
- * that was typed. This is the final character that results
- * after all modifiers have been applied. For example, when the
- * user types Ctrl+A, the character value is 0x01 (NUL). It is
- * important that applications do not attempt to modify the character
- * value based on a stateMask (such as SWT.CTRL) or the resulting
- * character will not be correct.
- */
- public char character;
-
- /**
- * depending on the event, the key code of the key that was typed,
- * as defined by the key code constants in class <code>SWT</code>.
- * When the character field of the event is ambiguous, this field
- * contains the unicode value of the original character. For example,
- * typing Ctrl+M or Return both result in the character '\r' but the
- * keyCode field will also contain '\r' when Return was typed.
- *
- * @see SWT
- */
- public int keyCode;
-
- /**
- * depending on the event, the state of the keyboard modifier
- * keys and mouse masks at the time the event was generated.
- *
- * @see SWT
- */
- public int stateMask;
-
- /**
- * depending on the event, the range of text being modified.
- * Setting these fields has no effect.
- */
- public int start, end;
-
- /**
- * depending on the event, the new text that will be inserted.
- * Setting this field will change the text that is about to
- * be inserted or deleted.
- */
- public String text;
-
- /**
- * depending on the event, a flag indicating whether the operation
- * should be allowed. Setting this field to false will cancel the
- * operation.
- */
- public boolean doit = true;
-
- /**
- * a field for application use
- */
- public Object data;
-
-/**
-* Gets the bounds.
-* <p>
-* @return a rectangle that is the bounds.
-*/
-public Rectangle getBounds () {
- return new Rectangle (x, y, width, height);
-}
-
-/**
-* Sets the bounds.
-* <p>
-* @param x the new x position
-* @param y the new y position
-* @param width the new width
-* @param height the new height
-*/
-public void setBounds (Rectangle rect) {
- this.x = rect.x;
- this.y = rect.y;
- this.width = rect.width;
- this.height = rect.height;
-}
-
-/**
-* Returns a string representation of the object.
-*
-* @return a string representation of the object
-*/
-public String toString () {
- return "Event {type=" + type + ",widget=" + widget + ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "}";
-}
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.graphics.*; + +/** + * Instances of this class provide a description of a particular + * event which occurred within SWT. The SWT <em>untyped listener</em> + * API uses these instances for all event dispatching. + * <p> + * Note: For a given event, only the fields which are appropriate + * will be filled in. The contents of the fields which are not used + * by the event are unspecified. + * </p> + * + * @see Listener + * @see org.eclipse.swt.events.TypedEvent + */ + +public class Event { + + /** + * the display where the event occurred + * + * @since 2.0 + */ + public Display display; + + /** + * the widget that issued the event + */ + public Widget widget; + + /** + * the type of event, as defined by the event type constants + * in class <code>SWT</code> + * + * @see SWT + */ + public int type; + + /** + * the event specific detail field, as defined by the detail constants + * in class <code>SWT</code> + * + * @see SWT + */ + public int detail; + + /** + * the item that the event occurred in (can be null) + */ + public Widget item; + + /** + * the graphics context to use when painting + * that is configured to use the colors, font and + * damaged region of the control. It is valid + * only during the paint and must not be disposed + */ + public GC gc; + + /** + * depending on the event type, the x offset of the bounding + * rectangle of the region that requires painting or the + * widget-relative, x coordinate of the pointer at the + * time the mouse button was pressed or released + */ + public int x; + + /** + * depending on the event type, the y offset of the bounding + * rectangle of the region that requires painting or the + * widget-relative, y coordinate of the pointer at the + * time the mouse button was pressed or released + */ + public int y; + + /** + * the width of the bounding rectangle of the + * region that requires painting + */ + public int width; + + /** + * the height of the bounding rectangle of the + * region that requires painting + */ + public int height; + + /** + * the number of following paint events which + * are pending which may always be zero on + * some platforms + */ + public int count; + + /** + * the time that the event occurred. + * + * NOTE: This field is an unsigned integer and should + * be AND'ed with 0xFFFFFFFFL so that it can be treated + * as a signed long. + */ + public int time; + + /** + * the button that was pressed or released; 1 for the + * first button, 2 for the second button, and 3 for the + * third button, etc. + */ + public int button; + + /** + * depending on the event, the character represented by the key + * that was typed. This is the final character that results + * after all modifiers have been applied. For example, when the + * user types Ctrl+A, the character value is 0x01 (NUL). It is + * important that applications do not attempt to modify the character + * value based on a stateMask (such as SWT.CTRL) or the resulting + * character will not be correct. + */ + public char character; + + /** + * depending on the event, the key code of the key that was typed, + * as defined by the key code constants in class <code>SWT</code>. + * When the character field of the event is ambiguous, this field + * contains the unicode value of the original character. For example, + * typing Ctrl+M or Return both result in the character '\r' but the + * keyCode field will also contain '\r' when Return was typed. + * + * @see SWT + */ + public int keyCode; + + /** + * depending on the event, the state of the keyboard modifier + * keys and mouse masks at the time the event was generated. + * + * @see SWT + */ + public int stateMask; + + /** + * depending on the event, the range of text being modified. + * Setting these fields has no effect. + */ + public int start, end; + + /** + * depending on the event, the new text that will be inserted. + * Setting this field will change the text that is about to + * be inserted or deleted. + */ + public String text; + + /** + * depending on the event, a flag indicating whether the operation + * should be allowed. Setting this field to false will cancel the + * operation. + */ + public boolean doit = true; + + /** + * a field for application use + */ + public Object data; + +/** +* Gets the bounds. +* <p> +* @return a rectangle that is the bounds. +*/ +public Rectangle getBounds () { + return new Rectangle (x, y, width, height); +} + +/** +* Sets the bounds. +* <p> +* @param x the new x position +* @param y the new y position +* @param width the new width +* @param height the new height +*/ +public void setBounds (Rectangle rect) { + this.x = rect.x; + this.y = rect.y; + this.width = rect.width; + this.height = rect.height; +} + +/** +* Returns a string representation of the object. +* +* @return a string representation of the object +*/ +public String toString () { + return "Event {type=" + type + ",widget=" + widget + ",x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "}"; +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/EventTable.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/EventTable.java index 702ff474c5..712f718feb 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/EventTable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/EventTable.java @@ -1,130 +1,130 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-
-
-/**
- * Instances of this class implement a simple
- * look up mechanism that maps an event type
- * to a listener. Muliple listeners for the
- * same event type are supported.
- */
-
-class EventTable {
- int [] types;
- Listener [] listeners;
- int level;
-
-public void hook (int eventType, Listener listener) {
- if (types == null) types = new int [4];
- if (listeners == null) listeners = new Listener [4];
- int length = types.length, index = length - 1;
- while (index >= 0) {
- if (types [index] != 0) break;
- --index;
- }
- index++;
- if (index == length) {
- if (level == 0) {
- index = 0;
- for (int i=0; i<types.length; i++) {
- if (types [i] != 0) {
- types [index] = types [i];
- listeners [index] = listeners [i];
- index++;
- }
- }
- for (int i=index; i<types.length; i++) {
- types [i] = 0;
- listeners [i] = null;
- }
- }
- if (index == length) {
- int [] newTypes = new int [length + 4];
- System.arraycopy (types, 0, newTypes, 0, length);
- types = newTypes;
- Listener [] newListeners = new Listener [length + 4];
- System.arraycopy (listeners, 0, newListeners, 0, length);
- listeners = newListeners;
- }
- }
- types [index] = eventType;
- listeners [index] = listener;
-}
-
-public boolean hooks (int eventType) {
- if (types == null) return false;
- for (int i=0; i<types.length; i++) {
- if (types [i] == eventType) return true;
- }
- return false;
-}
-
-public void sendEvent (Event event) {
- if (types == null) return;
- level++;
- try {
- for (int i=0; i<types.length; i++) {
- if (types [i] == event.type) {
- Listener listener = listeners [i];
- if (listener != null) listener.handleEvent (event);
- }
- }
- } finally {
- --level;
- }
-}
-
-public int size () {
- if (types == null) return 0;
- int count = 0;
- for (int i=0; i<types.length; i++) {
- if (types [i] != 0) count++;
- }
- return count;
-}
-
-void remove (int index) {
- if (level == 0) {
- int end = types.length - 1;
- System.arraycopy (types, index + 1, types, index, end - index);
- System.arraycopy (listeners, index + 1, listeners, index, end - index);
- index = end;
- }
- types [index] = 0;
- listeners [index] = null;
-}
-
-public void unhook (int eventType, Listener listener) {
- if (types == null) return;
- for (int i=0; i<types.length; i++) {
- if (types [i] == eventType && listeners [i] == listener) {
- remove (i);
- return;
- }
- }
-}
-
-public void unhook (int eventType, SWTEventListener listener) {
- if (types == null) return;
- for (int i=0; i<types.length; i++) {
- if (types [i] == eventType) {
- if (listeners [i] instanceof TypedListener) {
- TypedListener typedListener = (TypedListener) listeners [i];
- if (typedListener.getEventListener () == listener) {
- remove (i);
- return;
- }
- }
- }
- }
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; + + +/** + * Instances of this class implement a simple + * look up mechanism that maps an event type + * to a listener. Muliple listeners for the + * same event type are supported. + */ + +class EventTable { + int [] types; + Listener [] listeners; + int level; + +public void hook (int eventType, Listener listener) { + if (types == null) types = new int [4]; + if (listeners == null) listeners = new Listener [4]; + int length = types.length, index = length - 1; + while (index >= 0) { + if (types [index] != 0) break; + --index; + } + index++; + if (index == length) { + if (level == 0) { + index = 0; + for (int i=0; i<types.length; i++) { + if (types [i] != 0) { + types [index] = types [i]; + listeners [index] = listeners [i]; + index++; + } + } + for (int i=index; i<types.length; i++) { + types [i] = 0; + listeners [i] = null; + } + } + if (index == length) { + int [] newTypes = new int [length + 4]; + System.arraycopy (types, 0, newTypes, 0, length); + types = newTypes; + Listener [] newListeners = new Listener [length + 4]; + System.arraycopy (listeners, 0, newListeners, 0, length); + listeners = newListeners; + } + } + types [index] = eventType; + listeners [index] = listener; +} + +public boolean hooks (int eventType) { + if (types == null) return false; + for (int i=0; i<types.length; i++) { + if (types [i] == eventType) return true; + } + return false; +} + +public void sendEvent (Event event) { + if (types == null) return; + level++; + try { + for (int i=0; i<types.length; i++) { + if (types [i] == event.type) { + Listener listener = listeners [i]; + if (listener != null) listener.handleEvent (event); + } + } + } finally { + --level; + } +} + +public int size () { + if (types == null) return 0; + int count = 0; + for (int i=0; i<types.length; i++) { + if (types [i] != 0) count++; + } + return count; +} + +void remove (int index) { + if (level == 0) { + int end = types.length - 1; + System.arraycopy (types, index + 1, types, index, end - index); + System.arraycopy (listeners, index + 1, listeners, index, end - index); + index = end; + } + types [index] = 0; + listeners [index] = null; +} + +public void unhook (int eventType, Listener listener) { + if (types == null) return; + for (int i=0; i<types.length; i++) { + if (types [i] == eventType && listeners [i] == listener) { + remove (i); + return; + } + } +} + +public void unhook (int eventType, SWTEventListener listener) { + if (types == null) return; + for (int i=0; i<types.length; i++) { + if (types [i] == eventType) { + if (listeners [i] instanceof TypedListener) { + TypedListener typedListener = (TypedListener) listeners [i]; + if (typedListener.getEventListener () == listener) { + remove (i); + return; + } + } + } + } +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java index 189440f0d9..8a561af97a 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Item.java @@ -1,177 +1,177 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.graphics.*;
-
-/**
- * This class is the abstract superclass of all non-windowed
- * user interface objects that occur within specific controls.
- * For example, a tree will contain tree items.
- * <dl>
- * <dt><b>Styles:</b></dt>
- * <dd>(none)</dd>
- * <dt><b>Events:</b></dt>
- * <dd>(none)</dd>
- * </dl>
- */
-
-public abstract class Item extends Widget {
- String text;
- Image image;
-
-/**
- * Constructs a new instance of this class given its parent
- * and a style value describing its behavior and appearance.
- * The item is added to the end of the items maintained by its parent.
- * <p>
- * The style value is either one of the style constants defined in
- * class <code>SWT</code> which is applicable to instances of this
- * class, or must be built by <em>bitwise OR</em>'ing together
- * (that is, using the <code>int</code> "|" operator) two or more
- * of those <code>SWT</code> style constants. The class description
- * lists the style constants that are applicable to the class.
- * Style bits are also inherited from superclasses.
- * </p>
- *
- * @param parent a widget which will be the parent of the new instance (cannot be null)
- * @param style the style of item to construct
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
- * </ul>
- *
- * @see SWT
- * @see #getStyle
- */
-public Item (Widget parent, int style) {
- super (parent, style);
- text = "";
-}
-
-/**
- * Constructs a new instance of this class given its parent
- * and a style value describing its behavior and appearance,
- * and the index at which to place it in the items maintained
- * by its parent.
- * <p>
- * The style value is either one of the style constants defined in
- * class <code>SWT</code> which is applicable to instances of this
- * class, or must be built by <em>bitwise OR</em>'ing together
- * (that is, using the <code>int</code> "|" operator) two or more
- * of those <code>SWT</code> style constants. The class description
- * lists the style constants that are applicable to the class.
- * Style bits are also inherited from superclasses.
- * </p>
- *
- * @param parent a widget which will be the parent of the new instance (cannot be null)
- * @param style the style of item to construct
- * @param index the index at which to store the receiver in its parent
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
- * </ul>
- *
- * @see SWT
- * @see #getStyle
- */
-public Item (Widget parent, int style, int index) {
- this (parent, style);
-}
-
-protected void checkSubclass () {
- /* Do Nothing - Subclassing is allowed */
-}
-
-/**
- * Returns the receiver's image if it has one, or null
- * if it does not.
- *
- * @return the receiver's image
- *
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public Image getImage () {
- checkWidget ();
- return image;
-}
-
-String getNameText () {
- return getText ();
-}
-
-/**
- * Returns the receiver's text, which will be an empty
- * string if it has never been set.
- *
- * @return the receiver's text
- *
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public String getText () {
- checkWidget();
- return text;
-}
-
-void releaseWidget () {
- super.releaseWidget ();
- text = null;
- image = null;
-}
-/**
- * Sets the receiver's image to the argument, which may be
- * null indicating that no image should be displayed.
- *
- * @param image the image to display on the receiver (may be null)
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public void setImage (Image image) {
- checkWidget ();
- if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
- this.image = image;
-}
-
-/**
- * Sets the receiver's text.
- *
- * @param string the new text
- *
- * @exception IllegalArgumentException <ul>
- * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
- * </ul>
- * @exception SWTException <ul>
- * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
- * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
- * </ul>
- */
-public void setText (String string) {
- checkWidget ();
- text = string;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; + +/** + * This class is the abstract superclass of all non-windowed + * user interface objects that occur within specific controls. + * For example, a tree will contain tree items. + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>(none)</dd> + * <dt><b>Events:</b></dt> + * <dd>(none)</dd> + * </dl> + */ + +public abstract class Item extends Widget { + String text; + Image image; + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * The item is added to the end of the items maintained by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style the style of item to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see #getStyle + */ +public Item (Widget parent, int style) { + super (parent, style); + text = ""; +} + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance, + * and the index at which to place it in the items maintained + * by its parent. + * <p> + * The style value is either one of the style constants defined in + * class <code>SWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>SWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a widget which will be the parent of the new instance (cannot be null) + * @param style the style of item to construct + * @param index the index at which to store the receiver in its parent + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * </ul> + * + * @see SWT + * @see #getStyle + */ +public Item (Widget parent, int style, int index) { + this (parent, style); +} + +protected void checkSubclass () { + /* Do Nothing - Subclassing is allowed */ +} + +/** + * Returns the receiver's image if it has one, or null + * if it does not. + * + * @return the receiver's image + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public Image getImage () { + checkWidget (); + return image; +} + +String getNameText () { + return getText (); +} + +/** + * Returns the receiver's text, which will be an empty + * string if it has never been set. + * + * @return the receiver's text + * + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public String getText () { + checkWidget(); + return text; +} + +void releaseWidget () { + super.releaseWidget (); + text = null; + image = null; +} +/** + * Sets the receiver's image to the argument, which may be + * null indicating that no image should be displayed. + * + * @param image the image to display on the receiver (may be null) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public void setImage (Image image) { + checkWidget (); + if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT); + this.image = image; +} + +/** + * Sets the receiver's text. + * + * @param string the new text + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the text is null</li> + * </ul> + * @exception SWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + */ +public void setText (String string) { + checkWidget (); + text = string; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Layout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Layout.java index af6450636e..93e0fb0afa 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Layout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Layout.java @@ -1,83 +1,83 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.graphics.*;
-
-/**
- * A layout controls the position and size
- * of the children of a composite widget.
- * This class is the abstract base class for
- * layouts.
- */
-public abstract class Layout {
-
-/**
- * Computes and returns the size of the specified
- * composite's client area according to this layout.
- * <p>
- * This method computes the minimum size that the
- * client area of the composite must be in order to
- * position all children at their minimum size inside
- * the composite according to the layout algorithm
- * encoded by this layout.
- * </p>
- * <p>
- * When a width or height hint is supplied, it is
- * used to constrain the result. For example, if a
- * width hint is provided that is less than the minimum
- * width of the client area, the layout may choose
- * to wrap and increase height, clip, overlap, or
- * otherwise constrain the children.
- * </p>
- *
- * @param composite a composite widget using this layout
- * @param wHint width (<code>SWT.DEFAULT</code> for minimum)
- * @param hHint height (<code>SWT.DEFAULT</code> for minimum)
- * @param flushCache <code>true</code> means flush cached layout values
- * @return a point containing the computed size (width, height)
- *
- * @see #layout
- * @see Control#getBorderWidth
- * @see Control#getBounds
- * @see Control#getSize
- * @see Control#pack
- * @see "computeTrim, getClientArea for controls that implement them"
- */
-protected abstract Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache);
-
-/**
- * Lays out the children of the specified composite
- * according to this layout.
- * <p>
- * This method positions and sizes the children of a
- * composite using the layout algorithm encoded by this
- * layout. Children of the composite are positioned in
- * the client area of the composite. The position of
- * the composite is not altered by this method.
- * </p>
- * <p>
- * When the flush cache hint is true, the layout is
- * instructed to flush any cached values associated
- * with the children. Typically, a layout will cache
- * the preferred sizes of the children to avoid the
- * expense of computing these values each time the
- * widget is layed out.
- * </p>
- * <p>
- * When layout is triggered explicitly by the programmer
- * the flush cache hint is true. When layout is triggered
- * by a resize, either caused by the programmer or by the
- * user, the hint is false.
- * </p>
- *
- * @param composite a composite widget using this layout
- * @param flushCache <code>true</code> means flush cached layout values
- */
-protected abstract void layout (Composite composite, boolean flushCache);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.graphics.*; + +/** + * A layout controls the position and size + * of the children of a composite widget. + * This class is the abstract base class for + * layouts. + */ +public abstract class Layout { + +/** + * Computes and returns the size of the specified + * composite's client area according to this layout. + * <p> + * This method computes the minimum size that the + * client area of the composite must be in order to + * position all children at their minimum size inside + * the composite according to the layout algorithm + * encoded by this layout. + * </p> + * <p> + * When a width or height hint is supplied, it is + * used to constrain the result. For example, if a + * width hint is provided that is less than the minimum + * width of the client area, the layout may choose + * to wrap and increase height, clip, overlap, or + * otherwise constrain the children. + * </p> + * + * @param composite a composite widget using this layout + * @param wHint width (<code>SWT.DEFAULT</code> for minimum) + * @param hHint height (<code>SWT.DEFAULT</code> for minimum) + * @param flushCache <code>true</code> means flush cached layout values + * @return a point containing the computed size (width, height) + * + * @see #layout + * @see Control#getBorderWidth + * @see Control#getBounds + * @see Control#getSize + * @see Control#pack + * @see "computeTrim, getClientArea for controls that implement them" + */ +protected abstract Point computeSize (Composite composite, int wHint, int hHint, boolean flushCache); + +/** + * Lays out the children of the specified composite + * according to this layout. + * <p> + * This method positions and sizes the children of a + * composite using the layout algorithm encoded by this + * layout. Children of the composite are positioned in + * the client area of the composite. The position of + * the composite is not altered by this method. + * </p> + * <p> + * When the flush cache hint is true, the layout is + * instructed to flush any cached values associated + * with the children. Typically, a layout will cache + * the preferred sizes of the children to avoid the + * expense of computing these values each time the + * widget is layed out. + * </p> + * <p> + * When layout is triggered explicitly by the programmer + * the flush cache hint is true. When layout is triggered + * by a resize, either caused by the programmer or by the + * user, the hint is false. + * </p> + * + * @param composite a composite widget using this layout + * @param flushCache <code>true</code> means flush cached layout values + */ +protected abstract void layout (Composite composite, boolean flushCache); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Listener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Listener.java index df23674df5..624dc129cc 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Listener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Listener.java @@ -1,47 +1,47 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * <code>Listener</code>s implement a simple <code>handleEvent(...)</code>
- * method that is used internally by SWT to dispatch events.
- * <p>
- * After creating an instance of a class that implements this interface
- * it can be added to a widget using the
- * <code>addListener(int eventType, Listener handler)</code> method and
- * removed using the
- * <code>removeListener (int eventType, Listener handler)</code> method.
- * When the specified event occurs, <code>handleEvent(...)</code> will
- * will be sent to the instance.
- * </p>
- * <p>
- * Classes which implement this interface are described within SWT as
- * providing the <em>untyped listener</em> API. Typically, widgets will
- * also provide a higher-level <em>typed listener</em> API, that is based
- * on the standard <code>java.util.EventListener</code> pattern.
- * </p>
- * <p>
- * Note that, since all internal SWT event dispatching is based on untyped
- * listeners, it is simple to build subsets of SWT for use on memory
- * constrained, small footprint devices, by removing the classes and
- * methods which implement the typed listener API.
- * </p>
- *
- * @see Widget#addListener
- * @see java.util.EventListener
- * @see org.eclipse.swt.events
- */
-public interface Listener {
-
-/**
- * Sent when an event that the receiver has registered for occurs.
- *
- * @param event the event which occurred
- */
-void handleEvent (Event event);
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * <code>Listener</code>s implement a simple <code>handleEvent(...)</code> + * method that is used internally by SWT to dispatch events. + * <p> + * After creating an instance of a class that implements this interface + * it can be added to a widget using the + * <code>addListener(int eventType, Listener handler)</code> method and + * removed using the + * <code>removeListener (int eventType, Listener handler)</code> method. + * When the specified event occurs, <code>handleEvent(...)</code> will + * will be sent to the instance. + * </p> + * <p> + * Classes which implement this interface are described within SWT as + * providing the <em>untyped listener</em> API. Typically, widgets will + * also provide a higher-level <em>typed listener</em> API, that is based + * on the standard <code>java.util.EventListener</code> pattern. + * </p> + * <p> + * Note that, since all internal SWT event dispatching is based on untyped + * listeners, it is simple to build subsets of SWT for use on memory + * constrained, small footprint devices, by removing the classes and + * methods which implement the typed listener API. + * </p> + * + * @see Widget#addListener + * @see java.util.EventListener + * @see org.eclipse.swt.events + */ +public interface Listener { + +/** + * Sent when an event that the receiver has registered for occurs. + * + * @param event the event which occurred + */ +void handleEvent (Event event); +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/RunnableLock.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/RunnableLock.java index ae9ea81a26..543c44dc00 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/RunnableLock.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/RunnableLock.java @@ -1,35 +1,35 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-/**
- * Instances of this class are used to ensure that an
- * application cannot interfere with the locking mechanism
- * used to implement asynchonous and synchronous communication
- * between widgets and background threads.
- */
-
-class RunnableLock {
- Runnable runnable;
- Thread thread;
- Throwable throwable;
-
-RunnableLock (Runnable runnable) {
- this.runnable = runnable;
-}
-
-boolean done () {
- return runnable == null || throwable != null;
-}
-
-void run () {
- if (runnable != null) runnable.run ();
- runnable = null;
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +/** + * Instances of this class are used to ensure that an + * application cannot interfere with the locking mechanism + * used to implement asynchonous and synchronous communication + * between widgets and background threads. + */ + +class RunnableLock { + Runnable runnable; + Thread thread; + Throwable throwable; + +RunnableLock (Runnable runnable) { + this.runnable = runnable; +} + +boolean done () { + return runnable == null || throwable != null; +} + +void run () { + if (runnable != null) runnable.run (); + runnable = null; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Synchronizer.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Synchronizer.java index f3565259e6..11e30e40aa 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Synchronizer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/Synchronizer.java @@ -1,155 +1,155 @@ -package org.eclipse.swt.widgets;
-
-/*
- * Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
- * This file is made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.internal.Compatibility;
-
-/**
- * Instances of this class provide synchronization support
- * for displays. A default instance is created automatically
- * for each display, and this instance is sufficient for almost
- * all applications.
- * <p>
- * <b>IMPORTANT:</b> Typical application code <em>never</em>
- * needs to deal with this class. It is provided only to
- * allow applications which require non-standard
- * synchronization behavior to plug in the support they
- * require. <em>Subclasses which override the methods in
- * this class must ensure that the superclass methods are
- * invoked in their implementations</em>
- * </p>
- *
- * @see Display#setSynchronizer
- */
-public class Synchronizer {
- Display display;
- int messageCount;
- RunnableLock [] messages;
- Object messageLock = new Object ();
- Thread syncThread;
-
-public Synchronizer (Display display) {
- this.display = display;
-}
-
-void addLast (RunnableLock lock) {
- synchronized (messageLock) {
- if (messages == null) messages = new RunnableLock [4];
- if (messageCount == messages.length) {
- RunnableLock[] newMessages = new RunnableLock [messageCount + 4];
- System.arraycopy (messages, 0, newMessages, 0, messageCount);
- messages = newMessages;
- }
- messages [messageCount++] = lock;
- }
-}
-
-/**
- * Causes the <code>run()</code> method of the runnable to
- * be invoked by the user-interface thread at the next
- * reasonable opportunity. The caller of this method continues
- * to run in parallel, and is not notified when the
- * runnable has completed.
- *
- * @param runnable code to run on the user-interface thread.
- *
- * @see #syncExec
- */
-protected void asyncExec (Runnable runnable) {
- if (runnable != null) addLast (new RunnableLock (runnable));
- display.wake ();
-}
-
-void releaseSynchronizer () {
- display = null;
- messages = null;
- messageLock = null;
- syncThread = null;
-}
-
-RunnableLock removeFirst () {
- synchronized (messageLock) {
- if (messageCount == 0) return null;
- RunnableLock lock = messages [0];
- System.arraycopy (messages, 1, messages, 0, --messageCount);
- messages [messageCount] = null;
- if (messageCount == 0) messages = null;
- return lock;
- }
-}
-
-boolean runAsyncMessages () {
- if (messageCount == 0) return false;
- RunnableLock lock = removeFirst ();
- if (lock == null) return true;
- synchronized (lock) {
- syncThread = lock.thread;
- try {
- lock.run ();
- } catch (Throwable t) {
- lock.throwable = t;
- SWT.error (SWT.ERROR_FAILED_EXEC, t);
- } finally {
- syncThread = null;
- lock.notifyAll ();
- }
- }
- return true;
-}
-
-
-/**
- * Causes the <code>run()</code> method of the runnable to
- * be invoked by the user-interface thread at the next
- * reasonable opportunity. The thread which calls this method
- * is suspended until the runnable completes.
- *
- * @param runnable code to run on the user-interface thread.
- *
- * @exception SWTException <ul>
- * <li>ERROR_FAILED_EXEC - if an exception occured when executing the runnable</li>
- * </ul>
- *
- * @see #asyncExec
- */
-protected void syncExec (Runnable runnable) {
- if (display.isValidThread ()) {
- if (runnable != null) runnable.run ();
- return;
- }
- if (runnable == null) {
- display.wake ();
- return;
- }
- RunnableLock lock = new RunnableLock (runnable);
- /*
- * Only remember the syncThread for syncExec.
- */
- lock.thread = Thread.currentThread();
- synchronized (lock) {
- addLast (lock);
- display.wake ();
- boolean interrupted = false;
- while (!lock.done ()) {
- try {
- lock.wait ();
- } catch (InterruptedException e) {
- interrupted = true;
- }
- }
- if (interrupted) {
- Compatibility.interrupt();
- }
- if (lock.throwable != null) {
- SWT.error (SWT.ERROR_FAILED_EXEC, lock.throwable);
- }
- }
-}
-
-}
+package org.eclipse.swt.widgets; + +/* + * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. + * This file is made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.*; +import org.eclipse.swt.internal.Compatibility; + +/** + * Instances of this class provide synchronization support + * for displays. A default instance is created automatically + * for each display, and this instance is sufficient for almost + * all applications. + * <p> + * <b>IMPORTANT:</b> Typical application code <em>never</em> + * needs to deal with this class. It is provided only to + * allow applications which require non-standard + * synchronization behavior to plug in the support they + * require. <em>Subclasses which override the methods in + * this class must ensure that the superclass methods are + * invoked in their implementations</em> + * </p> + * + * @see Display#setSynchronizer + */ +public class Synchronizer { + Display display; + int messageCount; + RunnableLock [] messages; + Object messageLock = new Object (); + Thread syncThread; + +public Synchronizer (Display display) { + this.display = display; +} + +void addLast (RunnableLock lock) { + synchronized (messageLock) { + if (messages == null) messages = new RunnableLock [4]; + if (messageCount == messages.length) { + RunnableLock[] newMessages = new RunnableLock [messageCount + 4]; + System.arraycopy (messages, 0, newMessages, 0, messageCount); + messages = newMessages; + } + messages [messageCount++] = lock; + } +} + +/** + * Causes the <code>run()</code> method of the runnable to + * be invoked by the user-interface thread at the next + * reasonable opportunity. The caller of this method continues + * to run in parallel, and is not notified when the + * runnable has completed. + * + * @param runnable code to run on the user-interface thread. + * + * @see #syncExec + */ +protected void asyncExec (Runnable runnable) { + if (runnable != null) addLast (new RunnableLock (runnable)); + display.wake (); +} + +void releaseSynchronizer () { + display = null; + messages = null; + messageLock = null; + syncThread = null; +} + +RunnableLock removeFirst () { + synchronized (messageLock) { + if (messageCount == 0) return null; + RunnableLock lock = messages [0]; + System.arraycopy (messages, 1, messages, 0, --messageCount); + messages [messageCount] = null; + if (messageCount == 0) messages = null; + return lock; + } +} + +boolean runAsyncMessages () { + if (messageCount == 0) return false; + RunnableLock lock = removeFirst (); + if (lock == null) return true; + synchronized (lock) { + syncThread = lock.thread; + try { + lock.run (); + } catch (Throwable t) { + lock.throwable = t; + SWT.error (SWT.ERROR_FAILED_EXEC, t); + } finally { + syncThread = null; + lock.notifyAll (); + } + } + return true; +} + + +/** + * Causes the <code>run()</code> method of the runnable to + * be invoked by the user-interface thread at the next + * reasonable opportunity. The thread which calls this method + * is suspended until the runnable completes. + * + * @param runnable code to run on the user-interface thread. + * + * @exception SWTException <ul> + * <li>ERROR_FAILED_EXEC - if an exception occured when executing the runnable</li> + * </ul> + * + * @see #asyncExec + */ +protected void syncExec (Runnable runnable) { + if (display.isValidThread ()) { + if (runnable != null) runnable.run (); + return; + } + if (runnable == null) { + display.wake (); + return; + } + RunnableLock lock = new RunnableLock (runnable); + /* + * Only remember the syncThread for syncExec. + */ + lock.thread = Thread.currentThread(); + synchronized (lock) { + addLast (lock); + display.wake (); + boolean interrupted = false; + while (!lock.done ()) { + try { + lock.wait (); + } catch (InterruptedException e) { + interrupted = true; + } + } + if (interrupted) { + Compatibility.interrupt(); + } + if (lock.throwable != null) { + SWT.error (SWT.ERROR_FAILED_EXEC, lock.throwable); + } + } +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java index bc053d803e..2484e3124c 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java @@ -1,224 +1,224 @@ -package org.eclipse.swt.widgets;
-
-/*
+package org.eclipse.swt.widgets; + +/* * Copyright (c) 2000, 2002 IBM Corp. All rights reserved. * This file is made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import org.eclipse.swt.internal.SWTEventListener;
-import org.eclipse.swt.*;
-import org.eclipse.swt.events.*;
-
-/**
- * Instances of this class are <em>internal SWT implementation</em>
- * objects which provide a mapping between the typed and untyped
- * listener mechanisms that SWT supports.
- * <p>
- * <b>IMPORTANT:</b> This class is <em>not</em> part of the SWT
- * public API. It is marked public only so that it can be shared
- * within the packages provided by SWT. It should never be
- * referenced from application code.
- * </p>
- *
- * @see Listener
- *
- * @private
- */
-public class TypedListener implements Listener {
-
- /**
- * The receiver's event listener
- */
- protected SWTEventListener eventListener;
-
-/**
- * Constructs a new instance of this class for the given event listener.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
- * public API. It is marked public only so that it can be shared
- * within the packages provided by SWT. It should never be
- * referenced from application code.
- * </p>
- *
- * @param listener the event listener to store in the receiver
- */
-public TypedListener (SWTEventListener listener) {
- eventListener = listener;
-}
-
-/**
- * Returns the receiver's event listener.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
- * public API. It is marked public only so that it can be shared
- * within the packages provided by SWT. It should never be
- * referenced from application code.
- * </p>
- *
- * @return the receiver's event listener
- */
-public SWTEventListener getEventListener () {
- return eventListener;
-}
-
-/**
- * Handles the given event.
- * <p>
- * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
- * public API. It is marked public only so that it can be shared
- * within the packages provided by SWT. It should never be
- * referenced from application code.
- * </p>
- */
-public void handleEvent (Event e) {
- switch (e.type) {
- case SWT.Paint: {
- /* Field set by Control */
- PaintEvent event = new PaintEvent (e);
- ((PaintListener) eventListener).paintControl (event);
- e.gc = event.gc;
- break;
- }
- case SWT.Selection: {
- /* Fields set by Sash */
- SelectionEvent event = new SelectionEvent (e);
- ((SelectionListener) eventListener).widgetSelected (event);
- e.x = event.x;
- e.y = event.y;
- e.doit = event.doit;
- break;
- }
- case SWT.DefaultSelection: {
- ((SelectionListener)eventListener).widgetDefaultSelected(new SelectionEvent(e));
- break;
- }
- case SWT.Dispose: {
- ((DisposeListener) eventListener).widgetDisposed(new DisposeEvent(e));
- break;
- }
- case SWT.FocusIn: {
- ((FocusListener) eventListener).focusGained(new FocusEvent(e));
- break;
- }
- case SWT.FocusOut: {
- ((FocusListener) eventListener).focusLost(new FocusEvent(e));
- break;
- }
- case SWT.Hide: {
- ((MenuListener) eventListener).menuHidden(new MenuEvent(e));
- break;
- }
- case SWT.Show: {
- ((MenuListener) eventListener).menuShown(new MenuEvent(e));
- break;
- }
- case SWT.KeyDown: {
- ((KeyListener) eventListener).keyPressed(new KeyEvent(e));
- break;
- }
- case SWT.KeyUp: {
- ((KeyListener) eventListener).keyReleased(new KeyEvent(e));
- break;
- }
- case SWT.MouseDown: {
- ((MouseListener) eventListener).mouseDown(new MouseEvent(e));
- break;
- }
- case SWT.MouseUp: {
- ((MouseListener) eventListener).mouseUp(new MouseEvent(e));
- break;
- }
- case SWT.MouseDoubleClick: {
- ((MouseListener) eventListener).mouseDoubleClick(new MouseEvent(e));
- break;
- }
- case SWT.MouseMove: {
- ((MouseMoveListener) eventListener).mouseMove(new MouseEvent(e));
- return;
- }
- case SWT.Resize: {
- ((ControlListener) eventListener).controlResized(new ControlEvent(e));
- break;
- }
- case SWT.Move: {
- ((ControlListener) eventListener).controlMoved(new ControlEvent(e));
- break;
- }
- case SWT.Close: {
- /* Fields set by Decorations */
- ShellEvent event = new ShellEvent (e);
- ((ShellListener) eventListener).shellClosed(event);
- e.doit = event.doit;
- break;
- }
- case SWT.Activate: {
- ((ShellListener) eventListener).shellActivated(new ShellEvent(e));
- break;
- }
- case SWT.Deactivate: {
- ((ShellListener) eventListener).shellDeactivated(new ShellEvent(e));
- break;
- }
- case SWT.Iconify: {
- ((ShellListener) eventListener).shellIconified(new ShellEvent(e));
- break;
- }
- case SWT.Deiconify: {
- ((ShellListener) eventListener).shellDeiconified(new ShellEvent(e));
- break;
- }
- case SWT.Expand: {
- ((TreeListener) eventListener).treeExpanded(new TreeEvent(e));
- break;
- }
- case SWT.Collapse: {
- ((TreeListener) eventListener).treeCollapsed(new TreeEvent(e));
- break;
- }
- case SWT.Modify: {
- ((ModifyListener) eventListener).modifyText(new ModifyEvent(e));
- break;
- }
- case SWT.Verify: {
- /* Fields set by Text, RichText */
- VerifyEvent event = new VerifyEvent (e);
- ((VerifyListener) eventListener).verifyText (event);
- e.text = event.text;
- e.doit = event.doit;
- break;
- }
- case SWT.Help: {
- ((HelpListener) eventListener).helpRequested (new HelpEvent (e));
- break;
- }
- case SWT.Arm: {
- ((ArmListener) eventListener).widgetArmed (new ArmEvent (e));
- break;
- }
- case SWT.MouseExit: {
- ((MouseTrackListener) eventListener).mouseExit (new MouseEvent (e));
- break;
- }
- case SWT.MouseEnter: {
- ((MouseTrackListener) eventListener).mouseEnter (new MouseEvent (e));
- break;
- }
- case SWT.MouseHover: {
- ((MouseTrackListener) eventListener).mouseHover (new MouseEvent (e));
- break;
- }
- case SWT.Traverse: {
- /* Fields set by Control */
- TraverseEvent event = new TraverseEvent (e);
- ((TraverseListener) eventListener).keyTraversed (event);
- e.detail = event.detail;
- e.doit = event.doit;
- break;
- }
-
- }
-}
-
-}
+ * http://www.eclipse.org/legal/cpl-v10.html + */ + +import org.eclipse.swt.internal.SWTEventListener; +import org.eclipse.swt.*; +import org.eclipse.swt.events.*; + +/** + * Instances of this class are <em>internal SWT implementation</em> + * objects which provide a mapping between the typed and untyped + * listener mechanisms that SWT supports. + * <p> + * <b>IMPORTANT:</b> This class is <em>not</em> part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It should never be + * referenced from application code. + * </p> + * + * @see Listener + * + * @private + */ +public class TypedListener implements Listener { + + /** + * The receiver's event listener + */ + protected SWTEventListener eventListener; + +/** + * Constructs a new instance of this class for the given event listener. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It should never be + * referenced from application code. + * </p> + * + * @param listener the event listener to store in the receiver + */ +public TypedListener (SWTEventListener listener) { + eventListener = listener; +} + +/** + * Returns the receiver's event listener. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It should never be + * referenced from application code. + * </p> + * + * @return the receiver's event listener + */ +public SWTEventListener getEventListener () { + return eventListener; +} + +/** + * Handles the given event. + * <p> + * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT + * public API. It is marked public only so that it can be shared + * within the packages provided by SWT. It should never be + * referenced from application code. + * </p> + */ +public void handleEvent (Event e) { + switch (e.type) { + case SWT.Paint: { + /* Field set by Control */ + PaintEvent event = new PaintEvent (e); + ((PaintListener) eventListener).paintControl (event); + e.gc = event.gc; + break; + } + case SWT.Selection: { + /* Fields set by Sash */ + SelectionEvent event = new SelectionEvent (e); + ((SelectionListener) eventListener).widgetSelected (event); + e.x = event.x; + e.y = event.y; + e.doit = event.doit; + break; + } + case SWT.DefaultSelection: { + ((SelectionListener)eventListener).widgetDefaultSelected(new SelectionEvent(e)); + break; + } + case SWT.Dispose: { + ((DisposeListener) eventListener).widgetDisposed(new DisposeEvent(e)); + break; + } + case SWT.FocusIn: { + ((FocusListener) eventListener).focusGained(new FocusEvent(e)); + break; + } + case SWT.FocusOut: { + ((FocusListener) eventListener).focusLost(new FocusEvent(e)); + break; + } + case SWT.Hide: { + ((MenuListener) eventListener).menuHidden(new MenuEvent(e)); + break; + } + case SWT.Show: { + ((MenuListener) eventListener).menuShown(new MenuEvent(e)); + break; + } + case SWT.KeyDown: { + ((KeyListener) eventListener).keyPressed(new KeyEvent(e)); + break; + } + case SWT.KeyUp: { + ((KeyListener) eventListener).keyReleased(new KeyEvent(e)); + break; + } + case SWT.MouseDown: { + ((MouseListener) eventListener).mouseDown(new MouseEvent(e)); + break; + } + case SWT.MouseUp: { + ((MouseListener) eventListener).mouseUp(new MouseEvent(e)); + break; + } + case SWT.MouseDoubleClick: { + ((MouseListener) eventListener).mouseDoubleClick(new MouseEvent(e)); + break; + } + case SWT.MouseMove: { + ((MouseMoveListener) eventListener).mouseMove(new MouseEvent(e)); + return; + } + case SWT.Resize: { + ((ControlListener) eventListener).controlResized(new ControlEvent(e)); + break; + } + case SWT.Move: { + ((ControlListener) eventListener).controlMoved(new ControlEvent(e)); + break; + } + case SWT.Close: { + /* Fields set by Decorations */ + ShellEvent event = new ShellEvent (e); + ((ShellListener) eventListener).shellClosed(event); + e.doit = event.doit; + break; + } + case SWT.Activate: { + ((ShellListener) eventListener).shellActivated(new ShellEvent(e)); + break; + } + case SWT.Deactivate: { + ((ShellListener) eventListener).shellDeactivated(new ShellEvent(e)); + break; + } + case SWT.Iconify: { + ((ShellListener) eventListener).shellIconified(new ShellEvent(e)); + break; + } + case SWT.Deiconify: { + ((ShellListener) eventListener).shellDeiconified(new ShellEvent(e)); + break; + } + case SWT.Expand: { + ((TreeListener) eventListener).treeExpanded(new TreeEvent(e)); + break; + } + case SWT.Collapse: { + ((TreeListener) eventListener).treeCollapsed(new TreeEvent(e)); + break; + } + case SWT.Modify: { + ((ModifyListener) eventListener).modifyText(new ModifyEvent(e)); + break; + } + case SWT.Verify: { + /* Fields set by Text, RichText */ + VerifyEvent event = new VerifyEvent (e); + ((VerifyListener) eventListener).verifyText (event); + e.text = event.text; + e.doit = event.doit; + break; + } + case SWT.Help: { + ((HelpListener) eventListener).helpRequested (new HelpEvent (e)); + break; + } + case SWT.Arm: { + ((ArmListener) eventListener).widgetArmed (new ArmEvent (e)); + break; + } + case SWT.MouseExit: { + ((MouseTrackListener) eventListener).mouseExit (new MouseEvent (e)); + break; + } + case SWT.MouseEnter: { + ((MouseTrackListener) eventListener).mouseEnter (new MouseEvent (e)); + break; + } + case SWT.MouseHover: { + ((MouseTrackListener) eventListener).mouseHover (new MouseEvent (e)); + break; + } + case SWT.Traverse: { + /* Fields set by Control */ + TraverseEvent event = new TraverseEvent (e); + ((TraverseListener) eventListener).keyTraversed (event); + e.detail = event.detail; + e.doit = event.doit; + break; + } + + } +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt b/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt index 9f8d3cf97e..ad7435eb54 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt @@ -1 +1 @@ -version 2.131
+version 2.131 |