2
Copyright (C) 2002, 2004, 2005, 2006, 2007 Jeroen Frijters
3
Copyright (C) 2006 Active Endpoints, Inc.
4
Copyright (C) 2006, 2007, 2009 - 2011 Volker Berlin
6
This software is provided 'as-is', without any express or implied
7
warranty. In no event will the authors be held liable for any damages
8
arising from the use of this software.
10
Permission is granted to anyone to use this software for any purpose,
11
including commercial applications, and to alter it and redistribute it
12
freely, subject to the following restrictions:
14
1. The origin of this software must not be misrepresented; you must not
15
claim that you wrote the original software. If you use this software
16
in a product, an acknowledgment in the product documentation would be
17
appreciated but is not required.
18
2. Altered source versions must be plainly marked as such, and must not be
19
misrepresented as being the original software.
20
3. This notice may not be removed or altered from any source distribution.
29
using System.Drawing.Drawing2D;
30
using System.Drawing.Text;
37
using System.Windows.Media;
44
/*class NetFontMetrics : java.awt.FontMetrics
46
private static readonly Bitmap defaultbitmap = new Bitmap(1, 1);
48
private static Graphics threadLocalDefaultGraphics;
50
private static Graphics GetDefaultGraphics()
52
Graphics g = threadLocalDefaultGraphics;
55
g = threadLocalDefaultGraphics = Graphics.FromImage(defaultbitmap);
56
g.SmoothingMode = SmoothingMode.None;
57
g.PixelOffsetMode = PixelOffsetMode.None;
58
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
63
public NetFontMetrics(java.awt.Font font) : base(font)
67
private Font GetNetFont()
69
return font.getNetFont();
72
public override int getHeight()
74
return GetNetFont().Height;
77
public override int getLeading()
79
return (int)Math.Round(GetLeadingFloat());
82
public override int getMaxAdvance()
85
return charWidth('M');
88
public override int charWidth(char ch)
90
// HACK we average 20 characters to decrease the influence of the pre/post spacing
91
return stringWidth(new String(ch, 20)) / 20;
94
public override int charsWidth(char[] data, int off, int len)
96
return stringWidth(new String(data, off, len));
99
public override int getAscent()
101
return (int)Math.Round(GetAscentFloat());
104
public override int getDescent()
106
return (int)Math.Round(GetDescentFloat());
109
public override int stringWidth(string s)
111
return (int)Math.Round(GetStringWidth(s, GetDefaultGraphics()));
114
public float GetAscentFloat()
116
Font f = GetNetFont();
117
int ascent = f.FontFamily.GetCellAscent(f.Style);
118
return f.Size * ascent / f.FontFamily.GetEmHeight(f.Style);
121
public float GetDescentFloat()
123
Font f = GetNetFont();
124
int descent = f.FontFamily.GetCellDescent(f.Style);
125
return f.Size * descent / f.FontFamily.GetEmHeight(f.Style);
128
public float GetLeadingFloat()
130
float leading = getHeight() - (GetAscentFloat() + GetDescentFloat());
131
return Math.Max(0.0f, leading);
134
internal float GetStringWidth(String aString, System.Drawing.Graphics g)
136
if (aString.Length == 0)
140
// System.Windows.Forms.TextRenderer#MeasureText seems to large
141
// Graphics#MeasureString is many faster but work only correct with TextRenderingHint.AntiAlias
144
switch (g.TextRenderingHint)
146
// Fractional metrics
147
case TextRenderingHint.AntiAlias:
148
case TextRenderingHint.SingleBitPerPixel:
149
// this very mystic, if a StringFormat extends from GenericTypographic then the metric are different but like Java with fractional metrics
150
format = new StringFormat(StringFormat.GenericTypographic);
154
format = new StringFormat();
159
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap |
160
StringFormatFlags.FitBlackBox;
161
format.Trimming = StringTrimming.None;
162
format.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, aString.Length)});
163
Region[] regions = g.MeasureCharacterRanges(aString, GetNetFont(),
164
new RectangleF(0, 0, int.MaxValue, int.MaxValue), format);
165
SizeF size = regions[0].GetBounds(g).Size;
166
regions[0].Dispose();
167
//with Arial 9.0 and only one character under Vista .NET does not round it, that we rounding manualy
168
return rounding ? (int) Math.Round(size.Width) : size.Width;
171
internal java.awt.geom.Rectangle2D GetStringBounds(String aString, System.Drawing.Graphics g)
173
Font netFont = GetNetFont();
174
FontFamily family = netFont.FontFamily;
175
FontStyle style = netFont.Style;
176
float factor = netFont.Size / family.GetEmHeight(style);
177
float height = family.GetLineSpacing(style) * factor;
178
float descent = family.GetCellDescent(style) * factor;
179
float ascent = family.GetCellAscent(style) * factor;
180
float leading = height - ascent - descent;
182
return new java.awt.geom.Rectangle2D.Float(0, -ascent - leading / 2, GetStringWidth(aString, g), height);
185
public override java.awt.geom.Rectangle2D getStringBounds(String aString, java.awt.Graphics gr)
187
if (gr is NetGraphics)
189
return GetStringBounds(aString, ((NetGraphics)gr).JGraphics);
191
return GetStringBounds(aString, GetDefaultGraphics());
195
/* class NetFontPeer : java.awt.peer.FontPeer, IDisposable
197
internal readonly Font netFont;
199
internal NetFontPeer(string name, java.util.Map attrs)
202
netFont = J2C.ConvertFont(name, getStyle(null), getSize(null));
205
public override bool canDisplay(int codePoint)
207
//HACK There is no equivalent in C# http://msdn2.microsoft.com/en-us/library/sf4dhbw8(VS.80).aspx
211
public override int canDisplayUpTo(java.awt.Font font, java.text.CharacterIterator param2, int param3, int param4)
213
//HACK There is no equivalent in C# http://msdn2.microsoft.com/en-us/library/e8bh4szw(VS.80).aspx
217
public override GlyphVector createGlyphVector(java.awt.Font font, FontRenderContext frc, int[] glyphCodes)
219
char[] chars = new char[glyphCodes.Length];
220
for (int i = 0; i < chars.Length; i++)
222
chars[i] = (char)glyphCodes[i];
224
return new NetGlyphVector(netFont, font, frc, chars);
227
public override GlyphVector createGlyphVector(java.awt.Font font, FontRenderContext frc, java.text.CharacterIterator text)
229
int count = text.getEndIndex() - text.getBeginIndex();
230
char[] chars = new char[count];
232
for (int i = 0; i < count; i++)
234
chars[i] = text.current();
237
return new NetGlyphVector(netFont, font, frc, chars);
240
public override byte getBaselineFor(java.awt.Font font, char param2)
242
throw new NotImplementedException();
245
public override java.awt.FontMetrics getFontMetrics(java.awt.Font font)
247
return new NetFontMetrics(font);
250
public override string getGlyphName(java.awt.Font font, int param2)
252
throw new NotImplementedException();
255
public override LineMetrics getLineMetrics(java.awt.Font font, java.text.CharacterIterator aCharacterIterator, int aBegin, int aLimit, FontRenderContext aFontRenderContext)
257
string s = ToString(aCharacterIterator, aBegin, aLimit);
258
return new NetLineMetrics(font, s);
261
public override java.awt.geom.Rectangle2D getMaxCharBounds(java.awt.Font font, FontRenderContext param2)
263
throw new NotImplementedException();
266
public override int getMissingGlyphCode(java.awt.Font font)
268
throw new NotImplementedException();
271
public override int getNumGlyphs(java.awt.Font font)
273
throw new NotImplementedException();
276
public override string getPostScriptName(java.awt.Font font)
278
throw new NotImplementedException();
281
public override bool hasUniformLineMetrics(java.awt.Font font)
283
throw new NotImplementedException();
286
public override GlyphVector layoutGlyphVector(java.awt.Font font, FontRenderContext frc, char[] text, int beginIndex, int endIndex, int flags)
288
char[] chars = new char[endIndex - beginIndex];
289
Array.Copy(text, beginIndex, chars, 0, chars.Length);
290
return new NetGlyphVector(netFont, font, frc, chars);
293
public override string getSubFamilyName(java.awt.Font font, Locale param2)
295
throw new NotImplementedException();
298
private static string ToString(java.text.CharacterIterator aCharacterIterator, int aBegin, int aLimit)
300
aCharacterIterator.setIndex(aBegin);
301
StringBuilder sb = new StringBuilder();
303
for (int i = aBegin; i <= aLimit; ++i)
305
char c = aCharacterIterator.current();
307
aCharacterIterator.next();
310
return sb.ToString();
313
#region IDisposable Members
315
public void Dispose()
323
/* class NetGlyphVector : GlyphVector
325
private readonly Font netFont;
326
private readonly java.awt.Font font;
327
private readonly FontRenderContext frc;
328
private readonly char[] text;
329
private NetFontMetrics metrics;
332
internal NetGlyphVector(Font netFont, java.awt.Font font, FontRenderContext frc, char[] text)
334
this.netFont = netFont;
340
private NetFontMetrics getMetrics()
344
metrics = new NetFontMetrics(font);
349
public override bool equals(GlyphVector gv)
351
throw new NotImplementedException();
354
public override java.awt.Font getFont()
359
public override FontRenderContext getFontRenderContext()
364
public override int getGlyphCode(int i)
366
throw new NotImplementedException();
369
public override int[] getGlyphCodes(int i1, int i2, int[] iarr)
371
throw new NotImplementedException();
374
public override GlyphJustificationInfo getGlyphJustificationInfo(int i)
376
throw new NotImplementedException();
379
public override java.awt.Shape getGlyphLogicalBounds(int i)
381
throw new NotImplementedException();
384
public override GlyphMetrics getGlyphMetrics(int i)
386
throw new NotImplementedException();
389
public override java.awt.Shape getGlyphOutline(int i)
391
throw new NotImplementedException();
394
public override Point2D getGlyphPosition(int i)
396
throw new NotImplementedException();
399
public override float[] getGlyphPositions(int i1, int i2, float[] farr)
401
throw new NotImplementedException();
404
public override AffineTransform getGlyphTransform(int i)
406
throw new NotImplementedException();
409
public override java.awt.Shape getGlyphVisualBounds(int index)
411
return getMetrics().GetStringBounds(new String(text, index, 1));
414
public override Rectangle2D getLogicalBounds()
416
return getMetrics().GetStringBounds(new String(text));
419
public override int getNumGlyphs()
424
public override java.awt.Shape getOutline()
426
throw new NotImplementedException();
429
public override java.awt.Shape getOutline(float f1, float f2)
431
throw new NotImplementedException();
434
public override Rectangle2D getVisualBounds()
436
return new NetFontMetrics(font).GetStringBounds(new String(text));
439
public override void performDefaultLayout()
441
throw new NotImplementedException();
444
public override void setGlyphPosition(int i, Point2D pd)
446
throw new NotImplementedException();
449
public override void setGlyphTransform(int i, AffineTransform at)
451
throw new NotImplementedException();
454
public char[] getText()
460
/*class NetLineMetrics : LineMetrics
462
private java.awt.Font mFont;
463
private String mString;
464
private FontFamily fontFamily;
465
private FontStyle style;
466
private float factor;
468
public NetLineMetrics(java.awt.Font aFont, String aString)
472
fontFamily = J2C.CreateFontFamily(aFont.getName());
473
style = (FontStyle)mFont.getStyle();
474
factor = aFont.getSize2D() / fontFamily.GetEmHeight(style);
477
public override float getAscent()
479
return fontFamily.GetCellAscent(style) * factor;
482
public override int getBaselineIndex()
484
return 0; //I have no font see that return another value.
487
public override float[] getBaselineOffsets()
489
float ascent = getAscent();
490
return new float[] { 0, (getDescent() / 2f - ascent) / 2f, -ascent };
493
public override float getDescent()
495
return fontFamily.GetCellDescent(style) * factor;
498
public override float getHeight()
500
return fontFamily.GetLineSpacing(style) * factor;
503
public override float getLeading()
505
return getHeight() - getAscent() - getDescent();
508
public override int getNumChars()
510
return mString.Length;
514
private Typeface GetTypeface()
516
return new Typeface(fontFamily, style, FontWeight.Normal, FontStretch.Medium);
520
public override float getStrikethroughOffset()
523
return GetTypeface().StrikethroughPosition * factor;
525
return getAscent() / -3;
529
public override float getStrikethroughThickness()
532
return GetTypeface().StrikethroughThickness * factor;
534
return mFont.getSize2D() / 18;
538
public override float getUnderlineOffset()
541
return GetTypeface().UnderlinePosition * factor;
543
return mFont.getSize2D() / 8.7F;
547
public override float getUnderlineThickness()
550
return GetTypeface().UnderlineThickness * factor;
552
return mFont.getSize2D() / 18;