Search in sources :

Example 11 with TextAttribute

use of java.awt.font.TextAttribute in project tray by qzind.

the class LinkLabel method initialize.

private void initialize() {
    Map<TextAttribute, Object> attributes = new HashMap<>(getFont().getAttributes());
    attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
    setFont(getFont().deriveFont(attributes));
    actionListeners = new ArrayList<>();
    addMouseListener(new MouseListener() {

        @Override
        public void mouseClicked(MouseEvent e) {
            for (ActionListener actionListener : actionListeners) {
                actionListener.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "mouseClicked"));
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        }

        @Override
        public void mouseExited(MouseEvent e) {
            setCursor(Cursor.getDefaultCursor());
        }
    });
    refresh();
}
Also used : MouseListener(java.awt.event.MouseListener) MouseEvent(java.awt.event.MouseEvent) ActionListener(java.awt.event.ActionListener) HashMap(java.util.HashMap) TextAttribute(java.awt.font.TextAttribute) ActionEvent(java.awt.event.ActionEvent)

Example 12 with TextAttribute

use of java.awt.font.TextAttribute in project android by JetBrains.

the class ChooseApiLevelDialog method createCenterPanel.

@Nullable
@Override
protected JComponent createCenterPanel() {
    myDistributionChart.registerDistributionSelectionChangedListener(this);
    myDistributionChart.init();
    myScrollPane.getViewport().setOpaque(false);
    myScrollPane.setOpaque(false);
    myScrollPane.setBorder(null);
    myDescriptionLeft.setForeground(JBColor.foreground());
    myDescriptionLeft.setBackground(JBColor.background());
    myDescriptionRight.setForeground(JBColor.foreground());
    myDescriptionRight.setBackground(JBColor.background());
    myLearnMoreLinkLabel.setForeground(JBColor.blue);
    myLearnMoreLinkLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    Map<TextAttribute, ?> attributes = ImmutableMap.of(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
    myLearnMoreLinkLabel.setFont(myLearnMoreLinkLabel.getFont().deriveFont(attributes));
    myLearnMoreLinkLabel.addMouseListener(new MouseInputAdapter() {

        @Override
        public void mouseClicked(MouseEvent e) {
            try {
                BrowserUtil.browse(new URL(myLearnMoreLinkLabel.getText()));
            } catch (MalformedURLException e1) {
            // Pass
            }
        }
    });
    if (mySelectedApiLevel >= 0) {
        myDistributionChart.selectDistributionApiLevel(mySelectedApiLevel);
    }
    return myPanel;
}
Also used : MalformedURLException(java.net.MalformedURLException) MouseEvent(java.awt.event.MouseEvent) TextAttribute(java.awt.font.TextAttribute) MouseInputAdapter(javax.swing.event.MouseInputAdapter) URL(java.net.URL) Nullable(org.jetbrains.annotations.Nullable)

Example 13 with TextAttribute

use of java.awt.font.TextAttribute in project jdk8u_jdk by JetBrains.

the class PathGraphics method printedSimpleGlyphVector.

/* GlyphVectors are usually encountered because TextLayout is in use.
     * Some times TextLayout is needed to handle complex text or some
     * rendering attributes trigger it.
     * We try to print GlyphVectors by reconstituting into a String,
     * as that is most recoverable for applications that export to formats
     * such as Postscript or PDF. In some cases (eg where its not complex
     * text and its just that positions aren't what we'd expect) we print
     * one character at a time. positioning individually.
     * Failing that, if we can directly send glyph codes to the printer
     * then we do that (printGlyphVector).
     * As a last resort we return false and let the caller print as filled
     * shapes.
     */
boolean printedSimpleGlyphVector(GlyphVector g, float x, float y) {
    int flags = g.getLayoutFlags();
    /* We can't handle RTL, re-ordering, complex glyphs etc by
         * reconstituting glyphs into a String. So if any flags besides
         * position adjustments are set, see if we can directly
         * print the GlyphVector as glyph codes, using the positions
         * layout has assigned. If that fails return false;
         */
    if (flags != 0 && flags != GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) {
        return printGlyphVector(g, x, y);
    }
    Font font = g.getFont();
    Font2D font2D = FontUtilities.getFont2D(font);
    if (font2D.handle.font2D != font2D) {
        /* suspicious, may be a bad font. lets bail */
        return false;
    }
    Hashtable<Font2DHandle, Object> fontMap;
    synchronized (PathGraphics.class) {
        fontMap = fontMapRef.get();
        if (fontMap == null) {
            fontMap = new Hashtable<Font2DHandle, Object>();
            fontMapRef = new SoftReference<Hashtable<Font2DHandle, Object>>(fontMap);
        }
    }
    int numGlyphs = g.getNumGlyphs();
    int[] glyphCodes = g.getGlyphCodes(0, numGlyphs, null);
    char[] glyphToCharMap = null;
    char[][] mapArray = null;
    CompositeFont cf = null;
    /* Build the needed maps for this font in a synchronized block */
    synchronized (fontMap) {
        if (font2D instanceof CompositeFont) {
            cf = (CompositeFont) font2D;
            int numSlots = cf.getNumSlots();
            mapArray = (char[][]) fontMap.get(font2D.handle);
            if (mapArray == null) {
                mapArray = new char[numSlots][];
                fontMap.put(font2D.handle, mapArray);
            }
            for (int i = 0; i < numGlyphs; i++) {
                int slot = glyphCodes[i] >>> 24;
                if (slot >= numSlots) {
                    /* shouldn't happen */
                    return false;
                }
                if (mapArray[slot] == null) {
                    Font2D slotFont = cf.getSlotFont(slot);
                    char[] map = (char[]) fontMap.get(slotFont.handle);
                    if (map == null) {
                        map = getGlyphToCharMapForFont(slotFont);
                    }
                    mapArray[slot] = map;
                }
            }
        } else {
            glyphToCharMap = (char[]) fontMap.get(font2D.handle);
            if (glyphToCharMap == null) {
                glyphToCharMap = getGlyphToCharMapForFont(font2D);
                fontMap.put(font2D.handle, glyphToCharMap);
            }
        }
    }
    char[] chars = new char[numGlyphs];
    if (cf != null) {
        for (int i = 0; i < numGlyphs; i++) {
            int gc = glyphCodes[i];
            char[] map = mapArray[gc >>> 24];
            gc = gc & 0xffffff;
            if (map == null) {
                return false;
            }
            /* X11 symbol & dingbats fonts used only for global metrics,
                 * so the glyph codes we have really refer to Lucida Sans
                 * Regular.
                 * So its possible the glyph code may appear out of range.
                 * Note that later on we double-check the glyph codes that
                 * we get from re-creating the GV from the string are the
                 * same as those we started with.
                 *
                 * If the glyphcode is INVISIBLE_GLYPH_ID then this may
                 * be \t, \n or \r which are mapped to that by layout.
                 * This is a case we can handle. It doesn't matter what
                 * character we use (we use \n) so long as layout maps it
                 * back to this in the verification, since the invisible
                 * glyph isn't visible :)
                 */
            char ch;
            if (gc == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                ch = '\n';
            } else if (gc < 0 || gc >= map.length) {
                return false;
            } else {
                ch = map[gc];
            }
            if (ch != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                chars[i] = ch;
            } else {
                return false;
            }
        }
    } else {
        for (int i = 0; i < numGlyphs; i++) {
            int gc = glyphCodes[i];
            char ch;
            if (gc == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                ch = '\n';
            } else if (gc < 0 || gc >= glyphToCharMap.length) {
                return false;
            } else {
                ch = glyphToCharMap[gc];
            }
            if (ch != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                chars[i] = ch;
            } else {
                return false;
            }
        }
    }
    FontRenderContext gvFrc = g.getFontRenderContext();
    GlyphVector gv2 = font.createGlyphVector(gvFrc, chars);
    if (gv2.getNumGlyphs() != numGlyphs) {
        return printGlyphVector(g, x, y);
    }
    int[] glyphCodes2 = gv2.getGlyphCodes(0, numGlyphs, null);
    /*
         * Needed to double-check remapping of X11 symbol & dingbats.
         */
    for (int i = 0; i < numGlyphs; i++) {
        if (glyphCodes[i] != glyphCodes2[i]) {
            return printGlyphVector(g, x, y);
        }
    }
    FontRenderContext g2dFrc = getFontRenderContext();
    boolean compatibleFRC = gvFrc.equals(g2dFrc);
    /* If differ only in specifying A-A or a translation, these are
         * also compatible FRC's, and we can do one drawString call.
         */
    if (!compatibleFRC && gvFrc.usesFractionalMetrics() == g2dFrc.usesFractionalMetrics()) {
        AffineTransform gvAT = gvFrc.getTransform();
        AffineTransform g2dAT = getTransform();
        double[] gvMatrix = new double[4];
        double[] g2dMatrix = new double[4];
        gvAT.getMatrix(gvMatrix);
        g2dAT.getMatrix(g2dMatrix);
        compatibleFRC = true;
        for (int i = 0; i < 4; i++) {
            if (gvMatrix[i] != g2dMatrix[i]) {
                compatibleFRC = false;
                break;
            }
        }
    }
    String str = new String(chars, 0, numGlyphs);
    int numFonts = platformFontCount(font, str);
    if (numFonts == 0) {
        return false;
    }
    float[] positions = g.getGlyphPositions(0, numGlyphs, null);
    boolean noPositionAdjustments = ((flags & GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS) == 0) || samePositions(gv2, glyphCodes2, glyphCodes, positions);
    /* We have to consider that the application may be directly
         * creating a GlyphVector, rather than one being created by
         * TextLayout or indirectly from drawString. In such a case, if the
         * font has layout attributes, the text may measure differently
         * when we reconstitute it into a String and ask for the length that
         * drawString would use. For example, KERNING will be applied in such
         * a case but that Font attribute is not applied when the application
         * directly created a GlyphVector. So in this case we need to verify
         * that the text measures the same in both cases - ie that the
         * layout attribute has no effect. If it does we can't always
         * use the drawString call unless we can coerce the drawString call
         * into measuring and displaying the string to the same length.
         * That is the case where there is only one font used and we can
         * specify the overall advance of the string. (See below).
         */
    Point2D gvAdvancePt = g.getGlyphPosition(numGlyphs);
    float gvAdvanceX = (float) gvAdvancePt.getX();
    boolean layoutAffectsAdvance = false;
    if (font.hasLayoutAttributes() && printingGlyphVector && noPositionAdjustments) {
        /* If TRACKING is in use then the glyph vector will report
             * position adjustments, then that ought to be sufficient to
             * tell us we can't just ask native to do "drawString". But layout
             * always sets the position adjustment flag, so we don't believe
             * it and verify the positions are really different than
             * createGlyphVector() (with no layout) would create. However
             * inconsistently, TRACKING is applied when creating a GlyphVector,
             * since it doesn't actually require "layout" (even though its
             * considered a layout attribute), it just requires a fractional
             * tweak to the[default]advances. So we need to specifically
             * check for tracking until such time as as we can trust
             * the GlyphVector.FLAG_HAS_POSITION_ADJUSTMENTS bit.
             */
        Map<TextAttribute, ?> map = font.getAttributes();
        Object o = map.get(TextAttribute.TRACKING);
        boolean tracking = o != null && (o instanceof Number) && (((Number) o).floatValue() != 0f);
        if (tracking) {
            noPositionAdjustments = false;
        } else {
            Rectangle2D bounds = font.getStringBounds(str, gvFrc);
            float strAdvanceX = (float) bounds.getWidth();
            if (Math.abs(strAdvanceX - gvAdvanceX) > 0.00001) {
                layoutAffectsAdvance = true;
            }
        }
    }
    if (compatibleFRC && noPositionAdjustments && !layoutAffectsAdvance) {
        drawString(str, x, y, font, gvFrc, 0f);
        return true;
    }
    /* If positions have not been explicitly assigned, we can
         * ask the string to be drawn adjusted to this width.
         * This call is supported only in the PS generator.
         * GDI has API to specify the advance for each glyph in a
         * string which could be used here too, but that is not yet
         * implemented, and we'd need to update the signature of the
         * drawString method to take the advances (ie relative positions)
         * and use that instead of the width.
         */
    if (numFonts == 1 && canDrawStringToWidth() && noPositionAdjustments) {
        drawString(str, x, y, font, gvFrc, gvAdvanceX);
        return true;
    }
    /* In some scripts chars drawn individually do not have the
         * same representation (glyphs) as when combined with other chars.
         * The logic here is erring on the side of caution, in particular
         * in including supplementary characters.
         */
    if (FontUtilities.isComplexText(chars, 0, chars.length)) {
        return printGlyphVector(g, x, y);
    }
    /* If we reach here we have mapped all the glyphs back
         * one-to-one to simple unicode chars that we know are in the font.
         * We can call "drawChars" on each one of them in turn, setting
         * the position based on the glyph positions.
         * There's typically overhead in this. If numGlyphs is 'large',
         * it may even be better to try printGlyphVector() in this case.
         * This may be less recoverable for apps, but sophisticated apps
         * should be able to recover the text from simple glyph vectors
         * and we can avoid penalising the more common case - although
         * this is already a minority case.
         */
    if (numGlyphs > 10 && printGlyphVector(g, x, y)) {
        return true;
    }
    for (int i = 0; i < numGlyphs; i++) {
        String s = new String(chars, i, 1);
        drawString(s, x + positions[i * 2], y + positions[i * 2 + 1], font, gvFrc, 0f);
    }
    return true;
}
Also used : Font2D(sun.font.Font2D) TextAttribute(java.awt.font.TextAttribute) Font(java.awt.Font) CompositeFont(sun.font.CompositeFont) Point2D(java.awt.geom.Point2D) Font2DHandle(sun.font.Font2DHandle) CompositeFont(sun.font.CompositeFont) GlyphVector(java.awt.font.GlyphVector) Hashtable(java.util.Hashtable) Rectangle2D(java.awt.geom.Rectangle2D) RoundRectangle2D(java.awt.geom.RoundRectangle2D) Paint(java.awt.Paint) AffineTransform(java.awt.geom.AffineTransform) FontRenderContext(java.awt.font.FontRenderContext)

Example 14 with TextAttribute

use of java.awt.font.TextAttribute in project jdk8u_jdk by JetBrains.

the class KerningLeak method leak.

private static void leak() {
    Map<TextAttribute, Object> textAttributes = new HashMap<>();
    textAttributes.put(TextAttribute.FAMILY, "Sans Serif");
    textAttributes.put(TextAttribute.SIZE, 12);
    textAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
    Font font = Font.getFont(textAttributes);
    JLabel label = new JLabel();
    int dummy = 0;
    for (int i = 0; i < 500; i++) {
        if (i % 10 == 0)
            System.out.println("Starting iter " + (i + 1));
        for (int j = 0; j < 1000; j++) {
            FontMetrics fm = label.getFontMetrics(font);
            dummy += SwingUtilities.computeStringWidth(fm, Integer.toString(j));
        }
    }
    System.out.println("done " + dummy);
}
Also used : HashMap(java.util.HashMap) TextAttribute(java.awt.font.TextAttribute) FontMetrics(java.awt.FontMetrics) JLabel(javax.swing.JLabel) Font(java.awt.Font)

Example 15 with TextAttribute

use of java.awt.font.TextAttribute in project jdk8u_jdk by JetBrains.

the class OSXLigatureTest method main.

public static void main(String[] args) {
    if (!System.getProperty("os.name").startsWith("Mac")) {
        return;
    }
    String ligStr = "ffi";
    int w = 50, h = 50;
    BufferedImage bi1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D bi1Graphics = bi1.createGraphics();
    bi1Graphics.setColor(Color.white);
    bi1Graphics.fillRect(0, 0, w, h);
    bi1Graphics.setColor(Color.black);
    Font noLigFont = new Font("Gill Sans", Font.PLAIN, 30);
    bi1Graphics.setFont(noLigFont);
    bi1Graphics.drawString(ligStr, 10, 40);
    BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D bi2Graphics = bi2.createGraphics();
    bi2Graphics.setColor(Color.white);
    bi2Graphics.fillRect(0, 0, w, h);
    bi2Graphics.setColor(Color.black);
    Map<TextAttribute, Object> attributes = new HashMap<>();
    attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
    Font ligFont = noLigFont.deriveFont(attributes);
    bi2Graphics.setFont(ligFont);
    bi2Graphics.drawString(ligStr, 10, 40);
    boolean same = true;
    for (int x = 0; x < w; x++) {
        for (int y = 0; y < h; y++) {
            int c1 = bi1.getRGB(x, y);
            int c2 = bi2.getRGB(x, y);
            same &= (c1 == c2);
        }
        if (!same) {
            break;
        }
    }
    if (same) {
        throw new RuntimeException("Images do not differ - no ligature");
    }
}
Also used : HashMap(java.util.HashMap) TextAttribute(java.awt.font.TextAttribute) BufferedImage(java.awt.image.BufferedImage) Font(java.awt.Font) Graphics2D(java.awt.Graphics2D)

Aggregations

TextAttribute (java.awt.font.TextAttribute)31 Font (java.awt.Font)22 HashMap (java.util.HashMap)22 Configuration (com.haulmont.cuba.core.global.Configuration)2 DesktopConfig (com.haulmont.cuba.desktop.DesktopConfig)2 FontMetrics (java.awt.FontMetrics)2 Paint (java.awt.Paint)2 MouseEvent (java.awt.event.MouseEvent)2 AffineTransform (java.awt.geom.AffineTransform)2 Hashtable (java.util.Hashtable)2 DesktopResources (com.haulmont.cuba.desktop.DesktopResources)1 CollapsiblePanel (com.haulmont.cuba.desktop.sys.vcl.CollapsiblePanel)1 WebColors (com.revolsys.awt.WebColors)1 Geometry (com.revolsys.geometry.model.Geometry)1 SwingUtil (com.revolsys.swing.SwingUtil)1 ClipboardUtil (com.revolsys.swing.dnd.ClipboardUtil)1 AbstractRecordLayer (com.revolsys.swing.map.layer.record.AbstractRecordLayer)1 LayerRecord (com.revolsys.swing.map.layer.record.LayerRecord)1 LayerRecordMenu (com.revolsys.swing.map.layer.record.LayerRecordMenu)1 RecordLayerTableModel (com.revolsys.swing.map.layer.record.table.model.RecordLayerTableModel)1