如何搭建JDK源码
这里针对的是jdk8的源码搭建,其他版本的源码搭建与其差异不多,但是源码上会存在一些区别,还望希望注意
第一步:
先在官方网站下好jdk8,然后在你的安装目录找到即可,就不需要去网上找了(如想去读其他版本的源码就需要自行网上寻找,这里就不多说了)
第二步:
有了这个src的源码包,我们就可以去搭建一个项目将JDK源码包导入了,只需要一个最简单的java项目就行了,如果这个都不会搭建,就需要好好想想自己学的啥了
找到项目的src根目录,将刚刚的那个src解压到这里,解压过程不必多介绍
现在项目里面就已经导入好了我们的一个源码项目了,这里肯定有人会问我说,如果想自定义一个文件目录存放可以吗?当然是可以的,不过这些源码的路径,就需要注意了,还有千万千万不要直接拖进来,当然你电脑性能好当我没说,不然你的电脑CPU会吃不消,你要试也不要怪我哈
第三步:
现在我们已经把源码已经导入,这里我们就用一个HashMap的例子为由,来运行这个源码,启动过程需要加载很多源码,所以会很慢,需耐心等待
这里我直接提供给大家了,方便大家不用去找,只希望大家能够三连一下,谢谢
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.awt;
import java.awt.RenderingHints;
import static java.awt.RenderingHints.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.security.action.GetIntegerAction;
import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
import sun.java2d.opengl.OGLRenderQueue;
import java.lang.reflect.InvocationTargetException;
public abstract class UNIXToolkit extends SunToolkit {
/**
* All calls into GTK should be synchronized on this lock
*/
public static final Object GTK_LOCK = new Object();
private static final int[] BAND_OFFSETS = {0, 1, 2};
private static final int[] BAND_OFFSETS_ALPHA = {0, 1, 2, 3};
private static final int DEFAULT_DATATRANSFER_TIMEOUT = 10000;
private Boolean nativeGTKAvailable;
private Boolean nativeGTKLoaded;
private BufferedImage tmpImage = null;
public static int getDatatransferTimeout() {
Integer dt = (Integer) AccessController.doPrivileged(
new GetIntegerAction("sun.awt.datatransfer.timeout"));
if (dt == null || dt <= 0) {
return DEFAULT_DATATRANSFER_TIMEOUT;
} else {
return dt;
}
}
/**
* Returns true if the native GTK libraries are capable of being
* loaded and are expected to work properly, false otherwise. Note
* that this method will not leave the native GTK libraries loaded if
* they haven't already been loaded. This allows, for example, Swing's
* GTK L&F to test for the presence of native GTK support without
* leaving the native libraries loaded. To attempt long-term loading
* of the native GTK libraries, use the loadGTK() method instead.
*/
@Override
public boolean isNativeGTKAvailable() {
synchronized (GTK_LOCK) {
if (nativeGTKLoaded != null) {
// We've already attempted to load GTK, so just return the
// status of that attempt.
return nativeGTKLoaded.booleanValue();
} else if (nativeGTKAvailable != null) {
// We've already checked the availability of the native GTK
// libraries, so just return the status of that attempt.
return nativeGTKAvailable.booleanValue();
} else {
boolean success = check_gtk();
nativeGTKAvailable = Boolean.valueOf(success);
return success;
}
}
}
/**
* Loads the GTK libraries, if necessary. The first time this method
* is called, it will attempt to load the native GTK library. If
* successful, it leaves the library open and returns true; otherwise,
* the library is left closed and returns false. On future calls to
* this method, the status of the first attempt is returned (a simple
* lightweight boolean check, no native calls required).
*/
public boolean loadGTK() {
synchronized (GTK_LOCK) {
if (nativeGTKLoaded == null) {
boolean success = load_gtk();
nativeGTKLoaded = Boolean.valueOf(success);
}
}
return nativeGTKLoaded.booleanValue();
}
/**
* Overridden to handle GTK icon loading
*/
protected Object lazilyLoadDesktopProperty(String name) {
if (name.startsWith("gtk.icon.")) {
return lazilyLoadGTKIcon(name);
}
return super.lazilyLoadDesktopProperty(name);
}
/**
* Load a native Gtk stock icon.
*
* @param longname a desktop property name. This contains icon name, size
* and orientation, e.g. <code>"gtk.icon.gtk-add.4.rtl"</code>
* @return an <code>Image</code> for the icon, or <code>null</code> if the
* icon could not be loaded
*/
protected Object lazilyLoadGTKIcon(String longname) {
// Check if we have already loaded it.
Object result = desktopProperties.get(longname);
if (result != null) {
return result;
}
// We need to have at least gtk.icon.<stock_id>.<size>.<orientation>
String str[] = longname.split("\\.");
if (str.length != 5) {
return null;
}
// Parse out the stock icon size we are looking for.
int size = 0;
try {
size = Integer.parseInt(str[3]);
} catch (NumberFormatException nfe) {
return null;
}
// Direction.
TextDirection dir = ("ltr".equals(str[4]) ? TextDirection.LTR :
TextDirection.RTL);
// Load the stock icon.
BufferedImage img = getStockIcon(-1, str[2], size, dir.ordinal(), null);
if (img != null) {
// Create the desktop property for the icon.
setDesktopProperty(longname, img);
}
return img;
}
/**
* Returns a BufferedImage which contains the Gtk icon requested. If no
* such icon exists or an error occurs loading the icon the result will
* be null.
*
* @param filename
* @return The icon or null if it was not found or loaded.
*/
public BufferedImage getGTKIcon(final String filename) {
if (!loadGTK()) {
return null;
} else {
// Call the native method to load the icon.
synchronized (GTK_LOCK) {
if (!load_gtk_icon(filename)) {
tmpImage = null;
}
}
}
// Return local image the callback loaded the icon into.
return tmpImage;
}
/**
* Returns a BufferedImage which contains the Gtk stock icon requested.
* If no such stock icon exists the result will be null.
*
* @param widgetType one of WidgetType values defined in GTKNativeEngine or
* -1 for system default stock icon.
* @param stockId String which defines the stock id of the gtk item.
* For a complete list reference the API at www.gtk.org for StockItems.
* @param iconSize One of the GtkIconSize values defined in GTKConstants
* @param direction One of the TextDirection values defined in
* GTKConstants
* @param detail Render detail that is passed to the native engine (feel
* free to pass null)
* @return The stock icon or null if it was not found or loaded.
*/
public BufferedImage getStockIcon(final int widgetType, final String stockId,
final int iconSize, final int direction,
final String detail) {
if (!loadGTK()) {
return null;
} else {
// Call the native method to load the icon.
synchronized (GTK_LOCK) {
if (!load_stock_icon(widgetType, stockId, iconSize, direction, detail)) {
tmpImage = null;
}
}
}
// Return local image the callback loaded the icon into.
return tmpImage; // set by loadIconCallback
}
/**
* This method is used by JNI as a callback from load_stock_icon.
* Image data is passed back to us via this method and loaded into the
* local BufferedImage and then returned via getStockIcon.
* <p>
* Do NOT call this method directly.
*/
public void loadIconCallback(byte[] data, int width, int height,
int rowStride, int bps, int channels, boolean alpha) {
// Reset the stock image to null.
tmpImage = null;
// Create a new BufferedImage based on the data returned from the
// JNI call.
DataBuffer dataBuf = new DataBufferByte(data, (rowStride * height));
// Maybe test # channels to determine band offsets?
WritableRaster raster = Raster.createInterleavedRaster(dataBuf,
width, height, rowStride, channels,
(alpha ? BAND_OFFSETS_ALPHA : BAND_OFFSETS), null);
ColorModel colorModel = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB), alpha, false,
ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
// Set the local image so we can return it later from
// getStockIcon().
tmpImage = new BufferedImage(colorModel, raster, false, null);
}
private static native boolean check_gtk();
private static native boolean load_gtk();
private static native boolean unload_gtk();
private native boolean load_gtk_icon(String filename);
private native boolean load_stock_icon(int widget_type, String stock_id,
int iconSize, int textDirection, String detail);
private native void nativeSync();
public void sync() {
// flush the X11 buffer
nativeSync();
// now flush the OGL pipeline (this is a no-op if OGL is not enabled)
OGLRenderQueue.sync();
}
/*
* This returns the value for the desktop property "awt.font.desktophints"
* It builds this by querying the Gnome desktop properties to return
* them as platform independent hints.
* This requires that the Gnome properties have already been gathered.
*/
public static final String FONTCONFIGAAHINT = "fontconfig/Antialias";
protected RenderingHints getDesktopAAHints() {
Object aaValue = getDesktopProperty("gnome.Xft/Antialias");
if (aaValue == null) {
/* On a KDE desktop running KWin the rendering hint will
* have been set as property "fontconfig/Antialias".
* No need to parse further in this case.
*/
aaValue = getDesktopProperty(FONTCONFIGAAHINT);
if (aaValue != null) {
return new RenderingHints(KEY_TEXT_ANTIALIASING, aaValue);
} else {
return null; // no Gnome or KDE Desktop properties available.
}
}
/* 0 means off, 1 means some ON. What would any other value mean?
* If we require "1" to enable AA then some new value would cause
* us to default to "OFF". I don't think that's the best guess.
* So if its !=0 then lets assume AA.
*/
boolean aa = Boolean.valueOf(((aaValue instanceof Number) &&
((Number) aaValue).intValue() != 0));
Object aaHint;
if (aa) {
String subpixOrder =
(String) getDesktopProperty("gnome.Xft/RGBA");
if (subpixOrder == null || subpixOrder.equals("none")) {
aaHint = VALUE_TEXT_ANTIALIAS_ON;
} else if (subpixOrder.equals("rgb")) {
aaHint = VALUE_TEXT_ANTIALIAS_LCD_HRGB;
} else if (subpixOrder.equals("bgr")) {
aaHint = VALUE_TEXT_ANTIALIAS_LCD_HBGR;
} else if (subpixOrder.equals("vrgb")) {
aaHint = VALUE_TEXT_ANTIALIAS_LCD_VRGB;
} else if (subpixOrder.equals("vbgr")) {
aaHint = VALUE_TEXT_ANTIALIAS_LCD_VBGR;
} else {
/* didn't recognise the string, but AA is requested */
aaHint = VALUE_TEXT_ANTIALIAS_ON;
}
} else {
aaHint = VALUE_TEXT_ANTIALIAS_DEFAULT;
}
return new RenderingHints(KEY_TEXT_ANTIALIASING, aaHint);
}
private native boolean gtkCheckVersionImpl(int major, int minor,
int micro);
/**
* Returns {@code true} if the GTK+ library is compatible with the given
* version.
*
* @param major The required major version.
* @param minor The required minor version.
* @param micro The required micro version.
* @return {@code true} if the GTK+ library is compatible with the given
*/
public boolean checkGtkVersion(int major, int minor, int micro) {
if (loadGTK()) {
return gtkCheckVersionImpl(major, minor, micro);
}
return false;
}
}
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.font;
import java.util.Locale;
import sun.awt.SunHints;
import sun.awt.SunToolkit;
import sun.util.logging.PlatformLogger;
/**
* Small utility class to manage FontConfig.
*/
public class FontConfigManager {
static boolean fontConfigFailed = false;
/* This is populated by native */
private static final FontConfigInfo fcInfo = new FontConfigInfo();
/* Begin support for GTK Look and Feel - query libfontconfig and
* return a composite Font to Swing that uses the desktop font(s).
*/
/* These next three classes are just data structures.
*/
public static class FontConfigFont {
public String familyName; // eg Bitstream Vera Sans
public String styleStr; // eg Bold
public String fullName; // eg Bitstream Vera Sans Bold
public String fontFile; // eg /usr/X11/lib/fonts/foo.ttf
}
public static class FcCompFont {
public String fcName; // eg sans
public String fcFamily; // eg sans
public String jdkName; // eg sansserif
public int style; // eg 0=PLAIN
public FontConfigFont firstFont;
public FontConfigFont[] allFonts;
//boolean preferBitmaps; // if embedded bitmaps preferred over AA
public CompositeFont compFont; // null if not yet created/known.
}
public static class FontConfigInfo {
public int fcVersion;
public String[] cacheDirs = new String[4];
}
/* fontconfig recognises slants roman, italic, as well as oblique,
* and a slew of weights, where the ones that matter here are
* regular and bold.
* To fully qualify what we want, we can for example ask for (eg)
* Font.PLAIN : "serif:regular:roman"
* Font.BOLD : "serif:bold:roman"
* Font.ITALIC : "serif:regular:italic"
* Font.BOLD|Font.ITALIC : "serif:bold:italic"
*/
private static String[] fontConfigNames = {
"sans:regular:roman",
"sans:bold:roman",
"sans:regular:italic",
"sans:bold:italic",
"serif:regular:roman",
"serif:bold:roman",
"serif:regular:italic",
"serif:bold:italic",
"monospace:regular:roman",
"monospace:bold:roman",
"monospace:regular:italic",
"monospace:bold:italic",
};
/* This array has the array elements created in Java code and is
* passed down to native to be filled in.
*/
private FcCompFont[] fontConfigFonts;
/**
* Instantiates a new FontConfigManager getting the default instance
* of FontManager from the FontManagerFactory.
*/
public FontConfigManager() {
}
public static String[] getFontConfigNames() {
return fontConfigNames;
}
/* Called from code that needs to know what are the AA settings
* that apps using FC would pick up for the default desktop font.
* Note apps can change the default desktop font. etc, so this
* isn't certain to be right but its going to correct for most cases.
* Native return values map to the text aa values in sun.awt.SunHints.
* which is used to look up the renderinghint value object.
*/
public static Object getFontConfigAAHint() {
return getFontConfigAAHint("sans");
}
/* This is public solely so that for debugging purposes it can be called
* with other names, which might (eg) include a size, eg "sans-24"
* The return value is a text aa rendering hint value.
* Normally we should call the no-args version.
*/
public static Object getFontConfigAAHint(String fcFamily) {
if (FontUtilities.isWindows) {
return null;
} else {
int hint = getFontConfigAASettings(getFCLocaleStr(), fcFamily);
if (hint < 0) {
return null;
} else {
return SunHints.Value.get(SunHints.INTKEY_TEXT_ANTIALIASING,
hint);
}
}
}
private static String getFCLocaleStr() {
Locale l = SunToolkit.getStartupLocale();
String localeStr = l.getLanguage();
String country = l.getCountry();
if (!country.equals("")) {
localeStr = localeStr + "-" + country;
}
return localeStr;
}
/* This does cause the native libfontconfig to be loaded and unloaded,
* but it does not incur the overhead of initialisation of its
* data structures, so shouldn't have a measurable impact.
*/
public static native int getFontConfigVersion();
/* This can be made public if it's needed to force a re-read
* rather than using the cached values. The re-read would be needed
* only if some event signalled that the fontconfig has changed.
* In that event this method would need to return directly the array
* to be used by the caller in case it subsequently changed.
*/
public synchronized void initFontConfigFonts(boolean includeFallbacks) {
if (fontConfigFonts != null) {
if (!includeFallbacks || (fontConfigFonts[0].allFonts != null)) {
return;
}
}
if (FontUtilities.isWindows || fontConfigFailed) {
return;
}
long t0 = 0;
if (FontUtilities.isLogging()) {
t0 = System.nanoTime();
}
String[] fontConfigNames = FontConfigManager.getFontConfigNames();
FcCompFont[] fontArr = new FcCompFont[fontConfigNames.length];
for (int i = 0; i< fontArr.length; i++) {
fontArr[i] = new FcCompFont();
fontArr[i].fcName = fontConfigNames[i];
int colonPos = fontArr[i].fcName.indexOf(':');
fontArr[i].fcFamily = fontArr[i].fcName.substring(0, colonPos);
fontArr[i].jdkName = FontUtilities.mapFcName(fontArr[i].fcFamily);
fontArr[i].style = i % 4; // depends on array order.
}
getFontConfig(getFCLocaleStr(), fcInfo, fontArr, includeFallbacks);
FontConfigFont anyFont = null;
/* If don't find anything (eg no libfontconfig), then just return */
for (int i = 0; i< fontArr.length; i++) {
FcCompFont fci = fontArr[i];
if (fci.firstFont == null) {
if (FontUtilities.isLogging()) {
PlatformLogger logger = FontUtilities.getLogger();
logger.info("Fontconfig returned no font for " +
fontArr[i].fcName);
}
fontConfigFailed = true;
} else if (anyFont == null) {
anyFont = fci.firstFont;
}
}
if (anyFont == null) {
if (FontUtilities.isLogging()) {
PlatformLogger logger = FontUtilities.getLogger();
logger.info("Fontconfig returned no fonts at all.");
}
fontConfigFailed = true;
return;
} else if (fontConfigFailed) {
for (int i = 0; i< fontArr.length; i++) {
if (fontArr[i].firstFont == null) {
fontArr[i].firstFont = anyFont;
}
}
}
fontConfigFonts = fontArr;
if (FontUtilities.isLogging()) {
PlatformLogger logger = FontUtilities.getLogger();
long t1 = System.nanoTime();
logger.info("Time spent accessing fontconfig="
+ ((t1 - t0) / 1000000) + "ms.");
for (int i = 0; i< fontConfigFonts.length; i++) {
FcCompFont fci = fontConfigFonts[i];
logger.info("FC font " + fci.fcName+" maps to family " +
fci.firstFont.familyName +
" in file " + fci.firstFont.fontFile);
if (fci.allFonts != null) {
for (int f=0;f<fci.allFonts.length;f++) {
FontConfigFont fcf = fci.allFonts[f];
logger.info("Family=" + fcf.familyName +
" Style="+ fcf.styleStr +
" Fullname="+fcf.fullName +
" File="+fcf.fontFile);
}
}
}
}
}
public PhysicalFont registerFromFcInfo(FcCompFont fcInfo) {
SunFontManager fm = SunFontManager.getInstance();
/* If it's a TTC file we need to know that as we will need to
* make sure we return the right font */
String fontFile = fcInfo.firstFont.fontFile;
int offset = fontFile.length()-4;
if (offset <= 0) {
return null;
}
String ext = fontFile.substring(offset).toLowerCase();
boolean isTTC = ext.equals(".ttc");
/* If this file is already registered, can just return its font.
* However we do need to check in case it's a TTC as we need
* a specific font, so rather than directly returning it, let
* findFont2D resolve that.
*/
PhysicalFont physFont = fm.getRegisteredFontFile(fontFile);
if (physFont != null) {
if (isTTC) {
Font2D f2d = fm.findFont2D(fcInfo.firstFont.familyName,
fcInfo.style,
FontManager.NO_FALLBACK);
if (f2d instanceof PhysicalFont) { /* paranoia */
return (PhysicalFont)f2d;
} else {
return null;
}
} else {
return physFont;
}
}
/* If the font may hide a JRE font (eg fontconfig says it is
* Lucida Sans), we want to use the JRE version, so make it
* point to the JRE font.
*/
physFont = fm.findJREDeferredFont(fcInfo.firstFont.familyName,
fcInfo.style);
/* It is also possible the font file is on the "deferred" list,
* in which case we can just initialise it now.
*/
if (physFont == null &&
fm.isDeferredFont(fontFile) == true) {
physFont = fm.initialiseDeferredFont(fcInfo.firstFont.fontFile);
/* use findFont2D to get the right font from TTC's */
if (physFont != null) {
if (isTTC) {
Font2D f2d = fm.findFont2D(fcInfo.firstFont.familyName,
fcInfo.style,
FontManager.NO_FALLBACK);
if (f2d instanceof PhysicalFont) { /* paranoia */
return (PhysicalFont)f2d;
} else {
return null;
}
} else {
return physFont;
}
}
}
/* In the majority of cases we reach here, and need to determine
* the type and rank to register the font.
*/
if (physFont == null) {
int fontFormat = SunFontManager.FONTFORMAT_NONE;
int fontRank = Font2D.UNKNOWN_RANK;
if (ext.equals(".ttf") || isTTC) {
fontFormat = SunFontManager.FONTFORMAT_TRUETYPE;
fontRank = Font2D.TTF_RANK;
} else if (ext.equals(".pfa") || ext.equals(".pfb")) {
fontFormat = SunFontManager.FONTFORMAT_TYPE1;
fontRank = Font2D.TYPE1_RANK;
}
physFont = fm.registerFontFile(fcInfo.firstFont.fontFile, null,
fontFormat, true, fontRank);
}
return physFont;
}
/*
* We need to return a Composite font which has as the font in
* its first slot one obtained from fontconfig.
*/
public CompositeFont getFontConfigFont(String name, int style) {
name = name.toLowerCase();
initFontConfigFonts(false);
FcCompFont fcInfo = null;
for (int i=0; i<fontConfigFonts.length; i++) {
if (name.equals(fontConfigFonts[i].fcFamily) &&
style == fontConfigFonts[i].style) {
fcInfo = fontConfigFonts[i];
break;
}
}
if (fcInfo == null) {
fcInfo = fontConfigFonts[0];
}
if (FontUtilities.isLogging()) {
FontUtilities.getLogger()
.info("FC name=" + name + " style=" + style +
" uses " + fcInfo.firstFont.familyName +
" in file: " + fcInfo.firstFont.fontFile);
}
if (fcInfo.compFont != null) {
return fcInfo.compFont;
}
/* jdkFont is going to be used for slots 1..N and as a fallback.
* Slot 0 will be the physical font from fontconfig.
*/
FontManager fm = FontManagerFactory.getInstance();
CompositeFont jdkFont = (CompositeFont)
fm.findFont2D(fcInfo.jdkName, style, FontManager.LOGICAL_FALLBACK);
if (fcInfo.firstFont.familyName == null ||
fcInfo.firstFont.fontFile == null) {
return (fcInfo.compFont = jdkFont);
}
/* First, see if the family and exact style is already registered.
* If it is, use it. If it's not, then try to register it.
* If that registration fails (signalled by null) just return the
* regular JDK composite.
* Algorithmically styled fonts won't match on exact style, so
* will fall through this code, but the regisration code will
* find that file already registered and return its font.
*/
FontFamily family = FontFamily.getFamily(fcInfo.firstFont.familyName);
PhysicalFont physFont = null;
if (family != null) {
Font2D f2D = family.getFontWithExactStyleMatch(fcInfo.style);
if (f2D instanceof PhysicalFont) {
physFont = (PhysicalFont)f2D;
}
}
if (physFont == null ||
!fcInfo.firstFont.fontFile.equals(physFont.platName)) {
physFont = registerFromFcInfo(fcInfo);
if (physFont == null) {
return (fcInfo.compFont = jdkFont);
}
family = FontFamily.getFamily(physFont.getFamilyName(null));
}
/* Now register the fonts in the family (the other styles) after
* checking that they aren't already registered and are actually in
* a different file. They may be the same file in CJK cases.
* For cases where they are different font files - eg as is common for
* Latin fonts, then we rely on fontconfig to report these correctly.
* Assume that all styles of this font are found by fontconfig,
* so we can find all the family members which must be registered
* together to prevent synthetic styling.
*/
for (int i=0; i<fontConfigFonts.length; i++) {
FcCompFont fc = fontConfigFonts[i];
if (fc != fcInfo &&
physFont.getFamilyName(null).equals(fc.firstFont.familyName) &&
!fc.firstFont.fontFile.equals(physFont.platName) &&
family.getFontWithExactStyleMatch(fc.style) == null) {
registerFromFcInfo(fontConfigFonts[i]);
}
}
/* Now we have a physical font. We will back this up with the JDK
* logical font (sansserif, serif, or monospaced) that corresponds
* to the Pango/GTK/FC logical font name.
*/
return (fcInfo.compFont = new CompositeFont(physFont, jdkFont));
}
/**
*
* @param locale
* @param fcFamily
* @return
*/
public FcCompFont[] getFontConfigFonts() {
return fontConfigFonts;
}
/* Return an array of FcCompFont structs describing the primary
* font located for each of fontconfig/GTK/Pango's logical font names.
*/
private static native void getFontConfig(String locale,
FontConfigInfo fcInfo,
FcCompFont[] fonts,
boolean includeFallbacks);
void populateFontConfig(FcCompFont[] fcInfo) {
fontConfigFonts = fcInfo;
}
FcCompFont[] loadFontConfig() {
initFontConfigFonts(true);
return fontConfigFonts;
}
FontConfigInfo getFontConfigInfo() {
initFontConfigFonts(true);
return fcInfo;
}
private static native int
getFontConfigAASettings(String locale, String fcFamily);
}
再次启动,还会出现缺少一个com.sun.tools,这时我们就可以直接导入jdk安装目录上的这个lib文件,里面就有我们缺少的包,这里就不说导入方式了
第四步:
运行时,可能出现卡死的情况,我们可以调大一下设置里面的运行占用
然后调试时,我们会发现这里不会直接进去源码,这里我们需要设置一下
看这下我们就进入我们的源码了
然后我们发现这里是不允许我们做任何操作的,这是因为这里引用的还是原来的jdk自带的源码,它是有权限的,是不允许我们编辑的,这时我们需要去更改一下源码编辑的路径,这里我已经是更改过的了
再次重启我们就可以在这里愉快的添加注释了,是不是很棒
最后:
其实读源码不是说为了装逼,而是为了让自己的技术更加的上一个档次,学的更加扎实牢固,最后也希望大家能够喜欢本次的文章,制作不易,有问题还请多多评论讲解,谢谢啦