1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "nsFont.h"
39 : #include "nsString.h"
40 : #include "nsUnicharUtils.h"
41 : #include "nsCRT.h"
42 :
43 0 : nsFont::nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant,
44 : PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration,
45 : nscoord aSize, float aSizeAdjust,
46 : const nsString* aFeatureSettings,
47 0 : const nsString* aLanguageOverride)
48 : {
49 0 : NS_ASSERTION(aName && IsASCII(nsDependentCString(aName)),
50 : "Must only pass ASCII names here");
51 0 : name.AssignASCII(aName);
52 0 : style = aStyle;
53 0 : systemFont = false;
54 0 : variant = aVariant;
55 0 : weight = aWeight;
56 0 : stretch = aStretch;
57 0 : decorations = aDecoration;
58 0 : size = aSize;
59 0 : sizeAdjust = aSizeAdjust;
60 0 : if (aFeatureSettings) {
61 0 : featureSettings = *aFeatureSettings;
62 : }
63 0 : if (aLanguageOverride) {
64 0 : languageOverride = *aLanguageOverride;
65 : }
66 0 : }
67 :
68 0 : nsFont::nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant,
69 : PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration,
70 : nscoord aSize, float aSizeAdjust,
71 : const nsString* aFeatureSettings,
72 : const nsString* aLanguageOverride)
73 0 : : name(aName)
74 : {
75 0 : style = aStyle;
76 0 : systemFont = false;
77 0 : variant = aVariant;
78 0 : weight = aWeight;
79 0 : stretch = aStretch;
80 0 : decorations = aDecoration;
81 0 : size = aSize;
82 0 : sizeAdjust = aSizeAdjust;
83 0 : if (aFeatureSettings) {
84 0 : featureSettings = *aFeatureSettings;
85 : }
86 0 : if (aLanguageOverride) {
87 0 : languageOverride = *aLanguageOverride;
88 : }
89 0 : }
90 :
91 0 : nsFont::nsFont(const nsFont& aOther)
92 0 : : name(aOther.name)
93 : {
94 0 : style = aOther.style;
95 0 : systemFont = aOther.systemFont;
96 0 : variant = aOther.variant;
97 0 : weight = aOther.weight;
98 0 : stretch = aOther.stretch;
99 0 : decorations = aOther.decorations;
100 0 : size = aOther.size;
101 0 : sizeAdjust = aOther.sizeAdjust;
102 0 : featureSettings = aOther.featureSettings;
103 0 : languageOverride = aOther.languageOverride;
104 0 : }
105 :
106 0 : nsFont::nsFont()
107 : {
108 0 : }
109 :
110 0 : nsFont::~nsFont()
111 : {
112 0 : }
113 :
114 0 : bool nsFont::BaseEquals(const nsFont& aOther) const
115 : {
116 0 : if ((style == aOther.style) &&
117 : (systemFont == aOther.systemFont) &&
118 : (weight == aOther.weight) &&
119 : (stretch == aOther.stretch) &&
120 : (size == aOther.size) &&
121 : (sizeAdjust == aOther.sizeAdjust) &&
122 0 : name.Equals(aOther.name, nsCaseInsensitiveStringComparator()) &&
123 0 : (featureSettings == aOther.featureSettings) &&
124 0 : (languageOverride == aOther.languageOverride)) {
125 0 : return true;
126 : }
127 0 : return false;
128 : }
129 :
130 0 : bool nsFont::Equals(const nsFont& aOther) const
131 : {
132 0 : if (BaseEquals(aOther) &&
133 : (variant == aOther.variant) &&
134 : (decorations == aOther.decorations)) {
135 0 : return true;
136 : }
137 0 : return false;
138 : }
139 :
140 0 : nsFont& nsFont::operator=(const nsFont& aOther)
141 : {
142 0 : name = aOther.name;
143 0 : style = aOther.style;
144 0 : systemFont = aOther.systemFont;
145 0 : variant = aOther.variant;
146 0 : weight = aOther.weight;
147 0 : stretch = aOther.stretch;
148 0 : decorations = aOther.decorations;
149 0 : size = aOther.size;
150 0 : sizeAdjust = aOther.sizeAdjust;
151 0 : featureSettings = aOther.featureSettings;
152 0 : languageOverride = aOther.languageOverride;
153 0 : return *this;
154 : }
155 :
156 0 : static bool IsGenericFontFamily(const nsString& aFamily)
157 : {
158 : PRUint8 generic;
159 0 : nsFont::GetGenericID(aFamily, &generic);
160 0 : return generic != kGenericFont_NONE;
161 : }
162 :
163 : const PRUnichar kNullCh = PRUnichar('\0');
164 : const PRUnichar kSingleQuote = PRUnichar('\'');
165 : const PRUnichar kDoubleQuote = PRUnichar('\"');
166 : const PRUnichar kComma = PRUnichar(',');
167 :
168 0 : bool nsFont::EnumerateFamilies(nsFontFamilyEnumFunc aFunc, void* aData) const
169 : {
170 : const PRUnichar *p, *p_end;
171 0 : name.BeginReading(p);
172 0 : name.EndReading(p_end);
173 0 : nsAutoString family;
174 :
175 0 : while (p < p_end) {
176 0 : while (nsCRT::IsAsciiSpace(*p))
177 0 : if (++p == p_end)
178 0 : return true;
179 :
180 : bool generic;
181 0 : if (*p == kSingleQuote || *p == kDoubleQuote) {
182 : // quoted font family
183 0 : PRUnichar quoteMark = *p;
184 0 : if (++p == p_end)
185 0 : return true;
186 0 : const PRUnichar *nameStart = p;
187 :
188 : // XXX What about CSS character escapes?
189 0 : while (*p != quoteMark)
190 0 : if (++p == p_end)
191 0 : return true;
192 :
193 0 : family = Substring(nameStart, p);
194 0 : generic = false;
195 :
196 0 : while (++p != p_end && *p != kComma)
197 0 : /* nothing */ ;
198 :
199 : } else {
200 : // unquoted font family
201 0 : const PRUnichar *nameStart = p;
202 0 : while (++p != p_end && *p != kComma)
203 : /* nothing */ ;
204 :
205 0 : family = Substring(nameStart, p);
206 0 : family.CompressWhitespace(false, true);
207 0 : generic = IsGenericFontFamily(family);
208 : }
209 :
210 0 : if (!family.IsEmpty() && !(*aFunc)(family, generic, aData))
211 0 : return false;
212 :
213 0 : ++p; // may advance past p_end
214 : }
215 :
216 0 : return true;
217 : }
218 :
219 0 : static bool FontEnumCallback(const nsString& aFamily, bool aGeneric, void *aData)
220 : {
221 0 : *((nsString*)aData) = aFamily;
222 0 : return false;
223 : }
224 :
225 0 : void nsFont::GetFirstFamily(nsString& aFamily) const
226 : {
227 0 : EnumerateFamilies(FontEnumCallback, &aFamily);
228 0 : }
229 :
230 : /*static*/
231 0 : void nsFont::GetGenericID(const nsString& aGeneric, PRUint8* aID)
232 : {
233 0 : *aID = kGenericFont_NONE;
234 0 : if (aGeneric.LowerCaseEqualsLiteral("-moz-fixed")) *aID = kGenericFont_moz_fixed;
235 0 : else if (aGeneric.LowerCaseEqualsLiteral("serif")) *aID = kGenericFont_serif;
236 0 : else if (aGeneric.LowerCaseEqualsLiteral("sans-serif")) *aID = kGenericFont_sans_serif;
237 0 : else if (aGeneric.LowerCaseEqualsLiteral("cursive")) *aID = kGenericFont_cursive;
238 0 : else if (aGeneric.LowerCaseEqualsLiteral("fantasy")) *aID = kGenericFont_fantasy;
239 0 : else if (aGeneric.LowerCaseEqualsLiteral("monospace")) *aID = kGenericFont_monospace;
240 0 : }
|