TinyLine 2D Programming Guide

4 Graphics State

The exact effect of the drawing is determined by TinyState attributes as the current line thickness (stroke width), the current stroke color, the current fill alpha, etc. These TinyState attributes are part of the graphics state.

Below is the table of the Tiny2D attributes of the graphics state, sorted alphabetically.

For each attribute, the table lists the name of the attribute, the initial (default) value and the description.

Attribute Initial value Description
antialias true If it is true, Tiny2D draws with antialiasing.
bg 0xffffffff The background ARBG color.
capStyle CAP_BUTT The stroke cap style specifies the shape to be used at the end of open subpaths when they are stroked. There are three stoke cap styles: CAP_BUTT, CAP_ROUND and CAP_SQUARE.
dashArray null The stroke dash array controls the pattern of dashes and gaps used to stroke paths.
dashPhase 0 The stroke dash phase specifies the distance into the dash pattern to start the dash.
devBounds an empty rectangle The shape bounds in device space.
fillAlpha 255 The fill alpha specifies the opacity of the painting operation used to paint the interior the shape.
fillColor TinyColor(0xff000000) The fill color paints the interior of the given shape.
fillRule FILL_STYLE_EO The fill rule indicates the algorithm which is to be used to determine what parts of the canvas are included inside the shape. There are two types of winding rules: FILL_STYLE_EO and FILL_SYLE_WIND
globalAlpha 255 The global alpha specifies the opacity of all painting operations.
joinStyle JOIN_MITER The stroke join style specifies the shape to be used at the corners of paths or basic shapes when they are stroked. There are three line join styles: JOIN_BEVEL, JOIN_MITER and JOIN_ROUND.
matrix the identity matrix The transformation matrix that defines the mapping from user space to device space.
miterLimit 4<<FIX_BITS The stroke miter limit imposes a limit on the ratio of the miter length to the stroke width.
smoothbits false If it is true, Tiny2D draws images with anti-aliasing.
strokeAlpha 255 The stroke alpha specifies the opacity of the painting operation used to stroke the shape.
strokeColor TinyColor.NONE The stroke color paints along the outline of the given shape.
strokeWidth 1<<FIX_BITS The width of the stroke.
textDir TEXT_DIR_LR The current text direction.

4.1 Antialiasing

Aliasing occurs because vector objects like paths or text outlines have continuous, smooth curves and lines and pixels are discrete and square.

The Tiny2D drawing functions include the rasterization process - the process of converting vector data (TinyPath) into pixel data (TinyBuffer). Since pixels are square and uniformly colored, lines become jagged.

Antialiasing reduces these unwanted jagged borders between colors.

If the antialias is true, then Tiny2D drawing functions use antialiasing during the rasterization process. Because, antialiasing is computationally expensive, costs CPU, in some cases you might want to turn antialiasing on for some shapes and turn it off for the others.

Example: Alias.java

alias

View the example as applet (Java-enabled browsers only)

Before displaying the first oval, the application turns the antialiasing off:

            /* Turns the antialiasing off */
            tstate.antialias   = false;
            /* Draws the ovals */
            t2d.drawOval(20<<Tiny2D.FIX_BITS,
		         40<<Tiny2D.FIX_BITS,
                         100<<Tiny2D.FIX_BITS,
                         50<<Tiny2D.FIX_BITS);

Then we translate the current transformation matrix and turn the antialiasing on before drawing the same oval again:

            /* Translate the current transformation matrix */
            TinyMatrix m = new TinyMatrix();
            m.translate(0<<Tiny2D.FIX_BITS, 60<<Tiny2D.FIX_BITS );
            t2d.matrix = m;

            /* Turns the antialiasing on */
            tstate.antialias   = true;
            /* Draws the ovals */
            t2d.drawOval(20<<Tiny2D.FIX_BITS,
			 40<<Tiny2D.FIX_BITS,
                         100<<Tiny2D.FIX_BITS,
                         50<<Tiny2D.FIX_BITS);

4.2 Background color

The TinyBuffer object is a surface onto which graphics elements are drawn. We need to fill the TinyBuffer object with some initial color (background color) before we can draw anything.

4.3 Line cap style

