下面列出了java.awt.BasicStroke#getEndCap ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static Stroke setLineWidth(Stroke s, float lw) {
if(s instanceof BasicStroke) {
BasicStroke b = (BasicStroke)s;
float[] da = b.getDashArray();
if(da != null) {
float[] dsa = new float[da.length];
for(int i = 0; i < dsa.length; i++)
dsa[i] = da[i] * (lw / b.getLineWidth());
da = dsa;
}
return new BasicStroke(lw,
b.getEndCap(),
b.getLineJoin(),
b.getMiterLimit(),
da,
b.getDashPhase());
}
else return s;
}
/**
* Performs the writing of a single object.
*
* @param tagName the tag name.
* @param object the object ({@link BasicStroke} expected).
* @param writer the writer.
* @param mPlexAttribute ??
* @param mPlexValue ??
*
* @throws IOException if there is an I/O problem.
* @throws XMLWriterException if there is a problem with the writer.
*/
public void write(final String tagName, final Object object, final XMLWriter writer,
final String mPlexAttribute, final String mPlexValue)
throws IOException, XMLWriterException {
final BasicStroke stroke = (BasicStroke) object;
final float[] dashArray = stroke.getDashArray();
final float dashPhase = stroke.getDashPhase();
final int endCap = stroke.getEndCap();
final int lineJoin = stroke.getLineJoin();
final float lineWidth = stroke.getLineWidth();
final float miterLimit = stroke.getMiterLimit();
final AttributeList attribs = new AttributeList();
if (mPlexAttribute != null) {
attribs.setAttribute(mPlexAttribute, mPlexValue);
}
attribs.setAttribute("type", "basic");
attribs.setAttribute("endCap", String.valueOf(endCap));
attribs.setAttribute("lineJoin", String.valueOf(lineJoin));
attribs.setAttribute("lineWidth", String.valueOf(lineWidth));
attribs.setAttribute("miterLimit", String.valueOf(miterLimit));
if (dashArray != null) {
attribs.setAttribute("dashArray", toString(dashArray));
attribs.setAttribute("dashPhase", String.valueOf(dashPhase));
}
writer.writeTag(tagName, attribs, true);
}
private Stroke transformStroke( final Stroke stroke ) {
if ( !( stroke instanceof BasicStroke ) ) {
return stroke;
}
final BasicStroke st = (BasicStroke) stroke;
final float scale = (float) Math.sqrt( Math.abs( transform.getDeterminant() ) );
final float[] dash = st.getDashArray();
if ( dash != null ) {
final int dashLength = dash.length;
for ( int k = 0; k < dashLength; ++k ) {
dash[k] *= scale;
}
}
return new BasicStroke( st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st
.getDashPhase()
* scale );
}
private Stroke transformStroke(Stroke stroke) {
if (!(stroke instanceof BasicStroke)) {
return stroke;
}
BasicStroke st = (BasicStroke) stroke;
float scale = (float) Math.sqrt(Math.abs(transform.getDeterminant()));
float dash[] = st.getDashArray();
if (dash != null) {
for (int k = 0; k < dash.length; ++k) {
dash[k] *= scale;
}
}
return new BasicStroke(st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st.getDashPhase() * scale);
}
private Stroke transformStroke(Stroke stroke) {
if (!(stroke instanceof BasicStroke))
return stroke;
BasicStroke st = (BasicStroke)stroke;
float scale = (float)Math.sqrt(Math.abs(transform.getDeterminant()));
float dash[] = st.getDashArray();
if (dash != null) {
for (int k = 0; k < dash.length; ++k)
dash[k] *= scale;
}
return new BasicStroke(st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st.getDashPhase() * scale);
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
@Override
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
/**
* Adds stroke color and style information to the element passed in.
*
* @param currentElement
* the element to add style information to.
* @param isClipped
* boolean that determines whether to defer the clipping of the
* element
*/
protected void setStrokeStyle( Element currentElement, boolean deferClipped )
{
Element element = currentElement;
if ( deferStrokColor != null )
{
// Need to get the parent element.
element = deferStrokColor;
}
String style = element.getAttribute( "style" ); //$NON-NLS-1$
if ( style == null )
style = ""; //$NON-NLS-1$
if ( color != null )
{
style += "stroke:" + serializeToString( color ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
if ( ( stroke != null ) && ( stroke instanceof BasicStroke ) )
{
BasicStroke bs = (BasicStroke) stroke;
if ( bs.getLineWidth( ) > 0 )
style += "stroke-width:" + bs.getLineWidth( ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
if ( bs.getDashArray( ) != null )
{
StringBuffer dashArrayStr = new StringBuffer( );
for ( int x = 0; x < bs.getDashArray( ).length; x++ )
{
dashArrayStr.append( " " ).append( bs.getDashArray( )[x] ); //$NON-NLS-1$
}
if ( !( dashArrayStr.toString( ).equals( "" ) ) ) //$NON-NLS-1$
style += "stroke-dasharray:" + dashArrayStr + ";"; //$NON-NLS-1$ //$NON-NLS-2$
}
style += "stroke-miterlimit:" + bs.getMiterLimit( ) + ";"; //$NON-NLS-1$ //$NON-NLS-2$
switch ( bs.getLineJoin( ) )
{
case BasicStroke.JOIN_BEVEL :
style += "stroke-linejoin:bevel;"; //$NON-NLS-1$
break;
case BasicStroke.JOIN_ROUND :
style += "stroke-linejoin:round;"; //$NON-NLS-1$
break;
}
switch ( bs.getEndCap( ) )
{
case BasicStroke.CAP_ROUND :
style += "stroke-linecap:round;"; //$NON-NLS-1$
break;
case BasicStroke.CAP_SQUARE :
style += "stroke-linecap:square;"; //$NON-NLS-1$
break;
}
}
element.setAttribute( "style", style ); //$NON-NLS-1$
if ( styleClass != null )
element.setAttribute( "class", styleClass ); //$NON-NLS-1$
if ( id != null )
element.setAttribute( "id", id ); //$NON-NLS-1$
if ( ( clip != null ) && ( !deferClipped ) )
element.setAttribute( "clip-path", "url(#clip" + clip.hashCode( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
@Override
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
/**
* Draw a line using a pen created using the specified color
* and current stroke properties.
*/
@Override
protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd,
Color color) {
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
if (lineStroke.getDashArray() != null) {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
return;
}
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth);
AffineTransform deviceTransform = getTransform();
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin);
deviceTransform.transform(begin_pos, begin_pos);
Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd);
deviceTransform.transform(end_pos, end_pos);
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check if it's a one-pixel line */
if ((end_pos.getX() == begin_pos.getX())
&& (end_pos.getY() == begin_pos.getY())) {
/* endCap other than Round will not print!
* due to Windows GDI limitation, force it to CAP_ROUND
*/
endCap = BasicStroke.CAP_ROUND;
}
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* call native function that creates pen with style */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color)) {
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
/* selectStylePen is not supported, must be Win 9X */
else {
/* let's see if we can use a a default pen
* if it's round end (Windows' default style)
* or it's vertical/horizontal
* or stroke is too thin.
*/
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((endCap == BasicStroke.CAP_ROUND) ||
(((xBegin == xEnd) || (yBegin == yEnd)) &&
(deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
else {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
}
}
}
}
/**
* Draw a line using a pen created using the specified color
* and current stroke properties.
*/
protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd,
Color color) {
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
if (lineStroke.getDashArray() != null) {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
return;
}
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth);
AffineTransform deviceTransform = getTransform();
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin);
deviceTransform.transform(begin_pos, begin_pos);
Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd);
deviceTransform.transform(end_pos, end_pos);
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check if it's a one-pixel line */
if ((end_pos.getX() == begin_pos.getX())
&& (end_pos.getY() == begin_pos.getY())) {
/* endCap other than Round will not print!
* due to Windows GDI limitation, force it to CAP_ROUND
*/
endCap = BasicStroke.CAP_ROUND;
}
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* call native function that creates pen with style */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color)) {
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
/* selectStylePen is not supported, must be Win 9X */
else {
/* let's see if we can use a a default pen
* if it's round end (Windows' default style)
* or it's vertical/horizontal
* or stroke is too thin.
*/
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((endCap == BasicStroke.CAP_ROUND) ||
(((xBegin == xEnd) || (yBegin == yEnd)) &&
(deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
else {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
}
}
}
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
@Override
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
/**
* Returns a stroke style string based on the current stroke and
* alpha settings.
*
* @return A stroke style string.
*/
private String strokeStyle() {
double strokeWidth = 1.0f;
String strokeCap = DEFAULT_STROKE_CAP;
String strokeJoin = DEFAULT_STROKE_JOIN;
float miterLimit = DEFAULT_MITER_LIMIT;
float[] dashArray = new float[0];
if (this.stroke instanceof BasicStroke) {
BasicStroke bs = (BasicStroke) this.stroke;
strokeWidth = bs.getLineWidth() > 0.0 ? bs.getLineWidth()
: this.zeroStrokeWidth;
switch (bs.getEndCap()) {
case BasicStroke.CAP_ROUND:
strokeCap = "round";
break;
case BasicStroke.CAP_SQUARE:
strokeCap = "square";
break;
case BasicStroke.CAP_BUTT:
default:
// already set to "butt"
}
switch (bs.getLineJoin()) {
case BasicStroke.JOIN_BEVEL:
strokeJoin = "bevel";
break;
case BasicStroke.JOIN_ROUND:
strokeJoin = "round";
break;
case BasicStroke.JOIN_MITER:
default:
// already set to "miter"
}
miterLimit = bs.getMiterLimit();
dashArray = bs.getDashArray();
}
StringBuilder b = new StringBuilder();
b.append("stroke-width: ").append(strokeWidth).append(";");
b.append("stroke: ").append(svgColorStr()).append(";");
b.append("stroke-opacity: ").append(getColorAlpha() * getAlpha())
.append(";");
if (!strokeCap.equals(DEFAULT_STROKE_CAP)) {
b.append("stroke-linecap: ").append(strokeCap).append(";");
}
if (!strokeJoin.equals(DEFAULT_STROKE_JOIN)) {
b.append("stroke-linejoin: ").append(strokeJoin).append(";");
}
if (Math.abs(DEFAULT_MITER_LIMIT - miterLimit) < 0.001) {
b.append("stroke-miterlimit: ").append(geomDP(miterLimit));
}
if (dashArray != null && dashArray.length != 0) {
b.append("stroke-dasharray: ");
for (int i = 0; i < dashArray.length; i++) {
if (i != 0) b.append(", ");
b.append(dashArray[i]);
}
b.append(";");
}
if (this.checkStrokeControlHint) {
Object hint = getRenderingHint(RenderingHints.KEY_STROKE_CONTROL);
if (RenderingHints.VALUE_STROKE_NORMALIZE.equals(hint)
&& !this.shapeRendering.equals("crispEdges")) {
b.append("shape-rendering:crispEdges;");
}
if (RenderingHints.VALUE_STROKE_PURE.equals(hint)
&& !this.shapeRendering.equals("geometricPrecision")) {
b.append("shape-rendering:geometricPrecision;");
}
}
return b.toString();
}
/**
* Draw a line using a pen created using the specified color
* and current stroke properties.
*/
@Override
protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd,
Color color) {
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
if (lineStroke.getDashArray() != null) {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
return;
}
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth);
AffineTransform deviceTransform = getTransform();
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin);
deviceTransform.transform(begin_pos, begin_pos);
Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd);
deviceTransform.transform(end_pos, end_pos);
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check if it's a one-pixel line */
if ((end_pos.getX() == begin_pos.getX())
&& (end_pos.getY() == begin_pos.getY())) {
/* endCap other than Round will not print!
* due to Windows GDI limitation, force it to CAP_ROUND
*/
endCap = BasicStroke.CAP_ROUND;
}
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* call native function that creates pen with style */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color)) {
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
/* selectStylePen is not supported, must be Win 9X */
else {
/* let's see if we can use a a default pen
* if it's round end (Windows' default style)
* or it's vertical/horizontal
* or stroke is too thin.
*/
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((endCap == BasicStroke.CAP_ROUND) ||
(((xBegin == xEnd) || (yBegin == yEnd)) &&
(deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
else {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
}
}
}
}
/**
* Draw a line using a pen created using the specified color
* and current stroke properties.
*/
@Override
protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd,
Color color) {
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
if (lineStroke.getDashArray() != null) {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
return;
}
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth);
AffineTransform deviceTransform = getTransform();
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin);
deviceTransform.transform(begin_pos, begin_pos);
Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd);
deviceTransform.transform(end_pos, end_pos);
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check if it's a one-pixel line */
if ((end_pos.getX() == begin_pos.getX())
&& (end_pos.getY() == begin_pos.getY())) {
/* endCap other than Round will not print!
* due to Windows GDI limitation, force it to CAP_ROUND
*/
endCap = BasicStroke.CAP_ROUND;
}
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* call native function that creates pen with style */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color)) {
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
/* selectStylePen is not supported, must be Win 9X */
else {
/* let's see if we can use a a default pen
* if it's round end (Windows' default style)
* or it's vertical/horizontal
* or stroke is too thin.
*/
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((endCap == BasicStroke.CAP_ROUND) ||
(((xBegin == xEnd) || (yBegin == yEnd)) &&
(deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) {
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.moveTo((float)begin_pos.getX(),
(float)begin_pos.getY());
wPrinterJob.lineTo((float)end_pos.getX(),
(float)end_pos.getY());
}
else {
draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd));
}
}
}
}
/**
* Sets the stroke for this graphics context. For now, this implementation
* only recognises the {@link BasicStroke} class.
*
* @param stroke the stroke (<code>null</code> not permitted).
*
* @see #getStroke()
*/
public void setStroke(Stroke stroke) {
if (stroke instanceof BasicStroke) {
BasicStroke bs = (BasicStroke) stroke;
// linewidth
this.gc.setLineWidth((int) bs.getLineWidth());
// line join
switch (bs.getLineJoin()) {
case BasicStroke.JOIN_BEVEL :
this.gc.setLineJoin(SWT.JOIN_BEVEL);
break;
case BasicStroke.JOIN_MITER :
this.gc.setLineJoin(SWT.JOIN_MITER);
break;
case BasicStroke.JOIN_ROUND :
this.gc.setLineJoin(SWT.JOIN_ROUND);
break;
}
// line cap
switch (bs.getEndCap()) {
case BasicStroke.CAP_BUTT :
this.gc.setLineCap(SWT.CAP_FLAT);
break;
case BasicStroke.CAP_ROUND :
this.gc.setLineCap(SWT.CAP_ROUND);
break;
case BasicStroke.CAP_SQUARE :
this.gc.setLineCap(SWT.CAP_SQUARE);
break;
}
// set the line style to solid by default
this.gc.setLineStyle(SWT.LINE_SOLID);
// apply dash style if any
float[] dashes = bs.getDashArray();
if (dashes != null) {
int[] swtDashes = new int[dashes.length];
for (int i = 0; i < swtDashes.length; i++) {
swtDashes[i] = (int) dashes[i];
}
this.gc.setLineDash(swtDashes);
}
}
else {
throw new RuntimeException(
"Can only handle 'Basic Stroke' at present.");
}
}
/**
* Sets the stroke for this graphics context. For now, this implementation
* only recognises the {@link BasicStroke} class.
*
* @param stroke the stroke (<code>null</code> not permitted).
*
* @see #getStroke()
*/
public void setStroke(Stroke stroke) {
if (stroke instanceof BasicStroke) {
BasicStroke bs = (BasicStroke) stroke;
// linewidth
this.gc.setLineWidth((int) bs.getLineWidth());
// line join
switch (bs.getLineJoin()) {
case BasicStroke.JOIN_BEVEL :
this.gc.setLineJoin(SWT.JOIN_BEVEL);
break;
case BasicStroke.JOIN_MITER :
this.gc.setLineJoin(SWT.JOIN_MITER);
break;
case BasicStroke.JOIN_ROUND :
this.gc.setLineJoin(SWT.JOIN_ROUND);
break;
}
// line cap
switch (bs.getEndCap()) {
case BasicStroke.CAP_BUTT :
this.gc.setLineCap(SWT.CAP_FLAT);
break;
case BasicStroke.CAP_ROUND :
this.gc.setLineCap(SWT.CAP_ROUND);
break;
case BasicStroke.CAP_SQUARE :
this.gc.setLineCap(SWT.CAP_SQUARE);
break;
}
// set the line style to solid by default
this.gc.setLineStyle(SWT.LINE_SOLID);
// apply dash style if any
float[] dashes = bs.getDashArray();
if (dashes != null) {
int[] swtDashes = new int[dashes.length];
for (int i = 0; i < swtDashes.length; i++) {
swtDashes[i] = (int) dashes[i];
}
this.gc.setLineDash(swtDashes);
}
}
else {
throw new RuntimeException(
"Can only handle 'Basic Stroke' at present.");
}
}
/**
* Draw the bounding rectangle using transformed coordinates.
*/
@Override
protected void deviceFrameRect(int x, int y, int width, int height,
Color color) {
AffineTransform deviceTransform = getTransform();
/* check if rotated or sheared */
int transformType = deviceTransform.getType();
boolean usePath = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (usePath) {
draw(new Rectangle2D.Float(x, y, width, height));
return;
}
Stroke stroke = getStroke();
if (stroke instanceof BasicStroke) {
BasicStroke lineStroke = (BasicStroke) stroke;
int endCap = lineStroke.getEndCap();
int lineJoin = lineStroke.getLineJoin();
/* check for default style and try to optimize it by
* calling the frameRect native function instead of using paths.
*/
if ((endCap == BasicStroke.CAP_SQUARE) &&
(lineJoin == BasicStroke.JOIN_MITER) &&
(lineStroke.getMiterLimit() ==10.0f)) {
float lineWidth = lineStroke.getLineWidth();
Point2D.Float penSize = new Point2D.Float(lineWidth,
lineWidth);
deviceTransform.deltaTransform(penSize, penSize);
float deviceLineWidth = Math.min(Math.abs(penSize.x),
Math.abs(penSize.y));
/* transform upper left coordinate */
Point2D.Float ul_pos = new Point2D.Float(x, y);
deviceTransform.transform(ul_pos, ul_pos);
/* transform lower right coordinate */
Point2D.Float lr_pos = new Point2D.Float(x + width,
y + height);
deviceTransform.transform(lr_pos, lr_pos);
float w = (float) (lr_pos.getX() - ul_pos.getX());
float h = (float)(lr_pos.getY() - ul_pos.getY());
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
/* use selectStylePen, if supported */
if (wPrinterJob.selectStylePen(endCap, lineJoin,
deviceLineWidth, color) == true) {
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
/* not supported, must be a Win 9x */
else {
double lowerRes = Math.min(wPrinterJob.getXRes(),
wPrinterJob.getYRes());
if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) {
/* use the default pen styles for thin pens. */
wPrinterJob.selectPen(deviceLineWidth, color);
wPrinterJob.frameRect((float)ul_pos.getX(),
(float)ul_pos.getY(), w, h);
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
else {
draw(new Rectangle2D.Float(x, y, width, height));
}
}
}
private Stroke transformStroke(Stroke stroke) {
if (!(stroke instanceof BasicStroke))
return stroke;
BasicStroke st = (BasicStroke)stroke;
float scale = (float)Math.sqrt(Math.abs(transform.getDeterminant()));
float dash[] = st.getDashArray();
if (dash != null) {
for (int k = 0; k < dash.length; ++k)
dash[k] *= scale;
}
return new BasicStroke(st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st.getDashPhase() * scale);
}