1
18 package net.bull.javamelody.internal.web.pdf;
19
20 import java.awt.Color;
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.lang.reflect.Field;
25 import java.util.Locale;
26 import java.util.Properties;
27
28 import com.lowagie.text.DocumentException;
29 import com.lowagie.text.Font;
30 import com.lowagie.text.FontFactory;
31 import com.lowagie.text.pdf.BaseFont;
32
33 import net.bull.javamelody.internal.common.I18N;
34 import net.bull.javamelody.internal.common.InputOutput;
35 import net.bull.javamelody.internal.common.Parameters;
36
37
41 enum PdfFonts {
42 NORMAL(getFont(8f, Font.NORMAL)),
43 BOLD(getFont(8f, Font.BOLD)),
44 PARAGRAPH_TITLE(getFont(10f, Font.BOLD)),
45 TABLE_CELL(getFont(5.5f, Font.NORMAL)),
46 BOLD_CELL(getFont(5.5f, Font.BOLD)),
47 BLUE(getFont(5.5f, Font.NORMAL)),
48 INFO_CELL(getFont(5.5f, Font.NORMAL)),
49 WARNING_CELL(getFont(5.5f, Font.BOLD)),
50 SEVERE_CELL(getFont(5.5f, Font.BOLD)),
51 TABLE_HEADER(getFont(5.5f, Font.BOLD));
52
53 private static final String UKRAINIAN_LANGUAGE = "uk";
54 private static final String CZECH_LANGUAGE = "cs";
55
56 static {
57 BLUE.font.setColor(Color.BLUE);
58 INFO_CELL.font.setColor(Color.GREEN.darker());
59 WARNING_CELL.font.setColor(Color.ORANGE);
60 SEVERE_CELL.font.setColor(Color.RED);
61 }
62
63 private static BaseFont chineseBaseFont;
64 private static BaseFont dejaVuSansBaseFont;
65 private final transient Font font;
66 private transient Font chineseFont;
67 private transient Font dejaVuSansFont;
68
69 PdfFonts(Font font) {
70 this.font = font;
71 }
72
73 Font getFont() {
74 final String language = I18N.getResourceBundle().getLocale().getLanguage();
75 if (Locale.CHINESE.getLanguage().equals(language)) {
76 return getChineseFont();
77 } else if (UKRAINIAN_LANGUAGE.equals(language) || CZECH_LANGUAGE.equals(language)) {
78 return getDejaVuSansFont();
79 }
80 return font;
81 }
82
83 private static Font getFont(float size, int style) {
84 return FontFactory.getFont(FontFactory.HELVETICA, size, style);
85 }
86
87 private Font getChineseFont() {
88 if (chineseFont == null) {
89 final BaseFont bfChinese = getChineseBaseFont();
90 chineseFont = new Font(bfChinese, font.getSize(), font.getStyle());
91 }
92 return chineseFont;
93 }
94
95 private static synchronized BaseFont getChineseBaseFont() {
96 if (chineseBaseFont == null) {
97 try {
98 try {
99 chineseBaseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
100 BaseFont.NOT_EMBEDDED);
101 } catch (final DocumentException e) {
102
103 loadCJKFonts();
104 chineseBaseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
105 BaseFont.NOT_EMBEDDED);
106 }
107 } catch (final DocumentException | IOException e) {
108 throw new IllegalStateException(e);
109 }
110 }
111 return chineseBaseFont;
112 }
113
114
120 private static void loadCJKFonts() {
121 try {
122 final Class<?> cjkFontClass = Class.forName("com.lowagie.text.pdf.CJKFont");
123 final Field cjkFontsField = cjkFontClass.getDeclaredField("cjkFonts");
124 final Field cjkEncodingsField = cjkFontClass.getDeclaredField("cjkEncodings");
125 cjkFontsField.setAccessible(true);
126 cjkEncodingsField.setAccessible(true);
127 final Properties cjkFonts = (Properties) cjkFontsField.get(null);
128 final Properties cjkEncodings = (Properties) cjkEncodingsField.get(null);
129
130 if (cjkFonts.isEmpty()) {
131 try (InputStream is = BaseFont.getResourceStream(
132 BaseFont.RESOURCE_PATH + "cjkfonts.properties.renamedForIssue258")) {
133 cjkFonts.load(is);
134 }
135 }
136 if (cjkEncodings.isEmpty()) {
137 try (InputStream is = BaseFont.getResourceStream(
138 BaseFont.RESOURCE_PATH + "cjkencodings.properties.renamedForIssue258")) {
139 cjkEncodings.load(is);
140 }
141 }
142 } catch (final Exception e) {
143 throw new IllegalStateException(e);
144 }
145 }
146
147 private Font getDejaVuSansFont() {
148 if (dejaVuSansFont == null) {
149 final BaseFont bfDejaVuSans = getDejaVuSansBaseFont();
150 dejaVuSansFont = new Font(bfDejaVuSans, font.getSize(), font.getStyle());
151 }
152 return dejaVuSansFont;
153 }
154
155 private static synchronized BaseFont getDejaVuSansBaseFont() {
156 if (dejaVuSansBaseFont == null) {
157 final InputStream input = PdfFonts.class.getResourceAsStream("/DejaVuSans-Bold.ttf");
158
159 if (input != null) {
160 try {
161 try {
162 final File file = new File(Parameters.TEMPORARY_DIRECTORY,
163 "javamelody-ukrainian.ttf");
164 InputOutput.pumpToFile(input, file);
165 dejaVuSansBaseFont = BaseFont.createFont(file.getPath(),
166 BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
167 } finally {
168 input.close();
169 }
170 } catch (final IOException | DocumentException e) {
171 throw new IllegalStateException(e);
172 }
173 }
174 }
175 return dejaVuSansBaseFont;
176 }
177
178 static boolean shouldUseEnglishInsteadOfUkrainian() {
179 return UKRAINIAN_LANGUAGE.equals(I18N.getResourceBundle().getLocale().getLanguage())
180 && getDejaVuSansBaseFont() == null;
181 }
182 }
183