The line cap style (capStyle) specifies the shape to be used at the end of open subpaths when they are stroked. There are three line cap styles: CAP_BUTT, CAP_ROUND and CAP_SQUARE.

The CAP_BUTT line cap style ends unclosed subpaths and dash segments with no added decoration.

The CAP_ROUND line cap style ends unclosed subpaths and dash segments with a round decoration that has a radius equal to half of the width of the pen.

The CAP_SQUARE line cap ends unclosed subpaths and dash segments with a square projection that extends beyond the end of the segment to a distance equal to half of the line width.

Example: LineCap.java

linecap

View the example as applet (Java-enabled browsers only)

In the example, we draw the same line with different line cap styles. The thin white line is drawn only for emphasizing the difference between styles.

First, the line is drawn with the CAP_BUTT line cap style:


            /* Draws a black line with the CAP_BUTT line cap style */
            tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
            tstate.capStyle = Tiny2D.CAP_BUTT;

            t2d.drawLine(40<<Tiny2D.FIX_BITS,
			 60<<Tiny2D.FIX_BITS,
                         140<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS);

Then the line is drawn with the CAP_ROUND line cap style:


            /* Draws a black line with the CAP_ROUND line cap style */
            tstate.strokeColor = blackColor;
            tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
            tstate.capStyle = Tiny2D.CAP_ROUND;

            t2d.drawLine(40<<Tiny2D.FIX_BITS,
			 100<<Tiny2D.FIX_BITS,
                         140<<Tiny2D.FIX_BITS,
                         100<<Tiny2D.FIX_BITS);

Finally, we draw the line with the CAP_SQUARE line cap style:

            /* Draws a black line with the CAP_SQUARE line cap style */
            tstate.strokeColor = blackColor;
            tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
            tstate.capStyle = Tiny2D.CAP_SQUARE;

            t2d.drawLine(40<<Tiny2D.FIX_BITS,
			 140<<Tiny2D.FIX_BITS,
                         140<<Tiny2D.FIX_BITS,
                         140<<Tiny2D.FIX_BITS);

4.4 Line dash pattern

The line dash pattern (dashArray and dashArray ) specifies the pattern of dashes and gaps used to stoke paths.

The dashArray defines the lengths of dashes and gaps and the dashPhase defines the distance into the dash patterns to start the dash. Both values should be in user space. Dashes wrap around corners and go along curves just as stoked lines and curves do.

Example: Dash.java

dash

View the example as applet (Java-enabled browsers only)

In the example we draw the same line but with different line dash patterns. The line drawing code is similar for all cases:


            /* Draws a black line with the first dash array */
            tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
            tstate.capStyle = Tiny2D.CAP_BUTT;
            tstate.dashArray = dashArray1;
            t2d.drawLine(40<<Tiny2D.FIX_BITS,
			 60<<Tiny2D.FIX_BITS,
                         140<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS);

What is changing is the dashArray attribute of the Tiny2D graphics state.

For each line, the corresponding dash array is defined as:

    int dashArray1[] = { 2<<Tiny2D.FIX_BITS,  2<<Tiny2D.FIX_BITS };
    int dashArray2[] = { 6<<Tiny2D.FIX_BITS,  6<<Tiny2D.FIX_BITS };
    int dashArray3[] = { 4<<Tiny2D.FIX_BITS,  1<<Tiny2D.FIX_BITS,
                         2<<Tiny2D.FIX_BITS,  1<<Tiny2D.FIX_BITS,
                         1<<Tiny2D.FIX_BITS,  6<<Tiny2D.FIX_BITS };

4.5 Shape bounds

The shape bounds in device space devBounds specifies what area of the TinyBuffer will be updated.

4.6 Fill Alpha

The fillAlpha specifies the opacity of the painting operation used to paint the interior of paths and text characters. The valid values should be inside the range 0 (fully transparent) to 255 (fully opaque). The initial value is 255.

Example: FillAlpha.java

fillalpha

View the example as applet (Java-enabled browsers only)

