Bug 458861. Validate TrueType headers before activating downloaded font. r=roc, sr...
[wine-gecko.git] / gfx / src / thebes / nsSystemFontsOS2.cpp
blob2d1aad853fe7f19f0496cbf98095be286bd9317e
1 /* vim: set sw=4 sts=4 et cin: */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is OS/2 system font code in Thebes.
17 * The Initial Developer of the Original Code is
18 * Peter Weilbacher <mozilla@Weilbacher.org>.
19 * Portions created by the Initial Developer are Copyright (C) 2006
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Developers of code taken from nsDeviceContextOS2:
24 * John Fairhurst, <john_fairhurst@iname.com>
25 * Henry Sobotka <sobotka@axess.com>
26 * IBM Corp.
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #include "nsIDeviceContext.h"
43 #include "nsSystemFontsOS2.h"
44 #include <stdlib.h>
46 /************************
47 * Helper functions *
48 ************************/
49 static BOOL bIsDBCS;
50 static BOOL bIsDBCSSet = FALSE;
52 /* Helper function to determine if we are running on DBCS */
53 BOOL IsDBCS()
55 if (!bIsDBCSSet) {
56 // the following lines of code determine whether the system is a DBCS country
57 APIRET rc;
58 COUNTRYCODE ctrycodeInfo = {0};
59 CHAR achDBCSInfo[12] = {0}; // DBCS environmental vector
60 ctrycodeInfo.country = 0; // current country
61 ctrycodeInfo.codepage = 0; // current codepage
63 rc = DosQueryDBCSEnv(sizeof(achDBCSInfo), &ctrycodeInfo, achDBCSInfo);
64 if (rc == NO_ERROR) {
65 // Non-DBCS countries will have four bytes in the first four bytes of the
66 // DBCS environmental vector
67 if (achDBCSInfo[0] != 0 || achDBCSInfo[1] != 0 ||
68 achDBCSInfo[2] != 0 || achDBCSInfo[3] != 0)
70 bIsDBCS = TRUE;
71 } else {
72 bIsDBCS = FALSE;
74 } else {
75 bIsDBCS = FALSE;
76 } /* endif */
77 bIsDBCSSet = TRUE;
78 } /* endif */
79 return bIsDBCS;
82 /* Helper function to query font from INI file */
83 void QueryFontFromINI(char* fontType, char* fontName, ULONG ulLength)
85 ULONG ulMaxNameL = ulLength;
87 /* We had to switch to using PrfQueryProfileData because */
88 /* some users have binary font data in their INI files */
89 BOOL rc = PrfQueryProfileData(HINI_USER, "PM_SystemFonts", fontType,
90 fontName, &ulMaxNameL);
91 /* If there was no entry in the INI, default to something */
92 if (rc == FALSE) {
93 /* Different values for DBCS vs. SBCS */
94 /* WarpSans is only available on Warp 4, we exclude Warp 3 now */
95 if (!IsDBCS()) {
96 strcpy(fontName, "9.WarpSans");
97 } else {
98 strcpy(fontName, "9.WarpSans Combined");
100 } else {
101 /* null terminate fontname */
102 fontName[ulMaxNameL] = '\0';
106 /************************/
108 nsSystemFontsOS2::nsSystemFontsOS2()
110 #ifdef DEBUG_thebes
111 printf("nsSystemFontsOS2::nsSystemFontsOS2()\n");
112 #endif
116 * Query the font used for various CSS properties (aID) from the system.
117 * For OS/2, only very few fonts are defined in the system, so most of the IDs
118 * resolve to the same system font.
119 * The font queried will give back a string like
120 * 9.WarpSans Bold
121 * 12.Times New Roman Bold Italic
122 * 10.Times New Roman.Strikeout.Underline
123 * 20.Bitstream Vera Sans Mono Obli
124 * (always restricted to 32 chars, at least before the second dot)
125 * We use the value before the dot as the font size (in pt, and convert it to
126 * px using the screen resolution) and then try to use the rest of the string
127 * to determine the font style from it.
129 nsresult nsSystemFontsOS2::GetSystemFont(nsSystemFontID aID, nsString* aFontName,
130 gfxFontStyle *aFontStyle) const
132 #ifdef DEBUG_thebes
133 printf("nsSystemFontsOS2::GetSystemFont: ");
134 #endif
135 char szFontNameSize[MAXNAMEL];
137 switch (aID)
139 case eSystemFont_Icon:
140 QueryFontFromINI("IconText", szFontNameSize, MAXNAMEL);
141 #ifdef DEBUG_thebes
142 printf("IconText ");
143 #endif
144 break;
146 case eSystemFont_Menu:
147 QueryFontFromINI("Menus", szFontNameSize, MAXNAMEL);
148 #ifdef DEBUG_thebes
149 printf("Menus ");
150 #endif
151 break;
153 case eSystemFont_Caption:
154 case eSystemFont_MessageBox:
155 case eSystemFont_SmallCaption:
156 case eSystemFont_StatusBar:
157 case eSystemFont_Tooltips:
158 case eSystemFont_Widget:
160 case eSystemFont_Window: // css3
161 case eSystemFont_Document:
162 case eSystemFont_Workspace:
163 case eSystemFont_Desktop:
164 case eSystemFont_Info:
165 case eSystemFont_Dialog:
166 case eSystemFont_Button:
167 case eSystemFont_PullDownMenu:
168 case eSystemFont_List:
169 case eSystemFont_Field:
170 QueryFontFromINI("WindowText", szFontNameSize, MAXNAMEL);
171 #ifdef DEBUG_thebes
172 printf("WindowText ");
173 #endif
174 break;
176 default:
177 NS_WARNING("None of the listed font types, using WarpSans");
178 if (!IsDBCS()) {
179 strcpy(szFontNameSize, "9.WarpSans");
180 } else {
181 strcpy(szFontNameSize, "9.WarpSans Combined");
183 } // switch
184 #ifdef DEBUG_thebes
185 printf(" (%s)\n", szFontNameSize);
186 #endif
188 char *szFacename = strchr(szFontNameSize, '.');
189 if (!szFacename || (*(szFacename++) == '\0'))
190 return NS_ERROR_FAILURE;
192 // local DPI for size will be taken into account below
193 aFontStyle->size = atof(szFontNameSize);
195 // determine DPI resolution of screen device to compare compute
196 // font size in pixels
197 HPS ps = WinGetScreenPS(HWND_DESKTOP);
198 HDC dc = GpiQueryDevice(ps);
199 // effective vertical resolution in DPI
200 LONG vertScreenRes = 120; // assume 120 dpi as default
201 DevQueryCaps(dc, CAPS_VERTICAL_FONT_RES, 1, &vertScreenRes);
202 WinReleasePS(ps);
204 // now scale to make pixels from points (1 pt = 1/72in)
205 aFontStyle->size *= vertScreenRes / 72.0;
207 NS_ConvertUTF8toUTF16 fontFace(szFacename);
208 int pos = 0;
210 // this is a system font in any case
211 aFontStyle->systemFont = PR_TRUE;
213 // bold fonts should have " Bold" in their names, at least we hope that they
214 // do, otherwise it's bad luck
215 NS_NAMED_LITERAL_CSTRING(spcBold, " Bold");
216 if ((pos = fontFace.Find(spcBold.get(), PR_FALSE, 0, -1)) > -1) {
217 aFontStyle->weight = FONT_WEIGHT_BOLD;
218 // strip the attribute, now that we have set it in the gfxFontStyle
219 fontFace.Cut(pos, spcBold.Length());
220 } else {
221 aFontStyle->weight = FONT_WEIGHT_NORMAL;
224 // similar hopes for italic and oblique fonts...
225 NS_NAMED_LITERAL_CSTRING(spcItalic, " Italic");
226 NS_NAMED_LITERAL_CSTRING(spcOblique, " Oblique");
227 NS_NAMED_LITERAL_CSTRING(spcObli, " Obli");
228 if ((pos = fontFace.Find(spcItalic.get(), PR_FALSE, 0, -1)) > -1) {
229 aFontStyle->style = FONT_STYLE_ITALIC;
230 fontFace.Cut(pos, spcItalic.Length());
231 } else if ((pos = fontFace.Find(spcOblique.get(), PR_FALSE, 0, -1)) > -1) {
232 // oblique fonts are rare on OS/2 and not specially supported by
233 // the GPI system, but at least we are trying...
234 aFontStyle->style = FONT_STYLE_OBLIQUE;
235 fontFace.Cut(pos, spcOblique.Length());
236 } else if ((pos = fontFace.Find(spcObli.get(), PR_FALSE, 0, -1)) > -1) {
237 // especially oblique often gets cut by the 32 char limit to "Obli",
238 // so search for that, too (anything shorter would be ambiguous)
239 aFontStyle->style = FONT_STYLE_OBLIQUE;
240 // In this case, assume that this is the last property in the line
241 // and cut off everything else, too
242 // This is needed in case it was really Obliq or Obliqu...
243 fontFace.Cut(pos, fontFace.Length());
244 } else {
245 aFontStyle->style = FONT_STYLE_NORMAL;
248 // just throw away any modifiers that are separated by dots (which are either
249 // .Strikeout, .Underline, or .Outline, none of which have a corresponding
250 // gfxFont property)
251 if ((pos = fontFace.Find(".", PR_FALSE, 0, -1)) > -1) {
252 fontFace.Cut(pos, fontFace.Length());
255 #ifdef DEBUG_thebes
256 printf(" after=%s\n", NS_LossyConvertUTF16toASCII(fontFace).get());
257 printf(" style: %s %s %s\n",
258 (aFontStyle->weight == FONT_WEIGHT_BOLD) ? "BOLD" : "",
259 (aFontStyle->style == FONT_STYLE_ITALIC) ? "ITALIC" : "",
260 (aFontStyle->style == FONT_STYLE_OBLIQUE) ? "OBLIQUE" : "");
261 #endif
262 NS_NAMED_LITERAL_STRING(quote, "\""); // seems like we need quotes around the font name
263 *aFontName = quote + fontFace + quote;
265 return NS_OK;