diff options
-rw-r--r-- | awt/graphics.cs | 127 | ||||
-rw-r--r-- | openjdk/sun/font/StandardGlyphVector.java | 19 |
2 files changed, 74 insertions, 72 deletions
diff --git a/awt/graphics.cs b/awt/graphics.cs index 92f8652d..dff099a2 100644 --- a/awt/graphics.cs +++ b/awt/graphics.cs @@ -770,6 +770,7 @@ namespace ikvm.awt internal Pen pen; private CompositeHelper composite; private java.awt.Composite javaComposite = java.awt.AlphaComposite.SrcOver; + private Object fractionalHint = java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT; protected NetGraphics(Graphics g, java.awt.Font font, Color fgcolor, Color bgcolor) { @@ -1265,28 +1266,32 @@ namespace ikvm.awt drawString(str, (float)x, (float)y); } - public override void drawString(string text, float x, float y) - { - if (text.Length == 0) { - return; - } - StringFormat format; - switch (g.TextRenderingHint) + public override void drawString(String text, float x, float y) + { + if (text.Length == 0) { - // Fractional metrics - case TextRenderingHint.AntiAlias: - case TextRenderingHint.SingleBitPerPixel: - // this very mystic, if a StringFormat extends from GenericTypographic then the metric are different but like Java with fractional metrics - format = new StringFormat(StringFormat.GenericTypographic); - break; - default: - // Non Fractional metrics - format = new StringFormat(); - break; + return; } + bool fractional = isFractionalMetrics(); + StringFormat format = new StringFormat(StringFormat.GenericTypographic); format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox; format.Trimming = StringTrimming.None; - g.DrawString(text, netfont, brush, x, y - font.getSize(), format); + if (fractional || !sun.font.StandardGlyphVector.isSimpleString(font, text)) + { + g.DrawString(text, netfont, brush, x, y - font.getSize(), format); + } + else + { + // fixed metric for simple text, we position every character to simulate the Java behaviour + java.awt.font.FontRenderContext frc = new java.awt.font.FontRenderContext(null, isAntiAlias(), fractional); + sun.font.FontDesignMetrics metrics = sun.font.FontDesignMetrics.getMetrics(font, frc); + y -= font.getSize(); + for (int i = 0; i < text.Length; i++) + { + g.DrawString(text.Substring(i, 1), netfont, brush, x, y, format); + x += metrics.charWidth(text[i]); + } + } } public override void drawString(java.text.AttributedCharacterIterator iterator, int x, int y) @@ -1630,62 +1635,32 @@ namespace ikvm.awt } if (hintKey == java.awt.RenderingHints.KEY_TEXT_ANTIALIASING) { - if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT || hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) + if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT) { - switch (g.TextRenderingHint) { - case TextRenderingHint.SystemDefault: - case TextRenderingHint.AntiAlias: - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; - break; - case TextRenderingHint.AntiAliasGridFit: - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; - break; - } + g.TextRenderingHint = TextRenderingHint.SystemDefault; + return; + } + if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF) + { + g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; return; } if (hintValue == java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) { - switch (g.TextRenderingHint) { - case TextRenderingHint.SystemDefault: - case TextRenderingHint.SingleBitPerPixel: - g.TextRenderingHint = TextRenderingHint.AntiAlias; - break; - case TextRenderingHint.SingleBitPerPixelGridFit: - g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; - break; - } + g.TextRenderingHint = TextRenderingHint.AntiAlias; return; } return; } if (hintKey == java.awt.RenderingHints.KEY_FRACTIONALMETRICS) { - if (hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT || hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF) - { - // OFF means enable GridFit - switch (g.TextRenderingHint) { - case TextRenderingHint.SystemDefault: - case TextRenderingHint.SingleBitPerPixel: - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; - break; - case TextRenderingHint.AntiAlias: - g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; - break; - } - } - if (hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON) + if (hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT || + hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF || + hintValue == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON) { - // ON means remove GridFit - switch (g.TextRenderingHint) { - case TextRenderingHint.SingleBitPerPixelGridFit: - g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel; - break; - case TextRenderingHint.AntiAliasGridFit: - case TextRenderingHint.ClearTypeGridFit: - g.TextRenderingHint = TextRenderingHint.AntiAlias; - break; - } + fractionalHint = hintValue; } + return; } } @@ -1746,26 +1721,18 @@ namespace ikvm.awt { case TextRenderingHint.SystemDefault: hints.put(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); - hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT); break; case TextRenderingHint.SingleBitPerPixelGridFit: - hints.put(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); - hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF); - break; case TextRenderingHint.SingleBitPerPixel: hints.put(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); - hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON); break; case TextRenderingHint.AntiAlias: - hints.put(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON); - break; case TextRenderingHint.AntiAliasGridFit: case TextRenderingHint.ClearTypeGridFit: hints.put(java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF); break; } + hints.put(java.awt.RenderingHints.KEY_FRACTIONALMETRICS, fractionalHint); return hints; } @@ -1870,9 +1837,27 @@ namespace ikvm.awt return stroke; } + private bool isAntiAlias() + { + switch (g.TextRenderingHint) + { + case TextRenderingHint.AntiAlias: + case TextRenderingHint.AntiAliasGridFit: + case TextRenderingHint.ClearTypeGridFit: + return true; + default: + return false; + } + } + + private bool isFractionalMetrics() + { + return fractionalHint == java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON; + } + public override java.awt.font.FontRenderContext getFontRenderContext() { - return new java.awt.font.FontRenderContext(getTransform(), false, false); + return new java.awt.font.FontRenderContext(getTransform(), isAntiAlias(), isFractionalMetrics()); } public override void drawGlyphVector(java.awt.font.GlyphVector gv, float x, float y) diff --git a/openjdk/sun/font/StandardGlyphVector.java b/openjdk/sun/font/StandardGlyphVector.java index 1d3f9ca9..424643c3 100644 --- a/openjdk/sun/font/StandardGlyphVector.java +++ b/openjdk/sun/font/StandardGlyphVector.java @@ -429,9 +429,26 @@ public class StandardGlyphVector extends GlyphVector{ } } - void addDefaultGlyphAdvance(int glyphID, Point2D.Float result) { + private void addDefaultGlyphAdvance(int glyphID, Point2D.Float result) { Point2D.Float adv = strike.getGlyphMetrics(glyphID); result.x += adv.x; result.y += adv.y; } + + /** + * If the text is a simple text and we can use FontDesignMetrics without a stackoverflow. + * @see FontDesignMetrics#stringWidth(String) + * @return true, if a simple text. false it is a complex text. + */ + public static boolean isSimpleString(Font font, String str) { + if (font.hasLayoutAttributes()) { + return false; + } + for (int i = 0; i < str.length(); ++i) { + if (FontManager.isNonSimpleChar(str.charAt(i))) { + return false; + } + } + return true; + } } |