2
Copyright (C) 2009, 2010 Volker Berlin (i-net software)
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
27
import java.awt.font.FontRenderContext;
28
import java.lang.reflect.Constructor;
29
import java.lang.reflect.Method;
30
import java.util.Locale;
32
import cli.System.Drawing.FontFamily;
33
import cli.System.Drawing.FontStyle;
34
import cli.System.Globalization.CultureInfo;
37
* A Font2D implementation that based on .NET fonts. It replace the equals naming Sun class.
38
* A Font2D is define with the font name and the font style but it is independent of the size;
40
class PhysicalFont extends Font2D{
42
private final FontFamily family;
44
private String familyName; // family name for logical fonts
46
private final FontStyle style;
48
private static final FontStyle REGULAR = FontStyle.wrap(FontStyle.Regular);
50
private static final FontStyle BOLD = FontStyle.wrap(FontStyle.Bold);
52
private static final FontStyle ITALIC = FontStyle.wrap(FontStyle.Italic);
54
private static final FontStyle BOLD_ITALIC = FontStyle.wrap(FontStyle.Bold + FontStyle.Italic);
56
private static final cli.System.Drawing.GraphicsUnit PIXEL = cli.System.Drawing.GraphicsUnit
57
.wrap(cli.System.Drawing.GraphicsUnit.Pixel);
59
//for method getStyleMetrics
60
//for Reflection to the .NET 3.0 API in namespace System.Windows.Media of PresentationCore
61
//If we switch to .NET 3.0 then we can access it directly
62
private static boolean isMediaLoaded;
63
private static Class classMediaFontFamily;
64
private static Constructor ctorMediaFontFamily;
65
private static Method getFamilyTypefaces;
66
private static Method getItem;
67
private static Method getStrikethroughPosition;
68
private static Method getStrikethroughThickness;
69
private static Method getUnderlinePosition;
70
private static Method getUnderlineThickness;
71
private float strikethroughPosition;
72
private float strikethroughThickness;
73
private float underlinePosition;
74
private float underlineThickness;
77
PhysicalFont(String name, int style){
78
this.family = createFontFamily(name);
79
this.style = createFontStyle(family, style);
82
PhysicalFont(FontFamily family, int style){
84
this.style = createFontStyle(family, style);
93
public cli.System.Drawing.Font createNetFont(Font font){
94
float size2D = font.getSize2D();
98
return new cli.System.Drawing.Font(family, size2D, style, PIXEL);
102
* Search for .NET FamilyName. For logical fonts it set the variable familyName
103
* @param name the name of the font.
104
* @return ever a FontFamily
106
private FontFamily createFontFamily(String name){
107
if(Font.MONOSPACED.equalsIgnoreCase(name)){
108
familyName = Font.MONOSPACED;
109
return FontFamily.get_GenericMonospace();
111
if(Font.SERIF.equalsIgnoreCase(name)){
112
familyName = Font.SERIF;
113
return FontFamily.get_GenericSerif();
115
if(name == null || Font.SANS_SERIF.equalsIgnoreCase(name)){
116
familyName = Font.SANS_SERIF;
117
return FontFamily.get_GenericSansSerif();
119
if(Font.DIALOG.equalsIgnoreCase(name)){
120
familyName = Font.DIALOG;
121
return FontFamily.get_GenericSansSerif();
123
if(Font.DIALOG_INPUT.equalsIgnoreCase(name)){
124
familyName = Font.DIALOG_INPUT;
125
return FontFamily.get_GenericSansSerif();
128
if(false) throw new cli.System.ArgumentException();
129
return new FontFamily(name);
130
}catch(cli.System.ArgumentException ex){
134
//now we want map specific Name to a shorter Family Name like "Arial Bold" --> "Arial"
135
String shortName = name;
136
int spaceIdx = shortName.lastIndexOf(' ');
138
shortName = shortName.substring(0, spaceIdx).trim();
140
if(false) throw new cli.System.ArgumentException();
141
return new FontFamily(shortName);
142
}catch(cli.System.ArgumentException ex){
145
spaceIdx = shortName.lastIndexOf(' ');
148
//now we want map generic names to specific families like "courier" --> "Courier New"
149
FontFamily[] fontFanilies = FontFamily.get_Families();
150
name = name.toLowerCase();
151
for (int i = 0; i < fontFanilies.length; i++) {
152
FontFamily fontFamily = fontFanilies[i];
153
if(fontFamily.get_Name().toLowerCase().startsWith(name)){
158
//we have not find a valid font, we use the default font
159
familyName = Font.DIALOG;
160
return FontFamily.get_GenericSansSerif();
164
private static FontStyle createFontStyle(FontFamily family, int style){
165
int fs = FontStyle.Regular;
166
if((style & java.awt.Font.BOLD) != 0){
167
fs |= FontStyle.Bold;
169
if((style & java.awt.Font.ITALIC) != 0){
170
fs |= FontStyle.Italic;
172
FontStyle fontStyle = FontStyle.wrap(fs);
173
if(!family.IsStyleAvailable(fontStyle)){
174
// Some Fonts (for example Aharoni) does not support Regular style. This throw an exception else it is not
176
if(family.IsStyleAvailable(REGULAR)){
178
}else if(family.IsStyleAvailable(BOLD)){
180
}else if(family.IsStyleAvailable(ITALIC)){
182
}else if(family.IsStyleAvailable(BOLD_ITALIC)){
183
fontStyle = BOLD_ITALIC;
194
public FontStrike getStrike(Font font, FontRenderContext frc){
195
return new PhysicalStrike(font, family, style, frc);
203
public int getStyle(){
212
public String getPostscriptName(){
213
return family.get_Name();
221
public String getFontName(Locale locale){
222
return family.GetName(getLanguage(locale));
230
public String getFamilyName(Locale locale){
231
if(familyName != null){
234
return family.GetName(getLanguage(locale));
238
* Convert the Java locale to a language ID
240
private int getLanguage(Locale locale){
243
language = CultureInfo.GetCultureInfo(locale.toString().replace("_", "-")).get_LCID();
244
}catch(Throwable th){
246
language = CultureInfo.GetCultureInfo(locale.getLanguage()).get_LCID();
247
}catch(Throwable th2){}
257
public void getStyleMetrics(float pointSize, float[] metrics, int offset) {
261
classMediaFontFamily = Class.forName("System.Windows.Media.FontFamily, PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
262
ctorMediaFontFamily = classMediaFontFamily.getConstructor(String.class);
263
getFamilyTypefaces = classMediaFontFamily.getMethod("get_FamilyTypefaces");
265
if(classMediaFontFamily != null){
266
if(strikethroughPosition == 0.0){
267
Object mediaFontFamily = ctorMediaFontFamily.newInstance(family.get_Name());
268
Object familyTypefaces = getFamilyTypefaces.invoke(mediaFontFamily);
270
getItem = familyTypefaces.getClass().getMethod("get_Item", Integer.TYPE);
272
Object familyTypeface = getItem.invoke(familyTypefaces, 0);
273
if(getStrikethroughPosition == null){
274
getStrikethroughPosition = familyTypeface.getClass().getMethod("get_StrikethroughPosition");
275
getStrikethroughThickness = familyTypeface.getClass().getMethod(
276
"get_StrikethroughThickness");
277
getUnderlinePosition = familyTypeface.getClass().getMethod("get_UnderlinePosition");
278
getUnderlineThickness = familyTypeface.getClass().getMethod("get_UnderlineThickness");
280
strikethroughPosition = ((Number)getStrikethroughPosition.invoke(familyTypeface)).floatValue();
281
strikethroughThickness = ((Number)getStrikethroughThickness.invoke(familyTypeface))
283
underlinePosition = ((Number)getUnderlinePosition.invoke(familyTypeface)).floatValue();
284
underlineThickness = ((Number)getUnderlineThickness.invoke(familyTypeface)).floatValue();
287
metrics[offset++] = -strikethroughPosition * pointSize;
288
metrics[offset++] = strikethroughThickness * pointSize;
289
metrics[offset++] = -underlinePosition * pointSize;
290
metrics[offset] = underlineThickness * pointSize;
291
}catch(Throwable ex){
292
// ignore it, NET 3.0 is not available, use the default implementation
293
super.getStyleMetrics(pointSize, metrics, offset);
296
isMediaLoaded = true;