diff options
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java')
-rw-r--r-- | awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java new file mode 100644 index 0000000..322ba57 --- /dev/null +++ b/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java @@ -0,0 +1,263 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Ilya S. Okomin + * @version $Revision$ + */ +package org.apache.harmony.awt.gl.render; + +import java.awt.*; +import java.awt.image.*; + + +import java.awt.font.GlyphMetrics; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +import org.apache.harmony.awt.gl.TextRenderer; +import org.apache.harmony.awt.gl.font.CommonGlyphVector; +import org.apache.harmony.awt.gl.font.FontPeerImpl; +import org.apache.harmony.awt.gl.font.Glyph; +import org.apache.harmony.awt.gl.image.BufferedImageGraphics2D; + +public class JavaTextRenderer extends TextRenderer { + + public static final JavaTextRenderer inst = new JavaTextRenderer(); + + @Override + public void drawGlyphVector(Graphics2D g, GlyphVector glyphVector, + float x, float y) { + + AffineTransform at = g.getTransform(); + Rectangle c = g.getClipBounds(); + if (at != null){ + int atType = at.getType(); + if (atType == AffineTransform.TYPE_TRANSLATION) { + c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY())); + } + } + + WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster(); + ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel(); + + Rectangle rBounds = wr.getBounds(); + + Object color = cm.getDataElements(g.getColor().getRGB(), null); + + drawClipGlyphVector(wr, color, glyphVector, (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()), + Math.max(c.x,rBounds.x), + Math.max(c.y,rBounds.y), + Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())), + Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY()))); + + } + + @SuppressWarnings("deprecation") + @Override + public void drawString(Graphics2D g, String str, float x, float y) { + AffineTransform at = g.getTransform(); + Rectangle c = g.getClipBounds(); + if (at != null){ + int atType = at.getType(); + if (atType == AffineTransform.TYPE_TRANSLATION) { + c.translate((int)Math.round(at.getTranslateX()), (int)Math.round(at.getTranslateY())); + } + } + WritableRaster wr = ((BufferedImageGraphics2D)g).getWritableRaster(); + ColorModel cm = ((BufferedImageGraphics2D)g).getColorModel(); + Rectangle rBounds = wr.getBounds(); + + Object color = cm.getDataElements(g.getColor().getRGB(), null); + + drawClipString(wr, color, str, (FontPeerImpl) (g.getFont().getPeer()), + (int)Math.round(x + at.getTranslateX()), (int)Math.round(y + at.getTranslateY()), + Math.max(c.x,rBounds.x), + Math.max(c.y,rBounds.y), + Math.min((int)Math.round(c.getMaxX()), (int)Math.round(rBounds.getMaxX())), + Math.min((int)Math.round(c.getMaxY()), (int)Math.round(rBounds.getMaxY()))); + + } + + /** + * + * Draws string on specified raster at desired position. + * + * @param raster specified WritableRaster to draw at + * @param color color of the text + * @param glyphVector GlyphVector object to draw + * @param x start X position to draw + * @param y start Y position to draw + * @param cMinX minimum x of the raster area to draw + * @param cMinY minimum y of the raster area to draw + * @param cMaxX maximum x of the raster area to draw + * @param cMaxY maximum y of the raster area to draw + */ + public void drawClipGlyphVector(WritableRaster raster, Object color, + GlyphVector glyphVector, int x, int y, + int cMinX, int cMinY, int cMaxX, int cMaxY) { + // TODO: implement complex clipping + + int xSrcSurf, ySrcSurf; // Start point in String rectangle + int xDstSurf, yDstSurf; // Start point in Surface rectangle + int clWidth, clHeight; + + for (int i = 0; i < glyphVector.getNumGlyphs(); i++) { + Glyph gl = ((CommonGlyphVector) glyphVector).vector[i]; + + if (gl.getPointWidth() == 0) { + continue; + } + + byte[] data = gl.getBitmap(); + if (data != null) { + Point2D pos = glyphVector.getGlyphPosition(i); + + xSrcSurf = 0;//gl.bmp_left; + ySrcSurf = 0;//gl.bmp_rows - gl.bmp_top; + + xDstSurf = x + (int)pos.getX() + (int) gl.getGlyphPointMetrics().getLSB();// + gl.bmp_left; + yDstSurf = y - gl.bmp_top/*getPointHeight()*/ + (int) pos.getY();// - (gl.bmp_rows-gl.bmp_top); + + int textWidth = gl.bmp_width; + int textHeight = gl.getPointHeight(); + + // if Regions don't intersect + if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX) + || (yDstSurf + textHeight < cMinY)) { + // Nothing to do + } else { + if (xDstSurf >= cMinX) { + clWidth = Math.min(textWidth, cMaxX - xDstSurf); + } else { + xSrcSurf += cMinX - xDstSurf; + clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf)); + xDstSurf = cMinX; + } + if (yDstSurf >= cMinY) { + clHeight = Math.min(textHeight, cMaxY - yDstSurf); + } else { + ySrcSurf += cMinY - yDstSurf; + clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf)); + yDstSurf = cMinY; + } + // Drawing on the Raster + for (int h=0; h<clHeight; h++){ + for (int w=0; w < clWidth ; w++) { + byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8]; + boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0); + if (emptyByte) { + raster.setDataElements(xDstSurf+w, yDstSurf+h, color); + } else { + // Nothing to do + } + } + } + } + } + } + } + + /** + * Draws string on specified raster at desired position. + * + * @param raster specified WritableRaster to draw at + * @param color color of the text + * @param str text to draw + * @param font font peer to use for drawing text + * @param x start X position to draw + * @param y start Y position to draw + * @param cMinX minimum x of the raster area to draw + * @param cMinY minimum y of the raster area to draw + * @param cMaxX maximum x of the raster area to draw + * @param cMaxY maximum y of the raster area to draw + */ + public void drawClipString(WritableRaster raster, Object color, String str, + FontPeerImpl font, int x, int y, int cMinX, int cMinY, int cMaxX, + int cMaxY) { + // TODO: implement complex clipping + + int xSrcSurf, ySrcSurf; // Start point in String rectangle + int xDstSurf, yDstSurf; // Start point in Surface rectangle + int clWidth, clHeight; + + char[] chars = str.toCharArray(); + + int xBaseLine = x; + int yBaseLine = y; + + for (char element : chars) { + Glyph gl = font.getGlyph(element); + GlyphMetrics pointMetrics = gl.getGlyphPointMetrics(); + if (gl.getWidth() == 0) { + xBaseLine += pointMetrics.getAdvanceX(); + continue; + } + + byte[] data = gl.getBitmap(); + if (data == null) { + xBaseLine += pointMetrics.getAdvanceX(); + } else { + + xSrcSurf = 0; + ySrcSurf = 0; + + xDstSurf = Math.round(xBaseLine + gl.getGlyphPointMetrics().getLSB()); + yDstSurf = yBaseLine - gl.bmp_top; + + int textWidth = gl.bmp_width; + int textHeight = gl.getPointHeight(); + + // if Regions don't intersect + if ((xDstSurf > cMaxX) || (yDstSurf > cMaxY) || (xDstSurf + textWidth < cMinX) + || (yDstSurf + textHeight < cMinY)) { + // Nothing to do + } else { + if (xDstSurf >= cMinX) { + clWidth = Math.min(textWidth, cMaxX - xDstSurf); + } else { + xSrcSurf += cMinX - xDstSurf; + clWidth = Math.min(cMaxX - cMinX, textWidth - (cMinX - xDstSurf)); + xDstSurf = cMinX; + } + if (yDstSurf >= cMinY) { + clHeight = Math.min(textHeight, cMaxY - yDstSurf); + } else { + ySrcSurf += cMinY - yDstSurf; + clHeight = Math.min(cMaxY - cMinY, textHeight - (cMinY - yDstSurf)); + yDstSurf = cMinY; + } + + // Drawing on the Raster + for (int h=0; h<clHeight; h++){ + for (int w=0; w < clWidth ; w++) { + byte currByte = data[(ySrcSurf + h)*gl.bmp_pitch + (xSrcSurf+w)/8]; + boolean emptyByte = ((currByte & (1 << (7 - ((xSrcSurf+w) % 8)))) != 0); + if (emptyByte) { + raster.setDataElements(xDstSurf+w, yDstSurf+h, color); + } else { + // Nothing to do + } + } + } + } + xBaseLine += pointMetrics.getAdvanceX(); + } + } + } + +}
\ No newline at end of file |