In the example, first we draw the full opaque red rectangle and the full opaque green rectangle over the red one.

            /* Draws the red rectangle first */
            tstate.fillColor = (redColor);
            tstate.fillAlpha = 255;
            t2d.drawRect(40<<Tiny2D.FIX_BITS,
			 40<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS);
            /* Draws the green rectangle over the red one */
            tstate.fillColor = (greenColor);
            t2d.drawRect(20<<Tiny2D.FIX_BITS,
			 20<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS);

Then we shift the current transformation matrix and draw the full opaque red rectangle and the green rectangle with the semi transparent fillAlpha (127) over the red one.


            /* Draws the red rectangle first */
            tstate.fillColor = (redColor);
            t2d.drawRect(40<<Tiny2D.FIX_BITS,
			 40<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS);
            /* Draws the green rectangle over the red one */
            tstate.fillColor = (greenColor);
            tstate.fillAlpha = 127;
            t2d.drawRect(20<<Tiny2D.FIX_BITS,
			 20<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS);

4.7 Fill Color

The fillColor attribute is used to paint the interior of paths and text characters. The initial value is a solid back color 0xff000000 in ARGB format.

4.8 Fill Rule

The fillRule attribute indicates the algorithm that is to be used to determine what parts of the canvas are included inside the shape. There are two types of winding rules: FILL_STYLE_EO and FILL_SYLE_WIND. The initial value is FILL_STYLE_EO.

The FILL_STYLE_EO fill rule is an even-odd winding rule. The FILL_STYLE_EO winding rule means that enclosed regions of the path alternate between interior and exterior areas as traversed from the outside of the path towards a point inside the region.

The FILL_STYLE_WIND fill rule is a non-zero winding rule. The FILL_SYLE_WIND winding rule means the following. Let us assume an imaginary ray is drawn in any direction from a given point to infinity. If the places where the path intersects the ray are examined, the point is inside of the path if the number of times that the path crosses the ray from left to right does not equal the number of times that the path crosses the ray from right to left.

Example: FillRule.java

fillrule

View the example as applet (Java-enabled browsers only)

In the example, we draw the same path with the same fill color, but with different fill rules.

First, we draw the path with the FILL_STYLE_EO fill rule.

            /* Sets the fill rule. */
            tstate.fillRule = Tiny2D.FILL_STYLE_EO;

            /* Draws the path */
            t2d.drawPath(path);

Then we change the current transformation matrix and draw the path with the FILL_STYLE_WIND fill rule.

            /* Sets the fill rule. */
            tstate.fillRule = Tiny2D.FILL_STYLE_WIND;

            /* Draws the path */
            t2d.drawPath(path);

4.9 Global Alpha

The globalAlpha specifies the opacity of the all painting operations. The value must be in the range [0-255].

The picture below compares a global alpha setting of 127 with the default value of 255.

Example: GAlpha.java

galpha

View the example as applet (Java-enabled browsers only)

The example is similar to the FillAlpha.java excepts that we change the alpha for all painting operations when we drawing the second set of rectangles:

            tstate.globalAlpha = 127;

            /* Draws the red rectangle first */
            tstate.fillColor = (redColor);
            t2d.drawRect(40<<Tiny2D.FIX_BITS,
			 40<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS,
                         45<<Tiny2D.FIX_BITS);
            /* Draws the green rectangle over the red one */
            tstate.fillColor = (greenColor);
            t2d.drawRect(20<<Tiny2D.FIX_BITS,
			 20<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS,
                         60<<Tiny2D.FIX_BITS);

4.10 Line join style

The line join style (joinStyle) specifies the shape is to be used at the corners of stoked paths. There are three line join styles: JOIN_MITER, JOIN_ROUND and JOIN_BEVEL.

The JOIN_MITER line join style joins path segments by extending their outside edges until they meet.

The JOIN_ROUND line join style joins path segments by rounding off the corner at a radius of half the line width.

The JOIN_BEVEL line join style joins path segments by connecting the outer corners of their wide outlines with a straight segment.

Example: LineJoin.java

linejoin

View the example as applet (Java-enabled browsers only)

In the example, the same path is drawn with different line join styles. The thin white line is drawn only for emphasizing the difference between styles.

First, the path is drawn with the JOIN_MITER line join style:

           /* Draws a black path with the JOIN_MITER line join style */
           tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
           tstate.joinStyle = Tiny2D.JOIN_MITER;
           t2d.drawPath(path, null, null);

