| Summary: | implement rotate for ScaledGraphics | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Tools] GEF | Reporter: | Chris Lee <eclipse> | ||||||
| Component: | GEF-Legacy Draw2d | Assignee: | gef-inbox <gef-inbox> | ||||||
| Status: | RESOLVED WORKSFORME | QA Contact: | |||||||
| Severity: | enhancement | ||||||||
| Priority: | P3 | CC: | ahunter.eclipse, dsciamma, hudsonr, morten-eclipse, nyssen, robert.moloney, sbernard | ||||||
| Version: | 3.2 | Flags: | ahunter.eclipse:
galileo+
|
||||||
| Target Milestone: | --- | ||||||||
| Hardware: | PC | ||||||||
| OS: | Windows XP | ||||||||
| Whiteboard: | |||||||||
| Attachments: |
|
||||||||
|
Description
Chris Lee
It seems that rotate doesn't even work as expected on an SWTGraphics for trying to render rotated text (using a TextLayout)... have you taken a look at ImageUtilities#createRotatedImageOfString ? I hadn't before; it's a good starting point though; it only handles basic strings - how about a TextLayout (which does multiple fonts, underline and strikethrough)? This really should be implemented, you cannot use the advanced transforms much if you cannot use it also in scaled graphics. rotate() works for so much more than just text.. Disregard my other comment. In fact ScaledGraphics is obsolete as Graphics support scaling itself now and it works fine.
If you change ZoomContainer.java in the draw2d examples to this:
/**
* @see org.eclipse.draw2d.Figure#paintClientArea(Graphics)
*/
protected void paintClientArea(Graphics graphics) {
if (getChildren().isEmpty())
return;
boolean optimizeClip = getBorder() == null || getBorder().isOpaque();
// ScaledGraphics g = new ScaledGraphics(graphics);
//
// if (!optimizeClip)
// g.clipRect(getBounds().getCropped(getInsets()));
// g.translate(getBounds().x + getInsets().left, getBounds().y + getInsets().top);
// g.scale(zoom);
// g.pushState();
// paintChildren(g);
// g.popState();
// g.dispose();
// graphics.restoreState();
graphics.scale(zoom);
graphics.pushState();
paintChildren(graphics);
graphics.popState();
}
---
It works fine (even better looking.. well on Mac at least, font scaling is much smoother). This might not work for non-windows/linux/mac platforms that doesn't support advanced graphics..
ScaledGraphics is definitely not obsolete :) I actually tried using something similar to below for doing scaling on SWTGraphics and although it "mostly" worked, noticeable chunks of the rendering were much messier and/or simply didn't work. As a note on this, is there any further discussion on the Eclipse side for the ability to render complex rotated text, or is this something we'll have to do ourselves? Uhm, ScaledGraphics were made to support the .scale() function/transform it looks like. Now that method exists in Graphics, ScaledGraphics provides no functionality beyond Graphics anymore. Obviously they both have flaws and bugs, but keeping two implementation of scale transforms doesn't sound good to me. If Graphics.scale() is buggy to you, maybe that should be bug reported? (In reply to comment #7) > Uhm, ScaledGraphics were made to support the .scale() function/transform it > looks like. Now that method exists in Graphics, ScaledGraphics provides no > functionality beyond Graphics anymore. There is still a significant performance hit on win32 win using native scaling, and many differences in the results, including poor font rendering. Both versions are still needed, but with the restriction that ScaledGraphics will never use advanced graphics, so rotate and other methods can not be implemented. Clients needing rotate will have to accept the trade-offs of the native scaling in those cases. (In reply to comment #0) > The primary reason for this request is to render rotated text. > Agree, we have this requirement as well, so adding to the preliminary GEF 3.5 plan. I'm working on adding the rotation in GEF. I have began to add rotation on graphics and now I'm working on create a RotatableFigure. I will add an attachment of my work. Created attachment 113844 [details]
graphics modified
Currently, the rotate method on graphics makes a rotation around the point (0,0).Not really useable ...
So, I modified the graphics to allow the rotation around a given point.
public void rotate(float degrees,int x,int y) {
//Flush clipping, patter, etc., before applying transform
checkGC();
initTransform(true);
initRotateTransform();
//to make a rotation of center (x,y)
//translate to the origin
transformTranslateToOri.translate(-x,-y);
//rotate around the origin
transformRotate.rotate(degrees);
//translate to the center of rotation
transformTranslateToCenter.translate(x, y);
transform.multiply(transformTranslateToCenter);
transform.multiply(transformRotate);
transform.multiply(transformTranslateToOri);
//apply transform to gc
gc.setTransform(transform);
elementsNeedUpdate = true;
//Can no longer operate or maintain clipping
appliedState.relativeClip = currentState.relativeClip = null;
}
Created attachment 113846 [details]
An plugin with example of use
I have created a plugin with examples of use
Extract:
--------
Figure figure = new Figure(){
private final int insets= 25;
@Override
protected void paintFigure(Graphics graphics) {
graphics.setAntialias(SWT.ON);
// draw bounds
graphics.drawRectangle
(getBounds().getCopy().crop(new Insets(1)));
// draw rect rot 0
Rectangle rect = getBounds().getCopy().crop(new Insets(insets));
graphics.drawRectangle(rect);
// draw rect rot 22.5
graphics.rotate(22.5f,getBounds().getCenter());
graphics.setForegroundColor
(Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
graphics.drawRectangle(rect);
// draw rect rot 22.5+22.5
graphics.rotate(22.5f,getBounds().getCenter());
graphics.setForegroundColor
(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
graphics.drawRectangle(rect);
}
};
> // draw rect rot 22.5
> graphics.rotate(22.5f,getBounds().getCenter());
> graphics.setForegroundColor
> (Display.getCurrent().getSystemColor(SWT.COLOR_BLUE));
> graphics.drawRectangle(rect);
Simon, this new API is not needed. You can do the same thing using:
Point center = getBounds().getCenter();
graphics.translate(center.x, center.y);
graphics.rotate(22.5f);
graphics.translate(-center.x, -center.y);
Chris, if there are issues with using the scaling support, please open separate bugs. BTW, I've submitted a patch to SWT that addresses many of the GDI+ inconsistencies.
ScaledGraphics will not support rotation. By design, ScaledGraphics avoids advanced graphics, so emulating rotation would be very hard. The recommendation is to use SWTGraphics instead and invoke the advanced graphics support.
(In reply to comment #9) > > Agree, we have this requirement as well, so adding to the preliminary GEF 3.5 > plan. > Reopening, this enhancement is a plan item for GEF 3.5. Any dependent bugzillas need to be cross referenced here. Until we have a draw2d snippet checked into CVS demonstrating text rotation for scaled graphics, this Bugzilla will NOT be closed.
> ScaledGraphics will not support rotation. By design, ScaledGraphics avoids
> advanced graphics, so emulating rotation would be very hard.
Why does it avoid advanced Graphics ?
Oops! Sorry Anthony, didn't see your comment 9. Isn't this related to bug 103717? If ScaledGraphics were not being used, then rendering rotated text is already working. (In reply to comment #8) > (In reply to comment #7) > > Uhm, ScaledGraphics were made to support the .scale() function/transform it > > looks like. Now that method exists in Graphics, ScaledGraphics provides no > > functionality beyond Graphics anymore. > > There is still a significant performance hit on win32 win using native scaling, > and many differences in the results, including poor font rendering. Both > versions are still needed, but with the restriction that ScaledGraphics will > never use advanced graphics, so rotate and other methods can not be > implemented. Clients needing rotate will have to accept the trade-offs of the > native scaling in those cases. If we provide a hook as required/desired in bug #103717 to allow choosing between native and emulated scaling, wouldn't it be straightforward to change the implementation of ZoomManager and ScalableFigure implementors to use Graphics.scale by default, and to use a ScaledGraphics only if the provided Graphics does not support advanced mode or the emulation mode is explicitly required? (In reply to comment #14) > (In reply to comment #9) > > > > Agree, we have this requirement as well, so adding to the preliminary GEF 3.5 > > plan. > > > > Reopening, this enhancement is a plan item for GEF 3.5. Any dependent bugzillas > need to be cross referenced here. > > Until we have a draw2d snippet checked into CVS demonstrating text rotation for > scaled graphics, this Bugzilla will NOT be closed. As far as simple text is concerned, I think ScaledGraphics as well as SWTGraphics are feature-complete to this extent, as demonstrated by the following snippet (which I have not checked in yet). package org.eclipse.draw2d.examples.rotate; import org.eclipse.draw2d.SWTGraphics; import org.eclipse.draw2d.ScaledGraphics; import org.eclipse.draw2d.geometry.Point; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class RotatedTextExample { public static void main(String[] args) { Display d = new Display(); Shell shell = new Shell(d); shell.setLayout(new FillLayout()); shell.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { SWTGraphics nativeGraphics = new SWTGraphics(e.gc); nativeGraphics.rotate(22); nativeGraphics.drawText("Hello World", new Point(25, 0)); nativeGraphics.rotate(-22); ScaledGraphics emulatedGraphics = new ScaledGraphics( nativeGraphics); emulatedGraphics.rotate(22); emulatedGraphics.drawText("Hello World", new Point(125, 0)); emulatedGraphics.dispose(); nativeGraphics.dispose(); } }); shell.setText("Rotating Text"); shell.setSize(200, 150); shell.open(); while (!shell.isDisposed()) while (!d.readAndDispatch()) d.sleep(); } } I extended the Draw2d PathExample as follows: - Changed example to render a rotated text layout with a text style (underline) within PathFigure. - Added a button that allows to switch between native and emulated scaling within ZoomFigure (added a setScaleMethod() option to ZoomFigure, as proposed for all scalable figures within bug #103717). Resolving this as WORKSFORME, as the example can be used to demonstrate that rendering rotated text layout is feasible with SWTGraphics as well as ScaledGraphics. |