0001: /*
0002: *
0003: *
0004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: */
0026:
0027: package javax.microedition.lcdui;
0028:
0029: /**
0030: * Provides simple 2D geometric rendering capability.
0031: *
0032: * <p>Drawing primitives are provided for text, images, lines, rectangles,
0033: * and arcs. Rectangles and arcs may also be filled with a solid color.
0034: * Rectangles may also be specified with rounded corners. </p>
0035: *
0036: * <p>A <code>24</code>-bit color model is provided, with
0037: * <code>8</code> bits for each of red, green, and
0038: * blue components of a color. Not all devices support a full
0039: * <code>24</code> bits' worth
0040: * of color and thus they will map colors requested by the application into
0041: * colors available on the device. Facilities are provided in the
0042: * {@link
0043: * Display Display} class for obtaining device characteristics, such
0044: * as
0045: * whether color is available and how many distinct gray levels are
0046: * available.
0047: * Applications may also use {@link Graphics#getDisplayColor(int)
0048: * getDisplayColor()} to obtain the actual color that would be displayed
0049: * for a requested color.
0050: * This enables applications to adapt their behavior to a device without
0051: * compromising device independence. </p>
0052: *
0053: * <p>For all rendering operations, source pixels are always combined with
0054: * destination pixels using the <em>Source Over Destination</em> rule
0055: * [Porter-Duff]. Other schemes for combining source pixels with destination
0056: * pixels, such as raster-ops, are not provided.</p>
0057: *
0058: * <p>For the text, line, rectangle, and arc drawing and filling primitives,
0059: * the source pixel is a pixel representing the current color of the graphics
0060: * object being used for rendering. This pixel is always considered to be
0061: * fully opaque. With source pixel that is always fully opaque, the Source
0062: * Over Destination rule has the effect of pixel replacement, where
0063: * destination pixels are simply replaced with the source pixel from the
0064: * graphics object.</p>
0065: *
0066: * <p>The {@link #drawImage drawImage()} and {@link #drawRegion drawRegion()}
0067: * methods use an image as the source for rendering operations instead of the
0068: * current color of the graphics object. In this context, the Source Over
0069: * Destination rule has the following properties: a fully opaque pixel in the
0070: * source must replace the destination pixel, a fully transparent pixel in the
0071: * source must leave the destination pixel unchanged, and a semitransparent
0072: * pixel in the source must be alpha blended with the destination pixel.
0073: * Alpha blending of semitransparent pixels is required. If an implementation
0074: * does not support alpha blending, it must remove all semitransparency from
0075: * image source data at the time the image is created. See <a
0076: * href="Image.html#alpha">Alpha Processing</a> for further discussion.
0077: *
0078: * <p>The destinations of all graphics rendering are considered to consist
0079: * entirely of fully opaque pixels. A property of the Source Over Destination
0080: * rule is that compositing any pixel with a fully opaque destination pixel
0081: * always results in a fully opaque destination pixel. This has the effect of
0082: * confining full and partial transparency to immutable images, which may only
0083: * be used as the source for rendering operations.</p>
0084: *
0085: * <p>
0086: * Graphics may be rendered directly to the display or to an off-screen
0087: * image buffer. The destination of rendered graphics depends on the
0088: * provenance of the graphics object. A graphics object for rendering
0089: * to the display is passed to the <code>Canvas</code> object's
0090: * {@link Canvas#paint(Graphics) paint()}
0091: * method. This is the only means by which a graphics object may
0092: * be obtained whose destination is the display. Furthermore, applications
0093: * may draw using this graphics object only for the duration of the
0094: * <code>paint()</code> method. </p>
0095: * <p>
0096: * A graphics object for rendering to an off-screen image buffer may
0097: * be obtained by calling the
0098: * {@link Image#getGraphics() getGraphics()}
0099: * method on the desired image.
0100: * A graphics object so obtained may be held indefinitely
0101: * by the application, and requests may be issued on this graphics
0102: * object at any time. </p>
0103: *<p>
0104: * The default coordinate system's origin is at the
0105: * upper left-hand corner of the destination. The X-axis direction is
0106: * positive towards the right, and the Y-axis direction is positive
0107: * downwards. Applications may assume that horizontal and vertical
0108: * distances in the coordinate system represent equal distances on the
0109: * actual device display, that is, pixels are square. A facility is provided
0110: * for translating the origin of the coordinate system.
0111: * All coordinates are specified as integers. </p>
0112: * <p>
0113: * The coordinate system represents locations between pixels, not the
0114: * pixels themselves. Therefore, the first pixel in the upper left corner
0115: * of the display lies in the square bounded by coordinates
0116: * <code>(0,0) , (1,0) , (0,1) , (1,1)</code>. </p>
0117: * <p>
0118: * Under this definition, the semantics for fill operations are clear.
0119: * Since coordinate grid lines lie between pixels, fill operations
0120: * affect pixels that lie entirely within the region bounded by the
0121: * coordinates of the operation. For example, the operation </P>
0122: * <TABLE BORDER="2">
0123: * <TR>
0124: * <TD ROWSPAN="1" COLSPAN="1">
0125: * <pre><code>
0126: * g.fillRect(0, 0, 3, 2) </code></pre>
0127: * </TD>
0128: * </TR>
0129: * </TABLE>
0130: * <P>
0131: * paints exactly six pixels. (In this example, and in all subsequent
0132: * examples, the variable <code>g</code> is assumed to contain a
0133: * reference to a
0134: * <code>Graphics</code> object.) </p>
0135: * <p>
0136: * Each character of a font contains a set of pixels that forms the shape of
0137: * the character. When a character is painted, the pixels forming the
0138: * character's shape are filled with the <code>Graphics</code>
0139: * object's current color, and
0140: * the pixels not part of the character's shape are left untouched.
0141: * The text drawing calls
0142: * {@link #drawChar drawChar()},
0143: * {@link #drawChars drawChars()},
0144: * {@link #drawString drawString()}, and
0145: * {@link #drawSubstring drawSubstring()}
0146: * all draw text in this manner. </p>
0147: * <p>
0148: * Lines, arcs, rectangles, and rounded rectangles may be drawn with either a
0149: * <code>SOLID</code> or a <code>DOTTED</code> stroke style, as set by
0150: * the {@link #setStrokeStyle
0151: * setStrokeStyle()} method. The stroke style does not affect fill, text, and
0152: * image operations. </p>
0153: * <p>
0154: * For the <code>SOLID</code> stroke style,
0155: * drawing operations are performed with a one-pixel wide pen that fills
0156: * the pixel immediately
0157: * below and to the right of the specified coordinate. Drawn lines
0158: * touch pixels at both endpoints. Thus, the operation </P>
0159: * <TABLE BORDER="2">
0160: * <TR>
0161: * <TD ROWSPAN="1" COLSPAN="1">
0162: * <pre><code>
0163: * g.drawLine(0, 0, 0, 0); </code></pre>
0164: * </TD>
0165: * </TR>
0166: * </TABLE>
0167: * <p>
0168: * paints exactly one pixel, the first pixel in the upper left corner
0169: * of the display. </p>
0170: * <p>
0171: * Drawing operations under the <code>DOTTED</code> stroke style will
0172: * touch a subset of
0173: * pixels that would have been touched under the <code>SOLID</code>
0174: * stroke style. The
0175: * frequency and length of dots is implementation-dependent. The endpoints of
0176: * lines and arcs are not guaranteed to be drawn, nor are the corner points of
0177: * rectangles guaranteed to be drawn. Dots are drawn by painting with the
0178: * current color; spaces between dots are left untouched. </p>
0179: * <p>
0180: * An artifact of the coordinate system is that the area affected by a fill
0181: * operation differs slightly from the area affected by a draw operation given
0182: * the same coordinates. For example, consider the operations </P>
0183: * <TABLE BORDER="2">
0184: * <TR>
0185: * <TD ROWSPAN="1" COLSPAN="1">
0186: * <pre><code>
0187: * g.fillRect(x, y, w, h); // 1
0188: * g.drawRect(x, y, w, h); // 2 </code></pre>
0189: * </TD>
0190: * </TR>
0191: * </TABLE>
0192: * <P>
0193: * Statement (1) fills a rectangle <code>w</code> pixels wide and
0194: * <code>h</code> pixels high.
0195: * Statement (2) draws a rectangle whose left and top
0196: * edges are within the area filled by statement (1). However, the
0197: * bottom and right edges lie one pixel outside the filled area.
0198: * This is counterintuitive, but it preserves the invariant that </P>
0199: * <TABLE BORDER="2">
0200: * <TR>
0201: * <TD ROWSPAN="1" COLSPAN="1">
0202: * <pre><code>
0203: * g.drawLine(x, y, x+w, y);
0204: * g.drawLine(x+w, y, x+w, y+h);
0205: * g.drawLine(x+w, y+h, x, y+h);
0206: * g.drawLine(x, y+h, x, y); </code></pre>
0207: * </TD>
0208: * </TR>
0209: * </TABLE>
0210: * <P>
0211: * has an effect identical to statement (2) above. </p>
0212: * <p>
0213: * The exact pixels painted by <code>drawLine()</code> and
0214: * <code>drawArc()</code> are not
0215: * specified. Pixels touched by a fill operation must either
0216: * exactly overlap or directly abut pixels touched by the
0217: * corresponding draw operation. A fill operation must never leave
0218: * a gap between the filled area and the pixels touched by the
0219: * corresponding draw operation, nor may the fill operation touch
0220: * pixels outside the area bounded by the corresponding draw operation. </p>
0221: *
0222: * <p>
0223: * <a name="clip"></a>
0224: * <h3>Clipping</h3> <p>
0225: *
0226: * <p>
0227: * The clip is the set of pixels in the destination of the
0228: * <code>Graphics</code> object that may be modified by graphics rendering
0229: * operations.
0230: *
0231: * <p>
0232: * There is a single clip per <code>Graphics</code> object.
0233: * The only pixels modified by graphics operations are those that lie within the
0234: * clip. Pixels outside the clip are not modified by any graphics operations.
0235: *
0236: * <p>
0237: * Operations are provided for intersecting the current clip with
0238: * a given rectangle and for setting the current clip outright.
0239: * The application may specify the clip by supplying a clip rectangle
0240: * using coordinates relative to the current coordinate system.
0241: *
0242: * <p>
0243: * It is legal to specify a clip rectangle whose width or height is zero
0244: * or negative. In this case the clip is considered to be empty,
0245: * that is, no pixels are contained within it.
0246: * Therefore, if any graphics operations are issued under such a clip,
0247: * no pixels will be modified.
0248: *
0249: * <p>
0250: * It is legal to specify a clip rectangle that extends beyond or resides
0251: * entirely beyond the bounds of the destination. No pixels exist outside
0252: * the bounds of the destination, and the area of the clip rectangle
0253: * that is outside the destination is ignored. Only the pixels that lie
0254: * both within the destination and within the specified clip rectangle
0255: * are considered to be part of the clip.
0256: *
0257: * <p>
0258: * Operations on the coordinate system,
0259: * such as {@link Graphics#translate(int, int) translate()},
0260: * do not modify the clip.
0261: * The methods
0262: * {@link Graphics#getClipX() getClipX()},
0263: * {@link Graphics#getClipY() getClipY()},
0264: * {@link Graphics#getClipWidth() getClipWidth()} and
0265: * {@link Graphics#getClipHeight() getClipHeight()}
0266: * must return a rectangle that,
0267: * if passed to <code>setClip</code> without an intervening change to
0268: * the <code>Graphics</code> object's coordinate system, must result in
0269: * the identical set of pixels in the clip.
0270: * The rectangle returned from the <code>getClip</code> family of methods
0271: * may differ from the clip rectangle that was requested in
0272: * {@link Graphics#setClip(int, int, int, int) setClip()}.
0273: * This can occur if the coordinate system has been changed or if
0274: * the implementation has chosen to intersect the clip rectangle
0275: * with the bounds of the destination of the <code>Graphics</code> object.
0276: *
0277: * <p>
0278: * If a graphics operation is affected by the clip, the pixels
0279: * touched by that operation must be the same ones that would be touched
0280: * as if the clip did not affect the operation. For example,
0281: * consider a clip represented by the rectangle <code>(cx, cy, cw, ch)</code>
0282: * and a point <code>(x1, y1)</code> that
0283: * lies outside this rectangle and a point <code>(x2, y2)</code>
0284: * that lies within this
0285: * rectangle. In the following code fragment, </P>
0286: * <TABLE BORDER="2">
0287: * <TR>
0288: * <TD ROWSPAN="1" COLSPAN="1">
0289: * <pre><code>
0290: * g.setClip(0, 0, canvas.getWidth(),
0291: * canvas.getHeight());
0292: * g.drawLine(x1, y1, x2, y2); // 3
0293: * g.setClip(cx, cy, cw, ch);
0294: * g.drawLine(x1, y1, x2, y2); // 4 </code></pre>
0295: * </TD>
0296: * </TR>
0297: * </TABLE>
0298: * <P>
0299: * The pixels touched by statement (4) must be identical to the pixels
0300: * within <code>(cx, cy, cw, ch)</code> touched by statement (3). </p>
0301: * <p>
0302: * <a name="anchor"></a>
0303: * <h3>Anchor Points</h3> <p>
0304: *
0305: * The drawing of text is based on "anchor points".
0306: * Anchor points are used to minimize the amount of
0307: * computation required when placing text.
0308: * For example, in order to center a piece of text,
0309: * an application needs to call <code>stringWidth()</code> or
0310: * <code>charWidth()</code> to get the width and then perform a
0311: * combination of subtraction and division to
0312: * compute the proper location.
0313: * The method to draw text is defined as follows:
0314: * <pre><code>
0315: * public void drawString(String text, int x, int y, int anchor);
0316: * </code></pre>
0317: * This method draws text in the current color,
0318: * using the current font
0319: * with its anchor point at <code>(x,y)</code>. The definition
0320: * of the anchor point must be one of the
0321: * horizontal constants <code>(LEFT, HCENTER, RIGHT)</code>
0322: * combined with one of the vertical constants
0323: * <code>(TOP, BASELINE, BOTTOM)</code> using the bit-wise
0324: * <code>OR</code> operator.
0325: * Zero may also be used as the value of an anchor point.
0326: * Using zero for the anchor point value gives results
0327: * identical to using <code>TOP | LEFT</code>.</p>
0328: *
0329: * <p>
0330: * Vertical centering of the text is not specified since it is not considered
0331: * useful, it is hard to specify, and it is burdensome to implement. Thus,
0332: * the <code>VCENTER</code> value is not allowed in the anchor point
0333: * parameter of text
0334: * drawing calls. </p>
0335: * <p>
0336: * The actual position of the bounding box
0337: * of the text relative to the <code>(x, y)</code> location is
0338: * determined by the anchor point. These anchor
0339: * points occur at named locations along the
0340: * outer edge of the bounding box. Thus, if <code>f</code>
0341: * is <code>g</code>'s current font (as returned by
0342: * <code>g.getFont()</code>, the following calls will all have
0343: * identical results: </P>
0344: * <TABLE BORDER="2">
0345: * <TR>
0346: * <TD ROWSPAN="1" COLSPAN="1">
0347: * <pre><code>
0348: * g.drawString(str, x, y, TOP|LEFT);
0349: * g.drawString(str, x + f.stringWidth(str)/2, y, TOP|HCENTER);
0350: * g.drawString(str, x + f.stringWidth(str), y, TOP|RIGHT);
0351: *
0352: * g.drawString(str, x,
0353: * y + f.getBaselinePosition(), BASELINE|LEFT);
0354: * g.drawString(str, x + f.stringWidth(str)/2,
0355: * y + f.getBaselinePosition(), BASELINE|HCENTER);
0356: * g.drawString(str, x + f.stringWidth(str),
0357: * y + f.getBaselinePosition(), BASELINE|RIGHT);
0358: *
0359: * drawString(str, x,
0360: * y + f.getHeight(), BOTTOM|LEFT);
0361: * drawString(str, x + f.stringWidth(str)/2,
0362: * y + f.getHeight(), BOTTOM|HCENTER);
0363: * drawString(str, x + f.stringWidth(str),
0364: * y + f.getHeight(), BOTTOM|RIGHT); </code></pre>
0365: * </TD>
0366: * </TR>
0367: * </TABLE>
0368: * <p>
0369: * For text drawing, the inter-character and inter-line spacing (leading)
0370: * specified by the font designer are included as part of the values returned
0371: * in the {@link Font#stringWidth(java.lang.String) stringWidth()}
0372: * and {@link Font#getHeight() getHeight()}
0373: * calls of class {@link Font Font}.
0374: * For example, given the following code: </P>
0375: * <TABLE BORDER="2">
0376: * <TR>
0377: * <TD ROWSPAN="1" COLSPAN="1">
0378: * <pre><code>
0379: * // (5)
0380: * g.drawString(string1+string2, x, y, TOP|LEFT);
0381: *
0382: * // (6)
0383: * g.drawString(string1, x, y, TOP|LEFT);
0384: * g.drawString(string2, x + f.stringWidth(string1), y, TOP|LEFT);
0385: * </code></pre>
0386: * </TD>
0387: * </TR>
0388: * </TABLE>
0389: * </P>
0390: * <P>
0391: * Code fragments (5) and (6) behave similarly if not identically. This
0392: * occurs because <code>f.stringWidth()</code>
0393: * includes the inter-character spacing. The exact spacing of may differ
0394: * between these calls if the system supports font kerning.</p>
0395: *
0396: * <p>Similarly, reasonable vertical spacing may be
0397: * achieved simply by adding the font height
0398: * to the Y-position of subsequent lines. For example: </P>
0399: * <TABLE BORDER="2">
0400: * <TR>
0401: * <TD ROWSPAN="1" COLSPAN="1">
0402: * <pre><code>
0403: * g.drawString(string1, x, y, TOP|LEFT);
0404: * g.drawString(string2, x, y + f.fontHeight(), TOP|LEFT); </code></pre>
0405: * </TD>
0406: * </TR>
0407: * </TABLE>
0408: * <P>
0409: * draws <code>string1</code> and <code>string2</code> on separate lines with
0410: * an appropriate amount of inter-line spacing. </p>
0411: * <p>
0412: * The <code>stringWidth()</code> of the string and the
0413: * <code>fontHeight()</code> of the font in which
0414: * it is drawn define the size of the bounding box of a piece of text. As
0415: * described above, this box includes inter-line and inter-character spacing.
0416: * The implementation is required to put this space below and to right of the
0417: * pixels actually belonging to the characters drawn. Applications that wish
0418: * to position graphics closely with respect to text (for example, to paint a
0419: * rectangle around a string of text) may assume that there is space below and
0420: * to the right of a string and that there is <em>no</em> space above
0421: * and to the
0422: * left of the string. </p>
0423: * <p>
0424: * Anchor points are also used for positioning of images. Similar to text
0425: * drawing, the anchor point for an image specifies the point on the bounding
0426: * rectangle of the destination that is to positioned at the
0427: * <code>(x,y)</code> location
0428: * given in the graphics request. Unlike text, vertical centering of images
0429: * is well-defined, and thus the <code>VCENTER</code> value may be
0430: * used within the anchor
0431: * point parameter of image drawing requests. Because images have no notion
0432: * of a baseline, the <code>BASELINE</code> value may not be used
0433: * within the anchor point
0434: * parameter of image drawing requests. </p>
0435: *
0436: * <h3>Reference</h3>
0437: *
0438: * <dl>
0439: * <dt>Porter-Duff
0440: * <dd>Porter, T., and T. Duff. "Compositing Digital Images."
0441: * <em>Computer Graphics V18 N3 (SIGGRAPH 1984)</em>, p. 253-259.
0442: * </dl>
0443: *
0444: * @since MIDP 1.0
0445: */
0446:
0447: public class Graphics {
0448:
0449: // SYNC NOTE: the main Graphics class is entirely unlocked. There is only
0450: // one instance of Graphics (created in Display) and it is only ever legal
0451: // for the application to use it when the system calls the paint() method
0452: // of a Canvas. Since paint() calls are serialized, and these methods
0453: // modify only instance state, no locking is necessary. (If any method
0454: // were to read or modify global state, locking would need to be done in
0455: // those cases.)
0456:
0457: /**
0458: * Constant for centering text and images horizontally
0459: * around the anchor point
0460: *
0461: * <P>Value <code>1</code> is assigned to <code>HCENTER</code>.</P>
0462: */
0463: public static final int HCENTER = 1;
0464:
0465: /**
0466: * Constant for centering images vertically
0467: * around the anchor point.
0468: *
0469: * <P>Value <code>2</code> is assigned to <code>VCENTER</code>.</P>
0470: */
0471: public static final int VCENTER = 2;
0472:
0473: /**
0474: * Constant for positioning the anchor point of text and images
0475: * to the left of the text or image.
0476: *
0477: * <P>Value <code>4</code> is assigned to <code>LEFT</code>.</P>
0478: */
0479: public static final int LEFT = 4;
0480:
0481: /**
0482: * Constant for positioning the anchor point of text and images
0483: * to the right of the text or image.
0484: *
0485: * <P>Value <code>8</code> is assigned to <code>RIGHT</code>.</P>
0486: */
0487: public static final int RIGHT = 8;
0488:
0489: /**
0490: * Constant for positioning the anchor point of text and images
0491: * above the text or image.
0492: *
0493: * <P>Value <code>16</code> is assigned to <code>TOP</code>.</P>
0494: */
0495: public static final int TOP = 16;
0496:
0497: /**
0498: * Constant for positioning the anchor point of text and images
0499: * below the text or image.
0500: *
0501: * <P>Value <code>32</code> is assigned to <code>BOTTOM</code>.</P>
0502: */
0503: public static final int BOTTOM = 32;
0504:
0505: /**
0506: * Constant for positioning the anchor point at the baseline of text.
0507: *
0508: * <P>Value <code>64</code> is assigned to <code>BASELINE</code>.</P>
0509: */
0510: public static final int BASELINE = 64;
0511:
0512: /**
0513: * Constant for the <code>SOLID</code> stroke style.
0514: *
0515: * <P>Value <code>0</code> is assigned to <code>SOLID</code>.</P>
0516: */
0517: public static final int SOLID = 0;
0518:
0519: /**
0520: * Constant for the <code>DOTTED</code> stroke style.
0521: *
0522: * <P>Value <code>1</code> is assigned to <code>DOTTED</code>.</P>
0523: */
0524: public static final int DOTTED = 1;
0525:
0526: /**
0527: * Create a Graphics object
0528: */
0529: Graphics() {
0530: }
0531:
0532: /**
0533: * Sets the width and height member variables of this
0534: * Graphics object to reflect the correct values e.g. for
0535: * clipping correctly
0536: *
0537: * @param w the width of this Graphics object
0538: * @param h the height of this Graphics object
0539: */
0540: void setDimensions(int w, int h) {
0541: maxWidth = (short) (w & 0x7fff);
0542: maxHeight = (short) (h & 0x7fff);
0543: }
0544:
0545: /**
0546: * Translates the origin of the graphics context to the point
0547: * <code>(x, y)</code> in the current coordinate system. All coordinates
0548: * used in subsequent rendering operations on this graphics
0549: * context will be relative to this new origin.<p>
0550: *
0551: * The effect of calls to <code>translate()</code> are
0552: * cumulative. For example, calling
0553: * <code>translate(1, 2)</code> and then <code>translate(3,
0554: * 4)</code> results in a translation of
0555: * <code>(4, 6)</code>. <p>
0556: *
0557: * The application can set an absolute origin <code>(ax,
0558: * ay)</code> using the following
0559: * technique:<p>
0560: * <code>
0561: * g.translate(ax - g.getTranslateX(), ay - g.getTranslateY())
0562: * </code><p>
0563: *
0564: * @param x the x coordinate of the new translation origin
0565: * @param y the y coordinate of the new translation origin
0566: * @see #getTranslateX()
0567: * @see #getTranslateY()
0568: */
0569: public synchronized void translate(int x, int y) {
0570: transX += x;
0571: transY += y;
0572: }
0573:
0574: /**
0575: * Gets the X coordinate of the translated origin of this graphics context.
0576: * @return X of current origin
0577: */
0578: public synchronized int getTranslateX() {
0579: return transX;
0580: }
0581:
0582: /**
0583: * Gets the Y coordinate of the translated origin of this graphics context.
0584: * @return Y of current origin
0585: */
0586: public synchronized int getTranslateY() {
0587: return transY;
0588: }
0589:
0590: /**
0591: * Gets the current color.
0592: * @return an integer in form <code>0x00RRGGBB</code>
0593: * @see #setColor(int, int, int)
0594: */
0595: public synchronized int getColor() {
0596: return rgbColor;
0597: }
0598:
0599: /**
0600: * Gets the red component of the current color.
0601: * @return integer value in range <code>0-255</code>
0602: * @see #setColor(int, int, int)
0603: */
0604: public synchronized int getRedComponent() {
0605: return (rgbColor >> 16) & 0xff;
0606: }
0607:
0608: /**
0609: * Gets the green component of the current color.
0610: * @return integer value in range <code>0-255</code>
0611: * @see #setColor(int, int, int)
0612: */
0613: public synchronized int getGreenComponent() {
0614: return (rgbColor >> 8) & 0xff;
0615: }
0616:
0617: /**
0618: * Gets the blue component of the current color.
0619: * @return integer value in range <code>0-255</code>
0620: * @see #setColor(int, int, int)
0621: */
0622: public synchronized int getBlueComponent() {
0623: return rgbColor & 0xff;
0624: }
0625:
0626: /**
0627: * Gets the current grayscale value of the color being used for rendering
0628: * operations. If the color was set by
0629: * <code>setGrayScale()</code>, that value is simply
0630: * returned. If the color was set by one of the methods that allows setting
0631: * of the red, green, and blue components, the value returned is
0632: * computed from
0633: * the RGB color components (possibly in a device-specific fashion)
0634: * that best
0635: * approximates the brightness of that color.
0636: *
0637: * @return integer value in range <code>0-255</code>
0638: * @see #setGrayScale
0639: */
0640: public synchronized int getGrayScale() {
0641: return gray;
0642: }
0643:
0644: /**
0645: * Sets the current color to the specified RGB values. All subsequent
0646: * rendering operations will use this specified color.
0647: * @param red the red component of the color being set in range
0648: * <code>0-255</code>
0649: * @param green the green component of the color being set in range
0650: * <code>0-255</code>
0651: * @param blue the blue component of the color being set in range
0652: * <code>0-255</code>
0653: * @throws IllegalArgumentException if any of the color components
0654: * are outside of range <code>0-255</code>
0655: * @see #getColor
0656: */
0657: public synchronized void setColor(int red, int green, int blue) {
0658: if ((red < 0) || (red > 255) || (green < 0) || (green > 255)
0659: || (blue < 0) || (blue > 255)) {
0660: throw new IllegalArgumentException("Value out of range");
0661: }
0662:
0663: rgbColor = (red << 16) | (green << 8) | blue;
0664: gray = grayVal(red, green, blue);
0665: pixel = getPixel(rgbColor, gray, false);
0666: }
0667:
0668: /**
0669: * Sets the current color to the specified RGB values. All subsequent
0670: * rendering operations will use this specified color. The RGB value
0671: * passed in is interpreted with the least significant eight bits
0672: * giving the blue component, the next eight more significant bits
0673: * giving the green component, and the next eight more significant
0674: * bits giving the red component. That is to say, the color component
0675: * is specified in the form of <code>0x00RRGGBB</code>. The high
0676: * order byte of
0677: * this value is ignored.
0678: *
0679: * @param RGB the color being set
0680: * @see #getColor
0681: */
0682: public synchronized void setColor(int RGB) {
0683: if (pixel == -1 || (RGB & 0x00ffffff) != rgbColor) {
0684: int red = (RGB >> 16) & 0xff;
0685: int green = (RGB >> 8) & 0xff;
0686: int blue = (RGB) & 0xff;
0687:
0688: rgbColor = RGB & 0x00ffffff;
0689: gray = grayVal(red, green, blue);
0690: pixel = getPixel(rgbColor, gray, false);
0691: }
0692: }
0693:
0694: /**
0695: * Sets the current grayscale to be used for all subsequent
0696: * rendering operations. For monochrome displays, the behavior
0697: * is clear. For color displays, this sets the color for all
0698: * subsequent drawing operations to be a gray color equivalent
0699: * to the value passed in. The value must be in the range
0700: * <code>0-255</code>.
0701: * @param value the desired grayscale value
0702: * @throws IllegalArgumentException if the gray value is out of range
0703: * @see #getGrayScale
0704: */
0705: public synchronized void setGrayScale(int value) {
0706: if ((value < 0) || (value > 255)) {
0707: throw new IllegalArgumentException(
0708: "Gray value out of range");
0709: }
0710:
0711: if (pixel == -1 || gray != value) {
0712: rgbColor = (value << 16) | (value << 8) | value;
0713: gray = value;
0714: pixel = getPixel(rgbColor, gray, true);
0715: }
0716: }
0717:
0718: /**
0719: * Gets the current font.
0720: * @return current font
0721: * @see javax.microedition.lcdui.Font
0722: * @see #setFont(javax.microedition.lcdui.Font)
0723: */
0724: public synchronized Font getFont() {
0725: return currentFont;
0726: }
0727:
0728: /**
0729: * Sets the stroke style used for drawing lines, arcs, rectangles, and
0730: * rounded rectangles. This does not affect fill, text, and image
0731: * operations.
0732: * @param style can be <code>SOLID</code> or <code>DOTTED</code>
0733: * @throws IllegalArgumentException if the <code>style</code> is illegal
0734: * @see #getStrokeStyle
0735: */
0736: public synchronized void setStrokeStyle(int style) {
0737: if ((style != SOLID) && (style != DOTTED)) {
0738: throw new IllegalArgumentException("Invalid line style");
0739: }
0740:
0741: this .style = style;
0742: }
0743:
0744: /**
0745: * Gets the stroke style used for drawing operations.
0746: * @return stroke style, <code>SOLID</code> or <code>DOTTED</code>
0747: * @see #setStrokeStyle
0748: */
0749: public synchronized int getStrokeStyle() {
0750: return style;
0751: }
0752:
0753: /**
0754: * Sets the font for all subsequent text rendering operations. If font is
0755: * <code>null</code>, it is equivalent to
0756: * <code>setFont(Font.getDefaultFont())</code>.
0757: *
0758: * @param font the specified font
0759: * @see javax.microedition.lcdui.Font
0760: * @see #getFont()
0761: * @see #drawString(java.lang.String, int, int, int)
0762: * @see #drawChars(char[], int, int, int, int, int)
0763: */
0764: public synchronized void setFont(Font font) {
0765: currentFont = (font == null) ? Font.getDefaultFont() : font;
0766: }
0767:
0768: /**
0769: * Gets the X offset of the current clipping area, relative
0770: * to the coordinate system origin of this graphics context.
0771: * Separating the <code>getClip</code> operation into two methods returning
0772: * integers is more performance and memory efficient than one
0773: * <code>getClip()</code> call returning an object.
0774: * @return X offset of the current clipping area
0775: * @see #clipRect(int, int, int, int)
0776: * @see #setClip(int, int, int, int)
0777: */
0778: public synchronized int getClipX() {
0779: return clipX1 - transX;
0780: }
0781:
0782: /**
0783: * Gets the Y offset of the current clipping area, relative
0784: * to the coordinate system origin of this graphics context.
0785: * Separating the <code>getClip</code> operation into two methods returning
0786: * integers is more performance and memory efficient than one
0787: * <code>getClip()</code> call returning an object.
0788: * @return Y offset of the current clipping area
0789: * @see #clipRect(int, int, int, int)
0790: * @see #setClip(int, int, int, int)
0791: */
0792: public synchronized int getClipY() {
0793: return clipY1 - transY;
0794: }
0795:
0796: /**
0797: * Gets the width of the current clipping area.
0798: * @return width of the current clipping area.
0799: * @see #clipRect(int, int, int, int)
0800: * @see #setClip(int, int, int, int)
0801: */
0802: public synchronized int getClipWidth() {
0803: return clipX2 - clipX1;
0804: }
0805:
0806: /**
0807: * Gets the height of the current clipping area.
0808: * @return height of the current clipping area.
0809: * @see #clipRect(int, int, int, int)
0810: * @see #setClip(int, int, int, int)
0811: */
0812: public synchronized int getClipHeight() {
0813: return clipY2 - clipY1;
0814: }
0815:
0816: /**
0817: * Internal routine to get the clip in a single call. The input
0818: * parameter must be a 4 element integer array. The values of the
0819: * array upon return will be equal to the same values as would be
0820: * returned from getClipX(), getClipY(), getClipX()+getClipWidth(),
0821: * and getClipY()+getClipHeight().
0822: *
0823: * @param region a four element array to hold the clip rectangle
0824: */
0825: void getClip(int[] region) {
0826: region[0] = clipX1 - transX;
0827: region[1] = clipY1 - transY;
0828: region[2] = clipX2 - transX;
0829: region[3] = clipY2 - transY;
0830: }
0831:
0832: /**
0833: * Intersects the current clip with the specified rectangle.
0834: * The resulting clipping area is the intersection of the current
0835: * clipping area and the specified rectangle.
0836: * This method can only be used to make the current clip smaller.
0837: * To set the current clip larger, use the <code>setClip</code> method.
0838: * Rendering operations have no effect outside of the clipping area.
0839: * @param x the x coordinate of the rectangle to intersect the clip with
0840: * @param y the y coordinate of the rectangle to intersect the clip with
0841: * @param width the width of the rectangle to intersect the clip with
0842: * @param height the height of the rectangle to intersect the clip with
0843: * @see #setClip(int, int, int, int)
0844: */
0845: public synchronized void clipRect(int x, int y, int width,
0846: int height) {
0847:
0848: int translatedX1, translatedY1;
0849: int translatedX2, translatedY2;
0850:
0851: if (width <= 0 || height <= 0) {
0852: clipX1 = clipY1 = clipX2 = clipY2 = 0;
0853: clipped = true;
0854: return;
0855: }
0856:
0857: // Translate the given coordinates
0858: translatedX1 = x + transX;
0859: translatedY1 = y + transY;
0860:
0861: // Detect overflow
0862: if (translatedX1 < 0) {
0863: translatedX1 = (x < 0 || transX < 0) ? 0 : maxWidth;
0864: }
0865: if (translatedY1 < 0) {
0866: translatedY1 = (y < 0 || transY < 0) ? 0 : maxHeight;
0867: }
0868:
0869: // If the passed in rect is below our current clip
0870: if ((clipX2 < translatedX1) || (clipY2 < translatedY1)) {
0871: // we have no intersection
0872: clipX1 = clipY1 = clipX2 = clipY2 = 0;
0873: clipped = true;
0874: return;
0875: }
0876:
0877: if (translatedX1 > clipX1) {
0878: clipX1 = (short) (translatedX1 & 0x7fff);
0879: clipped = true;
0880: }
0881:
0882: if (translatedY1 > clipY1) {
0883: clipY1 = (short) (translatedY1 & 0x7fff);
0884: clipped = true;
0885: }
0886:
0887: // Start handling bottom right area
0888:
0889: translatedX2 = x + transX + width;
0890: translatedY2 = y + transY + height;
0891:
0892: // Detect Overflow
0893: if (translatedX2 < 0) {
0894: translatedX2 = (x < 0 || transX < 0) ? translatedX1
0895: : maxWidth;
0896: }
0897: if (translatedY2 < 0) {
0898: translatedY2 = (y < 0 || transY < 0) ? translatedY1
0899: : maxHeight;
0900: }
0901:
0902: // If the passed in rect is above our current clip
0903: if (translatedX2 < clipX1 || translatedY2 < clipY1) {
0904: // we have no intersection
0905: clipX1 = clipY1 = clipX2 = clipY2 = 0;
0906: clipped = true;
0907: return;
0908: }
0909:
0910: if (translatedX2 <= clipX2) {
0911: clipX2 = (short) translatedX2;
0912: clipped = true;
0913: }
0914:
0915: if (translatedY2 <= clipY2) {
0916: clipY2 = (short) translatedY2;
0917: clipped = true;
0918: }
0919:
0920: if (clipped == true) {
0921: if (clipX2 < clipX1)
0922: clipX2 = clipX1;
0923: if (clipY2 < clipY1)
0924: clipY2 = clipY1;
0925: }
0926: /**
0927: * sanity check
0928:
0929: if (clipX1 < 0 || clipY1 < 0 ||
0930: clipX2 > maxWidth || clipY2 > maxHeight ||
0931: clipX1 > clipX2 || clipY1 > clipY2)
0932: System.out.println("Graphics:clipRect error: clipX1 = "+clipX1+
0933: " clipY1 = "+clipY1+" clipX2 = "+clipX2+" clipY2 = "+clipY2+
0934: " maxWidth = "+maxWidth+" maxHeight = "+maxHeight);
0935: if (runtimeClipEnforce)
0936: System.out.println("Graphics:clipRect runtimeClipEnforce:"+
0937: " systemClipX1 = "+systemClipX1+" systemClipY1 = "+systemClipY1+
0938: " systemClipX2 = "+systemClipX2+" systemClipY2 = "+systemClipY2);
0939:
0940: * end sanity check
0941: */
0942:
0943: }
0944:
0945: /**
0946: * Sets the current clip to the rectangle specified by the
0947: * given coordinates.
0948: * Rendering operations have no effect outside of the clipping area.
0949: * @param x the x coordinate of the new clip rectangle
0950: * @param y the y coordinate of the new clip rectangle
0951: * @param width the width of the new clip rectangle
0952: * @param height the height of the new clip rectangle
0953: * @see #clipRect(int, int, int, int)
0954: */
0955: public synchronized void setClip(int x, int y, int width, int height) {
0956:
0957: int translatedX1, translatedY1;
0958: int translatedX2, translatedY2;
0959:
0960: // If width or height is zero or less then zero,
0961: // we do not preserve the current clipping and
0962: // set all clipping values to zero.
0963: if ((width <= 0) || (height <= 0)) {
0964: clipX1 = clipY1 = clipX2 = clipY2 = 0;
0965: clipped = true;
0966: return;
0967: }
0968:
0969: // Translate the given coordinates
0970: translatedX1 = x + transX;
0971: translatedY1 = y + transY;
0972:
0973: // Detect Overflow
0974: if (translatedX1 < 0) {
0975: translatedX1 = (x < 0 || transX < 0) ? 0 : maxWidth;
0976: }
0977: if (translatedY1 < 0) {
0978: translatedY1 = (y < 0 || transY < 0) ? 0 : maxHeight;
0979: }
0980:
0981: clipX1 = (short) (translatedX1 & 0x7fff);
0982: clipY1 = (short) (translatedY1 & 0x7fff);
0983:
0984: if ((translatedX1 >= maxWidth) || (translatedY1 >= maxHeight)) {
0985: clipX1 = clipY1 = clipX2 = clipY2 = 0;
0986: clipped = true;
0987: return;
0988: }
0989:
0990: // Check against the runtime library clip values
0991: if (runtimeClipEnforce) {
0992: if (clipX1 < systemClipX1)
0993: clipX1 = systemClipX1;
0994: if (clipY1 < systemClipY1) {
0995: clipY1 = systemClipY1;
0996: }
0997: }
0998:
0999: // Translate the given width, height to abs. coordinates
1000: translatedX2 = x + transX + width;
1001: translatedY2 = y + transY + height;
1002:
1003: // Detect overflow
1004: if (translatedX2 < 0) {
1005: translatedX2 = (x < 0 || transX < 0) ? translatedX1
1006: : maxWidth;
1007: } else {
1008: if (translatedX2 > maxWidth)
1009: translatedX2 = maxWidth;
1010: }
1011: if (translatedY2 < 0) {
1012: translatedY2 = (y < 0 || transY < 0) ? translatedY1
1013: : maxHeight;
1014: } else {
1015: if (translatedY2 > maxHeight)
1016: translatedY2 = maxHeight;
1017: }
1018:
1019: clipX2 = (short) (translatedX2 & 0x7FFF);
1020: clipY2 = (short) (translatedY2 & 0x7FFF);
1021:
1022: // Check against the runtime library clip values
1023: if (runtimeClipEnforce) {
1024: if (clipX2 > systemClipX2)
1025: clipX2 = systemClipX2;
1026: if (clipY2 > systemClipY2)
1027: clipY2 = systemClipY2;
1028: }
1029:
1030: if ((clipX1 != 0) || (clipY1 != 0) || (clipX2 != maxWidth)
1031: || (clipY2 != maxHeight)) {
1032: clipped = true;
1033: }
1034:
1035: /**
1036: * sanity check
1037: if (clipX1 < 0 || clipY1 < 0 ||
1038: clipX2 > maxWidth || clipY2 > maxHeight ||
1039: clipX1 > clipX2 || clipY1 > clipY2)
1040: System.out.println("Graphics:setClip error: clipX1 = "+clipX1+
1041: " clipY1 = "+clipY1+" clipX2 = "+clipX2+" clipY2 = "+clipY2+
1042: " maxWidth = "+maxWidth+" maxHeight = "+maxHeight);
1043: if (runtimeClipEnforce)
1044: System.out.println("Graphics:setClip runtimeClipEnforce:"+
1045: " systemClipX1 = "+systemClipX1+" systemClipY1 = "+systemClipY1+
1046: " systemClipX2 = "+systemClipX2+" systemClipY2 = "+systemClipY2);
1047:
1048: * end sanity check
1049: */
1050:
1051: }
1052:
1053: /**
1054: * Draws a line between the coordinates <code>(x1,y1)</code> and
1055: * <code>(x2,y2)</code> using
1056: * the current color and stroke style.
1057: * @param x1 the x coordinate of the start of the line
1058: * @param y1 the y coordinate of the start of the line
1059: * @param x2 the x coordinate of the end of the line
1060: * @param y2 the y coordinate of the end of the line
1061: */
1062: public native void drawLine(int x1, int y1, int x2, int y2);
1063:
1064: /**
1065: * Fills the specified rectangle with the current color.
1066: * If either width or height is zero or less,
1067: * nothing is drawn.
1068: * @param x the x coordinate of the rectangle to be filled
1069: * @param y the y coordinate of the rectangle to be filled
1070: * @param width the width of the rectangle to be filled
1071: * @param height the height of the rectangle to be filled
1072: * @see #drawRect(int, int, int, int)
1073: */
1074: public native void fillRect(int x, int y, int width, int height);
1075:
1076: /**
1077: * Draws the outline of the specified rectangle using the current
1078: * color and stroke style.
1079: * The resulting rectangle will cover an area <code>(width + 1)</code>
1080: * pixels wide by <code>(height + 1)</code> pixels tall.
1081: * If either width or height is less than
1082: * zero, nothing is drawn.
1083: * @param x the x coordinate of the rectangle to be drawn
1084: * @param y the y coordinate of the rectangle to be drawn
1085: * @param width the width of the rectangle to be drawn
1086: * @param height the height of the rectangle to be drawn
1087: * @see #fillRect(int, int, int, int)
1088: */
1089: public native void drawRect(int x, int y, int width, int height);
1090:
1091: /**
1092: * Draws the outline of the specified rounded corner rectangle
1093: * using the current color and stroke style.
1094: * The resulting rectangle will cover an area <code>(width +
1095: * 1)</code> pixels wide
1096: * by <code>(height + 1)</code> pixels tall.
1097: * If either <code>width</code> or <code>height</code> is less than
1098: * zero, nothing is drawn.
1099: * @param x the x coordinate of the rectangle to be drawn
1100: * @param y the y coordinate of the rectangle to be drawn
1101: * @param width the width of the rectangle to be drawn
1102: * @param height the height of the rectangle to be drawn
1103: * @param arcWidth the horizontal diameter of the arc at the four corners
1104: * @param arcHeight the vertical diameter of the arc at the four corners
1105: * @see #fillRoundRect(int, int, int, int, int, int)
1106: */
1107: public native void drawRoundRect(int x, int y, int width,
1108: int height, int arcWidth, int arcHeight);
1109:
1110: /**
1111: * Fills the specified rounded corner rectangle with the current color.
1112: * If either <code>width</code> or <code>height</code> is zero or less,
1113: * nothing is drawn.
1114: * @param x the x coordinate of the rectangle to be filled
1115: * @param y the y coordinate of the rectangle to be filled
1116: * @param width the width of the rectangle to be filled
1117: * @param height the height of the rectangle to be filled
1118: * @param arcWidth the horizontal diameter of the arc at the four
1119: * corners
1120: * @param arcHeight the vertical diameter of the arc at the four corners
1121: * @see #drawRoundRect(int, int, int, int, int, int)
1122: */
1123: public native void fillRoundRect(int x, int y, int width,
1124: int height, int arcWidth, int arcHeight);
1125:
1126: /**
1127: * Fills a circular or elliptical arc covering the specified rectangle.
1128: * <p>
1129: * The resulting arc begins at <code>startAngle</code> and extends
1130: * for <code>arcAngle</code> degrees.
1131: * Angles are interpreted such that <code>0</code> degrees
1132: * is at the <code>3</code> o'clock position.
1133: * A positive value indicates a counter-clockwise rotation
1134: * while a negative value indicates a clockwise rotation.
1135: * <p>
1136: * The center of the arc is the center of the rectangle whose origin
1137: * is (<em>x</em>, <em>y</em>) and whose size is specified by the
1138: * <code>width</code> and <code>height</code> arguments.
1139: * <p>
1140: * If either <code>width</code> or <code>height</code> is zero or less,
1141: * nothing is drawn.
1142: *
1143: * <p> The filled region consists of the "pie wedge"
1144: * region bounded
1145: * by the arc
1146: * segment as if drawn by <code>drawArc()</code>, the radius extending from
1147: * the center to
1148: * this arc at <code>startAngle</code> degrees, and radius extending
1149: * from the
1150: * center to this arc at <code>startAngle + arcAngle</code> degrees. </p>
1151: *
1152: * <p> The angles are specified relative to the non-square extents of
1153: * the bounding rectangle such that <code>45</code> degrees always
1154: * falls on the
1155: * line from the center of the ellipse to the upper right corner of
1156: * the bounding rectangle. As a result, if the bounding rectangle is
1157: * noticeably longer in one axis than the other, the angles to the
1158: * start and end of the arc segment will be skewed farther along the
1159: * longer axis of the bounds. </p>
1160: *
1161: * @param x the <em>x</em> coordinate of the upper-left corner of
1162: * the arc to be filled.
1163: * @param y the <em>y</em> coordinate of the upper-left corner of the
1164: * arc to be filled.
1165: * @param width the width of the arc to be filled
1166: * @param height the height of the arc to be filled
1167: * @param startAngle the beginning angle.
1168: * @param arcAngle the angular extent of the arc,
1169: * relative to the start angle.
1170: * @see #drawArc(int, int, int, int, int, int)
1171: */
1172: public native void fillArc(int x, int y, int width, int height,
1173: int startAngle, int arcAngle);
1174:
1175: /**
1176: * Draws the outline of a circular or elliptical arc
1177: * covering the specified rectangle,
1178: * using the current color and stroke style.
1179: * <p>
1180: * The resulting arc begins at <code>startAngle</code> and extends
1181: * for <code>arcAngle</code> degrees, using the current color.
1182: * Angles are interpreted such that <code>0</code> degrees
1183: * is at the <code>3</code> o'clock position.
1184: * A positive value indicates a counter-clockwise rotation
1185: * while a negative value indicates a clockwise rotation.
1186: * <p>
1187: * The center of the arc is the center of the rectangle whose origin
1188: * is (<em>x</em>, <em>y</em>) and whose size is specified by the
1189: * <code>width</code> and <code>height</code> arguments.
1190: * <p>
1191: * The resulting arc covers an area
1192: * <code>width + 1</code> pixels wide
1193: * by <code>height + 1</code> pixels tall.
1194: * If either <code>width</code> or <code>height</code> is less than zero,
1195: * nothing is drawn.
1196: *
1197: * <p> The angles are specified relative to the non-square extents of
1198: * the bounding rectangle such that <code>45</code> degrees always
1199: * falls on the
1200: * line from the center of the ellipse to the upper right corner of
1201: * the bounding rectangle. As a result, if the bounding rectangle is
1202: * noticeably longer in one axis than the other, the angles to the
1203: * start and end of the arc segment will be skewed farther along the
1204: * longer axis of the bounds. </p>
1205: *
1206: * @param x the <em>x</em> coordinate of the upper-left corner
1207: * of the arc to be drawn
1208: * @param y the <em>y</em> coordinate of the upper-left corner
1209: * of the arc to be drawn
1210: * @param width the width of the arc to be drawn
1211: * @param height the height of the arc to be drawn
1212: * @param startAngle the beginning angle
1213: * @param arcAngle the angular extent of the arc, relative to
1214: * the start angle
1215: * @see #fillArc(int, int, int, int, int, int)
1216: */
1217: public native void drawArc(int x, int y, int width, int height,
1218: int startAngle, int arcAngle);
1219:
1220: /**
1221: * Draws the specified <code>String</code> using the current font and color.
1222: * The <code>x,y</code> position is the position of the anchor point.
1223: * See <a href="#anchor">anchor points</a>.
1224: * @param str the <code>String</code> to be drawn
1225: * @param x the x coordinate of the anchor point
1226: * @param y the y coordinate of the anchor point
1227: * @param anchor the anchor point for positioning the text
1228: * @throws NullPointerException if <code>str</code> is <code>null</code>
1229: * @throws IllegalArgumentException if anchor is not a legal value
1230: * @see #drawChars(char[], int, int, int, int, int)
1231: */
1232: public native void drawString(java.lang.String str, int x, int y,
1233: int anchor);
1234:
1235: /**
1236: * Draws the specified <code>String</code> using the current font and color.
1237: * The <code>x,y</code> position is the position of the anchor point.
1238: * See <a href="#anchor">anchor points</a>.
1239: *
1240: * <p>The <code>offset</code> and <code>len</code> parameters must
1241: * specify a valid range of characters within
1242: * the string <code>str</code>.
1243: * The <code>offset</code> parameter must be within the
1244: * range <code>[0..(str.length())]</code>, inclusive.
1245: * The <code>len</code> parameter
1246: * must be a non-negative integer such that
1247: * <code>(offset + len) <= str.length()</code>.</p>
1248: *
1249: * @param str the <code>String</code> to be drawn
1250: * @param offset zero-based index of first character in the substring
1251: * @param len length of the substring
1252: * @param x the x coordinate of the anchor point
1253: * @param y the y coordinate of the anchor point
1254: * @param anchor the anchor point for positioning the text
1255: * @see #drawString(String, int, int, int).
1256: * @throws StringIndexOutOfBoundsException if <code>offset</code>
1257: * and <code>length</code> do not specify
1258: * a valid range within the <code>String</code> <code>str</code>
1259: * @throws IllegalArgumentException if <code>anchor</code>
1260: * is not a legal value
1261: * @throws NullPointerException if <code>str</code> is <code>null</code>
1262: */
1263: public native void drawSubstring(String str, int offset, int len,
1264: int x, int y, int anchor);
1265:
1266: /**
1267: * Draws the specified character using the current font and color.
1268: * @param character the character to be drawn
1269: * @param x the x coordinate of the anchor point
1270: * @param y the y coordinate of the anchor point
1271: * @param anchor the anchor point for positioning the text; see
1272: * <a href="#anchor">anchor points</a>
1273: *
1274: * @throws IllegalArgumentException if <code>anchor</code>
1275: * is not a legal value
1276: *
1277: * @see #drawString(java.lang.String, int, int, int)
1278: * @see #drawChars(char[], int, int, int, int, int)
1279: */
1280: public native void drawChar(char character, int x, int y, int anchor);
1281:
1282: /**
1283: * Draws the specified characters using the current font and color.
1284: *
1285: * <p>The <code>offset</code> and <code>length</code> parameters must
1286: * specify a valid range of characters within
1287: * the character array <code>data</code>.
1288: * The <code>offset</code> parameter must be within the
1289: * range <code>[0..(data.length)]</code>, inclusive.
1290: * The <code>length</code> parameter
1291: * must be a non-negative integer such that
1292: * <code>(offset + length) <= data.length</code>.</p>
1293: *
1294: * @param data the array of characters to be drawn
1295: * @param offset the start offset in the data
1296: * @param length the number of characters to be drawn
1297: * @param x the x coordinate of the anchor point
1298: * @param y the y coordinate of the anchor point
1299: * @param anchor the anchor point for positioning the text; see
1300: * <a href="#anchor">anchor points</a>
1301: *
1302: * @throws ArrayIndexOutOfBoundsException if <code>offset</code>
1303: * and <code>length</code>
1304: * do not specify a valid range within the data array
1305: * @throws IllegalArgumentException if anchor is not a legal value
1306: * @throws NullPointerException if <code>data</code> is <code>null</code>
1307: *
1308: * @see #drawString(java.lang.String, int, int, int)
1309: */
1310: public native void drawChars(char[] data, int offset, int length,
1311: int x, int y, int anchor);
1312:
1313: /**
1314: * Draws the specified image by using the anchor point.
1315: * The image can be drawn in different positions relative to
1316: * the anchor point by passing the appropriate position constants.
1317: * See <a href="#anchor">anchor points</a>.
1318: *
1319: * <p>If the source image contains transparent pixels, the corresponding
1320: * pixels in the destination image must be left untouched. If the source
1321: * image contains partially transparent pixels, a compositing operation
1322: * must be performed with the destination pixels, leaving all pixels of
1323: * the destination image fully opaque.</p>
1324: *
1325: * <p>If <code>img</code> is the same as the destination of this Graphics
1326: * object, the result is undefined. For copying areas within an
1327: * <code>Image</code>, {@link #copyArea copyArea} should be used instead.
1328: * </p>
1329: *
1330: * @param img the specified image to be drawn
1331: * @param x the x coordinate of the anchor point
1332: * @param y the y coordinate of the anchor point
1333: * @param anchor the anchor point for positioning the image
1334: * @throws IllegalArgumentException if <code>anchor</code>
1335: * is not a legal value
1336: * @throws NullPointerException if <code>img</code> is <code>null</code>
1337: * @see Image
1338: */
1339: public void drawImage(Image img, int x, int y, int anchor) {
1340: if (!img.render(this , x, y, anchor)) {
1341: throw new IllegalArgumentException("");
1342: }
1343: }
1344:
1345: /**
1346: * Copies a region of the specified source image to a location within
1347: * the destination, possibly transforming (rotating and reflecting)
1348: * the image data using the chosen transform function.
1349: *
1350: * <p>The destination, if it is an image, must not be the same image as
1351: * the source image. If it is, an exception is thrown. This restriction
1352: * is present in order to avoid ill-defined behaviors that might occur if
1353: * overlapped, transformed copies were permitted.</p>
1354: *
1355: * <p>The transform function used must be one of the following, as defined
1356: * in the {@link javax.microedition.lcdui.game.Sprite Sprite} class:<br>
1357: *
1358: * <code>Sprite.TRANS_NONE</code> - causes the specified image
1359: * region to be copied unchanged<br>
1360: * <code>Sprite.TRANS_ROT90</code> - causes the specified image
1361: * region to be rotated clockwise by 90 degrees.<br>
1362: * <code>Sprite.TRANS_ROT180</code> - causes the specified image
1363: * region to be rotated clockwise by 180 degrees.<br>
1364: * <code>Sprite.TRANS_ROT270</code> - causes the specified image
1365: * region to be rotated clockwise by 270 degrees.<br>
1366: * <code>Sprite.TRANS_MIRROR</code> - causes the specified image
1367: * region to be reflected about its vertical center.<br>
1368: * <code>Sprite.TRANS_MIRROR_ROT90</code> - causes the specified image
1369: * region to be reflected about its vertical center and then rotated
1370: * clockwise by 90 degrees.<br>
1371: * <code>Sprite.TRANS_MIRROR_ROT180</code> - causes the specified image
1372: * region to be reflected about its vertical center and then rotated
1373: * clockwise by 180 degrees.<br>
1374: * <code>Sprite.TRANS_MIRROR_ROT270</code> - causes the specified image
1375: * region to be reflected about its vertical center and then rotated
1376: * clockwise by 270 degrees.<br></p>
1377: *
1378: * <p>If the source region contains transparent pixels, the corresponding
1379: * pixels in the destination region must be left untouched. If the source
1380: * region contains partially transparent pixels, a compositing operation
1381: * must be performed with the destination pixels, leaving all pixels of
1382: * the destination region fully opaque.</p>
1383: *
1384: * <p> The <code>(x_src, y_src)</code> coordinates are relative to
1385: * the upper left
1386: * corner of the source image. The <code>x_src</code>,
1387: * <code>y_src</code>, <code>width</code>, and <code>height</code>
1388: * parameters specify a rectangular region of the source image. It is
1389: * illegal for this region to extend beyond the bounds of the source
1390: * image. This requires that: </P>
1391: * <TABLE BORDER="2">
1392: * <TR>
1393: * <TD ROWSPAN="1" COLSPAN="1">
1394: * <pre><code>
1395: * x_src >= 0
1396: * y_src >= 0
1397: * x_src + width <= source width
1398: * y_src + height <= source height </code></pre>
1399: * </TD>
1400: * </TR>
1401: * </TABLE>
1402: * <P>
1403: * The <code>(x_dest, y_dest)</code> coordinates are relative to
1404: * the coordinate
1405: * system of this Graphics object. It is legal for the destination
1406: * area to extend beyond the bounds of the <code>Graphics</code>
1407: * object. Pixels
1408: * outside of the bounds of the <code>Graphics</code> object will
1409: * not be drawn.</p>
1410: *
1411: * <p>The transform is applied to the image data from the region of the
1412: * source image, and the result is rendered with its anchor point
1413: * positioned at location <code>(x_dest, y_dest)</code> in the
1414: * destination.</p>
1415: *
1416: * @param src the source image to copy from
1417: * @param x_src the x coordinate of the upper left corner of the region
1418: * within the source image to copy
1419: * @param y_src the y coordinate of the upper left corner of the region
1420: * within the source image to copy
1421: * @param width the width of the region to copy
1422: * @param height the height of the region to copy
1423: * @param transform the desired transformation for the selected region
1424: * being copied
1425: * @param x_dest the x coordinate of the anchor point in the
1426: * destination drawing area
1427: * @param y_dest the y coordinate of the anchor point in the
1428: * destination drawing area
1429: * @param anchor the anchor point for positioning the region within
1430: * the destination image
1431: *
1432: * @throws IllegalArgumentException if <code>src</code> is the
1433: * same image as the
1434: * destination of this <code>Graphics</code> object
1435: * @throws NullPointerException if <code>src</code> is <code>null</code>
1436: * @throws IllegalArgumentException if <code>transform</code> is invalid
1437: * @throws IllegalArgumentException if <code>anchor</code> is invalid
1438: * @throws IllegalArgumentException if the region to be copied exceeds
1439: * the bounds of the source image
1440: */
1441: public void drawRegion(Image src, int x_src, int y_src, int width,
1442: int height, int transform, int x_dest, int y_dest,
1443: int anchor) {
1444: if (!src.renderRegion(this , x_src, y_src, width, height,
1445: transform, x_dest, y_dest, anchor)) {
1446: throw new IllegalArgumentException("");
1447: }
1448: }
1449:
1450: /**
1451: * Copies the contents of a rectangular area
1452: * <code>(x_src, y_src, width, height)</code> to a destination area,
1453: * whose anchor point identified by anchor is located at
1454: * <code>(x_dest, y_dest)</code>. The effect must be that the
1455: * destination area
1456: * contains an exact copy of the contents of the source area
1457: * immediately prior to the invocation of this method. This result must
1458: * occur even if the source and destination areas overlap.
1459: *
1460: * <p>The points <code>(x_src, y_src)</code> and <code>(x_dest,
1461: * y_dest)</code> are both specified
1462: * relative to the coordinate system of the <code>Graphics</code>
1463: * object. It is
1464: * illegal for the source region to extend beyond the bounds of the
1465: * graphic object. This requires that: </P>
1466: * <TABLE BORDER="2">
1467: * <TR>
1468: * <TD ROWSPAN="1" COLSPAN="1">
1469: * <pre><code>
1470: * x_src + tx >= 0
1471: * y_src + ty >= 0
1472: * x_src + tx + width <= width of Graphics object's destination
1473: * y_src + ty + height <= height of Graphics object's destination
1474: * </code></pre>
1475: * </TD>
1476: * </TR>
1477: * </TABLE>
1478: *
1479: * <p>where <code>tx</code> and <code>ty</code> represent the X and Y
1480: * coordinates of the translated origin of this graphics object, as
1481: * returned by <code>getTranslateX()</code> and
1482: * <code>getTranslateY()</code>, respectively.</p>
1483: *
1484: * <P>
1485: * However, it is legal for the destination area to extend beyond
1486: * the bounds of the <code>Graphics</code> object. Pixels outside
1487: * of the bounds of
1488: * the <code>Graphics</code> object will not be drawn.</p>
1489: *
1490: * <p>The <code>copyArea</code> method is allowed on all
1491: * <code>Graphics</code> objects except those
1492: * whose destination is the actual display device. This restriction is
1493: * necessary because allowing a <code>copyArea</code> method on
1494: * the display would
1495: * adversely impact certain techniques for implementing
1496: * double-buffering.</p>
1497: *
1498: * <p>Like other graphics operations, the <code>copyArea</code>
1499: * method uses the Source
1500: * Over Destination rule for combining pixels. However, since it is
1501: * defined only for mutable images, which can contain only fully opaque
1502: * pixels, this is effectively the same as pixel replacement.</p>
1503: *
1504: * @param x_src the x coordinate of upper left corner of source area
1505: * @param y_src the y coordinate of upper left corner of source area
1506: * @param width the width of the source area
1507: * @param height the height of the source area
1508: * @param x_dest the x coordinate of the destination anchor point
1509: * @param y_dest the y coordinate of the destination anchor point
1510: * @param anchor the anchor point for positioning the region within
1511: * the destination image
1512: *
1513: * @throws IllegalStateException if the destination of this
1514: * <code>Graphics</code> object is the display device
1515: * @throws IllegalArgumentException if the region to be copied exceeds
1516: * the bounds of the source image
1517: *
1518: */
1519: public synchronized void copyArea(int x_src, int y_src, int width,
1520: int height, int x_dest, int y_dest, int anchor) {
1521:
1522: if (isScreenGraphics()) {
1523: throw new IllegalStateException();
1524: } else {
1525: doCopyArea(x_src, y_src, width, height, x_dest, y_dest,
1526: anchor);
1527: }
1528: }
1529:
1530: /**
1531: * Fills the specified triangle will the current color. The lines
1532: * connecting each pair of points are included in the filled
1533: * triangle.
1534: *
1535: * @param x1 the x coordinate of the first vertex of the triangle
1536: * @param y1 the y coordinate of the first vertex of the triangle
1537: * @param x2 the x coordinate of the second vertex of the triangle
1538: * @param y2 the y coordinate of the second vertex of the triangle
1539: * @param x3 the x coordinate of the third vertex of the triangle
1540: * @param y3 the y coordinate of the third vertex of the triangle
1541: *
1542: */
1543: public native void fillTriangle(int x1, int y1, int x2, int y2,
1544: int x3, int y3);
1545:
1546: /**
1547: * Native implementation of CopyArea method.
1548: *
1549: * @param x_src the x coordinate of upper left corner of source area
1550: * @param y_src the y coordinate of upper left corner of source area
1551: * @param width the width of the source area
1552: * @param height the height of the source area
1553: * @param x_dest the x coordinate of the destination anchor point
1554: * @param y_dest the y coordinate of the destination anchor point
1555: * @param anchor the anchor point for positioning the region within
1556: * the destination image
1557: *
1558: * @throws IllegalArgumentException if the region to be copied exceeds
1559: * the bounds of the source image
1560: */
1561: private native void doCopyArea(int x_src, int y_src, int width,
1562: int height, int x_dest, int y_dest, int anchor);
1563:
1564: /**
1565: * Renders a series of device-independent RGB+transparency values in a
1566: * specified region. The values are stored in
1567: * <code>rgbData</code> in a format
1568: * with <code>24</code> bits of RGB and an eight-bit alpha value
1569: * (<code>0xAARRGGBB</code>),
1570: * with the first value stored at the specified offset. The
1571: * <code>scanlength</code>
1572: * specifies the relative offset within the array between the
1573: * corresponding pixels of consecutive rows. Any value for
1574: * <code>scanlength</code> is acceptable (even negative values)
1575: * provided that all resulting references are within the
1576: * bounds of the <code>rgbData</code> array. The ARGB data is
1577: * rasterized horizontally from left to right within each row.
1578: * The ARGB values are
1579: * rendered in the region specified by <code>x</code>,
1580: * <code>y</code>, <code>width</code> and <code>height</code>, and
1581: * the operation is subject to the current clip region
1582: * and translation for this <code>Graphics</code> object.
1583: *
1584: * <p>Consider <code>P(a,b)</code> to be the value of the pixel
1585: * located at column <code>a</code> and row <code>b</code> of the
1586: * Image, where rows and columns are numbered downward from the
1587: * top starting at zero, and columns are numbered rightward from
1588: * the left starting at zero. This operation can then be defined
1589: * as:</p>
1590: *
1591: * <TABLE BORDER="2">
1592: * <TR>
1593: * <TD ROWSPAN="1" COLSPAN="1">
1594: * <pre><code>
1595: * P(a, b) = rgbData[offset + (a - x) + (b - y) * scanlength]
1596: * </code></pre>
1597: * </TD>
1598: * </TR>
1599: * </TABLE>
1600: *
1601: * <p> for </p>
1602: *
1603: * <TABLE BORDER="2">
1604: * <TR>
1605: * <TD ROWSPAN="1" COLSPAN="1">
1606: * <pre><code>
1607: * x <= a < x + width
1608: * y <= b < y + height </code></pre>
1609: * </TD>
1610: * </TR>
1611: * </TABLE>
1612: * <p> This capability is provided in the <code>Graphics</code>
1613: * class so that it can be
1614: * used to render both to the screen and to offscreen
1615: * <code>Image</code> objects. The
1616: * ability to retrieve ARGB values is provided by the {@link Image#getRGB}
1617: * method. </p>
1618: *
1619: * <p> If <code>processAlpha</code> is <code>true</code>, the
1620: * high-order byte of the ARGB format
1621: * specifies opacity; that is, <code>0x00RRGGBB</code> specifies a
1622: * fully transparent
1623: * pixel and <code>0xFFRRGGBB</code> specifies a fully opaque
1624: * pixel. Intermediate
1625: * alpha values specify semitransparency. If the implementation does not
1626: * support alpha blending for image rendering operations, it must remove
1627: * any semitransparency from the source data prior to performing any
1628: * rendering. (See <a href="Image.html#alpha">Alpha Processing</a> for
1629: * further discussion.)
1630: * If <code>processAlpha</code> is <code>false</code>, the alpha
1631: * values are ignored and all pixels
1632: * must be treated as completely opaque.</p>
1633: *
1634: * <p> The mapping from ARGB values to the device-dependent
1635: * pixels is platform-specific and may require significant
1636: * computation.</p>
1637: *
1638: * @param rgbData an array of ARGB values in the format
1639: * <code>0xAARRGGBB</code>
1640: * @param offset the array index of the first ARGB value
1641: * @param scanlength the relative array offset between the
1642: * corresponding pixels in consecutive rows in the
1643: * <code>rgbData</code> array
1644: * @param x the horizontal location of the region to be rendered
1645: * @param y the vertical location of the region to be rendered
1646: * @param width the width of the region to be rendered
1647: * @param height the height of the region to be rendered
1648: * @param processAlpha <code>true</code> if <code>rgbData</code>
1649: * has an alpha channel,
1650: * false if all pixels are fully opaque
1651: *
1652: * @throws ArrayIndexOutOfBoundsException if the requested operation
1653: * will attempt to access an element of <code>rgbData</code>
1654: * whose index is either negative or beyond its length
1655: * @throws NullPointerException if <code>rgbData</code> is <code>null</code>
1656: *
1657: */
1658: public native void drawRGB(int[] rgbData, int offset,
1659: int scanlength, int x, int y, int width, int height,
1660: boolean processAlpha);
1661:
1662: /**
1663: * Gets the color that will be displayed if the specified color
1664: * is requested. This method enables the developer to check the
1665: * manner in which RGB values are mapped to the set of distinct
1666: * colors that the device can actually display. For example,
1667: * with a monochrome device, this method will return either
1668: * <code>0xFFFFFF</code> (white) or <code>0x000000</code> (black)
1669: * depending on the brightness of the specified color.
1670: *
1671: * @param color the desired color (in <code>0x00RRGGBB</code>
1672: * format, the high-order
1673: * byte is ignored)
1674: * @return the corresponding color that will be displayed on the device's
1675: * screen (in <code>0x00RRGGBB</code> format)
1676: *
1677: */
1678: public native int getDisplayColor(int color);
1679:
1680: // private implementation //
1681:
1682: /**
1683: * The clip values are in the translated
1684: * coordinate system and maintained as intersected
1685: * with 0,0,maxWidth,maxHeight
1686: */
1687: private short clipX1, clipY1, clipX2, clipY2;
1688:
1689: /** Translated x,y coordinates */
1690: private int transX, transY;
1691: /**
1692: * System clip to hold any system clipping.
1693: * This saves the clip values imposed by
1694: * the system (e.g. from Theme support).
1695: * The clip values are in the translated
1696: * coordinate system.
1697: */
1698: private short systemClipX1, systemClipY1, systemClipX2,
1699: systemClipY2;
1700: /** used by dsPaint for saving translated values */
1701: private int ax, ay;
1702: /** A flag indicating the clipping state */
1703: private boolean clipped = false;
1704: /** Pixel values (-1 when uninitialized) */
1705: private int rgbColor, gray;
1706: /** pixel value (-1 when uninitialized) */
1707: private int pixel;
1708: /** Line stroke style */
1709: private int style;
1710: /** The current Font */
1711: private Font currentFont;
1712: /** The maximum width and height */
1713: private short maxWidth, maxHeight;
1714: /** A flag indicating MIDP runtime library clip state */
1715: private boolean runtimeClipEnforce = false;
1716:
1717: /**
1718: * The display ID associated with the device Graphics.
1719: * Note: that Graphics created with an Image will have display ID set
1720: * to -1. For device Graphics it will be set in
1721: * <code> getScreenGraphics() </code>.
1722: */
1723: private int displayId = -1;
1724:
1725: /**
1726: * If not null, this instance represent Graphics context for that
1727: * Image.
1728: */
1729: private Image img;
1730:
1731: /**
1732: * Retrieve the Graphics context for the given Image
1733: *
1734: * @param img The Image to get a Graphics context for
1735: * @return Graphics Will return a new ImageGraphics object if
1736: * the Image is non-null.
1737: */
1738: static Graphics getImageGraphics(Image img) {
1739: if (null == img) {
1740: throw new NullPointerException();
1741: }
1742:
1743: Graphics g = new Graphics();
1744: g.img = img;
1745: g.setDimensions(img.getWidth(), img.getHeight());
1746: g.reset();
1747:
1748: // construct and return a new ImageGraphics
1749: // object that uses the Image img as the
1750: // destination.
1751: return g;
1752: }
1753:
1754: /**
1755: * Retrieve the Graphics context for the given Image and
1756: * explicitly set the dimensions of the created context.
1757: *
1758: * It is possible the Image is bigger than area the Graphics
1759: * context should provide access to, e.g. off-screen buffer
1760: * created for full screen mode, but used for both normal and
1761: * full modes with no resizing.
1762: *
1763: * @param img The Image to get a Graphics context for
1764: * @param width The width of the Graphics context
1765: * @param height The height of the Graphics context
1766: * @return Graphics Will return a new ImageGraphics object if
1767: * the Image is non-null.
1768: */
1769: static Graphics getImageGraphics(Image img, int width, int height) {
1770: if (null == img) {
1771: throw new NullPointerException();
1772: }
1773:
1774: int w = img.getWidth();
1775: int h = img.getHeight();
1776: if (w > width) {
1777: w = width;
1778: }
1779: if (h > height) {
1780: h = height;
1781: }
1782:
1783: Graphics g = new Graphics();
1784: g.img = img;
1785: g.setDimensions(w, h);
1786: g.reset();
1787: return g;
1788: }
1789:
1790: /**
1791: * Retrieve the Graphics context that renders to the
1792: * device's display
1793: *
1794: * @param displayId The graphics object will be associated
1795: * with Display with that displayId
1796: * @param width The width of the Graphics context
1797: * @param height The height of the Graphics context.
1798: * @return Graphics
1799: */
1800: static Graphics getScreenGraphics(int displayId, int width,
1801: int height) {
1802:
1803: Graphics g = new Graphics();
1804: g.displayId = displayId;
1805:
1806: g.img = null;
1807: g.setDimensions(width, height);
1808: g.reset();
1809:
1810: return g;
1811: }
1812:
1813: /**
1814: * Determines if this a <code>Graphics</code> object used to
1815: * represent the device.
1816: * @return true if this Graphics represents the device;
1817: * false - otherwise
1818: */
1819: boolean isScreenGraphics() {
1820: return (displayId != -1);
1821: }
1822:
1823: /**
1824: * Reset this Graphics context with the given coordinates
1825: *
1826: * @param x1 The upper left x coordinate
1827: * @param y1 The upper left y coordinate
1828: * @param x2 The lower right x coordinate
1829: * @param y2 The lower right y coordinate
1830: */
1831: void reset(int x1, int y1, int x2, int y2) {
1832: resetGC();
1833: transX = transY = 0;
1834: setClip(x1, y1, x2 - x1, y2 - y1);
1835: }
1836:
1837: /**
1838: * Reset this Graphics context to its default dimensions
1839: * (same as reset(0, 0, maxWidth, maxHeight)
1840: */
1841: void reset() {
1842: reset(0, 0, maxWidth, maxHeight);
1843: }
1844:
1845: /**
1846: * Reset the Graphic context with all items related
1847: * to machine independent context.
1848: * There is no translation and clipping involve
1849: * since different implementations may map it
1850: * directly or not.
1851: * Only Font, Style, and Color are reset in
1852: * this function.
1853: */
1854: void resetGC() {
1855: currentFont = Font.getDefaultFont();
1856: style = SOLID;
1857: rgbColor = gray = 0;
1858: pixel = getPixel(rgbColor, gray, true);
1859: }
1860:
1861: /**
1862: * Preserve MIDP runtime GC.
1863: * - Our internal MIDP clip to protect
1864: * it from MIDlet drawing on top of our widget.
1865: * - Translation
1866: *
1867: * @param systemX The system upper left x coordinate
1868: * @param systemY The system upper left y coordinate
1869: * @param systemW The system width of the rectangle
1870: * @param systemH The system height of the rectangle
1871: */
1872: void preserveMIDPRuntimeGC(int systemX, int systemY, int systemW,
1873: int systemH) {
1874: runtimeClipEnforce = true;
1875: clipRect(systemX, systemY, systemW, systemH);
1876:
1877: // this is the first time, we setup
1878: // the systemClip values.
1879: systemClipX1 = clipX1;
1880: systemClipY1 = clipY1;
1881: systemClipX2 = clipX2;
1882: systemClipY2 = clipY2;
1883:
1884: // Preserve the translation system
1885: translate(systemX, systemY);
1886: ax = getTranslateX();
1887: ay = getTranslateY();
1888: }
1889:
1890: /**
1891: * Restore the runtime GC.
1892: * - Release the internal runtime clip values by
1893: * unsetting the variable.
1894: * - Restore the original translation
1895: */
1896: void restoreMIDPRuntimeGC() {
1897: runtimeClipEnforce = false;
1898: translate(ax - getTranslateX(), ay - getTranslateY());
1899: }
1900:
1901: /**
1902: * Get a gray value given the RGB values
1903: *
1904: * @param red The Red pixel value
1905: * @param green The Green pixel value
1906: * @param blue The Blue pixel value
1907: * @return int The grayscale value corresponding to the RGB color
1908: */
1909: private static int grayVal(int red, int green, int blue) {
1910: /* CCIR Rec 601 luma (nonlinear rgb to nonlinear "gray") */
1911: return (red * 76 + green * 150 + blue * 29) >> 8;
1912: }
1913:
1914: /**
1915: * Get a specific pixel value
1916: *
1917: * @param rgb
1918: * @param gray
1919: * @param isGray
1920: * @return int
1921: */
1922: private native int getPixel(int rgb, int gray, boolean isGray);
1923:
1924: /**
1925: * Returns the maximal width available for the clipping
1926: * withing this Graphics context
1927: * @return The width of the Graphics context
1928: */
1929: short getMaxWidth() {
1930: return maxWidth;
1931: }
1932:
1933: /**
1934: * Returns the maximal height available for the clipping
1935: * withing this Graphics context
1936: * @return The height of the Graphics context
1937: */
1938: short getMaxHeight() {
1939: return maxHeight;
1940: }
1941:
1942: /**
1943: * The creator of this Graphics instance
1944: *
1945: * IMPL_NOTE: The information about Graphics object creator is
1946: * needed to JSRs (e.g. JSR239) that are given with Graphics
1947: * instance and has no further information on its creator changes,
1948: * e.g. of resizing, but at the same time should be able to paint
1949: * properly into this Graphics.
1950: */
1951: private Object creator = null;
1952:
1953: /**
1954: * Returns the creator of this Graphics object
1955: * @return Graphics creator reference
1956: */
1957: synchronized Object getCreator() {
1958: return creator;
1959: }
1960:
1961: /**
1962: * Sets the creator of this Graphics object
1963: * @param creator the reference to creator of this Graphics object
1964: */
1965: synchronized void setCreator(Object creator) {
1966: // Ignore repeated attempts to set creator
1967: if (this .creator == null) {
1968: this .creator = creator;
1969: }
1970: }
1971:
1972: } // class Graphics
|