Java tutorial
/******************************************************************************* * Copyright (c) 2007,2008 Actuate Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Actuate Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.birt.report.engine.layout.pdf.font; import java.util.Collection; import java.util.LinkedHashSet; import com.lowagie.text.Font; import com.lowagie.text.pdf.BaseFont; /** * * The composite font is defined by multiple physical fonts. * <p> * Each font can be used to display different character. The physical fonts are * owned by different catalogs. The catalogs defines the search sequence of * those fonts. * <p> * The composite font can be full indexed. The full indexed means the char * segments describes all the character in the font, so it is no need to call * each font's charExits() to see if it can display a character. It always has * more better performance. */ public class CompositeFont { CompositeFontConfig config; CompositeFont parent; /** * the internal fonts used by this composite font, the order is the prefer * order */ String[] usedFonts; /** * if the composite font is full indexed. */ boolean fullIndexed; CharSegment[] specialCharacters; /** * the index for internal fonts, in the same order with usedFonts */ CharSegment[][] fontsIndex; /** * base fonts used to test if the char exits, in the same order with * usedFonts */ BaseFont[] baseFonts; /** * index of all the chars in the composite font. It is only used when * fullIndexed. */ CharSegment[] fullIndex; public CompositeFont(FontMappingManager manager, CompositeFontConfig config, String[] sequence) { FontMappingManager parentManager = manager.getParent(); if (parentManager != null) { this.parent = parentManager.getCompositeFont(config.fontName); } this.config = config; this.specialCharacters = config.getSpecialCharacters(); // create the fonts follows the sequence LinkedHashSet fonts = new LinkedHashSet(); if (sequence != null) { for (int i = 0; i < sequence.length; i++) { Collection catalogFonts = config.getFontByCatalog(sequence[i]); if (catalogFonts != null) { fonts.addAll(catalogFonts); } } } fonts.addAll(config.getAllFonts()); usedFonts = (String[]) fonts.toArray(new String[] {}); fullIndexed = true; fontsIndex = new CharSegment[usedFonts.length][]; for (int i = 0; i < usedFonts.length; i++) { fontsIndex[i] = config.getCharSegment(usedFonts[i]); if (fontsIndex[i] == null) { fullIndexed = false; } } if (fullIndexed) { fullIndex = CharSegment.merge(fontsIndex); } else { baseFonts = new BaseFont[usedFonts.length]; for (int i = 0; i < baseFonts.length; i++) { baseFonts[i] = manager.createFont(usedFonts[i], Font.NORMAL); } } } public String getFontName() { return config.fontName; } public String getDefaultFont() { if (config.defaultFont != null) { return config.defaultFont; } if (parent != null) { return parent.getDefaultFont(); } return null; } public String getUsedFont(char ch) { String usedFont = findUsedFont(ch); if (usedFont != null) { return usedFont; } return getDefaultFont(); } protected String findUsedFont(char ch) { if (specialCharacters != null) { int index = CharSegment.search(specialCharacters, ch); if (index != -1) { return specialCharacters[index].name; } } if (fullIndexed) { int index = CharSegment.search(fullIndex, ch); if (index != -1) { return fullIndex[index].name; } } else { // search one by one for (int i = 0; i < usedFonts.length; i++) { if (fontsIndex[i] != null) { if (CharSegment.search(fontsIndex[i], ch) != -1) { return usedFonts[i]; } } else { if (baseFonts[i] != null) { if (baseFonts[i].charExists(ch)) { return usedFonts[i]; } } } } } if (parent != null) { return parent.getUsedFont(ch); } return null; } }