~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to substance/src/main/java/org/pushingpixels/substance/internal/fonts/DefaultKDEFontPolicy.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 *  o Redistributions of source code must retain the above copyright notice,
 
8
 *    this list of conditions and the following disclaimer.
 
9
 *
 
10
 *  o Redistributions in binary form must reproduce the above copyright notice,
 
11
 *    this list of conditions and the following disclaimer in the documentation
 
12
 *    and/or other materials provided with the distribution.
 
13
 *
 
14
 *  o Neither the name of Substance Kirill Grouchnikov nor the names of
 
15
 *    its contributors may be used to endorse or promote products derived
 
16
 *    from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
20
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
21
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
25
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
26
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 
27
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
package org.pushingpixels.substance.internal.fonts;
 
31
 
 
32
import java.awt.Font;
 
33
import java.io.*;
 
34
import java.util.regex.Pattern;
 
35
 
 
36
import javax.swing.UIDefaults;
 
37
 
 
38
import org.pushingpixels.substance.api.fonts.FontPolicy;
 
39
import org.pushingpixels.substance.api.fonts.FontSet;
 
40
 
 
41
/**
 
42
 * The default font policy for KDE desktops.
 
43
 * 
 
44
 * @author <a href="mailto:paranoid.tiberiumlabs@gmail.com">Paranoid</a>
 
45
 */
 
