// get next word Stroke getNextStroke(BufferedReader logReader) { Stroke stroke = new Stroke(); String line = null; try { line = logReader.readLine(); int indexOfTransl = -1; if (line != null) indexOfTransl = line.indexOf("Translation"); if (line != null && indexOfTransl > -1) { boolean isMultipleWorld = false; int indexOfLast = 1 + line.indexOf(",) : "); if (indexOfLast < 1) { isMultipleWorld = true; indexOfLast = line.indexOf(" : "); } if (indexOfTransl == 24) { stroke.isDelete = false; } else { stroke.isDelete = true; } stroke.stroke = getStroke(line, indexOfTransl + 14, indexOfLast - 2); stroke.word = line.substring(indexOfLast + (isMultipleWorld ? 2 : 3), line.length() - 1); return stroke; } else { return null; } } catch (Exception e) { println("Error while reading stroke from Plover log file: " + e.getMessage()); } return null; }
static { Stroke stroke = new BasicStroke(2); selectionShape = stroke.createStrokedShape(hitRect); format.setMinimumIntegerDigits(1); format.setMinimumFractionDigits(1); format.setMaximumFractionDigits(2); }
public void draw(GraphicsWrapper gw) { gw.setLineWidth(5); for (Stroke s : strokes) { s.draw(gw); } gw.setLineWidth(1); }
public AlignedRectangle2D getBoundingRectangle() { if (isBoundingRectangleDirty) { boundingRectangle.clear(); for (Stroke s : strokes) { boundingRectangle.bound(s.getBoundingRectangle()); } isBoundingRectangleDirty = false; } return boundingRectangle; }
public void draw(GraphicsWrapper gw) { palette.draw(gw); // draw filled rectangles over the selected strokes gw.setCoordinateSystemToWorldSpaceUnits(); for (Stroke s : selectedStrokes) { AlignedRectangle2D r = s.getBoundingRectangle(); gw.setColor(1.0f, 0.5f, 0, 0.2f); // transparent orange Vector2D diagonal = r.getDiagonal(); gw.fillRect(r.getMin().x(), r.getMin().y(), diagonal.x(), diagonal.y()); } gw.setCoordinateSystemToPixels(); // draw cursors for (int i = 0; i < cursorContainer.getNumCursors(); ++i) { MyCursor cursor = cursorContainer.getCursorByIndex(i); if (cursor.type == MyCursor.TYPE_NOTHING) gw.setColor(0.5f, 0, 0, 0.65f); // red (because this cursor is being ignored) else gw.setColor(0, 0.5f, 0.5f, 0.65f); // cyan gw.fillCircle(cursor.getCurrentPosition().x() - 10, cursor.getCurrentPosition().y() - 10, 10); if (cursor.type == MyCursor.TYPE_INKING) { // draw ink trail gw.setColor(0, 0, 0); gw.drawPolyline(cursor.getPositions()); } else if (cursor.type == MyCursor.TYPE_SELECTION) { if (cursor.doesDragLookLikeLassoGesture()) { // draw filled polygon gw.setColor(0, 0, 0, 0.2f); gw.fillPolygon(cursor.getPositions()); } else { // draw polyline to indicate that a lasso could be started gw.setColor(0, 0, 0); gw.drawPolyline(cursor.getPositions()); // also draw selection rectangle gw.setColor(0, 0, 0, 0.2f); Vector2D diagonal = Point2D.diff(cursor.getCurrentPosition(), cursor.getFirstPosition()); gw.fillRect( cursor.getFirstPosition().x(), cursor.getFirstPosition().y(), diagonal.x(), diagonal.y()); } } } }
@Override public Mark copy() { Mark copy = new Mark(); copy.wellKnown = wellKnown; copy.fill = fill.copy(); copy.stroke = stroke.copy(); copy.markIndex = markIndex; // these two should be safe to just copy the references: copy.shape = shape; copy.font = font; return copy; }
public void paintComponent(Graphics g) { super.paintComponent(g); this.setBackground(Color.WHITE); Graphics2D g2d = (Graphics2D) g; RenderingHints rh = new RenderingHints( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHints(rh); for (int i = 0; i < strokes.size(); i++) { Stroke currentStroke = strokes.get(i); g2d.setPaint(currentStroke.getColor()); g2d.setStroke(new BasicStroke(currentStroke.getThickness())); ArrayList<Point2D> currentStrokePoints = currentStroke.getPoints(); for (int j = 1; j < currentStrokePoints.size(); j++) { g2d.drawLine( (int) (currentStrokePoints.get(j - 1).getX() * this.getSize().getWidth()), (int) (currentStrokePoints.get(j - 1).getY() * this.getSize().getHeight()), (int) (currentStrokePoints.get(j).getX() * this.getSize().getWidth()), (int) (currentStrokePoints.get(j).getY() * this.getSize().getHeight())); } } }
public void setStroke(Stroke s) { if (s != null) { m_localGraphicsState.setStroke(s); if (s.equals(m_psGraphicsState.getStroke())) { return; } m_psGraphicsState.setStroke(s); } else { m_localGraphicsState.setStroke(new BasicStroke()); m_psGraphicsState.setStroke(getStroke()); } // ouput postscript here to set stroke. }
public ArrayList<Integer> strokesToPrimitives(ArrayList<Stroke> strokes) { if (strokes == null) return null; ArrayList<Integer> primitives = new ArrayList<Integer>(); for (Stroke stroke : strokes) { String type = stroke.StrokeGetType(); if (type.equals("arc")) primitives.add(Line(stroke.StrokeGetArc())); if (type.equals("cubicbezier")) primitives.add(BezierCubic(stroke.StrokeGet3Bezier())); if (type.equals("line")) primitives.add(Line(stroke.StrokeGetLine())); if (type.equals("quadraticbezier")) primitives.add(BezierQuadratic(stroke.StrokeGet2Bezier())); } return primitives; }
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { ServletFileUpload upload = new ServletFileUpload(); res.setContentType("text/plain"); KanjiDao dao = new KanjiDao(); FileItemIterator iterator = upload.getItemIterator(req); while (iterator.hasNext()) { FileItemStream item = iterator.next(); InputStream stream = item.openStream(); if (item.isFormField()) { log.warning("Got a form field: " + item.getFieldName()); } else { log.info("Got an uploaded file: " + item.getFieldName() + ", name = " + item.getName()); KanjSvgParser parser = new KanjSvgParser(stream); Kanji kanji = parser.parse(); if (kanji == null) { log.warning("Could not parse SVG"); continue; } PersistenceManager pm = PMF.get().getPersistenceManager(); try { Kanji existing = dao.findKanji(pm, kanji.getUnicodeNumber()); if (existing == null) { log.warning( String.format("Kanji %s not found. Nothing to update", kanji.getUnicodeNumber())); continue; } List<Stroke> newStrokes = kanji.getStrokes(); List<Stroke> existingStrokes = existing.getStrokes(); for (int i = 0; i < existingStrokes.size(); i++) { Stroke s = newStrokes.get(i); Stroke old = existingStrokes.get(i); log.info("old stroke: " + old); log.info("new stroke: " + s); old.setPath(s.getPath()); old.setNumber(s.getNumber()); } log.info( String.format( "Updated strokes for %s(%s)", existing.getMidashi(), existing.getUnicodeNumber())); log.info(String.format("Removing %s from cache", existing.getUnicodeNumber())); CacheController.remove(existing.getUnicodeNumber()); } finally { pm.close(); } } res.sendRedirect("/update-strokes.xhtml"); } } catch (Exception ex) { throw new ServletException(ex); } }
public Mark() { stroke.color = BLACK; }
// returns true if a redraw is requested public boolean processMultitouchInputEvent( int id, float x, // in pixels float y, // in pixels int type, GraphicsWrapper gw, boolean doOtherUserContextsHaveCursors) { // Find the cursor that corresponds to the event id, if such a cursor already exists. // If no such cursor exists, the below index will be -1, and the reference to cursor will be // null. int cursorIndex = cursorContainer.findIndexOfCursorById(id); MyCursor cursor = (cursorIndex == -1) ? null : cursorContainer.getCursorByIndex(cursorIndex); if (cursor == null) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // This should never happen, but if it does, just ignore the event. return false; } // The event does not correspond to any existing cursor. // In other words, this is a new finger touching the screen. // The event is probably of type TOUCH_EVENT_DOWN. // A new cursor will need to be created for the event. if (palette.contains(x, y)) { // The event occurred inside the palette. if (cursorContainer.getNumCursors() == 0) { // There are currently no cursors engaged for this user context. // In other words, this new finger is the only finger for the user context. // So, we allow the event for the new finger to activate a button in the palette. // We branch according to the button under the event. // int indexOfButton = palette.indexOfButtonContainingTheGivenPoint(x, y); if (indexOfButton == palette.movePalette_buttonIndex) { palette.buttons.get(indexOfButton).isPressed = true; // Cause a new cursor to be created to keep track of this event id in the future cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INTERACTING_WITH_WIDGET, indexOfButton); } else if (indexOfButton == palette.ink_buttonIndex || indexOfButton == palette.select_buttonIndex || indexOfButton == palette.manipulate_buttonIndex || indexOfButton == palette.camera_buttonIndex) { // We transition to the mode corresponding to the button palette.buttons.get(palette.currentlyActiveModalButton).isPressed = false; palette.currentlyActiveModalButton = indexOfButton; palette.buttons.get(indexOfButton).isPressed = true; // Cause a new cursor to be created to keep track of this event id in the future cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INTERACTING_WITH_WIDGET, indexOfButton); } else if (indexOfButton == palette.black_buttonIndex || indexOfButton == palette.red_buttonIndex || indexOfButton == palette.green_buttonIndex) { // We transition to the color corresponding to the button palette.buttons.get(palette.currentlyActiveColorButton).isPressed = false; palette.currentlyActiveColorButton = indexOfButton; palette.buttons.get(indexOfButton).isPressed = true; if (indexOfButton == palette.black_buttonIndex) { palette.current_red = 0; palette.current_green = 0; palette.current_blue = 0; } else if (indexOfButton == palette.red_buttonIndex) { palette.current_red = 1.0f; palette.current_green = 0; palette.current_blue = 0; } else if (indexOfButton == palette.green_buttonIndex) { palette.current_red = 0; palette.current_green = 1.0f; palette.current_blue = 0; } // Cause a new cursor to be created to keep track of this event id in the future cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INTERACTING_WITH_WIDGET, indexOfButton); } else if (indexOfButton == palette.horizFlip_buttonIndex) { palette.buttons.get(indexOfButton).isPressed = true; // Cause a new cursor to be created to keep track of this event id in the future cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INTERACTING_WITH_WIDGET, indexOfButton); // Flip the selected strokes horizontally (around a vertical axis) for (Stroke s : selectedStrokes) { Point2D center = s.getBoundingRectangle().getCenter(); for (Point2D p : s.getPoints()) { p.copy(center.x() - (p.x() - center.x()), p.y()); } s.markBoundingRectangleDirty(); } drawing.markBoundingRectangleDirty(); } else if (indexOfButton == palette.frameAll_buttonIndex) { palette.buttons.get(indexOfButton).isPressed = true; // Cause a new cursor to be created to keep track of this event id in the future cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INTERACTING_WITH_WIDGET, indexOfButton); // Frame the entire drawing gw.frame(drawing.getBoundingRectangle(), true); } else { // The event occurred on some part of the palette where there are no buttons. // We cause a new cursor to be created to keep track of this event id in the future. cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); // Prevent the cursor from doing anything in the future. cursor.setType(MyCursor.TYPE_NOTHING); } } else { // There is already at least one cursor. // In other words, there is already one or more other fingers being tracked in this user // context // (possibly on a palette button, and/or over the drawing). // To keep things simple, we prevent this new finger from doing anything. // We create a new cursor ... cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); // ... and prevent the cursor from doing anything in the future. cursor.setType(MyCursor.TYPE_NOTHING); } } else { // The event did not occur inside the palette. // This new finger may have been placed down to start // drawing a stroke, or start camera manipulation, etc. // We branch according to the current mode. // if (palette.currentlyActiveModalButton == palette.ink_buttonIndex) { // start drawing a stroke cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_INKING); } else if (palette.currentlyActiveModalButton == palette.select_buttonIndex) { // The new finger should only start selecting // if there is not already another finger performing selection. if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_SELECTION) == 0) { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_SELECTION); } else { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_NOTHING); } } else if (palette.currentlyActiveModalButton == palette.manipulate_buttonIndex) { // The new finger should only manipulate the selection // if there are not already 2 fingers manipulating the selection. if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_DIRECT_MANIPULATION) < 2) { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_DIRECT_MANIPULATION); } else { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_NOTHING); } } else if (palette.currentlyActiveModalButton == palette.camera_buttonIndex) { // The new finger should only manipulate the camera // if there are not already 2 fingers manipulating the camera. if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_CAMERA_PAN_ZOOM) < 2) { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_CAMERA_PAN_ZOOM); } else { cursorIndex = cursorContainer.updateCursorById(id, x, y); cursor = cursorContainer.getCursorByIndex(cursorIndex); cursor.setType(MyCursor.TYPE_NOTHING); } } } } else { // The event corresponds to an already existing cursor // (and the cursor was probably created during an earlier event of type TOUCH_EVENT_DOWN). // The current event is probably of type TOUCH_EVENT_MOVE or TOUCH_EVENT_UP. if (type == MultitouchFramework.TOUCH_EVENT_MOVE) { // The event is a move event, and corresponds to an existing cursor. // Is the location of the event different from the last reported location? Point2D newPosition = new Point2D(x, y); if (cursor.getCurrentPosition().equals(newPosition)) { // The event's location is the same as last time. // Don't bother processing the event any further. return false; // do not request a redraw } } // We branch according to the type of cursor. // if (cursor.type == MyCursor.TYPE_NOTHING) { // Update the cursor with its new position. cursorContainer.updateCursorById(id, x, y); if (type == MultitouchFramework.TOUCH_EVENT_UP) cursorContainer.removeCursorByIndex(cursorIndex); } else if (cursor.type == MyCursor.TYPE_INTERACTING_WITH_WIDGET) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // The user lifted their finger off of a palette button. cursorContainer.removeCursorByIndex(cursorIndex); if (!palette.buttons.get(cursor.indexOfButton).isSticky) { palette.buttons.get(cursor.indexOfButton).isPressed = false; } } else { // Earlier, the user pressed down on a button in the palette, // and now they are dragging their finger over the button // (and possibly onto other buttons). // If this is the "move palette" button, we move the palette. if (cursor.indexOfButton == palette.movePalette_buttonIndex) { movePalette(x - cursor.getCurrentPosition().x(), y - cursor.getCurrentPosition().y()); } cursorIndex = cursorContainer.updateCursorById(id, x, y); } } else if (cursor.type == MyCursor.TYPE_INKING) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // up event cursorIndex = cursorContainer.updateCursorById(id, x, y); // Add the newly drawn stroke to the drawing Stroke newStroke = new Stroke(); newStroke.setColor(palette.current_red, palette.current_green, palette.current_blue); for (Point2D p : cursor.getPositions()) { newStroke.addPoint(gw.convertPixelsToWorldSpaceUnits(p)); } drawing.addStroke(newStroke); cursorContainer.removeCursorByIndex(cursorIndex); } else { // drag event; just update the cursor with the new position cursorIndex = cursorContainer.updateCursorById(id, x, y); } } else if (cursor.type == MyCursor.TYPE_CAMERA_PAN_ZOOM) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // up event cursorContainer.removeCursorByIndex(cursorIndex); } else { // drag event cursorIndex = cursorContainer.updateCursorById(id, x, y); if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_CAMERA_PAN_ZOOM) == 2) { MyCursor cursor0 = cursorContainer.getCursorByType(MyCursor.TYPE_CAMERA_PAN_ZOOM, 0); MyCursor cursor1 = cursorContainer.getCursorByType(MyCursor.TYPE_CAMERA_PAN_ZOOM, 1); gw.panAndZoomBasedOnDisplacementOfTwoPoints( id == cursor0.id ? cursor0.getPreviousPosition() : cursor0.getCurrentPosition(), id == cursor1.id ? cursor1.getPreviousPosition() : cursor1.getCurrentPosition(), cursor0.getCurrentPosition(), cursor1.getCurrentPosition()); } else if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_CAMERA_PAN_ZOOM) == 1) { gw.pan( cursor.getCurrentPosition().x() - cursor.getPreviousPosition().x(), cursor.getCurrentPosition().y() - cursor.getPreviousPosition().y()); } } } else if (cursor.type == MyCursor.TYPE_SELECTION) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // up event cursorIndex = cursorContainer.updateCursorById(id, x, y); // Update the selection if (cursor.doesDragLookLikeLassoGesture()) { // complete a lasso selection // Need to transform the positions of the cursor from pixels to world space coordinates. // We will store the world space coordinates in the following data structure. ArrayList<Point2D> lassoPolygonPoints = new ArrayList<Point2D>(); for (Point2D p : cursor.getPositions()) { lassoPolygonPoints.add(gw.convertPixelsToWorldSpaceUnits(p)); } selectedStrokes.clear(); for (Stroke s : drawing.strokes) { if (s.isContainedInLassoPolygon(lassoPolygonPoints)) selectedStrokes.add(s); } } else { // complete a rectangle selection AlignedRectangle2D selectedRectangle = new AlignedRectangle2D( gw.convertPixelsToWorldSpaceUnits(cursor.getFirstPosition()), gw.convertPixelsToWorldSpaceUnits(cursor.getCurrentPosition())); selectedStrokes.clear(); for (Stroke s : drawing.strokes) { if (s.isContainedInRectangle(selectedRectangle)) selectedStrokes.add(s); } } cursorContainer.removeCursorByIndex(cursorIndex); } else { // drag event; just update the cursor with the new position cursorIndex = cursorContainer.updateCursorById(id, x, y); } } else if (cursor.type == MyCursor.TYPE_DIRECT_MANIPULATION) { if (type == MultitouchFramework.TOUCH_EVENT_UP) { // up event cursorContainer.removeCursorByIndex(cursorIndex); } else { // drag event cursorIndex = cursorContainer.updateCursorById(id, x, y); if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_DIRECT_MANIPULATION) == 2) { MyCursor cursor0 = cursorContainer.getCursorByType(MyCursor.TYPE_DIRECT_MANIPULATION, 0); MyCursor cursor1 = cursorContainer.getCursorByType(MyCursor.TYPE_DIRECT_MANIPULATION, 1); // convert cursor positions to world space Point2D cursor0_currentPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor0.getCurrentPosition()); Point2D cursor1_currentPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor1.getCurrentPosition()); Point2D cursor0_previousPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor0.getPreviousPosition()); Point2D cursor1_previousPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor1.getPreviousPosition()); for (Stroke s : selectedStrokes) { Point2DUtil.transformPointsBasedOnDisplacementOfTwoPoints( s.getPoints(), id == cursor0.id ? cursor0_previousPosition_worldSpace : cursor0_currentPosition_worldSpace, id == cursor1.id ? cursor1_previousPosition_worldSpace : cursor1_currentPosition_worldSpace, cursor0_currentPosition_worldSpace, cursor1_currentPosition_worldSpace); s.markBoundingRectangleDirty(); } drawing.markBoundingRectangleDirty(); } else if (cursorContainer.getNumCursorsOfGivenType(MyCursor.TYPE_DIRECT_MANIPULATION) == 1) { // convert cursor positions to world space Point2D cursor_currentPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor.getCurrentPosition()); Point2D cursor_previousPosition_worldSpace = gw.convertPixelsToWorldSpaceUnits(cursor.getPreviousPosition()); // compute translation vector Vector2D translationVector = Point2D.diff(cursor_currentPosition_worldSpace, cursor_previousPosition_worldSpace); // apply the translation to the selected strokes for (Stroke s : selectedStrokes) { for (Point2D p : s.getPoints()) { p.copy(Point2D.sum(p, translationVector)); } s.markBoundingRectangleDirty(); } drawing.markBoundingRectangleDirty(); } } } } return true; // request a redraw }