< prev index next >

modules/controls/src/main/java/com/sun/javafx/scene/control/skin/Utils.java

Print this page




  31 package com.sun.javafx.scene.control.skin;
  32 
  33 import com.sun.javafx.scene.control.behavior.TextBinding;
  34 import com.sun.javafx.scene.text.TextLayout;
  35 import com.sun.javafx.tk.Toolkit;
  36 import javafx.application.ConditionalFeature;
  37 import javafx.application.Platform;
  38 import javafx.beans.InvalidationListener;
  39 import javafx.beans.Observable;
  40 import javafx.beans.value.ObservableValue;
  41 import javafx.collections.ObservableList;
  42 import javafx.geometry.Bounds;
  43 import javafx.geometry.HPos;
  44 import javafx.geometry.Point2D;
  45 import javafx.geometry.VPos;
  46 import javafx.scene.Scene;
  47 import javafx.scene.control.ContextMenu;
  48 import javafx.scene.control.MenuItem;
  49 import javafx.scene.control.OverrunStyle;
  50 import com.sun.javafx.scene.control.ContextMenuContent;

  51 import java.net.URL;
  52 import javafx.scene.input.KeyCombination;
  53 import javafx.scene.input.Mnemonic;
  54 import javafx.scene.paint.Color;
  55 import javafx.scene.text.Font;
  56 import javafx.scene.text.Text;
  57 import javafx.scene.text.TextBoundsType;
  58 import javafx.scene.text.HitInfo;
  59 
  60 import java.text.Bidi;
  61 import java.util.Locale;
  62 import java.util.function.Consumer;
  63 
  64 import static javafx.scene.control.OverrunStyle.CENTER_ELLIPSIS;
  65 import static javafx.scene.control.OverrunStyle.CENTER_WORD_ELLIPSIS;
  66 import static javafx.scene.control.OverrunStyle.CLIP;
  67 import static javafx.scene.control.OverrunStyle.ELLIPSIS;
  68 import static javafx.scene.control.OverrunStyle.LEADING_ELLIPSIS;
  69 import static javafx.scene.control.OverrunStyle.LEADING_WORD_ELLIPSIS;
  70 import static javafx.scene.control.OverrunStyle.WORD_ELLIPSIS;


  79 public class Utils {
  80 
  81     static final Text helper = new Text();
  82     static final double DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
  83     static final double DEFAULT_LINE_SPACING = helper.getLineSpacing();
  84     static final String DEFAULT_TEXT = helper.getText();
  85     static final TextBoundsType DEFAULT_BOUNDS_TYPE = helper.getBoundsType();
  86 
  87     /* Using TextLayout directly for simple text measurement.
  88      * Instead of restoring the TextLayout attributes to default values
  89      * (each renders the TextLayout unable to efficiently cache layout data).
  90      * It always sets all the attributes pertinent to calculation being performed.
  91      * Note that lineSpacing and boundsType are important when computing the height
  92      * but irrelevant when computing the width.
  93      *
  94      * Note: This code assumes that TextBoundsType#VISUAL is never used by controls.
  95      * */
  96     static final TextLayout layout = Toolkit.getToolkit().getTextLayoutFactory().createLayout();
  97 
  98     public static double getAscent(Font font, TextBoundsType boundsType) {
  99         layout.setContent("", font.impl_getNativeFont());
 100         layout.setWrapWidth(0);
 101         layout.setLineSpacing(0);
 102         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 103             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 104         } else {
 105             layout.setBoundsType(0);
 106         }
 107         return -layout.getBounds().getMinY();
 108     }
 109 
 110     public static double getLineHeight(Font font, TextBoundsType boundsType) {
 111         layout.setContent("", font.impl_getNativeFont());
 112         layout.setWrapWidth(0);
 113         layout.setLineSpacing(0);
 114         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 115             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 116         } else {
 117             layout.setBoundsType(0);
 118         }
 119 
 120         // RT-37092: Use the line bounds specifically, to include font leading.
 121         return layout.getLines()[0].getBounds().getHeight();
 122     }
 123 
 124     public static double computeTextWidth(Font font, String text, double wrappingWidth) {
 125         layout.setContent(text != null ? text : "", font.impl_getNativeFont());
 126         layout.setWrapWidth((float)wrappingWidth);
 127         return layout.getBounds().getWidth();
 128     }
 129 
 130     public static double computeTextHeight(Font font, String text, double wrappingWidth, TextBoundsType boundsType) {
 131         return computeTextHeight(font, text, wrappingWidth, 0, boundsType);
 132     }
 133 
 134     @SuppressWarnings("deprecation")
 135     public static double computeTextHeight(Font font, String text, double wrappingWidth, double lineSpacing, TextBoundsType boundsType) {
 136         layout.setContent(text != null ? text : "", font.impl_getNativeFont());
 137         layout.setWrapWidth((float)wrappingWidth);
 138         layout.setLineSpacing((float)lineSpacing);
 139         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 140             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 141         } else {
 142             layout.setBoundsType(0);
 143         }
 144         return layout.getBounds().getHeight();
 145     }
 146 
 147     public static int computeTruncationIndex(Font font, String text, double width) {
 148         helper.setText(text);
 149         helper.setFont(font);
 150         helper.setWrappingWidth(0);
 151         helper.setLineSpacing(0);
 152         // The -2 is a fudge to make sure the result more often matches
 153         // what we get from using computeTextWidth instead. It's not yet
 154         // clear what causes the small discrepancies.
 155         Bounds bounds = helper.getLayoutBounds();
 156         Point2D endPoint = new Point2D(width - 2, bounds.getMinY() + bounds.getHeight() / 2);




  31 package com.sun.javafx.scene.control.skin;
  32 
  33 import com.sun.javafx.scene.control.behavior.TextBinding;
  34 import com.sun.javafx.scene.text.TextLayout;
  35 import com.sun.javafx.tk.Toolkit;
  36 import javafx.application.ConditionalFeature;
  37 import javafx.application.Platform;
  38 import javafx.beans.InvalidationListener;
  39 import javafx.beans.Observable;
  40 import javafx.beans.value.ObservableValue;
  41 import javafx.collections.ObservableList;
  42 import javafx.geometry.Bounds;
  43 import javafx.geometry.HPos;
  44 import javafx.geometry.Point2D;
  45 import javafx.geometry.VPos;
  46 import javafx.scene.Scene;
  47 import javafx.scene.control.ContextMenu;
  48 import javafx.scene.control.MenuItem;
  49 import javafx.scene.control.OverrunStyle;
  50 import com.sun.javafx.scene.control.ContextMenuContent;
  51 import com.sun.javafx.text.FontHelper;
  52 import java.net.URL;
  53 import javafx.scene.input.KeyCombination;
  54 import javafx.scene.input.Mnemonic;
  55 import javafx.scene.paint.Color;
  56 import javafx.scene.text.Font;
  57 import javafx.scene.text.Text;
  58 import javafx.scene.text.TextBoundsType;
  59 import javafx.scene.text.HitInfo;
  60 
  61 import java.text.Bidi;
  62 import java.util.Locale;
  63 import java.util.function.Consumer;
  64 
  65 import static javafx.scene.control.OverrunStyle.CENTER_ELLIPSIS;
  66 import static javafx.scene.control.OverrunStyle.CENTER_WORD_ELLIPSIS;
  67 import static javafx.scene.control.OverrunStyle.CLIP;
  68 import static javafx.scene.control.OverrunStyle.ELLIPSIS;
  69 import static javafx.scene.control.OverrunStyle.LEADING_ELLIPSIS;
  70 import static javafx.scene.control.OverrunStyle.LEADING_WORD_ELLIPSIS;
  71 import static javafx.scene.control.OverrunStyle.WORD_ELLIPSIS;


  80 public class Utils {
  81 
  82     static final Text helper = new Text();
  83     static final double DEFAULT_WRAPPING_WIDTH = helper.getWrappingWidth();
  84     static final double DEFAULT_LINE_SPACING = helper.getLineSpacing();
  85     static final String DEFAULT_TEXT = helper.getText();
  86     static final TextBoundsType DEFAULT_BOUNDS_TYPE = helper.getBoundsType();
  87 
  88     /* Using TextLayout directly for simple text measurement.
  89      * Instead of restoring the TextLayout attributes to default values
  90      * (each renders the TextLayout unable to efficiently cache layout data).
  91      * It always sets all the attributes pertinent to calculation being performed.
  92      * Note that lineSpacing and boundsType are important when computing the height
  93      * but irrelevant when computing the width.
  94      *
  95      * Note: This code assumes that TextBoundsType#VISUAL is never used by controls.
  96      * */
  97     static final TextLayout layout = Toolkit.getToolkit().getTextLayoutFactory().createLayout();
  98 
  99     public static double getAscent(Font font, TextBoundsType boundsType) {
 100         layout.setContent("", FontHelper.getNativeFont(font));
 101         layout.setWrapWidth(0);
 102         layout.setLineSpacing(0);
 103         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 104             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 105         } else {
 106             layout.setBoundsType(0);
 107         }
 108         return -layout.getBounds().getMinY();
 109     }
 110 
 111     public static double getLineHeight(Font font, TextBoundsType boundsType) {
 112         layout.setContent("", FontHelper.getNativeFont(font));
 113         layout.setWrapWidth(0);
 114         layout.setLineSpacing(0);
 115         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 116             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 117         } else {
 118             layout.setBoundsType(0);
 119         }
 120 
 121         // RT-37092: Use the line bounds specifically, to include font leading.
 122         return layout.getLines()[0].getBounds().getHeight();
 123     }
 124 
 125     public static double computeTextWidth(Font font, String text, double wrappingWidth) {
 126         layout.setContent(text != null ? text : "", FontHelper.getNativeFont(font));
 127         layout.setWrapWidth((float)wrappingWidth);
 128         return layout.getBounds().getWidth();
 129     }
 130 
 131     public static double computeTextHeight(Font font, String text, double wrappingWidth, TextBoundsType boundsType) {
 132         return computeTextHeight(font, text, wrappingWidth, 0, boundsType);
 133     }
 134 
 135     @SuppressWarnings("deprecation")
 136     public static double computeTextHeight(Font font, String text, double wrappingWidth, double lineSpacing, TextBoundsType boundsType) {
 137         layout.setContent(text != null ? text : "", FontHelper.getNativeFont(font));
 138         layout.setWrapWidth((float)wrappingWidth);
 139         layout.setLineSpacing((float)lineSpacing);
 140         if (boundsType == TextBoundsType.LOGICAL_VERTICAL_CENTER) {
 141             layout.setBoundsType(TextLayout.BOUNDS_CENTER);
 142         } else {
 143             layout.setBoundsType(0);
 144         }
 145         return layout.getBounds().getHeight();
 146     }
 147 
 148     public static int computeTruncationIndex(Font font, String text, double width) {
 149         helper.setText(text);
 150         helper.setFont(font);
 151         helper.setWrappingWidth(0);
 152         helper.setLineSpacing(0);
 153         // The -2 is a fudge to make sure the result more often matches
 154         // what we get from using computeTextWidth instead. It's not yet
 155         // clear what causes the small discrepancies.
 156         Bounds bounds = helper.getLayoutBounds();
 157         Point2D endPoint = new Point2D(width - 2, bounds.getMinY() + bounds.getHeight() / 2);


< prev index next >