public TextChunkLocationDefaultImp(Vector startLocation, Vector endLocation, float charSpaceWidth) { this.startLocation = startLocation; this.endLocation = endLocation; this.charSpaceWidth = charSpaceWidth; Vector oVector = endLocation.subtract(startLocation); if (oVector.length() == 0) { oVector = new Vector(1, 0, 0); } orientationVector = oVector.normalize(); orientationMagnitude = (int) (Math.atan2(orientationVector.get(Vector.I2), orientationVector.get(Vector.I1)) * 1000); // see http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html // the two vectors we are crossing are in the same plane, so the result will be purely // in the z-axis (out of plane) direction, so we just take the I3 component of the result Vector origin = new Vector(0, 0, 1); distPerpendicular = (int) (startLocation.subtract(origin)).cross(orientationVector).get(Vector.I3); distParallelStart = orientationVector.dot(startLocation); distParallelEnd = orientationVector.dot(endLocation); }
/** * Computes the length of this vector * <br> * <b>Note:</b> If you are working with raw vectors from PDF, be careful - * the Z axis will generally be set to 1. If you want to compute the * length of a vector, subtract it from the origin first (this will set * the Z axis to 0). * <br> * For example: * <code>aVector.subtract(originVector).length();</code> * * @return the length of this vector */ public float length() { return (float) Math.sqrt(lengthSquared()); }
float dist = (x2.subtract(x1)).cross((x1.subtract(start))).lengthSquared() / x2.subtract(x1).lengthSquared(); } else if (!firstRender){ if (result.charAt(result.length()-1) != ' ' && renderInfo.getText().length() > 0 && renderInfo.getText().charAt(0) != ' '){ // we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space float spacing = lastEnd.subtract(start).length(); if (spacing > renderInfo.getSingleSpaceWidth()/2f){ appendTextChunk(" ");
/** * Multiplies the vector by a scalar * * @param by the scalar to multiply by * @return the result of the scalar multiplication */ public Vector multiply(float by) { float x = vals[I1] * by; float y = vals[I2] * by; float z = vals[I3] * by; return new Vector(x, y, z); }
/** * Checks if a segment contains a given point in itself * @param point a point to be checked * @return true if this segment contains given point, false otherwise */ public boolean containsPoint(Vector point) { if (point == null) { return false; } Vector diff1 = point.subtract(startPoint); if (diff1.get(0) < 0 || diff1.get(1) < 0 || diff1.get(2) < 0) { return false; } Vector diff2 = endPoint.subtract(point); if (diff2.get(0) < 0 || diff2.get(1) < 0 || diff2.get(2) < 0) { return false; } return true; } }
Vector mergedStart = new Vector(Math.min(lastTextChunk.getLocation().getStartLocation().get(0), segment.getStartPoint().get(0)), Math.min(lastTextChunk.getLocation().getStartLocation().get(1), segment.getStartPoint().get(1)), Math.min(lastTextChunk.getLocation().getStartLocation().get(2), segment.getStartPoint().get(2))); Vector mergedEnd = new Vector(Math.max(lastTextChunk.getLocation().getEndLocation().get(0), segment.getEndPoint().get(0)), Math.max(lastTextChunk.getLocation().getEndLocation().get(1), segment.getEndPoint().get(1)), Math.max(lastTextChunk.getLocation().getEndLocation().get(2), segment.getEndPoint().get(2))); TextChunk merged = new TextChunk(lastTextChunk.getText(), tclStrat.createLocation(renderInfo, new LineSegment(mergedStart, mergedEnd)));
/** * Computes the bounding rectangle for this line segment. The rectangle has a rotation 0 degrees * with respect to the coordinate system that the line system is in. For example, if a line segment * is 5 unit long and sits at a 37 degree angle from horizontal, the bounding rectangle will have * origin of the lower left hand end point of the segment, with width = 4 and height = 3. * @return the bounding rectangle */ public Rectangle getBoundingRectangle(){ float x1 = getStartPoint().get(Vector.I1); float y1 = getStartPoint().get(Vector.I2); float x2 = getEndPoint().get(Vector.I1); float y2 = getEndPoint().get(Vector.I2); return new Rectangle(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2-x1), Math.abs(y2-y1)); }
if (location.getStartLocation().equals(location.getEndLocation())) { boolean foundBaseToAttachTo = false; for (int baseInd = 0; baseInd < textChunks.size(); baseInd++) { if (markInd != baseInd) { ITextChunkLocation baseLocation = textChunks.get(baseInd).getLocation(); if (!baseLocation.getStartLocation().equals(baseLocation.getEndLocation()) && TextChunkLocationDefaultImp.containsMark(baseLocation, location)) { TextChunkMarks currentMarks = marks.get(textChunks.get(baseInd)); if (currentMarks == null) {
/** * Computes the cross product of this vector and the specified vector * * @param with the vector to cross this vector with * @return the cross product */ public Vector cross(Vector with) { float x = vals[I2] * with.vals[I3] - vals[I3] * with.vals[I2]; float y = vals[I3] * with.vals[I1] - vals[I1] * with.vals[I3]; float z = vals[I1] * with.vals[I2] - vals[I2] * with.vals[I1]; return new Vector(x, y, z); }
static boolean containsMark(ITextChunkLocation baseLocation, ITextChunkLocation markLocation) { return baseLocation.getStartLocation().get(Vector.I1) <= markLocation.getStartLocation().get(Vector.I1) && baseLocation.getEndLocation().get(Vector.I1) >= markLocation.getEndLocation().get(Vector.I1) && Math.abs(baseLocation.distPerpendicular() - markLocation.distPerpendicular()) <= DIACRITICAL_MARKS_ALLOWED_VERTICAL_DEVIATION; }
public boolean isAtWordBoundary(ITextChunkLocation previous) { /* * Here we handle a very specific case which in PDF may look like: * -.232 Tc [( P)-226.2(r)-231.8(e)-230.8(f)-238(a)-238.9(c)-228.9(e)]TJ * The font's charSpace width is 0.232 and it's compensated with charSpacing of 0.232. * And a resultant TextChunk.charSpaceWidth comes to TextChunk constructor as 0. * In this case every chunk is considered as a word boundary and space is added. * We should consider charSpaceWidth equal (or close) to zero as a no-space. */ if (getCharSpaceWidth() < 0.1f) { return false; } // In case a text chunk is of zero length, this probably means this is a mark character, // and we do not actually want to insert a space in such case if (startLocation.equals(endLocation) || previous.getEndLocation().equals(previous.getStartLocation())) { return false; } float dist = distanceFromEndOf(previous); return dist < -getCharSpaceWidth() || dist > getCharSpaceWidth() / 2.0f; }
/** * Computes the difference between this vector and the specified vector * * @param v the vector to subtract from this one * @return the results of the subtraction */ public Vector subtract(Vector v) { float x = vals[I1] - v.vals[I1]; float y = vals[I2] - v.vals[I2]; float z = vals[I3] - v.vals[I3]; return new Vector(x, y, z); }
@Override public boolean accept(IEventData data, EventType type) { if (type.equals(EventType.RENDER_TEXT)) { TextRenderInfo renderInfo = (TextRenderInfo) data; LineSegment segment = renderInfo.getBaseline(); Vector startPoint = segment.getStartPoint(); Vector endPoint = segment.getEndPoint(); float x1 = startPoint.get(Vector.I1); float y1 = startPoint.get(Vector.I2); float x2 = endPoint.get(Vector.I1); float y2 = endPoint.get(Vector.I2); return filterRect == null || filterRect.intersectsLine(x1, y1, x2, y2); } else { return false; } } }
/** * @param height the height, in text space * @return the height in user space */ private float convertHeightFromTextSpaceToUserSpace(float height) { LineSegment textSpace = new LineSegment(new Vector(0, 0, 1), new Vector(0, height, 1)); LineSegment userSpace = textSpace.transformBy(textToUserSpaceTransformMatrix); return userSpace.getLength(); }
public CharacterRenderInfo(TextRenderInfo tri) { super(tri == null ? "" : tri.getText(), tri == null ? null : getLocation(tri)); if (tri == null) throw new IllegalArgumentException("TextRenderInfo argument is not nullable."); // determine bounding box float x0 = tri.getDescentLine().getStartPoint().get(0); float y0 = tri.getDescentLine().getStartPoint().get(1); float h = tri.getAscentLine().getStartPoint().get(1) - tri.getDescentLine().getStartPoint().get(1); float w = Math.abs(tri.getBaseline().getStartPoint().get(0) - tri.getBaseline().getEndPoint().get(0)); this.boundingBox = new Rectangle(x0, y0, w, h); }
/** * @param width the width, in text space * @return the width in user space */ private float convertWidthFromTextSpaceToUserSpace(float width) { LineSegment textSpace = new LineSegment(new Vector(0, 0, 1), new Vector(width, 0, 1)); LineSegment userSpace = textSpace.transformBy(textToUserSpaceTransformMatrix); return userSpace.getLength(); }