jdk/src/share/classes/sun/swing/SwingUtilities2.java
changeset 3976 6758b915b581
parent 3749 d0ecbd7075b1
child 3980 b41744c10146
equal deleted inserted replaced
3975:097245f7db08 3976:6758b915b581
   191     static {
   191     static {
   192         fontCache = new LSBCacheEntry[CACHE_SIZE];
   192         fontCache = new LSBCacheEntry[CACHE_SIZE];
   193     }
   193     }
   194 
   194 
   195     /**
   195     /**
       
   196      * Fill the character buffer cache.  Return the buffer length.
       
   197      */
       
   198     private static int syncCharsBuffer(String s) {
       
   199         int length = s.length();
       
   200         if ((charsBuffer == null) || (charsBuffer.length < length)) {
       
   201             charsBuffer = s.toCharArray();
       
   202         } else {
       
   203             s.getChars(0, length, charsBuffer, 0);
       
   204         }
       
   205         return length;
       
   206     }
       
   207 
       
   208     /**
   196      * checks whether TextLayout is required to handle characters.
   209      * checks whether TextLayout is required to handle characters.
   197      *
   210      *
   198      * @param text characters to be tested
   211      * @param text characters to be tested
   199      * @param start start
   212      * @param start start
   200      * @param limit limit
   213      * @param limit limit
   351      */
   364      */
   352     public static int stringWidth(JComponent c, FontMetrics fm, String string){
   365     public static int stringWidth(JComponent c, FontMetrics fm, String string){
   353         if (string == null || string.equals("")) {
   366         if (string == null || string.equals("")) {
   354             return 0;
   367             return 0;
   355         }
   368         }
   356         return fm.stringWidth(string);
   369         boolean needsTextLayout = ((c != null) &&
       
   370                 (c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
       
   371         if (needsTextLayout) {
       
   372             synchronized(charsBufferLock) {
       
   373                 int length = syncCharsBuffer(string);
       
   374                 needsTextLayout = isComplexLayout(charsBuffer, 0, length);
       
   375             }
       
   376         }
       
   377         if (needsTextLayout) {
       
   378             TextLayout layout = createTextLayout(c, string,
       
   379                                     fm.getFont(), fm.getFontRenderContext());
       
   380             return (int) layout.getAdvance();
       
   381         } else {
       
   382             return fm.stringWidth(string);
       
   383         }
   357     }
   384     }
   358 
   385 
   359 
   386 
   360     /**
   387     /**
   361      * Clips the passed in String to the space provided.
   388      * Clips the passed in String to the space provided.
   392      */
   419      */
   393     public static String clipString(JComponent c, FontMetrics fm,
   420     public static String clipString(JComponent c, FontMetrics fm,
   394                                     String string, int availTextWidth) {
   421                                     String string, int availTextWidth) {
   395         // c may be null here.
   422         // c may be null here.
   396         String clipString = "...";
   423         String clipString = "...";
   397         int stringLength = string.length();
       
   398         availTextWidth -= SwingUtilities2.stringWidth(c, fm, clipString);
   424         availTextWidth -= SwingUtilities2.stringWidth(c, fm, clipString);
   399         if (availTextWidth <= 0) {
       
   400             //can not fit any characters
       
   401             return clipString;
       
   402         }
       
   403 
       
   404         boolean needsTextLayout;
   425         boolean needsTextLayout;
   405 
   426 
   406         synchronized (charsBufferLock) {
   427         synchronized (charsBufferLock) {
   407             if (charsBuffer == null || charsBuffer.length < stringLength) {
   428             int stringLength = syncCharsBuffer(string);
   408                 charsBuffer  = string.toCharArray();
       
   409             } else {
       
   410                 string.getChars(0, stringLength, charsBuffer, 0);
       
   411             }
       
   412             needsTextLayout =
   429             needsTextLayout =
   413                 isComplexLayout(charsBuffer, 0, stringLength);
   430                 isComplexLayout(charsBuffer, 0, stringLength);
   414             if (!needsTextLayout) {
   431             if (!needsTextLayout) {
   415                 int width = 0;
   432                 int width = 0;
   416                 for (int nChars = 0; nChars < stringLength; nChars++) {
   433                 for (int nChars = 0; nChars < stringLength; nChars++) {
   423             }
   440             }
   424         }
   441         }
   425         if (needsTextLayout) {
   442         if (needsTextLayout) {
   426             FontRenderContext frc = getFontRenderContext(c, fm);
   443             FontRenderContext frc = getFontRenderContext(c, fm);
   427             AttributedString aString = new AttributedString(string);
   444             AttributedString aString = new AttributedString(string);
       
   445             if (c != null) {
       
   446                 aString.addAttribute(TextAttribute.NUMERIC_SHAPING,
       
   447                         c.getClientProperty(TextAttribute.NUMERIC_SHAPING));
       
   448             }
   428             LineBreakMeasurer measurer =
   449             LineBreakMeasurer measurer =
   429                 new LineBreakMeasurer(aString.getIterator(), frc);
   450                 new LineBreakMeasurer(aString.getIterator(), frc);
   430             int nChars = measurer.nextOffset(availTextWidth);
   451             int nChars = measurer.nextOffset(availTextWidth);
   431             string = string.substring(0, nChars);
   452             string = string.substring(0, nChars);
   432 
   453 
   463                  * it to fit in the screen width. This distributes the spacing
   484                  * it to fit in the screen width. This distributes the spacing
   464                  * more evenly than directly laying out to the screen advances.
   485                  * more evenly than directly laying out to the screen advances.
   465                  */
   486                  */
   466                 float screenWidth = (float)
   487                 float screenWidth = (float)
   467                    g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth();
   488                    g2d.getFont().getStringBounds(text, DEFAULT_FRC).getWidth();
   468                 TextLayout layout = new TextLayout(text, g2d.getFont(),
   489                 TextLayout layout = createTextLayout(c, text, g2d.getFont(),
   469                                                    g2d.getFontRenderContext());
   490                                                    g2d.getFontRenderContext());
   470 
   491 
   471                 layout = layout.getJustifiedLayout(screenWidth);
   492                 layout = layout.getJustifiedLayout(screenWidth);
   472                 /* Use alternate print color if specified */
   493                 /* Use alternate print color if specified */
   473                 Color col = g2d.getColor();
   494                 Color col = g2d.getColor();
   503                     g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
   524                     g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST,
   504                                         info.lcdContrastHint);
   525                                         info.lcdContrastHint);
   505                 }
   526                 }
   506             }
   527             }
   507 
   528 
   508             g.drawString(text, x, y);
   529             boolean needsTextLayout = ((c != null) &&
       
   530                 (c.getClientProperty(TextAttribute.NUMERIC_SHAPING) != null));
       
   531             if (needsTextLayout) {
       
   532                 synchronized(charsBufferLock) {
       
   533                     int length = syncCharsBuffer(text);
       
   534                     needsTextLayout = isComplexLayout(charsBuffer, 0, length);
       
   535                 }
       
   536             }
       
   537             if (needsTextLayout) {
       
   538                 TextLayout layout = createTextLayout(c, text, g2.getFont(),
       
   539                                                     g2.getFontRenderContext());
       
   540                 layout.draw(g2, x, y);
       
   541             } else {
       
   542                 g.drawString(text, x, y);
       
   543             }
   509 
   544 
   510             if (oldAAValue != null) {
   545             if (oldAAValue != null) {
   511                 g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
   546                 g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
   512             }
   547             }
   513             if (oldContrast != null) {
   548             if (oldContrast != null) {
   545             int underlineRectWidth = 0;
   580             int underlineRectWidth = 0;
   546             boolean isPrinting = isPrinting(g);
   581             boolean isPrinting = isPrinting(g);
   547             boolean needsTextLayout = isPrinting;
   582             boolean needsTextLayout = isPrinting;
   548             if (!needsTextLayout) {
   583             if (!needsTextLayout) {
   549                 synchronized (charsBufferLock) {
   584                 synchronized (charsBufferLock) {
   550                     if (charsBuffer == null || charsBuffer.length < textLength) {
   585                     syncCharsBuffer(text);
   551                         charsBuffer = text.toCharArray();
       
   552                     } else {
       
   553                         text.getChars(0, textLength, charsBuffer, 0);
       
   554                     }
       
   555                     needsTextLayout =
   586                     needsTextLayout =
   556                         isComplexLayout(charsBuffer, 0, textLength);
   587                         isComplexLayout(charsBuffer, 0, textLength);
   557                 }
   588                 }
   558             }
   589             }
   559             if (!needsTextLayout) {
   590             if (!needsTextLayout) {
   565                                                   charAt(underlinedIndex));
   596                                                   charAt(underlinedIndex));
   566             } else {
   597             } else {
   567                 Graphics2D g2d = getGraphics2D(g);
   598                 Graphics2D g2d = getGraphics2D(g);
   568                 if (g2d != null) {
   599                 if (g2d != null) {
   569                     TextLayout layout =
   600                     TextLayout layout =
   570                         new TextLayout(text, g2d.getFont(),
   601                         createTextLayout(c, text, g2d.getFont(),
   571                                        g2d.getFontRenderContext());
   602                                        g2d.getFontRenderContext());
   572                     if (isPrinting) {
   603                     if (isPrinting) {
   573                         float screenWidth = (float)g2d.getFont().
   604                         float screenWidth = (float)g2d.getFont().
   574                             getStringBounds(text, DEFAULT_FRC).getWidth();
   605                             getStringBounds(text, DEFAULT_FRC).getWidth();
   575                         layout = layout.getJustifiedLayout(screenWidth);
   606                         layout = layout.getJustifiedLayout(screenWidth);
   726                 FontRenderContext frc = getFontRenderContext(c);
   757                 FontRenderContext frc = getFontRenderContext(c);
   727                 if (frc != null &&
   758                 if (frc != null &&
   728                     !isFontRenderContextPrintCompatible
   759                     !isFontRenderContextPrintCompatible
   729                     (deviceFontRenderContext, frc)) {
   760                     (deviceFontRenderContext, frc)) {
   730                     TextLayout layout =
   761                     TextLayout layout =
   731                         new TextLayout(new String(data,offset,length),
   762                         createTextLayout(c, new String(data, offset, length),
   732                                        g2d.getFont(),
   763                                        g2d.getFont(),
   733                                        deviceFontRenderContext);
   764                                        deviceFontRenderContext);
   734                     float screenWidth = (float)g2d.getFont().
   765                     float screenWidth = (float)g2d.getFont().
   735                         getStringBounds(data, offset, offset + length, frc).
   766                         getStringBounds(data, offset, offset + length, frc).
   736                         getWidth();
   767                         getWidth();
   842         if (isPrinting) {
   873         if (isPrinting) {
   843             g.setColor(col);
   874             g.setColor(col);
   844         }
   875         }
   845 
   876 
   846         return retVal;
   877         return retVal;
       
   878     }
       
   879 
       
   880     private static TextLayout createTextLayout(JComponent c, String s,
       
   881                                             Font f, FontRenderContext frc) {
       
   882         Object shaper = (c == null ?
       
   883                     null : c.getClientProperty(TextAttribute.NUMERIC_SHAPING));
       
   884         if (shaper == null) {
       
   885             return new TextLayout(s, f, frc);
       
   886         } else {
       
   887             Map<TextAttribute, Object> a = new HashMap<TextAttribute, Object>();
       
   888             a.put(TextAttribute.FONT, f);
       
   889             a.put(TextAttribute.NUMERIC_SHAPING, shaper);
       
   890             return new TextLayout(s, a, frc);
       
   891         }
   847     }
   892     }
   848 
   893 
   849     /*
   894     /*
   850      * Checks if two given FontRenderContexts are compatible for printing.
   895      * Checks if two given FontRenderContexts are compatible for printing.
   851      * We can't just use equals as we want to exclude from the comparison :
   896      * We can't just use equals as we want to exclude from the comparison :