Need a way to scale a font to fit a rectangle

前端 未结 6 1257
耶瑟儿~
耶瑟儿~ 2021-01-01 19:46

I just wrote some code to scale a font to fit within (the length of) a rectangle. It starts at 18 width and iterates down until it fits.

This seems horribly ineffic

6条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-01 20:51

    private Font scaleFont ( String text, Rectangle rect, Graphics gc )
    {
        final float fMinimumFont = 0.1f;
        float fMaximumFont = 1000f;
    
        /* Use Point2d.Float to hold ( font, width of font in pixels ) pairs. */
        Point2D.Float lowerPoint = new Point2D.Float ( fMinimumFont, getWidthInPixelsOfString ( text, fMinimumFont, gc ) );
        Point2D.Float upperPoint = new Point2D.Float ( fMaximumFont, getWidthInPixelsOfString ( text, fMaximumFont, gc ) );
        Point2D.Float midPoint = new Point2D.Float ();
    
        for ( int i = 0; i < 50; i++ )
        {
            float middleFont = ( lowerPoint.x + upperPoint.x ) / 2;
    
            midPoint.setLocation ( middleFont, getWidthInPixelsOfString ( text, middleFont, gc ) );
    
            if ( midPoint.y >= rect.getWidth () * .95 && midPoint.y <= rect.getWidth () )
                break;
            else if ( midPoint.y < rect.getWidth () )
                lowerPoint.setLocation ( midPoint );
            else if ( midPoint.y > rect.getWidth () )
                upperPoint.setLocation ( midPoint );
        }
    
        fMaximumFont = midPoint.x;
    
        Font font = gc.getFont ().deriveFont ( fMaximumFont );
    
        /* Now use Point2d.Float to hold ( font, height of font in pixels ) pairs. */
        lowerPoint.setLocation ( fMinimumFont, getHeightInPixelsOfString ( text, fMinimumFont, gc ) );
        upperPoint.setLocation ( fMaximumFont, getHeightInPixelsOfString ( text, fMaximumFont, gc ) );
    
        if ( upperPoint.y < rect.getHeight () )
            return font;
    
        for ( int i = 0; i < 50; i++ )
        {
            float middleFont = ( lowerPoint.x + upperPoint.x ) / 2;
    
            midPoint.setLocation ( middleFont, getHeightInPixelsOfString ( text, middleFont, gc ) );
    
            if ( midPoint.y >= rect.getHeight () * .95 && midPoint.y <= rect.getHeight () )
                break;
            else if ( midPoint.y < rect.getHeight () )
                lowerPoint.setLocation ( midPoint );
            else if ( midPoint.y > rect.getHeight () )
                upperPoint.setLocation ( midPoint );
        }
    
        fMaximumFont = midPoint.x;
    
        font = gc.getFont ().deriveFont ( fMaximumFont );
    
        return font;
    }
    
    
    private float getWidthInPixelsOfString ( String str, float fontSize, Graphics gc )
    {
        Font font = gc.getFont ().deriveFont ( fontSize );
    
        return getWidthInPixelsOfString ( str, font, gc );
    }
    
    private float getWidthInPixelsOfString ( String str, Font font, Graphics gc )
    {
        FontMetrics fm = gc.getFontMetrics ( font );
        int nWidthInPixelsOfCurrentFont = fm.stringWidth ( str );
    
        return (float) nWidthInPixelsOfCurrentFont;
    }
    
    
    private float getHeightInPixelsOfString ( String string, float fontSize, Graphics gc )
    {
        Font font = gc.getFont ().deriveFont ( fontSize );
    
        return getHeightInPixelsOfString ( string, font, gc );
    }
    
    private float getHeightInPixelsOfString ( String string, Font font, Graphics gc )
    {
        FontMetrics metrics = gc.getFontMetrics ( font );
        int nHeightInPixelsOfCurrentFont = (int) metrics.getStringBounds ( string, gc ).getHeight () - metrics.getDescent () - metrics.getLeading ();
    
        return (float) nHeightInPixelsOfCurrentFont * .75f;
    }
    

提交回复
热议问题