use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.
the class WPathGraphics method drawString.
/**
* Renders the text specified by the specified <code>String</code>,
* using the current <code>Font</code> and <code>Paint</code> attributes
* in the <code>Graphics2D</code> context.
* The baseline of the first character is at position
* (<i>x</i>, <i>y</i>) in the User Space.
* The rendering attributes applied include the <code>Clip</code>,
* <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
* <code>Composite</code> attributes. For characters in script systems
* such as Hebrew and Arabic, the glyphs can be rendered from right to
* left, in which case the coordinate supplied is the location of the
* leftmost character on the baseline.
* @param s the <code>String</code> to be rendered
* @param x, y the coordinates where the <code>String</code>
* should be rendered
* @see #setPaint
* @see java.awt.Graphics#setColor
* @see java.awt.Graphics#setFont
* @see #setTransform
* @see #setComposite
* @see #setClip
*/
@Override
public void drawString(String str, float x, float y, Font font, FontRenderContext frc, float targetW) {
if (str.length() == 0) {
return;
}
if (WPrinterJob.shapeTextProp) {
super.drawString(str, x, y, font, frc, targetW);
return;
}
/* If the Font has layout attributes we need to delegate to TextLayout.
* TextLayout renders text as GlyphVectors. We try to print those
* using printer fonts - ie using Postscript text operators so
* we may be reinvoked. In that case the "!printingGlyphVector" test
* prevents us recursing and instead sends us into the body of the
* method where we can safely ignore layout attributes as those
* are already handled by TextLayout.
* Similarly if layout is needed based on the text, then we
* delegate to TextLayout if possible, or failing that we delegate
* upwards to filled shapes.
*/
boolean layoutNeeded = strNeedsTextLayout(str, font);
if ((font.hasLayoutAttributes() || layoutNeeded) && !printingGlyphVector) {
TextLayout layout = new TextLayout(str, font, frc);
layout.draw(this, x, y);
return;
} else if (layoutNeeded) {
super.drawString(str, x, y, font, frc, targetW);
return;
}
AffineTransform deviceTransform = getTransform();
AffineTransform fontTransform = new AffineTransform(deviceTransform);
fontTransform.concatenate(font.getTransform());
int transformType = fontTransform.getType();
/* Use GDI for the text if the graphics transform is something
* for which we can obtain a suitable GDI font.
* A flip or shearing transform on the graphics or a transform
* on the font force us to decompose the text into a shape.
*/
boolean directToGDI = ((transformType != AffineTransform.TYPE_GENERAL_TRANSFORM) && ((transformType & AffineTransform.TYPE_FLIP) == 0));
WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
try {
wPrinterJob.setTextColor((Color) getPaint());
} catch (ClassCastException e) {
// peek should detect such paints.
directToGDI = false;
}
if (!directToGDI) {
super.drawString(str, x, y, font, frc, targetW);
return;
}
/* Now we have checked everything is OK to go through GDI as text
* with the exception of testing GDI can find and use the font. That
* is handled in the textOut() call.
*/
/* Compute the starting position of the string in
* device space.
*/
Point2D.Float userpos = new Point2D.Float(x, y);
Point2D.Float devpos = new Point2D.Float();
/* Already have the translate from the deviceTransform,
* but the font may have a translation component too.
*/
if (font.isTransformed()) {
AffineTransform fontTx = font.getTransform();
float translateX = (float) (fontTx.getTranslateX());
float translateY = (float) (fontTx.getTranslateY());
if (Math.abs(translateX) < 0.00001)
translateX = 0f;
if (Math.abs(translateY) < 0.00001)
translateY = 0f;
userpos.x += translateX;
userpos.y += translateY;
}
deviceTransform.transform(userpos, devpos);
if (getClip() != null) {
deviceClip(getClip().getPathIterator(deviceTransform));
}
/* Get the font size in device coordinates.
* The size needed is the font height scaled to device space.
* Although we have already tested that there is no shear,
* there may be a non-uniform scale, so the width of the font
* does not scale equally with the height. That is handled
* by specifying an 'average width' scale to GDI.
*/
float fontSize = font.getSize2D();
double devResX = wPrinterJob.getXRes();
double devResY = wPrinterJob.getYRes();
double fontDevScaleY = devResY / DEFAULT_USER_RES;
int orient = getPageFormat().getOrientation();
if (orient == PageFormat.LANDSCAPE || orient == PageFormat.REVERSE_LANDSCAPE) {
double tmp = devResX;
devResX = devResY;
devResY = tmp;
}
double devScaleX = devResX / DEFAULT_USER_RES;
double devScaleY = devResY / DEFAULT_USER_RES;
fontTransform.scale(1.0 / devScaleX, 1.0 / devScaleY);
Point2D.Double pty = new Point2D.Double(0.0, 1.0);
fontTransform.deltaTransform(pty, pty);
double scaleFactorY = Math.sqrt(pty.x * pty.x + pty.y * pty.y);
float scaledFontSizeY = (float) (fontSize * scaleFactorY * fontDevScaleY);
Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
fontTransform.deltaTransform(ptx, ptx);
double scaleFactorX = Math.sqrt(ptx.x * ptx.x + ptx.y * ptx.y);
float awScale = getAwScale(scaleFactorX, scaleFactorY);
int iangle = getAngle(ptx);
ptx = new Point2D.Double(1.0, 0.0);
deviceTransform.deltaTransform(ptx, ptx);
double advanceScaleX = Math.sqrt(ptx.x * ptx.x + ptx.y * ptx.y);
pty = new Point2D.Double(0.0, 1.0);
deviceTransform.deltaTransform(pty, pty);
double advanceScaleY = Math.sqrt(pty.x * pty.x + pty.y * pty.y);
Font2D font2D = FontUtilities.getFont2D(font);
if (font2D instanceof TrueTypeFont) {
textOut(str, font, (TrueTypeFont) font2D, frc, scaledFontSizeY, iangle, awScale, advanceScaleX, advanceScaleY, x, y, devpos.x, devpos.y, targetW);
} else if (font2D instanceof CompositeFont) {
/* Composite fonts are made up of multiple fonts and each
* substring that uses a particular component font needs to
* be separately sent to GDI.
* This works for standard composite fonts, alternate ones,
* Fonts that are a physical font backed by a standard composite,
* and with fallback fonts.
*/
CompositeFont compFont = (CompositeFont) font2D;
float userx = x, usery = y;
float devx = devpos.x, devy = devpos.y;
char[] chars = str.toCharArray();
int len = chars.length;
int[] glyphs = new int[len];
compFont.getMapper().charsToGlyphs(len, chars, glyphs);
int startChar = 0, endChar = 0, slot = 0;
while (endChar < len) {
startChar = endChar;
slot = glyphs[startChar] >>> 24;
while (endChar < len && ((glyphs[endChar] >>> 24) == slot)) {
endChar++;
}
String substr = new String(chars, startChar, endChar - startChar);
PhysicalFont slotFont = compFont.getSlotFont(slot);
textOut(substr, font, slotFont, frc, scaledFontSizeY, iangle, awScale, advanceScaleX, advanceScaleY, userx, usery, devx, devy, 0f);
Rectangle2D bds = font.getStringBounds(substr, frc);
float xAdvance = (float) bds.getWidth();
userx += xAdvance;
userpos.x += xAdvance;
deviceTransform.transform(userpos, devpos);
devx = devpos.x;
devy = devpos.y;
}
} else {
super.drawString(str, x, y, font, frc, targetW);
}
}
use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.
the class GlyphListPipe method drawString.
public void drawString(SunGraphics2D sg2d, String s, double x, double y) {
FontInfo info = sg2d.getFontInfo();
if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
SurfaceData.outlineTextRenderer.drawString(sg2d, s, x, y);
return;
}
float devx, devy;
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
double[] origin = { x + info.originX, y + info.originY };
sg2d.transform.transform(origin, 0, origin, 0, 1);
devx = (float) origin[0];
devy = (float) origin[1];
} else {
devx = (float) (x + info.originX + sg2d.transX);
devy = (float) (y + info.originY + sg2d.transY);
}
/* setFromString returns false if shaping is needed, and we then back
* off to a TextLayout. Such text may benefit slightly from a lower
* overhead in this approach over the approach in previous releases.
*/
GlyphList gl = GlyphList.getInstance();
if (gl.setFromString(info, s, devx, devy)) {
drawGlyphList(sg2d, gl);
gl.dispose();
} else {
// release this asap.
gl.dispose();
TextLayout tl = new TextLayout(s, sg2d.getFont(), sg2d.getFontRenderContext());
tl.draw(sg2d, (float) x, (float) y);
}
}
use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.
the class PSPathGraphics method drawString.
protected void drawString(String str, float x, float y, Font font, FontRenderContext frc, float w) {
if (str.length() == 0) {
return;
}
/* If the Font has layout attributes we need to delegate to TextLayout.
* TextLayout renders text as GlyphVectors. We try to print those
* using printer fonts - ie using Postscript text operators so
* we may be reinvoked. In that case the "!printingGlyphVector" test
* prevents us recursing and instead sends us into the body of the
* method where we can safely ignore layout attributes as those
* are already handled by TextLayout.
*/
if (font.hasLayoutAttributes() && !printingGlyphVector) {
TextLayout layout = new TextLayout(str, font, frc);
layout.draw(this, x, y);
return;
}
Font oldFont = getFont();
if (!oldFont.equals(font)) {
setFont(font);
} else {
oldFont = null;
}
boolean drawnWithPS = false;
float translateX = 0f, translateY = 0f;
boolean fontisTransformed = getFont().isTransformed();
if (fontisTransformed) {
AffineTransform fontTx = getFont().getTransform();
int transformType = fontTx.getType();
/* TYPE_TRANSLATION is a flag bit but we can do "==" here
* because we want to detect when its just that bit set and
*
*/
if (transformType == AffineTransform.TYPE_TRANSLATION) {
translateX = (float) (fontTx.getTranslateX());
translateY = (float) (fontTx.getTranslateY());
if (Math.abs(translateX) < 0.00001)
translateX = 0f;
if (Math.abs(translateY) < 0.00001)
translateY = 0f;
fontisTransformed = false;
}
}
boolean directToPS = !fontisTransformed;
if (!PSPrinterJob.shapeTextProp && directToPS) {
PSPrinterJob psPrinterJob = (PSPrinterJob) getPrinterJob();
if (psPrinterJob.setFont(getFont())) {
/* Set the text color.
* We should not be in this shape printing path
* if the application is drawing with non-solid
* colors. We should be in the raster path. Because
* we are here in the shape path, the cast of the
* paint to a Color should be fine.
*/
try {
psPrinterJob.setColor((Color) getPaint());
} catch (ClassCastException e) {
if (oldFont != null) {
setFont(oldFont);
}
throw new IllegalArgumentException("Expected a Color instance");
}
psPrinterJob.setTransform(getTransform());
psPrinterJob.setClip(getClip());
drawnWithPS = psPrinterJob.textOut(this, str, x + translateX, y + translateY, font, frc, w);
}
}
/* The text could not be converted directly to PS text
* calls so decompose the text into a shape.
*/
if (drawnWithPS == false) {
if (oldFont != null) {
setFont(oldFont);
oldFont = null;
}
super.drawString(str, x, y, font, frc, w);
}
if (oldFont != null) {
setFont(oldFont);
}
}
use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.
the class PathGraphics method drawString.
protected void drawString(String str, float x, float y, Font font, FontRenderContext frc, float w) {
TextLayout layout = new TextLayout(str, font, frc);
Shape textShape = layout.getOutline(AffineTransform.getTranslateInstance(x, y));
fill(textShape);
}
use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.
the class PathGraphics method drawString.
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
if (iterator == null) {
throw new NullPointerException("attributedcharacteriterator is null");
}
TextLayout layout = new TextLayout(iterator, getFontRenderContext());
layout.draw(this, x, y);
}
Aggregations