46
public class DefaultKDEFontPolicy implements FontPolicy {
 
47
 
 
48
        /**
 
49
         * method to check if current user session is KDE
 
50
         * 
 
51
         * @return true
 
52
     * if KDE session is currently running.
 
53
         */
 
54
        public static boolean isKDERunning() {
 
55
                // KDE_FULL_SESSION=true
 
56
                return "true".equals(System.getenv("KDE_FULL_SESSION"));
 
57
        }
 
58
 
 
59
        /**
 
60
         * Checks for KDE4 flags in current env. There are few possible flags:<br/>
 
61
         * {@code KDE_SESSION_VERSION=4<br/> DESKTOP_SESSION=kde4<br/>} If distro
 
62
         * for some readon don't set this flags - KDE3 is possibli
 
63
         * running.<br/><br/>
 
64
         * 
 
65
         * There is one more way to determine current KDE version. We can run
 
66
         * {@code "konsole --version"} command and parse output, but KDE3 don't have
 
67
         * own env flags, so this command will run every time we using KDE3.
 
68
         * 
 
69
         * @return {@code true} if KDE4 env flags found, {@code false} otherwise.
 
70
         */
 
71
        private static boolean isKDE4Running() {
 
72
                if (!isKDERunning()) {
 
73
                        throw new IllegalStateException("KDE is not running");
 
74
                }
 
75
                return "4".equals(System.getenv("KDE_SESSION_VERSION"))
 
76
                                || "kde4".equals(System.getenv("DESKTOP_SESSION"));
 
77
        }
 
78
 
 
79
        private static final String SANS_SERIF = "SansSerif";
 
80
        private static FontSet fontSet = null;
 
81
 
 
82
        @Override
 
83
    public synchronized FontSet getFontSet(String lafName, UIDefaults table) {
 
84
                if (fontSet == null) {
 
85
                        fontSet = getInternalFontSet(lafName, table);
 
86
                }
 
87
                return fontSet;
 
88
        }
 
89
 
 
90
        private FontSet getInternalFontSet(String lafName, UIDefaults table) {
 
91
 
 
92
                // size is the most important, then family and then style
 
93
                int commonSize = 10;
 
94
                int menuSize = 10;
 
95
                int titleSize = 10;
 
96
                int commonStyle = Font.PLAIN;
 
97
                int menuStyle = Font.PLAIN;
 
98
                int titleStyle = Font.BOLD;
 
99
                String commonFamily = SANS_SERIF;
 
100
                String menuFamily = SANS_SERIF;
 
101
                String titleFamily = SANS_SERIF;
 
102
 
 
103
                // size is the most important, then family and then style
 
104
 
 
105
                /*
 
106
                 * KDE4 can set common, menu, small and window title, while KDE3 can set
 
107
                 * only common, menu and window title. But in KDE4 config files small
 
108
                 * font is named "smallestReadableFont"
 
109
                 */
 
110
 
 
111
                // <editor-fold defaultstate="collapsed" desc=" reading fonts ">
 
112
                try {
 
113
 
 
114
                        String kdeglobals = getFileContent("kdeglobals");
 
115
 
 
116
                        Pattern pattern = Pattern.compile(",");
 
117
 
 
118
                        try {
 
119
 
 
120
                                String fontParam = getIniParam(kdeglobals, "[General]", "font");
 
121
                                String[] fontParams = pattern.split(fontParam);
 
122
                                commonFamily = fontParams[0];
 
123
                                commonSize = Integer.parseInt(fontParams[1]);
 
124
                                boolean bold = "75".equals(fontParams[4]);
 
125
                                boolean italic = "1".equals(fontParams[5]);
 
126
                                if (bold && italic) {
 
127
                                        commonStyle = Font.BOLD + Font.ITALIC;
 
128
                                } else if (italic) {
 
129
                                        commonStyle = Font.ITALIC;
 
130
                                } else if (bold) {
 
131
                                        commonStyle = Font.BOLD;
 
132
                                } else {
 
133
                                        commonStyle = Font.PLAIN;
 
134
                                }
 
135
 
 
136
                        } catch (Exception commonReadException) {
 
137
                                commonFamily = SANS_SERIF;
 
138
                                commonSize = 10;
 
139
                                commonStyle = Font.PLAIN;
 
140
                        }
 
141
 
 
142
                        try {
 
143
 
 
144
                                String menuFontParam = getIniParam(kdeglobals, "[General]",
 
145
                                                "menuFont");
 
146
                                String[] menuFontParams = pattern.split(menuFontParam);
 
147
                                menuFamily = menuFontParams[0];
 
148
                                menuSize = Integer.parseInt(menuFontParams[1]);
 
149
                                boolean bold = "75".equals(menuFontParams[4]);
 
150
                                boolean italic = "1".equals(menuFontParams[5]);
 
151
                                if (bold && italic) {
 
152
                                        menuStyle = Font.BOLD + Font.ITALIC;
 
153
                                } else if (italic) {
 
154
                                        menuStyle = Font.ITALIC;
 
155
                                } else if (bold) {
 
156
                                        menuStyle = Font.BOLD;
 
157
                                } else {
 
158
                                        menuStyle = Font.PLAIN;
 
159
                                }
 
160
 
 
161
                        } catch (Exception menuReadException) {
 
162
                                menuFamily = SANS_SERIF;
 
163
                                menuSize = 10;
 
164
                                menuStyle = Font.PLAIN;
 
165
                        }
 
166
 
 
167
                        try {
 
168
 
 
169
                                String activeFontParam = getIniParam(kdeglobals, "[WM]",
 
170
                                                "activeFont");
 
171
                                String[] activeFontParams = pattern.split(activeFontParam);
 
172
                                titleFamily = activeFontParams[0];
 
173
                                titleSize = Integer.parseInt(activeFontParams[1]);
 
174
                                boolean bold = "75".equals(activeFontParams[4]);
 
175
                                boolean italic = "1".equals(activeFontParams[5]);
 
176
                                if (bold && italic) {
 
177
                                        titleStyle = Font.BOLD + Font.ITALIC;
 
178
                                } else if (italic) {
 
179
                                        titleStyle = Font.ITALIC;
 
180
                                } else if (bold) {
 
181
                                        titleStyle = Font.BOLD;
 
182
                                } else {
 
183
                                        titleStyle = Font.PLAIN;
 
184
                                }
 
185
 
 
186
                        } catch (Exception titleReadException) {
 
187
                                titleFamily = SANS_SERIF;
 
188
                                titleSize = 10;
 
189
                                titleStyle = Font.BOLD;
 
190
                        }
 
191
 
 
192
                } catch (Exception kdeglobalsReadException) {
 
193
 
 
194
                        commonFamily = SANS_SERIF;
 
195
                        commonSize = 10;
 
196
                        commonStyle = Font.PLAIN;
 
197
 
 
198
                        menuFamily = SANS_SERIF;
 
199
                        menuSize = 10;
 
200
                        menuStyle = Font.PLAIN;
 
201
 
 
202
                        titleFamily = SANS_SERIF;
 
203
                        titleSize = 10;
 
204
                        titleStyle = Font.BOLD;
 
205
 
 
206
                }
 
207
 
 
208
                // </editor-fold>
 
209
 
 
210
                // <editor-fold defaultstate="collapsed" desc=" dpi settings ">
 
211
 
 
212
                double dcommonSize = commonSize;
 
213
                double dmenuSize = menuSize;
 
214
                double dtitleSize = titleSize;
 
215
 
 
216
                int dpi;
 
217
                try {
 
218
                        String dpiParam = getIniParam(getFileContent("kcmfonts"),
 
219
                                        "[General]", "forceFontDPI");
 
220
                        dpi = Integer.parseInt(dpiParam);
 
221
                } catch (Exception dpiReadException) {
 
222
                        dpi = 96;
 
223
                }
 
224
                // kcmfonts common for both KDE3 and KDE4
 
225
                if (dpi <= 0) {
 
226
                        dpi = 96;
 
227
                }
 
228
                if (dpi < 50) {
 
229
                        dpi = 50;
 
230
                }
 
231
                dcommonSize = ((commonSize * dpi) / 72.0);
 
232
                dmenuSize = ((menuSize * dpi) / 72.0);
 
233
                dtitleSize = ((titleSize * dpi) / 72.0);
 
234
 
 
235
                commonSize = (int) (dcommonSize + 0.5);
 
236
                if (commonSize < 1) {
 
237
                        commonSize = 1;
 
238
                }
 
239
 
 
240
                menuSize = (int) (dmenuSize + 0.5);
 
241
                if (menuSize < 1) {
 
242
                        menuSize = 1;
 
243
                }
 
244
 
 
245
                titleSize = (int) (dtitleSize + 0.5);
 
246
                if (titleSize < 1) {
 
247
                        titleSize = 1;
 
248
                }
 
249
 
 
250
                // </editor-fold>
 
251
 
 
252
                Font commonFont = new Font(commonFamily, commonStyle, commonSize);
 
253
                Font menuFont = new Font(menuFamily, menuStyle, menuSize);
 
254
                Font titleFont = new Font(titleFamily, titleStyle, titleSize);
 
255
 
 
256
                return FontSets.createDefaultFontSet(commonFont, menuFont, commonFont,
 
257
                                commonFont, commonFont, titleFont);
 
258
        }
 
259
 
 
260
        private String getIniParam(String content, String category, String param)
 
261
                        throws Exception {
 
262
                // checking if our param in our category - we don't need same params
 
263
                // from other categories
 
264
                int categoryIndex = content.indexOf(category);
 
265
                
 
266
                // fix for defect 483 - https://substance.dev.java.net/issues/show_bug.cgi?id=483
 
267
                // lineSeparator + 
 
268
                String lineSeparator = System.getProperty("line.separator");// JDK7: System.lineSeparator()
 
269
                int nextCategoryIndex = content.indexOf(lineSeparator + '[', categoryIndex + 1);
 
270
                
 
271
                if (nextCategoryIndex < 0) {
 
272
                        nextCategoryIndex = content.length();
 
273
                }
 
274
                int paramIndex = content.indexOf(param, categoryIndex);
 
275
                if (paramIndex >= 0 && paramIndex < nextCategoryIndex) {
 
276
 
 
277
                        // now paramString contains full string of our parameter
 
278
                        int lineEnd = content.indexOf(lineSeparator,
 
279
                                        paramIndex);
 
280
                        if (lineEnd <= 0) {
 
281
                                lineEnd = content.length();
 
282
                        }
 
283
                        String paramString = content.substring(paramIndex, lineEnd);
 
284
 
 
285
                        // getting just our value, we don't need other symbols
 
286
                        int equalityIndex = paramString.indexOf('=');
 
287
                        /*
 
288
                         * paramString.indexOf('#'); paramString.indexOf(';');
 
289
                         * 
 
290
                         * don't know do we need to remove trailing comments after this
 
291
                         * symbols? have nothing similar in my system...
 
292
                         */
 
293
                        String result = paramString.substring(equalityIndex + 1).trim();
 
294
                        if (result.length() > 0) {
 
295
                                return result;
 
296
                        }
 
297
                }
 
298
                throw new Exception("No such param in current category");
 
299
        }
 
300
 
 
301
        private String getFileContent(String fileName) throws IOException {
 
302
 
 
303
                /*
 
304
                 * preparing KDE home folder. KDE4 may be stored in .kde4 folder, and
 
305
                 * may be in .kde.
 
306
                 * 
 
307
                 * we check for .kde4 folder, if it exists - we will use it. Otherwise
 
308
                 * we will left kdeHome empty, and it will be set to .kde in both cases
 
309
                 * of KDE3 and KDE4 with .kde folder.
 
310
                 */
 
311
                String userHome = System.getProperty("user.home");
 
312
                String kdeHome = null;
 
313
                if (isKDE4Running()) {
 
314
                        File kdeHomeFolder = new File(userHome, ".kde4");
 
315
                        if (kdeHomeFolder.exists()) {
 
316
                                kdeHome = ".kde4";
 
317
                        }
 
318
                }
 
319
                if (kdeHome == null) {
 
320
                        kdeHome = ".kde";
 
321
                }
 
322
 
 
323
                char fs = File.separatorChar;
 
324
                fileName = userHome + fs + kdeHome + "/share/config/" + fileName;
 
325
                if (fs != '/') {
 
326
                        fileName = fileName.replace('/', fs);
 
327
                }
 
328
 
 
329
                // creating file from user home, using system's file separator:
 
330
                BufferedReader in = new BufferedReader(new FileReader(fileName));
 
331
                StringBuilder sb = new StringBuilder();
 
332
                // size same as inside BufferedReader code
 
333
                char[] buffer = new char[8192];
 
334
                int read = 0;
 
335
                while ((read = in.read(buffer)) >= 0) {
 
336
                        sb.append(buffer, 0, read);
 
337
                }
 
338
                in.close();
 
339
 
 
340
                return sb.toString();
 
341
        }
 
342
 
 
343
}