/* * @(#)ClearType.java 1.2.1 2004-07-16 * * Copyright (c) 1999 Werner Randelshofer, Goldau, Switzerland. * All rights reserved. * * You may not use, copy or modify this file, except in compliance with the * license agreement you entered into with Werner Randelshofer. * For details see accompanying license terms. */ /* * Source taken from * http://blog.monstuff.com/archives/000022.html */ package org.monte.media.image; import java.awt.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class ClearType { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(430,180); f.setTitle("ClearType"); JPanel p = new JPanel() { public void update(Graphics g) { paint(g); } public void paint(Graphics g) { Font f = new Font("Times New Roman", Font.PLAIN, 18); Graphics2D grph =(Graphics2D) g; grph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); g.setFont(f); g.setColor(Color.white); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(Color.black); g.drawString("Sample Text String", 5, getFontMetrics(f).getHeight()); drawClearType(g, "Sample Text String", 5, getFontMetrics(f).getHeight() * 3); } public void drawClearType(Graphics g, String s, int x, int y) { Font f = g.getFont(); FontMetrics fm = getFontMetrics(f); int width = fm.stringWidth(s) * 3; int height = fm.getHeight(); BufferedImage img = (BufferedImage) createImage(width, height); Graphics2D grph = img.createGraphics(); grph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); grph.setColor(Color.white); grph.fillRect(0, 0, width, height); grph.setColor(Color.black); grph.setFont(f.deriveFont(AffineTransform.getScaleInstance(3, 1))); grph.drawString(s, 0, height - fm.getMaxDescent()); int[] pixelsA = getPixelArray(img); int[] pixels = new int[pixelsA.length]; int[] newpixels = new int[(width / 3) * height]; for (int i = 0; i < width * height; i++) { newpixels[i / 3] = (0xff << 24); if (i != width * height - 1) { pixels[i + 1] = fuzz(pixels[i + 1], pixelsA[i]); } pixels[i] = fuzz(pixels[i], pixelsA[i]); if (i != 0) { pixels[i - 1] = fuzz(pixels[i - 1], pixelsA[i]); } } for (int i = 0; i < width * height; i++) { switch (i % 3) { case 0: newpixels[i / 3] |= (pixels[i]) & 0xff0000; break; case 1: newpixels[i / 3] |= (pixels[i]) & 0xff00; break; case 2: newpixels[i / 3] |= (pixels[i]) & 0xff; break; } } grph.dispose(); g.drawImage(imageFromPixels(newpixels, width / 3, height), x, y - height, width / 3, height, this); g.drawImage(img, x,y,width,height,this); } }; f.setContentPane(p); f.setVisible(true); } }); } /** Adds one third of b to a */ private static int fuzz(int a, int b) { int red = ((b >> 16) & 0xff) / 3 + ((a >> 16) & 0xff); int green = ((b >> 8) & 0xff) / 3 + ((a >> 8) & 0xff); int blue = (b & 0xff) / 3 + (a & 0xff); return (0xff << 24) | (red << 16) | (green << 8) | blue; } private static int[] getPixelArray(Image img) { int width = img.getWidth(null); int height = img.getHeight(null); int[] pixels = new int[width * height]; PixelGrabber pg = new PixelGrabber(img, 0, 0, width, height, pixels, 0, width); try { pg.grabPixels(); } catch (Exception e) { } return pixels; } /** Renders an image with clear type. Note the width of the image must be divideable by 3. */ public static void drawClearType(Graphics g, Image img, int x, int y, int superY, ImageObserver observer) { int width = img.getWidth(null); int height = img.getHeight(null); int[] pixelsA = getPixelArray(img); int[] pixels = new int[pixelsA.length]; int[] newpixels = new int[(width / 3) * height]; for (int i = 0; i < width * height; i++) { newpixels[i / 3] = (0xff << 24); if (i != width * height - 1) { pixels[i + 1] = fuzz(pixels[i + 1], pixelsA[i]); } pixels[i] = fuzz(pixels[i], pixelsA[i]); if (i != 0) { pixels[i - 1] = fuzz(pixels[i - 1], pixelsA[i]); } } for (int i = 0; i < width * height; i++) { switch (i % 3) { case 0: newpixels[i / 3] |= (pixels[i]) & 0xff0000; break; case 1: newpixels[i / 3] |= (pixels[i]) & 0xff00; break; case 2: newpixels[i / 3] |= (pixels[i]) & 0xff; break; } } g.drawImage(imageFromPixels(newpixels, width / 3, height), x, y, width / 3, height / superY, observer); } private static Image imageFromPixels(int[] pixels, int width, int height) { return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, pixels, 0, width)); } }