Jump to: navigation, search

Difference between revisions of "GEF/GEF4/Graphics"

< GEF‎ | GEF4
m
m
(37 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
== Introduction ==
 
== Introduction ==
  
The GEF 4 Graphics component provides a level of abstraction over different drawing toolkits. At the moment, SWT and AWT backends are in development. Its goal is to be as complete as possible, i.e. you should have access to all the functionality that you have access to when working directly with one of the underlying drawing toolkits. Of course, this is not always viable, but rather the greatest common divisor of the underlying drawing toolkits is accessible via the abstraction layer.
+
The GEF4 Graphics component provides a level of abstraction over different drawing toolkits (natives). At the moment, SWT and AWT backends are in development. Its goal is to be as complete as possible, i.e. you should have access to all the functionality that you have access to when working directly with one of the natives (SWT or AWT). Of course, this is not always viable. But we aim to provide at least the greatest common divisor of the functionality that is offered by the individual natives and additionally, decent simulations for operations which are not offered by all natives.
 +
 
 +
== Features ==
 +
 
 +
{|border="0" borderwidth="10"
 +
!width="*"|
 +
!width="130" align="center"|GEF4 Graphics
 +
!width="130" align="center"|GEF 3.x Draw2d
 +
!width="130" align="center"|SWT
 +
!width="130" align="center"|AWT
 +
!width="*"|
 +
|-
 +
|'''General'''
 +
|-
 +
|Affine coordinate transformations
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Missing transformation: shearing.">1</span></span></sup></div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to transform the coordinate system|how-to]]
 +
|-
 +
|Resolution independent rendering
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|-
 +
|State stack mechanism: push/pop/restore
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|[[#How to use the states stack|how-to]]
 +
|-
 +
|Off-screen rendering support
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:#555; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">?</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to do off-screen rendering|how-to]]
 +
|-
 +
|'''Drawing geometric primitives'''
 +
|-
 +
|Lines, polylines, rectangles, polygons, arcs, rounded-rectangles, and ellipses
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to draw geometric primitives|how-to]]
 +
|-
 +
|Arbitrary Bezier curves, curved-polygons, and polybeziers
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Implemented for quadratic and cubic Bezier curves.">2</span></span></sup></div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Implemented for quadratic and cubic Bezier curves.">2</span></span></sup></div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Implemented for quadratic and cubic Bezier curves.">2</span></span></sup></div>
 +
|[[#How to draw arbitrary Bezier curves|how-to]]
 +
|-
 +
|Arbitrary clipping area
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to use the clipping area|how-to]]
 +
|-
 +
|Basic stroke: width, caps, joins, dashes
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to change the stroke|how-to]]
 +
|-
 +
|Single-stop, cyclic/acyclic, linear gradients
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="No support for cyclic gradients.">3</span></span></sup></div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="No support for cyclic gradients.">3</span></span></sup></div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to use linear gradients|how-to]]
 +
|-
 +
|Multi-stop, cyclic/acyclic, linear gradients
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to use linear gradients|how-to]]
 +
|-
 +
|Multi-stop, cyclic/acyclic, radial gradients
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to use radial gradients|how-to]]
 +
|-
 +
|Image fill
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to do an image fill|how-to]]
 +
|-
 +
|'''Displaying text'''
 +
|-
 +
|Basic text drawing
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to draw text|how-to]]
 +
|-
 +
|Font styles: italic, bold, and underlined
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Missing font style: underlined.">4</span></span></sup></div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Missing font style: underlined.">4</span></span></sup></div>
 +
|<div style="background-color:#a90; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+/-<sup><span style="position:absolute">&nbsp;&nbsp;<span style="border-bottom:1px dotted; cursor:help;" title="Missing font style: underlined.">4</span></span></sup></div>
 +
|[[#How to change the font style|how-to]]
 +
|-
 +
|Filling text with a gradient
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to fill text with a gradient|how-to]]
 +
|-
 +
|Filling text with image data
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to fill text with image data|how-to]]
 +
|-
 +
|'''Image operations'''
 +
|-
 +
|Basic image drawing
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to display images|how-to]]
 +
|-
 +
