diff --git a/lib/jsyntaxpane-0.9.5.jar b/lib/jsyntaxpane-0.9.5.jar index 8433d8962..bfd9ec51f 100644 Binary files a/lib/jsyntaxpane-0.9.5.jar and b/lib/jsyntaxpane-0.9.5.jar differ diff --git a/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java b/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java index c885237d9..1b3a22ff4 100644 --- a/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java +++ b/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/SyntaxView.java @@ -15,12 +15,14 @@ package jsyntaxpane; import java.awt.Color; import java.awt.Font; +import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Toolkit; +import java.awt.geom.Rectangle2D; import java.util.Iterator; import java.util.Map; import java.util.logging.Level; @@ -31,6 +33,9 @@ import javax.swing.text.Element; import javax.swing.text.PlainView; import javax.swing.text.Position; import javax.swing.text.Segment; +import javax.swing.text.TabExpander; +import javax.swing.text.Utilities; +import javax.swing.text.View; import javax.swing.text.ViewFactory; import jsyntaxpane.util.Configuration; @@ -194,8 +199,13 @@ public class SyntaxView extends PlainView { int p0 = line.getStartOffset(); Segment s = new Segment(); doc.getText(p0, pos - p0, s); - int xOffs = UniTools.getTabbedTextWidth(s, metrics, tabBase, this,p0); - + int xOffs = UniTools.getTabbedTextWidth(getContainer().getGraphics(), s, tabBase, this,p0); + //System.err.println("calling Utilities.getTabbedTextWidth from normal: x = " + tabBase + ", startOffset = "+(p0)); + /*int xOffs2 = Utilities.getTabbedTextWidth(s, metrics, tabBase, this,p0); + System.err.println("result = " + xOffs2); + System.err.println("UniTools.getTabbedTextWidth = " +xOffs); + System.err.println("Utilities.getTabbedTextWidth = " +xOffs2); +*/ // fill in the results and return lineArea.x += xOffs; lineArea.width = 1; @@ -256,7 +266,7 @@ public class SyntaxView extends PlainView { Segment s = new Segment(); doc.getText(p0, p1 - p0, s); int tabBase = alloc.x; - int offs = p0 + UniTools.getTabbedTextOffset(s, metrics, + int offs = p0 + UniTools.getTabbedTextOffset(getContainer().getGraphics(), s, metrics, tabBase, x, this, p0); //SegmentCache.releaseSharedSegment(s); return offs; @@ -267,4 +277,7 @@ public class SyntaxView extends PlainView { } } } + + + } diff --git a/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/UniTools.java b/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/UniTools.java index 16048ecfa..d4a249288 100644 --- a/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/UniTools.java +++ b/libsrc/jsyntaxpane/jsyntaxpane/src/main/java/jsyntaxpane/UniTools.java @@ -4,7 +4,6 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsEnvironment; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -12,7 +11,6 @@ import javax.swing.JLabel; import javax.swing.text.Segment; import javax.swing.text.TabExpander; import javax.swing.text.Utilities; -import javax.swing.text.View; /** * @@ -47,34 +45,10 @@ public class UniTools { } } - public static int getTabbedTextOffset(Segment segment, FontMetrics metrics, int tabBase,int x,TabExpander e, int startOffset){ - List segments=new ArrayList(); - List unis=new ArrayList(); - - Font origFont=metrics.getFont(); - getSegments(origFont, segment, segments, unis); - Graphics g=new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getGraphics(); - Font uniFont = defaultUniFont.deriveFont(origFont.getStyle(),origFont.getSize2D()); - int ofs=0; - int totalto = 0; - for(int i=0;i segments,List unis){ - + private static void getSegments(Font f,Segment segment,List segments,List unis){ int start=0; int len=0; - boolean uni=false; + boolean uni=false; for(int i=0;i segments=new ArrayList(); - List unis=new ArrayList(); + List segments=new ArrayList<>(); + List unis=new ArrayList<>(); getSegments(g.getFont(), segment, segments, unis); - Font origFont=g.getFont(); + Font origFont = g.getFont(); Font uniFont = defaultUniFont.deriveFont(origFont.getStyle(),origFont.getSize2D()); + FontMetrics metrics = g.getFontMetrics(origFont); + FontMetrics uniMetrics = g.getFontMetrics(uniFont); int ret=0; int pos=0; for(int i=0;i= x) { + // x before x0, return. + return 0; + } + float nextX = x0; + // s may be a shared segment, so it is copied prior to calling + // the tab expander + char[] txt = s.array; + int txtOffset = s.offset; + int txtCount = s.count; + int spaceAddon = 0 ; + int spaceAddonLeftoverEnd = -1; + int startJustifiableContent = 0 ; + int endJustifiableContent = 0; + int n = s.offset + s.count; + for (int i = s.offset; i < n; i++) { + if (txt[i] == '\t' + || ((spaceAddon != 0 || i <= spaceAddonLeftoverEnd) + && (txt[i] == ' ') + && startJustifiableContent <= i + && i <= endJustifiableContent + )){ + if (txt[i] == '\t') { + if (e != null) { + nextX = e.nextTabStop(nextX, startOffset + i - txtOffset); + } else { + nextX += getFontCharWidth(g, ' ', metrics); + } + } else if (txt[i] == ' ') { + nextX += getFontCharWidth(g, ' ', metrics); + nextX += spaceAddon; + if (i <= spaceAddonLeftoverEnd) { + nextX++; + } + } + } else { + nextX += getFontCharWidth(g, txt[i], metrics); + } + if (x < nextX) { + // found the hit position... return the appropriate side + int offset; + + // the length of the string measured as a whole may differ from + // the sum of individual character lengths, for example if + // fractional metrics are enabled; and we must guard from this. + offset = i + 1 - txtOffset; + + float width = getFontCharsWidth(g, txt, txtOffset, offset, + metrics); + float span = x - x0; + + if (span < width) { + while (offset > 0) { + float charsWidth = getFontCharsWidth(g, txt, txtOffset, + offset - 1, metrics); + float nextWidth = offset > 1 ? charsWidth : 0; + + if (span >= nextWidth) { + if (span - nextWidth < width - span) { + offset--; + } + + break; + } + + width = nextWidth; + offset--; + } + } + + return offset; + } + } + + // didn't find, return end offset + return txtCount; + } + + private static float getFontCharWidth(Graphics g, char c, FontMetrics fm) + { + return getFontCharsWidth(g, new char[]{c}, 0, 1, fm); + } + private static float getFontCharsWidth(Graphics g, char[] data, int offset, int len, + FontMetrics fm) + { + if (len == 0) { + return 0; + } + + Font uniFont = defaultUniFont.deriveFont(fm.getFont().getStyle(),fm.getFont().getSize2D()); + FontMetrics uniMetrics = g.getFontMetrics(uniFont); + + int w = 0; + int batchStart = offset; + boolean lastUni = false; + for (int i = offset; i < offset + len; i++) { + char c = data[i]; + boolean uni = fm.getFont().canDisplay(c); + + if (uni != lastUni && i > offset) { + if (!lastUni) { + w += uniMetrics.charsWidth(data, batchStart, i - batchStart); + } else { + w += fm.charsWidth(data, batchStart, i - batchStart); + } + + batchStart = i; + } + lastUni = uni; + } + if (!lastUni) { + w += uniMetrics.charsWidth(data, batchStart, offset + len - batchStart); + } else { + w += fm.charsWidth(data, batchStart, offset + len - batchStart); + } + return w; + } }