You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by jo...@apache.org on 2010/12/02 00:06:35 UTC
svn commit: r1041206 -
/uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java
Author: joern
Date: Wed Dec 1 23:06:34 2010
New Revision: 1041206
URL: http://svn.apache.org/viewvc?rev=1041206&view=rev
Log:
UIMA-1875 Updated placement of tags and fixed minor drawing issues
Modified:
uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java
Modified: uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java?rev=1041206&r1=1041205&r2=1041206&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java (original)
+++ uima/uimaj/trunk/uimaj-ep-cas-editor/src/main/java/org/apache/uima/caseditor/editor/annotation/TagDrawingStrategy.java Wed Dec 1 23:06:34 2010
@@ -27,23 +27,24 @@ import org.eclipse.swt.custom.StyledText
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
-// TODO: needs a path to a feature to draw
-// TODO: Annotation Editor needs to modify line spacing
-// TODO: needs a strategy to avoid overlaps
-// TODO: Check if its possible to increase the space which is used to
-// draw a white space (e.g. space char, tab char)
-// Add to annotation editor: sourceViewer.getTextWidget().setLineSpacing(12);
+
/**
- * Experimental implementation, to figure out how tag drawing could be implemented.
- * To test it, add the line spacing to the Annotation Editor and enable this class to be a
- * drawing strategy.
*
- * Issue for this work is UIMA-1875.
*/
+// TODO: Check if its possible to increase the space between characters,
+// or suggest to use mono space font for long tags ...
class TagDrawingStrategy implements IDrawingStrategy {
+ private static final int TAG_FONT_SIZE = 11;
+ private static final int MAX_LEFT_TAG_OVERLAP = 1;
+ private static final int MAX_RIGHT_TAG_OVERLAP = 1;
+ private static final int TAG_OVERLAP = MAX_LEFT_TAG_OVERLAP + MAX_RIGHT_TAG_OVERLAP;
+
+ private IDrawingStrategy annotationDrawingStyle = new BoxDrawingStrategy();
+
/**
* The name of the feature to print.
*/
@@ -60,6 +61,9 @@ class TagDrawingStrategy implements IDra
public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length,
Color color) {
+ // Always draw a box around the annotation itself
+ annotationDrawingStyle.draw(annotation, gc, textWidget, offset, length, color);
+
if (annotation instanceof EclipseAnnotationPeer) {
AnnotationFS annotationFS = ((EclipseAnnotationPeer) annotation).getAnnotationFS();
@@ -69,28 +73,118 @@ class TagDrawingStrategy implements IDra
String featureValue = annotationFS.getFeatureValueAsString(feature);
- if (featureValue != null) {
- Rectangle bounds = textWidget.getTextBounds(offset, offset + length - 1);
+ // Annotation can be rendered into multiple lines, always draw
+ // the tag in the first line where annotation starts
+ if (featureValue != null && annotationFS.getBegin() == offset) {
+
+ // Calculate how much overhang on both sides of the annotation for a tag is allowed
+ int lineIndex = textWidget.getLineAtOffset(offset);
+ int firstCharInLineOffset = textWidget.getOffsetAtLine(lineIndex);
+
+ int maxBeginOverhang;
+ if (firstCharInLineOffset == offset) {
+ maxBeginOverhang = 0;
+ }
+ else {
+ maxBeginOverhang = MAX_LEFT_TAG_OVERLAP;
+ }
+
+ int maxEndOverhang = 0;
+// TODO: Not compatible with 3.3
+// if ((firstCharInLineOffset + textWidget.getLine(lineIndex).length()) == offset + length) {
+// maxEndOverhang = 0;
+// }
+// else {
+// maxEndOverhang = MAX_RIGHT_TAG_OVERLAP;
+// }
+
+ Rectangle bounds = textWidget.getTextBounds(offset, offset + length);
if (gc != null && featureValue != null) {
-
- gc.setForeground(color);
-
+
+ int lastCharIndex;
+
+ if (length == 0)
+ lastCharIndex = offset;
+ else
+ lastCharIndex = offset + length - 1;
+
+ Point annotationStringExtent = gc.stringExtent(
+ textWidget.getText(offset, lastCharIndex));
+
Font currentFont = gc.getFont();
// TODO: Figure out if that is safe
Font tagFont = new Font(currentFont.getDevice(), currentFont.getFontData()[0].getName(),
- 12, currentFont.getFontData()[0].getStyle());
+ TAG_FONT_SIZE, currentFont.getFontData()[0].getStyle());
gc.setFont(tagFont);
+ gc.setForeground(color);
+
+ // Cutoffs the tag if two chars longer than annotation
+ // and replaces it with a scissor
+ int maxAllowedLength = length + maxBeginOverhang + maxEndOverhang;
+ if (featureValue.length() > maxAllowedLength) {
+ if (length > 0) {
+ // Trim featureValue to substring which is length -1 + scissor symbol
+ char scissorChar = (char) 0x2704;
+ featureValue = featureValue.substring(0, maxAllowedLength - 1) + scissorChar;
+ }
+ else
+ // If zero length annotation, just draw nothing
+ featureValue = "";
+ }
+
+ // Drawing after the end of a line, and before the begin does not work ...
+ Point tagStringExtent = gc.stringExtent(featureValue);
+
+ int centerOfAnnotation = annotationStringExtent.x / 2;
+ int centerOfTag = tagStringExtent.x / 2;
- // TODO: if string does not fit, still draw ?!
+ // Tag can be positioned at three different places
+ // if there is an overhang on both side, its centered
+ int newX = bounds.x + centerOfAnnotation - centerOfTag;
- gc.drawString(featureValue, bounds.x, bounds.y + bounds.height - 2, true);
+ // Figure out if there is an overhang allowed, and recalculate the position.
+
+ // No overhang means that the annotation is the first or last in the line,
+ // in this case the tag should be placed as close as possible to the begin
+ // or end of the annotation boundary.
+
+ // if no overhang on the left side allowed,
+ // the tag must start with the annotation bound
+ if (maxBeginOverhang == 0) {
+ newX = bounds.x;
+ }
+ // if no overhang on the right side allowed,
+ // the tag must end with the annotation bound
+ else if (maxEndOverhang == 0) {
+ newX = bounds.x + (annotationStringExtent.x - tagStringExtent.x);
+ }
+
+ // TODO: Might not be too safe, if bounds.height == 0,
+ // passed parameter could be -1
+ gc.drawString(featureValue, newX, bounds.y + bounds.height - 1, true);
gc.setFont(currentFont);
} else {
- // TODO: How to calculate redraw area ?!
- textWidget.redraw(bounds.x, bounds.y + bounds.height -2, bounds.width, bounds.height, true);
+
+ // The area into which the tag will be drawn must be marked
+ // to be redrawn, that requires a calculation of that area.
+
+ // Note: Did not find a way to calculate the tag extent correctly here
+ // GC.stringExtent cannot be called, because the passed GC is null
+ //
+ // The width is assumed to be the font size multiplied by the length
+ // of annotation string + TAG_OVERLAP, this is not optimal, but should give
+ // a little to large estimate
+ //
+ // Note: It unknown what happens if a too big area is drawn
+ // Doesn't seem to cause a crash on OS X
+ // TODO: Test that on windows 7, Windows XP and Linux
+
+ textWidget.redraw(bounds.x - TAG_FONT_SIZE * TAG_OVERLAP, bounds.y + bounds.height -1,
+ TAG_FONT_SIZE * (length + TAG_OVERLAP),
+ bounds.height, true);
}
}
}