Changeset 8994 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2015-11-07T13:24:20+01:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r8870 r8994 26 26 import java.awt.geom.Point2D; 27 27 import java.awt.geom.Rectangle2D; 28 import java.text.Bidi;29 28 import java.util.ArrayList; 30 29 import java.util.Collection; … … 1248 1247 } 1249 1248 1250 FontRenderContext frc = g.getFontRenderContext(); 1251 char[] chars = name.toCharArray(); 1252 int dirFlag = Bidi.DIRECTION_LEFT_TO_RIGHT; 1253 if (Bidi.requiresBidi(chars, 0, chars.length)) { 1254 Bidi bd = new Bidi(name, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); 1255 if (bd.isRightToLeft()) { 1256 dirFlag = Bidi.DIRECTION_RIGHT_TO_LEFT; 1257 } 1258 } 1259 // only works for text that is completely left-to-right or completely right-to-left, not bi-directional text 1260 GlyphVector gv = text.font.layoutGlyphVector(frc, chars, 0, chars.length, dirFlag); 1261 1262 for (int i = 0; i < gv.getNumGlyphs(); ++i) { 1263 Rectangle2D rect = gv.getGlyphLogicalBounds(i).getBounds2D(); 1264 double t = tStart + offsetSign * (rect.getX() + rect.getWidth()/2) / pathLength; 1265 double[] p = pointAt(t, poly, pathLength); 1266 if (p != null) { 1267 AffineTransform trfm = AffineTransform.getTranslateInstance(p[0] - rect.getX(), p[1]); 1268 trfm.rotate(p[2]+angleOffset); 1269 double off = -rect.getY() - rect.getHeight()/2 + text.yOffset; 1270 trfm.translate(-rect.getWidth()/2, off); 1271 if (isGlyphVectorDoubleTranslationBug(text.font)) { 1272 // scale the translation components by one half 1273 AffineTransform tmp = AffineTransform.getTranslateInstance(-0.5 * trfm.getTranslateX(), -0.5 * trfm.getTranslateY()); 1274 tmp.concatenate(trfm); 1275 trfm = tmp; 1276 } 1277 gv.setGlyphTransform(i, trfm); 1278 } 1279 } 1280 displayText(gv, null, 0, 0, way.isDisabled(), text); 1249 List<GlyphVector> gvs = Utils.getGlyphVectorsBidi(name, text.font, g.getFontRenderContext()); 1250 double gvOffset = 0; 1251 for (GlyphVector gv : gvs) { 1252 double gvWidth = gv.getLogicalBounds().getBounds2D().getWidth(); 1253 for (int i = 0; i < gv.getNumGlyphs(); ++i) { 1254 Rectangle2D rect = gv.getGlyphLogicalBounds(i).getBounds2D(); 1255 double t = tStart + offsetSign * (gvOffset + rect.getX() + rect.getWidth()/2) / pathLength; 1256 double[] p = pointAt(t, poly, pathLength); 1257 if (p != null) { 1258 AffineTransform trfm = AffineTransform.getTranslateInstance(p[0] - rect.getX(), p[1]); 1259 trfm.rotate(p[2]+angleOffset); 1260 double off = -rect.getY() - rect.getHeight()/2 + text.yOffset; 1261 trfm.translate(-rect.getWidth()/2, off); 1262 if (isGlyphVectorDoubleTranslationBug(text.font)) { 1263 // scale the translation components by one half 1264 AffineTransform tmp = AffineTransform.getTranslateInstance(-0.5 * trfm.getTranslateX(), -0.5 * trfm.getTranslateY()); 1265 tmp.concatenate(trfm); 1266 trfm = tmp; 1267 } 1268 gv.setGlyphTransform(i, trfm); 1269 } 1270 } 1271 displayText(gv, null, 0, 0, way.isDisabled(), text); 1272 gvOffset += gvWidth; 1273 } 1281 1274 } 1282 1275 -
trunk/src/org/openstreetmap/josm/tools/Utils.java
r8933 r8994 6 6 7 7 import java.awt.Color; 8 import java.awt.Font; 8 9 import java.awt.Toolkit; 9 10 import java.awt.datatransfer.Clipboard; … … 13 14 import java.awt.datatransfer.Transferable; 14 15 import java.awt.datatransfer.UnsupportedFlavorException; 16 import java.awt.font.FontRenderContext; 17 import java.awt.font.GlyphVector; 15 18 import java.io.BufferedReader; 16 19 import java.io.ByteArrayOutputStream; … … 34 37 import java.security.MessageDigest; 35 38 import java.security.NoSuchAlgorithmException; 39 import java.text.Bidi; 36 40 import java.text.MessageFormat; 37 41 import java.util.AbstractCollection; … … 1493 1497 return hashMapInitialCapacity(nEntries, 0.75f); 1494 1498 } 1499 1500 /** 1501 * Utility class to save a string along with its rendering direction 1502 * (left-to-right or right-to-left). 1503 */ 1504 private static class DirectionString { 1505 public int direction; 1506 public String str; 1507 1508 public DirectionString(int direction, String str) { 1509 this.direction = direction; 1510 this.str = str; 1511 } 1512 } 1513 1514 /** 1515 * Convert a string to a list of {@link GlyphVector}s. The string may contain 1516 * bi-directional text. The result will be in correct visual order. 1517 * Each element of the resulting list corresponds to one section of the 1518 * string with consistent writing direction (left-to-right or right-to-left). 1519 * 1520 * @param string the string to render 1521 * @param font the font 1522 * @param frc a FontRenderContext object 1523 * @return a list of GlyphVectors 1524 */ 1525 public static List<GlyphVector> getGlyphVectorsBidi(String string, Font font, FontRenderContext frc) { 1526 List<GlyphVector> gvs = new ArrayList<>(); 1527 Bidi bidi = new Bidi(string, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT); 1528 byte[] levels = new byte[bidi.getRunCount()]; 1529 DirectionString[] dirStrings = new DirectionString[levels.length]; 1530 for (int i = 0; i < levels.length; ++i) { 1531 levels[i] = (byte) bidi.getRunLevel(i); 1532 String substr = string.substring(bidi.getRunStart(i), bidi.getRunLimit(i)); 1533 int dir = levels[i] % 2 == 0 ? Bidi.DIRECTION_LEFT_TO_RIGHT : Bidi.DIRECTION_RIGHT_TO_LEFT; 1534 dirStrings[i] = new DirectionString(dir, substr); 1535 } 1536 Bidi.reorderVisually(levels, 0, dirStrings, 0, levels.length); 1537 for (int i = 0; i < dirStrings.length; ++i) { 1538 char[] chars = dirStrings[i].str.toCharArray(); 1539 gvs.add(font.layoutGlyphVector(frc, chars, 0, chars.length, dirStrings[i].direction)); 1540 } 1541 return gvs; 1542 } 1543 1495 1544 }
Note:
See TracChangeset
for help on using the changeset viewer.