< prev index next >

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

Print this page

   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

  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;
  67 
  68     private char[] text;
  69     private TextSpan[] spans;   /* Rich text  (null for single font text) */
  70     private PGFont font;        /* Single font text (null for rich text) */
  71     private FontStrike strike;  /* cached strike of font (identity) */
  72     private Integer cacheKey;
  73     private TextLine[] lines;
  74     private TextRun[] runs;
  75     private int runCount;
  76     private BaseBounds logicalBounds;
  77     private RectBounds visualBounds;
  78     private float layoutWidth, layoutHeight;
  79     private float wrapWidth, spacing;
  80     private LayoutCache layoutCache;
  81     private Shape shape;
  82     private int flags;

  83 
  84     public PrismTextLayout() {
  85         logicalBounds = new RectBounds();
  86         flags = ALIGN_LEFT;
  87     }
  88 
  89     private void reset() {
  90         layoutCache = null;
  91         runs = null;
  92         flags &= ~ANALYSIS_MASK;
  93         relayout();
  94     }
  95 
  96     private void relayout() {
  97         logicalBounds.makeEmpty();
  98         visualBounds = null;
  99         layoutWidth = layoutHeight = 0;
 100         flags &= ~(FLAGS_WRAPPED | FLAGS_CACHED_UNDERLINE | FLAGS_CACHED_STRIKETHROUGH);
 101         lines = null;
 102         shape = null;

 631                     rect.x = runX;
 632                     rect.y = runY + metrics.getStrikethroughOffset();
 633                     rect.width = run.getWidth();
 634                     rect.height = metrics.getStrikethroughThickness();
 635                     outline.append(rect, false);
 636                 }
 637                 if (text && run.getGlyphCount() > 0) {
 638                     tx.restoreTransform(1, 0, 0, 1, runX, runY);
 639                     Path2D path = (Path2D)fontStrike.getOutline(run, tx);
 640                     outline.append(path, false);
 641                 }
 642             }
 643         }
 644 
 645         if (text && !underline && !strikethrough) {
 646             shape = outline;
 647         }
 648         return outline;
 649     }
 650 












 651     /***************************************************************************
 652      *                                                                         *
 653      *                     Text Layout Implementation                          *
 654      *                                                                         *
 655      **************************************************************************/
 656 
 657     private int getLineIndex(float y) {
 658         int index = 0;
 659         float bottom = 0;
 660         int lineCount = getLineCount();
 661         while (index < lineCount) {
 662             bottom += lines[index].getBounds().getHeight() + spacing;
 663             if (index + 1 == lineCount) bottom -= lines[index].getLeading();
 664             if (bottom > y) break;
 665             index++;
 666         }
 667         return index;
 668     }
 669 
 670     private boolean copyCache() {

 987             }
 988         }
 989     }
 990 
 991     private float getTabAdvance() {
 992         float spaceAdvance = 0;
 993         if (spans != null) {
 994             /* Rich text case - use the first font (for now) */
 995             for (int i = 0; i < spans.length; i++) {
 996                 TextSpan span = spans[i];
 997                 PGFont font = (PGFont)span.getFont();
 998                 if (font != null) {
 999                     FontStrike strike = font.getStrike(IDENTITY);
1000                     spaceAdvance = strike.getCharAdvance(' ');
1001                     break;
1002                 }
1003             }
1004         } else {
1005             spaceAdvance = strike.getCharAdvance(' ');
1006         }
1007         return 8 * spaceAdvance;
1008     }
1009 
1010     private void layout() {
1011         /* Try the cache */
1012         initCache();
1013 
1014         /* Whole layout retrieved from the cache */
1015         if (lines != null) return;
1016         char[] chars = getText();
1017 
1018         /* runs and runCount are set in reuseRuns or buildRuns */
1019         if ((flags & FLAGS_ANALYSIS_VALID) != 0 && isSimpleLayout()) {
1020             reuseRuns();
1021         } else {
1022             buildRuns(chars);
1023         }
1024 
1025         GlyphLayout layout = null;
1026         if ((flags & (FLAGS_HAS_COMPLEX)) != 0) {
1027             layout = GlyphLayout.getInstance();

   1 /*
   2  * Copyright (c) 2012, 2019, 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

  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;
  67 
  68     private char[] text;
  69     private TextSpan[] spans;   /* Rich text  (null for single font text) */
  70     private PGFont font;        /* Single font text (null for rich text) */
  71     private FontStrike strike;  /* cached strike of font (identity) */
  72     private Integer cacheKey;
  73     private TextLine[] lines;
  74     private TextRun[] runs;
  75     private int runCount;
  76     private BaseBounds logicalBounds;
  77     private RectBounds visualBounds;
  78     private float layoutWidth, layoutHeight;
  79     private float wrapWidth, spacing;
  80     private LayoutCache layoutCache;
  81     private Shape shape;
  82     private int flags;
  83     private int tabSize = DEFAULT_TAB_SIZE;
  84 
  85     public PrismTextLayout() {
  86         logicalBounds = new RectBounds();
  87         flags = ALIGN_LEFT;
  88     }
  89 
  90     private void reset() {
  91         layoutCache = null;
  92         runs = null;
  93         flags &= ~ANALYSIS_MASK;
  94         relayout();
  95     }
  96 
  97     private void relayout() {
  98         logicalBounds.makeEmpty();
  99         visualBounds = null;
 100         layoutWidth = layoutHeight = 0;
 101         flags &= ~(FLAGS_WRAPPED | FLAGS_CACHED_UNDERLINE | FLAGS_CACHED_STRIKETHROUGH);
 102         lines = null;
 103         shape = null;

 632                     rect.x = runX;
 633                     rect.y = runY + metrics.getStrikethroughOffset();
 634                     rect.width = run.getWidth();
 635                     rect.height = metrics.getStrikethroughThickness();
 636                     outline.append(rect, false);
 637                 }
 638                 if (text && run.getGlyphCount() > 0) {
 639                     tx.restoreTransform(1, 0, 0, 1, runX, runY);
 640                     Path2D path = (Path2D)fontStrike.getOutline(run, tx);
 641                     outline.append(path, false);
 642                 }
 643             }
 644         }
 645 
 646         if (text && !underline && !strikethrough) {
 647             shape = outline;
 648         }
 649         return outline;
 650     }
 651 
 652     @Override
 653     public boolean setTabSize(int spaces) {
 654         if (spaces < 1)
 655             spaces = 1;
 656         if (tabSize != spaces) {
 657             tabSize = spaces;
 658             relayout();
 659             return true;
 660         }
 661         return false;
 662     }
 663 
 664     /***************************************************************************
 665      *                                                                         *
 666      *                     Text Layout Implementation                          *
 667      *                                                                         *
 668      **************************************************************************/
 669 
 670     private int getLineIndex(float y) {
 671         int index = 0;
 672         float bottom = 0;
 673         int lineCount = getLineCount();
 674         while (index < lineCount) {
 675             bottom += lines[index].getBounds().getHeight() + spacing;
 676             if (index + 1 == lineCount) bottom -= lines[index].getLeading();
 677             if (bottom > y) break;
 678             index++;
 679         }
 680         return index;
 681     }
 682 
 683     private boolean copyCache() {

1000             }
1001         }
1002     }
1003 
1004     private float getTabAdvance() {
1005         float spaceAdvance = 0;
1006         if (spans != null) {
1007             /* Rich text case - use the first font (for now) */
1008             for (int i = 0; i < spans.length; i++) {
1009                 TextSpan span = spans[i];
1010                 PGFont font = (PGFont)span.getFont();
1011                 if (font != null) {
1012                     FontStrike strike = font.getStrike(IDENTITY);
1013                     spaceAdvance = strike.getCharAdvance(' ');
1014                     break;
1015                 }
1016             }
1017         } else {
1018             spaceAdvance = strike.getCharAdvance(' ');
1019         }
1020         return tabSize * spaceAdvance;
1021     }
1022 
1023     private void layout() {
1024         /* Try the cache */
1025         initCache();
1026 
1027         /* Whole layout retrieved from the cache */
1028         if (lines != null) return;
1029         char[] chars = getText();
1030 
1031         /* runs and runCount are set in reuseRuns or buildRuns */
1032         if ((flags & FLAGS_ANALYSIS_VALID) != 0 && isSimpleLayout()) {
1033             reuseRuns();
1034         } else {
1035             buildRuns(chars);
1036         }
1037 
1038         GlyphLayout layout = null;
1039         if ((flags & (FLAGS_HAS_COMPLEX)) != 0) {
1040             layout = GlyphLayout.getInstance();
< prev index next >