1 /*
2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
27
28
29 import javafx.scene.shape.LineTo;
30 import javafx.scene.shape.MoveTo;
31 import javafx.scene.shape.PathElement;
32 import com.sun.javafx.font.CharToGlyphMapper;
33 import com.sun.javafx.font.FontResource;
34 import com.sun.javafx.font.FontStrike;
35 import com.sun.javafx.font.Metrics;
36 import com.sun.javafx.font.PGFont;
37 import com.sun.javafx.font.PrismFontFactory;
38 import com.sun.javafx.geom.BaseBounds;
39 import com.sun.javafx.geom.Path2D;
40 import com.sun.javafx.geom.Point2D;
41 import com.sun.javafx.geom.RectBounds;
42 import com.sun.javafx.geom.RoundRectangle2D;
43 import com.sun.javafx.geom.Shape;
44 import com.sun.javafx.geom.transform.BaseTransform;
45 import com.sun.javafx.geom.transform.Translate2D;
46 import com.sun.javafx.scene.text.GlyphList;
47 import com.sun.javafx.scene.text.HitInfo;
48 import com.sun.javafx.scene.text.TextLayout;
49 import com.sun.javafx.scene.text.TextSpan;
50 import java.text.Bidi;
51 import java.text.BreakIterator;
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.Hashtable;
55
56 public class PrismTextLayout implements TextLayout {
57 private static final BaseTransform IDENTITY = BaseTransform.IDENTITY_TRANSFORM;
58 private static final int X_MIN_INDEX = 0;
59 private static final int Y_MIN_INDEX = 1;
60 private static final int X_MAX_INDEX = 2;
61 private static final int Y_MAX_INDEX = 3;
62
63 private static final Hashtable<Integer, LayoutCache> stringCache = new Hashtable<>();
64 private static final Object CACHE_SIZE_LOCK = new Object();
65 private static int cacheSize = 0;
66 private static final int MAX_STRING_SIZE = 256;
67 private static final int MAX_CACHE_SIZE = PrismFontFactory.cacheLayoutSize;
390 if (isMirrored()) {
391 lineX2 = getMirroringWidth() - lineX2;
392 }
393 lineX2 += x;
394 PathElement[] result = new PathElement[4];
395 result[0] = new MoveTo(lineX, lineY);
396 result[1] = new LineTo(lineX, lineY + lineHeight / 2);
397 result[2] = new MoveTo(lineX2, lineY + lineHeight / 2);
398 result[3] = new LineTo(lineX2, lineY + lineHeight);
399 return result;
400 }
401 }
402 }
403 }
404 PathElement[] result = new PathElement[2];
405 result[0] = new MoveTo(lineX, lineY);
406 result[1] = new LineTo(lineX, lineY + lineHeight);
407 return result;
408 }
409
410 public HitInfo getHitInfo(float x, float y) {
411 ensureLayout();
412 HitInfo info = new HitInfo();
413 int lineIndex = getLineIndex(y);
414 if (lineIndex >= getLineCount()) {
415 info.setCharIndex(getCharCount());
416 } else {
417 if (isMirrored()) {
418 x = getMirroringWidth() - x;
419 }
420 TextLine line = lines[lineIndex];
421 TextRun[] runs = line.getRuns();
422 RectBounds bounds = line.getBounds();
423 TextRun run = null;
424 x -= bounds.getMinX();
425 //TODO binary search
426 for (int i = 0; i < runs.length; i++) {
427 run = runs[i];
428 if (x < run.getWidth()) break;
429 if (i + 1 < runs.length) {
430 if (runs[i + 1].isLinebreak()) break;
431 x -= run.getWidth();
432 }
433 }
434 if (run != null) {
435 int[] trailing = new int[1];
436 info.setCharIndex(run.getStart() + run.getOffsetAtX(x, trailing));
437 info.setLeading(trailing[0] == 0);
438 } else {
439 //empty line, set to line break leading
440 info.setCharIndex(line.getStart());
441 info.setLeading(true);
442 }
443 }
444 return info;
445 }
446
447 public PathElement[] getRange(int start, int end, int type,
448 float x, float y) {
449 ensureLayout();
450 int lineCount = getLineCount();
451 ArrayList<PathElement> result = new ArrayList<PathElement>();
452 float lineY = 0;
453
454 for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
455 TextLine line = lines[lineIndex];
456 RectBounds lineBounds = line.getBounds();
457 int lineStart = line.getStart();
458 if (lineStart >= end) break;
459 int lineEnd = lineStart + line.getLength();
460 if (start > lineEnd) {
461 lineY += lineBounds.getHeight() + spacing;
462 continue;
463 }
464
|
1 /*
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
27
28
29 import javafx.scene.shape.LineTo;
30 import javafx.scene.shape.MoveTo;
31 import javafx.scene.shape.PathElement;
32 import com.sun.javafx.font.CharToGlyphMapper;
33 import com.sun.javafx.font.FontResource;
34 import com.sun.javafx.font.FontStrike;
35 import com.sun.javafx.font.Metrics;
36 import com.sun.javafx.font.PGFont;
37 import com.sun.javafx.font.PrismFontFactory;
38 import com.sun.javafx.geom.BaseBounds;
39 import com.sun.javafx.geom.Path2D;
40 import com.sun.javafx.geom.Point2D;
41 import com.sun.javafx.geom.RectBounds;
42 import com.sun.javafx.geom.RoundRectangle2D;
43 import com.sun.javafx.geom.Shape;
44 import com.sun.javafx.geom.transform.BaseTransform;
45 import com.sun.javafx.geom.transform.Translate2D;
46 import com.sun.javafx.scene.text.GlyphList;
47 import com.sun.javafx.scene.text.TextLayout;
48 import com.sun.javafx.scene.text.TextSpan;
49 import java.text.Bidi;
50 import java.text.BreakIterator;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Hashtable;
54
55 public class PrismTextLayout implements TextLayout {
56 private static final BaseTransform IDENTITY = BaseTransform.IDENTITY_TRANSFORM;
57 private static final int X_MIN_INDEX = 0;
58 private static final int Y_MIN_INDEX = 1;
59 private static final int X_MAX_INDEX = 2;
60 private static final int Y_MAX_INDEX = 3;
61
62 private static final Hashtable<Integer, LayoutCache> stringCache = new Hashtable<>();
63 private static final Object CACHE_SIZE_LOCK = new Object();
64 private static int cacheSize = 0;
65 private static final int MAX_STRING_SIZE = 256;
66 private static final int MAX_CACHE_SIZE = PrismFontFactory.cacheLayoutSize;
389 if (isMirrored()) {
390 lineX2 = getMirroringWidth() - lineX2;
391 }
392 lineX2 += x;
393 PathElement[] result = new PathElement[4];
394 result[0] = new MoveTo(lineX, lineY);
395 result[1] = new LineTo(lineX, lineY + lineHeight / 2);
396 result[2] = new MoveTo(lineX2, lineY + lineHeight / 2);
397 result[3] = new LineTo(lineX2, lineY + lineHeight);
398 return result;
399 }
400 }
401 }
402 }
403 PathElement[] result = new PathElement[2];
404 result[0] = new MoveTo(lineX, lineY);
405 result[1] = new LineTo(lineX, lineY + lineHeight);
406 return result;
407 }
408
409 public Hit getHitInfo(float x, float y) {
410 int charIndex = -1;
411 boolean leading = false;
412
413 ensureLayout();
414 int lineIndex = getLineIndex(y);
415 if (lineIndex >= getLineCount()) {
416 charIndex = getCharCount();
417 } else {
418 if (isMirrored()) {
419 x = getMirroringWidth() - x;
420 }
421 TextLine line = lines[lineIndex];
422 TextRun[] runs = line.getRuns();
423 RectBounds bounds = line.getBounds();
424 TextRun run = null;
425 x -= bounds.getMinX();
426 //TODO binary search
427 for (int i = 0; i < runs.length; i++) {
428 run = runs[i];
429 if (x < run.getWidth()) break;
430 if (i + 1 < runs.length) {
431 if (runs[i + 1].isLinebreak()) break;
432 x -= run.getWidth();
433 }
434 }
435 if (run != null) {
436 int[] trailing = new int[1];
437 charIndex = run.getStart() + run.getOffsetAtX(x, trailing);
438 leading = (trailing[0] == 0);
439 } else {
440 //empty line, set to line break leading
441 charIndex = line.getStart();
442 leading = true;
443 }
444 }
445 return new Hit(charIndex, -1, leading);
446 }
447
448 public PathElement[] getRange(int start, int end, int type,
449 float x, float y) {
450 ensureLayout();
451 int lineCount = getLineCount();
452 ArrayList<PathElement> result = new ArrayList<PathElement>();
453 float lineY = 0;
454
455 for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
456 TextLine line = lines[lineIndex];
457 RectBounds lineBounds = line.getBounds();
458 int lineStart = line.getStart();
459 if (lineStart >= end) break;
460 int lineEnd = lineStart + line.getLength();
461 if (start > lineEnd) {
462 lineY += lineBounds.getHeight() + spacing;
463 continue;
464 }
465
|