< prev index next >

modules/graphics/src/main/java/com/sun/javafx/text/PrismTextLayout.java

Print this page


   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 


< prev index next >