Doug Felt
Mon, 04 Feb 2002 16:07:15 -0800
First, let me apologize for the inadequate documentation on FontRenderContext (FRC) and its role in text layout and rendering. Unfortunately, the documentation for FRC does not define the behavior when the FRC does not match the state of the Graphics.
The JDK 1.3. documentation for the FRC class does warn about unpredictable results when using an FRC not obtained from a Graphics, and in fact, in JDK 1.3.1 and prior, Graphics2D.getFontRenderContext always returns an FRC with an identity transform, regardless of what Graphics it is or what transforms have been applied to it. Behavior using FRCs not obtained from a Graphics2D is unspecified. The behavior you saw in JDK 1.3 was actually a bug. Let me briefly (?) explain how the FRC is used. Layout of text is based on the FRC in effect when layout is performed, but the actual rendering is based on the current graphics state. Typically these are the same (for example, they're always the same with Graphics.drawString) but they don't have to be. You might, for example, want to layout text based on printer resolution, but display it at screen resolution. Or you might layout text based on a standard horizontal line, but use a transform to zoom or rotate the display. The key point is, the metrics of the text (overall advance, glyph positions, logical and visual bounds) are constant, and are based on the FRC used to construct the layout. The actual rendered appearance of the glyphs, though, depends on the graphics state at the time of rendering. This is what allows TextLayout to compute metric information for the text independently of the graphics transform used to render the layout. TextLayout metrics are in 'user space,' which is independent of the transform applied to the graphics. So, for example, you can use the text metrics to compute a rectangle to frame the text, and then draw both text and frame without adjustment under different graphics transforms, and get the same alignment of the text and the frame. You can layout text based on one graphics state (for instance, one that coresponds to the printer you plan on printing to) but display it in another graphics state (for instance, the screen) while keeping the same overall metrics (advance, ascent/descent, glyph and caret positions). You can 'zoom in' on the text on the screen and it won't change the positions or metrics, but it will attempt to give you the best image, because the individual glyphs rendered to the screen are hinted based on the current graphics state. The FRC represents the information about the graphics device that impact text metrics, such as advance vector and bounding box, and in particular, the AffineTransform of the FRC represents the resolution and orientation of the pixel grid to which glyphs are hinted. You can see this very clearly when the FractionalMetrics text rendering hint is off, and the FRC transform is small, say [0.02 0 0 0.02]. This FRC transform is saying that pixels are very big-- the identity transform corresponds to 72 pixels per inch, so this transform corresponds to a raster of about one and a half pixels per inch. When fractional metrics is off, advances are rounded to pixel boundaries, and with such large pixels you can really see the effect on glyph placement. As another example, a rotated FRC transform means that the pixel raster is rotated, and generally when the raster is rotated, glyph hinting not performed (since then the hinting rules in the font don't work correctly). Hinting is what gives you balanced stem weights and spacing (for example, in the letter 'm') and it can affect the glyph advance with some rasterizers. If you render a TextLayout using the same FRC in the graphics, you will see results that exactly match the metrics returned from TextLayout. When you render text, we use the glyph positions and advances computed under the FRC, but rehint and render the individual glyphs based on the current graphics transform and rendering hints. (Anti-aliasing should work this way too, but some rasterizers/fonts can't support AA rendering, and in our current implementation if we use a different AA flag to render the pipeline can end up using different fonts and get different actual glyphs. This is a problem we plan to remedy in the future, but didn't manage to fix for JDK 1.4). Anyway, since we recompute the glyph raster based on the rendering transform, the glyph still looks good under the rendering transform. In the example above that had a very coarse raster in the FRC, the glyph position was determined based on the glyph advances under the FRC raster, but since the rendered glyphs are based on the current screen raster, the glyphs are still legible-- otherwise each glyph would just be a large blob. The supported way to get the effect you described is to apply a transform to the graphics before rendering the TextLayout. You can wrap each TextLayout in another object that applies the transform (and perhaps other things like color) to the graphics before delegating the actual rendering to the TextLayout. Or you can just set up the graphics before rendering. Once again, let me apologize for the poor documentation. The documentation should have described how the rendering system uses the FRC in much more detail. Doug =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".