|Image resizing
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to resize images|how-to]]
 +
|-
 +
|Image blurring
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|[[#How to blur images|how-to]]
 +
|-
 +
|Combining images via standard arithmetic or logical operations
 +
|<div style="background-color:darkgreen; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">+</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|<div style="background-color:darkred; color:white; font-weight:bold; border-radius:8px; -moz-border-radius:8px; text-align:center;">-</div>
 +
|[[#How to do image arithmetic|how-to]]
 +
|}
 +
 
 +
<br />
 +
 
 +
'''Footnotes:'''
 +
#Missing transformation: shearing.
 +
#Implemented for quadratic and cubic Bezier curves.
 +
#No support for cyclic gradients.
 +
#Missing font style: underlined.
  
 
== IGraphics ==
 
== IGraphics ==
  
The heart of the GEF 4 Graphics component is the IGraphics interface. Normally, you will be handed over an IGraphics to accomplish your displaying tasks by a surrounding framework, but it can be used stand-alone, too. Thereto, you have to create a specific IGraphics implementation. Let us consider the following SWT example:
+
The heart of the GEF4 Graphics component is the IGraphics interface. Normally, you will be handed over an IGraphics to accomplish your displaying tasks by a surrounding framework, but it can be used stand-alone, too. Thereto, you have to create a specific IGraphics implementation. Let us consider the following SWT example:
  
 +
''[Example 001: Simple Graphics]''
 
<source lang="java">
 
<source lang="java">
package org.eclipse.gef4.graphics.examples;
+
/*******************************************************************************
 +
* Copyright (c) 2012, 2013 itemis AG and others.
 +
*
 +
* All rights reserved. This program and the accompanying materials
 +
* are made available under the terms of the Eclipse Public License v1.0
 +
* which accompanies this distribution, and is available at
 +
* http://www.eclipse.org/legal/epl-v10.html
 +
*
 +
* Contributors:
 +
*    Matthias Wienand (itemis AG) - initial API and implementation
 +
*   
 +
*******************************************************************************/
 +
package org.eclipse.gef4.graphics.examples.doc;
  
 
import org.eclipse.gef4.geometry.planar.Ellipse;
 
import org.eclipse.gef4.geometry.planar.Ellipse;
import org.eclipse.gef4.graphics.Color;
+
import org.eclipse.gef4.geometry.planar.Polygon;
 +
import org.eclipse.gef4.geometry.planar.Rectangle;
 
import org.eclipse.gef4.graphics.IGraphics;
 
import org.eclipse.gef4.graphics.IGraphics;
import org.eclipse.gef4.graphics.swt.DisplayGraphics;
+
import org.eclipse.gef4.graphics.LineCap;
 +
import org.eclipse.gef4.graphics.LineJoin;
 +
import org.eclipse.gef4.graphics.color.Color;
 +
import org.eclipse.gef4.graphics.swt.SwtGraphics;
 
import org.eclipse.swt.SWT;
 
import org.eclipse.swt.SWT;
 
import org.eclipse.swt.events.PaintEvent;
 
import org.eclipse.swt.events.PaintEvent;
Line 24: Line 207:
 
import org.eclipse.swt.widgets.Shell;
 
import org.eclipse.swt.widgets.Shell;
  
public class SWTGraphicsExample implements PaintListener {
+
public class Example001 implements PaintListener {
  
 
public static void main(String[] args) {
 
public static void main(String[] args) {
new SWTGraphicsExample("GEF 4 Graphics - SWT");
+
new Example001("Simple Graphics");
 
}
 
}
  
public SWTGraphicsExample(String title) {
+
public Example001(String title) {
 
Display display = new Display();
 
Display display = new Display();
  
Line 39: Line 222:
  
 
shell.addPaintListener(this);
 
shell.addPaintListener(this);
 +
shell.redraw(); // platform independently triggers a PaintEvent
  
 
while (!shell.isDisposed()) {
 
while (!shell.isDisposed()) {
Line 47: Line 231:
 
}
 
}
  
 +
@Override
 
public void paintControl(PaintEvent e) {
 
public void paintControl(PaintEvent e) {
DisplayGraphics g = new DisplayGraphics(e.gc);
+
SwtGraphics g = new SwtGraphics(e.gc);
 
renderScene(g);
 
renderScene(g);
 
g.cleanUp();
 
g.cleanUp();
Line 54: Line 239:
  
 
public void renderScene(IGraphics g) {
 
public void renderScene(IGraphics g) {
g.fillProperties().setColor(new Color(255, 0, 0, 255));
+
// The rendering code goes here. It is independent of the actual
g.fill(new Ellipse(50, 50, 350, 200));
+
// IGraphics implementation. Therefore, it is independent of the
 +
// underlying drawing toolkit, too.
 +
 
 +
final Ellipse ellipse = new Ellipse(50, 50, 350, 200);
 +
final Rectangle rectangle = new Rectangle(100, 160, 125, 220);
 +
final Polygon triangle = new Polygon(260, 170, 190, 300, 330, 300);
 +
 
 +
g.setFill(new Color(255, 0, 0)).setDraw(new Color(128, 0, 0))
 +
.setDashArray(25, 10);
 +
 
 +
g.fill(ellipse).draw(ellipse.getOutline());
 +
 
 +
g.setFill(new Color(0, 0, 255)).setLineJoin(LineJoin.ROUND)
 +
.setLineCap(LineCap.ROUND);
 +
 
 +
g.fill(rectangle).draw(rectangle.getOutline());
 +
 
 +
g.setFill(new Color(0, 255, 0)).setDraw(new Color(0, 128, 0))
 +
.setLineJoin(LineJoin.MITER);
 +
 
 +
g.fill(triangle).draw(triangle.getOutline());
 
}
 
}
  
 
}
 
}
 
</source>
 
</source>
 +
[[Image:GEF4Graphics-example001.png|Simple GEF4 Graphics example (SWT)]]
  
As you can see in this example, the DisplayGraphics is an IGraphics implementation. It can be constructed via a SWT GC which is passed-in to the paintControl() event handler. The renderScene() method does not know anything about the actual IGraphics implemention that is used. That's why we do not need to adjust our rendering code when switching to AWT, for example. You may wonder why we have to call the cleanUp() method on the DisplayGraphics. In the case of SWT, this is necessary to fully free the system resources that will be allocated during the rendering process. But let us concentrate on the renderScene() method.
+
''[Note: You can tryout the examples in your local GEF4 installation. Every example shown in this documentation exists in the org.eclipse.gef4.graphics.examples project under the org.eclipse.gef4.graphics.examples.doc package. The examples are easily found via their identification number which is written atop the source code.]''
  
There are two important things to notice:
+
As you can see in this example, the SwtGraphics is an IGraphics implementation. It can be constructed via a SWT GC which is passed-in to the paintControl() event handler. The renderScene() method does not know anything about the actual IGraphics implemention that is used. That's why we would not need to adjust our rendering code when switching to AWT, for example. You may wonder why we have to call the cleanUp() method on the IGraphics. In the case of SWT, this is necessary to fully free the system resources that will be allocated during the rendering process.
# A set of property groups exists which control the state of the IGraphics. In the example, the color attribute of the fillProperties is set to a fully opaque red. This will affect any fill() operation on our IGraphics.
+
# The GEF 4 Geometry component is integrated into the IGraphics interface, so that we can easily display geometry objects.
+
  
=== Properties & Drawing Operations ===
+
When looking at the code, there are two important observations:
 +
# The GEF4 Geometry component is integrated into the IGraphics interface, so that we can easily display geometry objects. Notably, the power of the draw() and fill() operations is directly coupled with the power of the Geometry component. All drawing primitives, such as lines, rectangles, ellipses, and many more, are represented by corresponding Geometry objects.
 +
# The drawing operations of the IGraphics are influenced by a set of attributes which are managed by the IGraphics (draw-color, fill-color, etc.). A full set of attributes is referred to as a GraphicsState.
  
There are four different drawing operations available on an IGraphics: draw(), fill(), write(), and blit(). Correspondingly, you can get the active drawProperties(), fillProperties(), writeProperties(), and blitProperties() out of an IGraphics. They are mutable, so that changing their attributes directly affects the next operation. Additionally, the canvasProperties() are used to control global IGraphics settings, such as the current drawing position.
+
[[Image:GEF4Graphics-IGraphics-drawing-operations.png|IGraphics drawing operations]]
  
* draw()
+
There are four different drawing operations available on an IGraphics: draw(), fill(), write(), and blit().
  
The IGraphics#draw(ICurve) and IGraphics#draw(Path) methods will draw the (contour of the) passed-in geometry object. For a reference of all available geometry objects, take a look at the GEF 4 Geometry component ([[GEF/GEF4/Geometry]]).
+
* Using the IGraphics#draw(ICurve) and IGraphics#draw(Path) methods, you can display the (contour of the) passed-in geometry object.
 +
** For a reference of all available geometry objects, take a look at the GEF4 Geometry component ([[GEF/GEF4/Geometry]]).
 +
** Influencing attributes: draw-pattern (Color, Gradient, and Image), stroke (dash-array, dash-begin, line-cap, line-join, line-width, miter-limit)
 +
* Analogical, the IGraphics#fill(IShape), IGraphics#fill(IMultiShape), and IGraphics#fill(Path) methods will fill the interior of the passed-in geometry object.
 +
** Influencing attributes: fill-pattern (Color, Gradient, and Image)
 +
* Using the IGraphics#blit(Image) method, you can display the passed-in Image object.
 +
** Influencing attributes: interpolation-hint
 +
* Using the IGraphics#write(String) method, you can display the passed-in String object.
 +
** Influencing attributes: font, write-pattern (Color, Gradient, and Image), background-color
 +
 
 +
=== GraphicsState ===
 +
 
 +
A GraphicsState represents one set of IGraphics attributes. The following list presents all available attributes, default values, and a short description of the attributes.
 +
 
 +
* '''InterpolationHint = QUALITY'''<br />When displaying a transformed Image, the InterpolationHint specifies whether to apply a fast and low-quality (InterpolationHint#SPEED) interpolation, or to apply a slower but higher-quality (InterpolationHint#QUALITY) interpolation.
 +
* '''Draw-Pattern = black'''<br />Specifies the draw-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the drawing color.
 +
* '''Dash-Array = {}'''<br />Specifies a double[] consisting of distance values which alternatingly specify opaque and transparent sections.
 +
* '''Dash-Begin = 0'''<br />Specifies the initially assumed covered distance when applying the DashArray.
 +
* '''LineCap = FLAT'''<br />Specifies how to display unconnected end points of displayed lines. A FLAT LineCap will not extend a drawn line beyond its unconnected end points. A ROUND LineCap will draw a semi-circle at the unconnected end points of a displayed line. A SQUARE LineCap will extend a drawn line beyond its unconnected end points by half the line's width.
 +
* '''LineJoin = BEVEL'''<br />Specifies how to display the connection point of two displayed lines. A BEVEL LineJoin fills the bent corner triangular. A MITER LineJoin fills the bent corner up to the intersection point of the two outermost lines if its distance to the middle intersection is less than or equal to the MiterLimit. In case of exceeding the MiterLimit, the BEVEL LineJoin is used.
 +
* '''Line-Width = 1'''<br />Specifies the width of displayed lines.
 +
* '''Miter-Limit = 10'''<br />Restricts the use of the MITER LineJoin, because for low intersection angles, the intersection point may lie far away from the original connection point. Its value is the maximal quotient of the distance between the intersection point and the connection point and the line width.
 +
* '''Fill-Pattern = black'''<br />Specifies the fill-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the filling color.
 +
* '''Write-Pattern = black'''<br />Specifies the write-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the writing color.
 +
* '''Write-Background = transparent white'''<br />Specifies the background color for write() operations.
 +
 
 +
Additional to these attributes, a GraphicsState consists of four general attributes, which will affect all drawing operations:
 +
 
 +
* '''AffineTransform = identity transform'''<br />Transforms the coordinate system before applying any drawing operations.
 +
* '''Clip = null'''<br />Specifies a Path which serves as the clipping area for all subsequent drawing operations. Setting the clip to <tt>null</tt> disables clipping.
 +
* '''Antialiasing = true'''<br />If enabled, anti-aliasing is used to smooth drawn edges.
 +
* '''Xor-mode = false'''<br />If enabled, combines source and destination colors via binary exclusive-or when drawing.
 +
 
 +
== How to ==
 +
 
 +
The "How to..." sections explain how to use specific functionality of the GEF4 Graphics component. You can try out the various presented code snippets using the HowToSnippets demo in the org.eclipse.gef4.graphics.examples project under the org.eclipse.gef4.graphics.examples.doc package.
 +
 
 +
=== How to draw geometric primitives ===
 +
 
 +
[[Image:GEF4Graphics-howto-001.png|thumb|How-to snippet 001]]
 +
 
 +
[[Image:GEF4Graphics-howto-002.png|thumb|How-to snippet 002]]
 +
 
 +
The GEF4 Geometry component provides many geometric abstractions. It is integrated into the GEF4 Graphics component. Therefore, the GEF4 Graphics component allows for rendering those geometric abstractions. You can use the draw() and fill() methods of the IGraphics in order to draw the contour of a geometric abstraction or fill it with a color, a gradient, or an image.
 +
 
 +
''How-to snippet 001:''
 +
<source lang="Java">
 +
graphics.setDraw(new Color(0, 0, 0)).draw(new Line(10, 10, 90, 90));
 +
graphics.setFill(new Color(255, 0, 0)).fill(new Ellipse(30, 5, 20, 20));
 +
graphics.draw(new Rectangle(5, 50, 30, 10).getOutline());
 +
</source>
 +
 
 +
The list of provided geometric primitives contains all of the standard geometric objects, such as arcs, lines, ellipses, paths, polygons, polylines, rectangles, and rounded rectangles. Complementary, additional abstractions for the use of Bezier curves are provided, namely curved-polygons and polybeziers where the edges are arbitrary Bezier curves.
 +
 
 +
''How-to snippet 002:''
 +
<source lang="Java">
 +
// connection passes through the given points
 +
PolyBezier connection = PolyBezier.interpolateCubic(
 +
    new Point(10, 10), new Point(10, 90), new Point(180, 90), new Point(180, 200)
 +
);
 +
graphics.draw(connection);
 +
</source>
 +
 
 +
=== How to draw arbitrary Bezier curves ===
 +
 
 +
[[Image:GEF4Graphics-howto-003.png|thumb|How-to snippet 003]]
 +
 
 +
Bezier curves are used in the GEF4 Geometry component to represent edges of geometric objects. They can be visualized like any other of the geometric abstractions.
 +
 
 +
''How-to snippet 003:''
 +
<source lang="Java">
 +
graphics.draw(new BezierCurve(new Point(300, 25), new Point(330, 165), new Point(110, 65),
 +
new Point(180, 240), new Point(160, 220), new Point(100, 165)));
 +
graphics.draw(new BezierCurve(new Point(10, 150), new Point(86, 90), new Point(162, 25),
 +
new Point(238, 130), new Point(314, 200), new Point(380, 150)));
 +
</source>
  
* fill()
+
As you can see, a Bezier curve approaches the polyline of its control points. The first control point is called the start point, the last control point is called the end point, and the intermediate control points are called the handle points of the Bezier curve. The number of control points determines the curve's degree. A degree 0 (1 control point) Bezier curve represents a single point. A degree 1 curve represents a straight line segment. Higher degree Bezier curves generally proceed along a meandering path.
  
* blit()
+
=== How to draw text ===
  
* write()
+
=== How to change the font style ===
  
==== ICanvasProperties ====
+
=== How to display images ===
  
=== State Control ===
+
=== How to resize images ===
  
... pushState() ... popState() ...
+
=== How to blur images ===
  
=== Other IGraphics Implementations ===
+
=== How to do image arithmetic ===
  
== Extension Mechanisms ==
+
[[Category:GEF]]

Revision as of 11:49, 4 March 2013

Note to non-wiki readers: This documentation is generated from the Eclipse wiki - if you have corrections or additions it would be awesome if you added them in the original wiki page.


Introduction

The GEF4 Graphics component provides a level of abstraction over different drawing toolkits (natives). At the moment, SWT and AWT backends are in development. Its goal is to be as complete as possible, i.e. you should have access to all the functionality that you have access to when working directly with one of the natives (SWT or AWT). Of course, this is not always viable. But we aim to provide at least the greatest common divisor of the functionality that is offered by the individual natives and additionally, decent simulations for operations which are not offered by all natives.

Features

GEF4 Graphics GEF 3.x Draw2d SWT AWT
General
Affine coordinate transformations
+
+/-  1
+
+
how-to
Resolution independent rendering
+
-
-
-
State stack mechanism: push/pop/restore
+
+
-
-
how-to
Off-screen rendering support
+
?
+
+
how-to
Drawing geometric primitives
Lines, polylines, rectangles, polygons, arcs, rounded-rectangles, and ellipses
+
+
+
+
how-to
Arbitrary Bezier curves, curved-polygons, and polybeziers
+
+/-  2
+/-  2
+/-  2
how-to
Arbitrary clipping area
+
+
+
+
how-to
Basic stroke: width, caps, joins, dashes
+
+
+
+
how-to
Single-stop, cyclic/acyclic, linear gradients
+
+/-  3
+/-  3
+
how-to
Multi-stop, cyclic/acyclic, linear gradients
+
-
-
+
how-to
Multi-stop, cyclic/acyclic, radial gradients
+
-
-
+
how-to
Image fill
+
+
+
+
how-to
Displaying text
Basic text drawing
+
+
+
+
how-to
Font styles: italic, bold, and underlined
+
+/-  4
+/-  4
+/-  4
how-to
Filling text with a gradient
+
-
-
+
how-to
Filling text with image data
+
-
-
+
how-to
Image operations
Basic image drawing
+
+
+
+
how-to
Image resizing
+
+
+
+
how-to
Image blurring
+
-
-
+
how-to
Combining images via standard arithmetic or logical operations
+
-
-
-
how-to


Footnotes:

  1. Missing transformation: shearing.
  2. Implemented for quadratic and cubic Bezier curves.
  3. No support for cyclic gradients.
  4. Missing font style: underlined.

IGraphics

The heart of the GEF4 Graphics component is the IGraphics interface. Normally, you will be handed over an IGraphics to accomplish your displaying tasks by a surrounding framework, but it can be used stand-alone, too. Thereto, you have to create a specific IGraphics implementation. Let us consider the following SWT example:

[Example 001: Simple Graphics]

/*******************************************************************************
 * Copyright (c) 2012, 2013 itemis AG and others.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Matthias Wienand (itemis AG) - initial API and implementation
 *     
 *******************************************************************************/
package org.eclipse.gef4.graphics.examples.doc;
 
import org.eclipse.gef4.geometry.planar.Ellipse;
import org.eclipse.gef4.geometry.planar.Polygon;
import org.eclipse.gef4.geometry.planar.Rectangle;
import org.eclipse.gef4.graphics.IGraphics;
import org.eclipse.gef4.graphics.LineCap;
import org.eclipse.gef4.graphics.LineJoin;
import org.eclipse.gef4.graphics.color.Color;
import org.eclipse.gef4.graphics.swt.SwtGraphics;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
 
public class Example001 implements PaintListener {
 
	public static void main(String[] args) {
		new Example001("Simple Graphics");
	}
 
	public Example001(String title) {
		Display display = new Display();
 
		Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED);
		shell.setText(title);
		shell.setBounds(0, 0, 640, 480);
		shell.open();
 
		shell.addPaintListener(this);
		shell.redraw(); // platform independently triggers a PaintEvent
 
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
 
	@Override
	public void paintControl(PaintEvent e) {
		SwtGraphics g = new SwtGraphics(e.gc);
		renderScene(g);
		g.cleanUp();
	}
 
	public void renderScene(IGraphics g) {
		// The rendering code goes here. It is independent of the actual
		// IGraphics implementation. Therefore, it is independent of the
		// underlying drawing toolkit, too.
 
		final Ellipse ellipse = new Ellipse(50, 50, 350, 200);
		final Rectangle rectangle = new Rectangle(100, 160, 125, 220);
		final Polygon triangle = new Polygon(260, 170, 190, 300, 330, 300);
 
		g.setFill(new Color(255, 0, 0)).setDraw(new Color(128, 0, 0))
				.setDashArray(25, 10);
 
		g.fill(ellipse).draw(ellipse.getOutline());
 
		g.setFill(new Color(0, 0, 255)).setLineJoin(LineJoin.ROUND)
				.setLineCap(LineCap.ROUND);
 
		g.fill(rectangle).draw(rectangle.getOutline());
 
		g.setFill(new Color(0, 255, 0)).setDraw(new Color(0, 128, 0))
				.setLineJoin(LineJoin.MITER);
 
		g.fill(triangle).draw(triangle.getOutline());
	}
 
}

Simple GEF4 Graphics example (SWT)

[Note: You can tryout the examples in your local GEF4 installation. Every example shown in this documentation exists in the org.eclipse.gef4.graphics.examples project under the org.eclipse.gef4.graphics.examples.doc package. The examples are easily found via their identification number which is written atop the source code.]

As you can see in this example, the SwtGraphics is an IGraphics implementation. It can be constructed via a SWT GC which is passed-in to the paintControl() event handler. The renderScene() method does not know anything about the actual IGraphics implemention that is used. That's why we would not need to adjust our rendering code when switching to AWT, for example. You may wonder why we have to call the cleanUp() method on the IGraphics. In the case of SWT, this is necessary to fully free the system resources that will be allocated during the rendering process.

When looking at the code, there are two important observations:

  1. The GEF4 Geometry component is integrated into the IGraphics interface, so that we can easily display geometry objects. Notably, the power of the draw() and fill() operations is directly coupled with the power of the Geometry component. All drawing primitives, such as lines, rectangles, ellipses, and many more, are represented by corresponding Geometry objects.
  2. The drawing operations of the IGraphics are influenced by a set of attributes which are managed by the IGraphics (draw-color, fill-color, etc.). A full set of attributes is referred to as a GraphicsState.

IGraphics drawing operations

There are four different drawing operations available on an IGraphics: draw(), fill(), write(), and blit().

  • Using the IGraphics#draw(ICurve) and IGraphics#draw(Path) methods, you can display the (contour of the) passed-in geometry object.
    • For a reference of all available geometry objects, take a look at the GEF4 Geometry component (GEF/GEF4/Geometry).
    • Influencing attributes: draw-pattern (Color, Gradient, and Image), stroke (dash-array, dash-begin, line-cap, line-join, line-width, miter-limit)
  • Analogical, the IGraphics#fill(IShape), IGraphics#fill(IMultiShape), and IGraphics#fill(Path) methods will fill the interior of the passed-in geometry object.
    • Influencing attributes: fill-pattern (Color, Gradient, and Image)
  • Using the IGraphics#blit(Image) method, you can display the passed-in Image object.
    • Influencing attributes: interpolation-hint
  • Using the IGraphics#write(String) method, you can display the passed-in String object.
    • Influencing attributes: font, write-pattern (Color, Gradient, and Image), background-color

GraphicsState

A GraphicsState represents one set of IGraphics attributes. The following list presents all available attributes, default values, and a short description of the attributes.

  • InterpolationHint = QUALITY
    When displaying a transformed Image, the InterpolationHint specifies whether to apply a fast and low-quality (InterpolationHint#SPEED) interpolation, or to apply a slower but higher-quality (InterpolationHint#QUALITY) interpolation.
  • Draw-Pattern = black
    Specifies the draw-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the drawing color.
  • Dash-Array = {}
    Specifies a double[] consisting of distance values which alternatingly specify opaque and transparent sections.
  • Dash-Begin = 0
    Specifies the initially assumed covered distance when applying the DashArray.
  • LineCap = FLAT
    Specifies how to display unconnected end points of displayed lines. A FLAT LineCap will not extend a drawn line beyond its unconnected end points. A ROUND LineCap will draw a semi-circle at the unconnected end points of a displayed line. A SQUARE LineCap will extend a drawn line beyond its unconnected end points by half the line's width.
  • LineJoin = BEVEL
    Specifies how to display the connection point of two displayed lines. A BEVEL LineJoin fills the bent corner triangular. A MITER LineJoin fills the bent corner up to the intersection point of the two outermost lines if its distance to the middle intersection is less than or equal to the MiterLimit. In case of exceeding the MiterLimit, the BEVEL LineJoin is used.
  • Line-Width = 1
    Specifies the width of displayed lines.
  • Miter-Limit = 10
    Restricts the use of the MITER LineJoin, because for low intersection angles, the intersection point may lie far away from the original connection point. Its value is the maximal quotient of the distance between the intersection point and the connection point and the line width.
  • Fill-Pattern = black
    Specifies the fill-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the filling color.
  • Write-Pattern = black
    Specifies the write-pattern which consists of a Color, a Gradient, an Image, and a Mode. The pattern's mode specifies which of the three values (Color, Gradient, and Image) is queried for the writing color.
  • Write-Background = transparent white
    Specifies the background color for write() operations.

Additional to these attributes, a GraphicsState consists of four general attributes, which will affect all drawing operations:

  • AffineTransform = identity transform
    Transforms the coordinate system before applying any drawing operations.
  • Clip = null
    Specifies a Path which serves as the clipping area for all subsequent drawing operations. Setting the clip to null disables clipping.
  • Antialiasing = true
    If enabled, anti-aliasing is used to smooth drawn edges.
  • Xor-mode = false
    If enabled, combines source and destination colors via binary exclusive-or when drawing.

How to

The "How to..." sections explain how to use specific functionality of the GEF4 Graphics component. You can try out the various presented code snippets using the HowToSnippets demo in the org.eclipse.gef4.graphics.examples project under the org.eclipse.gef4.graphics.examples.doc package.

How to draw geometric primitives

How-to snippet 001
How-to snippet 002

The GEF4 Geometry component provides many geometric abstractions. It is integrated into the GEF4 Graphics component. Therefore, the GEF4 Graphics component allows for rendering those geometric abstractions. You can use the draw() and fill() methods of the IGraphics in order to draw the contour of a geometric abstraction or fill it with a color, a gradient, or an image.

How-to snippet 001:

graphics.setDraw(new Color(0, 0, 0)).draw(new Line(10, 10, 90, 90));
graphics.setFill(new Color(255, 0, 0)).fill(new Ellipse(30, 5, 20, 20));
graphics.draw(new Rectangle(5, 50, 30, 10).getOutline());

The list of provided geometric primitives contains all of the standard geometric objects, such as arcs, lines, ellipses, paths, polygons, polylines, rectangles, and rounded rectangles. Complementary, additional abstractions for the use of Bezier curves are provided, namely curved-polygons and polybeziers where the edges are arbitrary Bezier curves.

How-to snippet 002:

// connection passes through the given points
PolyBezier connection = PolyBezier.interpolateCubic(
    new Point(10, 10), new Point(10, 90), new Point(180, 90), new Point(180, 200)
);
graphics.draw(connection);

How to draw arbitrary Bezier curves

How-to snippet 003

Bezier curves are used in the GEF4 Geometry component to represent edges of geometric objects. They can be visualized like any other of the geometric abstractions.

How-to snippet 003:

graphics.draw(new BezierCurve(new Point(300, 25), new Point(330, 165), new Point(110, 65),
	new Point(180, 240), new Point(160, 220), new Point(100, 165)));
graphics.draw(new BezierCurve(new Point(10, 150), new Point(86, 90), new Point(162, 25),
	new Point(238, 130), new Point(314, 200), new Point(380, 150)));

As you can see, a Bezier curve approaches the polyline of its control points. The first control point is called the start point, the last control point is called the end point, and the intermediate control points are called the handle points of the Bezier curve. The number of control points determines the curve's degree. A degree 0 (1 control point) Bezier curve represents a single point. A degree 1 curve represents a straight line segment. Higher degree Bezier curves generally proceed along a meandering path.

How to draw text

How to change the font style

How to display images

How to resize images

How to blur images

How to do image arithmetic