Then the path is drawn with the JOIN_ROUND line join style:

           /* Draws a black path with the JOIN_ROUND line join style */
           tstate.strokeColor = blackColor;
           tstate.fillColor   = TinyColor.NONE;
           tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
           tstate.joinStyle = Tiny2D.JOIN_ROUND;
           t2d.drawPath(path, null, null);

Finally, we draw the path with the JOIN_BEVEL line join style:

           /* Draws a black path with the JOIN_BEVEL line join style */
           tstate.strokeColor = blackColor;
           tstate.fillColor   = TinyColor.NONE;
           tstate.strokeWidth = (20<<Tiny2D.FIX_BITS);
           tstate.joinStyle = Tiny2D.JOIN_BEVEL;
           t2d.drawPath(path, null, null);

4.11 Matrix

The matrix attribute is the matrix specifying transformation from user space to device space.

4.12 Miter limit

When two line segments meet at a sharp angle and JOIN_MITER is specified for the line join style joinStyle, it is possible for the miter to extend far beyond the thickness of the line stroking the path.

The miterLimit imposes a limit on the ratio of the miter length to the strokeWidth. When the limit is exceeded, the join style is converted from JOIN_MITER to JOIN_BEVEL.

The value of miterLimit must be a number greater than or equal to 1<<FIX_BITS. The initial value is 4<<FIX_BITS.

4.13 Smooth Bits

Aliasing occurs also when drawing with a bitmap color the source image has been transformed (for example scaled). Anti-aliasing reduces unwanted jagged borders between colors.

If the smoothbits is true, then Tiny2D draws images with anti-aliasing. Because, anti-aliasing is computationally expensive, costs CPU, in some cases you might want to turn anti-aliasing on for some images and turn it off for the others.

Example: SmoothBits.java

smoothbits

View the example as applet (Java-enabled browsers only)

Before displaying the first rectangle, the application turns the smoothbits off:

	   /*
	   * Draw the first rectangle with the bitmap color without 
           * anti-aliasing
           */
	   tstate.devMat = matrix1;
	   tstate.fillColor = color;
	   tstate.strokeColor = TinyColor.NONE;
	   /* Tiny2D draws images without anti-aliasing. */
	   tstate.smoothbits = false;
	   t2d.drawRect(0 << Tiny2D.FIX_BITS, 0 << Tiny2D.FIX_BITS,
		        60 << Tiny2D.FIX_BITS, 40 << Tiny2D.FIX_BITS);            

Then we translate the current transformation matrix and turn the anti-aliasing on (smoothbits) before drawing the same rectangle again:

  
           /*
           * Draw the second rectangle with the bitmap color with
           * anti-aliasing
           */
           tstate.devMat = matrix2;
           tstate.fillColor = color;
           tstate.strokeColor = TinyColor.NONE;
           /* Tiny2D draws images with anti-aliasing. */
           tstate.smoothbits = true;
	   t2d.drawRect(0 << Tiny2D.FIX_BITS, 0 << Tiny2D.FIX_BITS,
		        60 << Tiny2D.FIX_BITS, 40 << Tiny2D.FIX_BITS);            

4.14 Stroke Alpha

The strokeAlpha attribute specifies the opacity of the painting operation used to paint the border of paths and text characters. The valid values should be inside the range 0 (fully transparent) to 255 (fully opaque). The initial value is 255.

4.15 Stroke Color

The stroke attribute is used to paint the border of paths and text characters. The initial value is TinyColor.NONE that causes no stroke to be painted.

4.16 Stroke Width

The strokeWidth specifies the thickness of the line used to stoke a path or a text and is measured in user space units. A stroke width of 0 causes no stroke to be painted. The initial value is 1<<FIX_BITS.

4.17 Text layout direction

The characters in certain scripts are written from right-to-left or from top-to-bottom. The textDir attribute specifies whether the progression direction for a text should be left-to-right, right-to-left, or top-to-bottom. There are three text direction styles: TEXT_DIR_LR, TEXT_DIR_RL and TEXT_DIR_TB. The initial value is TEXT_DIR_LR.

© 2010 TinyLine. All rights reserved.