2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include "nsFont.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsUnicharUtils.h"
|
|
|
|
#include "nsCRT.h"
|
2012-04-25 23:22:24 -07:00
|
|
|
#include "gfxFont.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsFont::nsFont(const char* aName, PRUint8 aStyle, PRUint8 aVariant,
|
2009-01-29 12:39:18 -08:00
|
|
|
PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration,
|
2010-07-13 13:30:42 -07:00
|
|
|
nscoord aSize, float aSizeAdjust,
|
|
|
|
const nsString* aLanguageOverride)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ASSERTION(aName && IsASCII(nsDependentCString(aName)),
|
|
|
|
"Must only pass ASCII names here");
|
|
|
|
name.AssignASCII(aName);
|
|
|
|
style = aStyle;
|
2011-10-17 07:59:28 -07:00
|
|
|
systemFont = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
variant = aVariant;
|
|
|
|
weight = aWeight;
|
2009-01-29 12:39:18 -08:00
|
|
|
stretch = aStretch;
|
2007-03-22 10:30:00 -07:00
|
|
|
decorations = aDecoration;
|
|
|
|
size = aSize;
|
|
|
|
sizeAdjust = aSizeAdjust;
|
2010-07-13 13:30:42 -07:00
|
|
|
if (aLanguageOverride) {
|
|
|
|
languageOverride = *aLanguageOverride;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFont::nsFont(const nsString& aName, PRUint8 aStyle, PRUint8 aVariant,
|
2009-01-29 12:39:18 -08:00
|
|
|
PRUint16 aWeight, PRInt16 aStretch, PRUint8 aDecoration,
|
2010-07-13 13:30:42 -07:00
|
|
|
nscoord aSize, float aSizeAdjust,
|
|
|
|
const nsString* aLanguageOverride)
|
2007-03-22 10:30:00 -07:00
|
|
|
: name(aName)
|
|
|
|
{
|
|
|
|
style = aStyle;
|
2011-10-17 07:59:28 -07:00
|
|
|
systemFont = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
variant = aVariant;
|
|
|
|
weight = aWeight;
|
2009-01-29 12:39:18 -08:00
|
|
|
stretch = aStretch;
|
2007-03-22 10:30:00 -07:00
|
|
|
decorations = aDecoration;
|
|
|
|
size = aSize;
|
|
|
|
sizeAdjust = aSizeAdjust;
|
2010-07-13 13:30:42 -07:00
|
|
|
if (aLanguageOverride) {
|
|
|
|
languageOverride = *aLanguageOverride;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFont::nsFont(const nsFont& aOther)
|
|
|
|
: name(aOther.name)
|
|
|
|
{
|
|
|
|
style = aOther.style;
|
|
|
|
systemFont = aOther.systemFont;
|
|
|
|
variant = aOther.variant;
|
|
|
|
weight = aOther.weight;
|
2009-01-29 12:39:18 -08:00
|
|
|
stretch = aOther.stretch;
|
2007-03-22 10:30:00 -07:00
|
|
|
decorations = aOther.decorations;
|
|
|
|
size = aOther.size;
|
|
|
|
sizeAdjust = aOther.sizeAdjust;
|
2010-07-13 13:30:42 -07:00
|
|
|
languageOverride = aOther.languageOverride;
|
2012-04-25 23:22:24 -07:00
|
|
|
fontFeatureSettings = aOther.fontFeatureSettings;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFont::nsFont()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsFont::~nsFont()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool nsFont::BaseEquals(const nsFont& aOther) const
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if ((style == aOther.style) &&
|
|
|
|
(systemFont == aOther.systemFont) &&
|
|
|
|
(weight == aOther.weight) &&
|
2009-01-29 12:39:18 -08:00
|
|
|
(stretch == aOther.stretch) &&
|
2007-03-22 10:30:00 -07:00
|
|
|
(size == aOther.size) &&
|
|
|
|
(sizeAdjust == aOther.sizeAdjust) &&
|
2010-07-13 13:30:42 -07:00
|
|
|
name.Equals(aOther.name, nsCaseInsensitiveStringComparator()) &&
|
2012-04-25 23:22:24 -07:00
|
|
|
(languageOverride == aOther.languageOverride) &&
|
|
|
|
(fontFeatureSettings == aOther.fontFeatureSettings)) {
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool nsFont::Equals(const nsFont& aOther) const
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (BaseEquals(aOther) &&
|
|
|
|
(variant == aOther.variant) &&
|
|
|
|
(decorations == aOther.decorations)) {
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFont& nsFont::operator=(const nsFont& aOther)
|
|
|
|
{
|
|
|
|
name = aOther.name;
|
|
|
|
style = aOther.style;
|
|
|
|
systemFont = aOther.systemFont;
|
|
|
|
variant = aOther.variant;
|
|
|
|
weight = aOther.weight;
|
2009-01-29 12:39:18 -08:00
|
|
|
stretch = aOther.stretch;
|
2007-03-22 10:30:00 -07:00
|
|
|
decorations = aOther.decorations;
|
|
|
|
size = aOther.size;
|
|
|
|
sizeAdjust = aOther.sizeAdjust;
|
2010-07-13 13:30:42 -07:00
|
|
|
languageOverride = aOther.languageOverride;
|
2012-04-25 23:22:24 -07:00
|
|
|
fontFeatureSettings = aOther.fontFeatureSettings;
|
2007-03-22 10:30:00 -07:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-04-25 23:22:24 -07:00
|
|
|
void
|
|
|
|
nsFont::AddFontFeaturesToStyle(gfxFontStyle *aStyle) const
|
|
|
|
{
|
|
|
|
// simple copy for now, font-variant implementation will expand
|
|
|
|
aStyle->featureSettings.AppendElements(fontFeatureSettings);
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool IsGenericFontFamily(const nsString& aFamily)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
PRUint8 generic;
|
|
|
|
nsFont::GetGenericID(aFamily, &generic);
|
|
|
|
return generic != kGenericFont_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
const PRUnichar kNullCh = PRUnichar('\0');
|
|
|
|
const PRUnichar kSingleQuote = PRUnichar('\'');
|
|
|
|
const PRUnichar kDoubleQuote = PRUnichar('\"');
|
|
|
|
const PRUnichar kComma = PRUnichar(',');
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool nsFont::EnumerateFamilies(nsFontFamilyEnumFunc aFunc, void* aData) const
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
const PRUnichar *p, *p_end;
|
|
|
|
name.BeginReading(p);
|
|
|
|
name.EndReading(p_end);
|
|
|
|
nsAutoString family;
|
|
|
|
|
|
|
|
while (p < p_end) {
|
|
|
|
while (nsCRT::IsAsciiSpace(*p))
|
|
|
|
if (++p == p_end)
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool generic;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (*p == kSingleQuote || *p == kDoubleQuote) {
|
|
|
|
// quoted font family
|
|
|
|
PRUnichar quoteMark = *p;
|
|
|
|
if (++p == p_end)
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
const PRUnichar *nameStart = p;
|
|
|
|
|
|
|
|
// XXX What about CSS character escapes?
|
|
|
|
while (*p != quoteMark)
|
|
|
|
if (++p == p_end)
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
family = Substring(nameStart, p);
|
2011-10-17 07:59:28 -07:00
|
|
|
generic = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
while (++p != p_end && *p != kComma)
|
|
|
|
/* nothing */ ;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// unquoted font family
|
|
|
|
const PRUnichar *nameStart = p;
|
|
|
|
while (++p != p_end && *p != kComma)
|
|
|
|
/* nothing */ ;
|
|
|
|
|
|
|
|
family = Substring(nameStart, p);
|
2011-10-17 07:59:28 -07:00
|
|
|
family.CompressWhitespace(false, true);
|
2007-03-22 10:30:00 -07:00
|
|
|
generic = IsGenericFontFamily(family);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!family.IsEmpty() && !(*aFunc)(family, generic, aData))
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
++p; // may advance past p_end
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool FontEnumCallback(const nsString& aFamily, bool aGeneric, void *aData)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
*((nsString*)aData) = aFamily;
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsFont::GetFirstFamily(nsString& aFamily) const
|
|
|
|
{
|
|
|
|
EnumerateFamilies(FontEnumCallback, &aFamily);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/
|
|
|
|
void nsFont::GetGenericID(const nsString& aGeneric, PRUint8* aID)
|
|
|
|
{
|
|
|
|
*aID = kGenericFont_NONE;
|
|
|
|
if (aGeneric.LowerCaseEqualsLiteral("-moz-fixed")) *aID = kGenericFont_moz_fixed;
|
|
|
|
else if (aGeneric.LowerCaseEqualsLiteral("serif")) *aID = kGenericFont_serif;
|
|
|
|
else if (aGeneric.LowerCaseEqualsLiteral("sans-serif")) *aID = kGenericFont_sans_serif;
|
|
|
|
else if (aGeneric.LowerCaseEqualsLiteral("cursive")) *aID = kGenericFont_cursive;
|
|
|
|
else if (aGeneric.LowerCaseEqualsLiteral("fantasy")) *aID = kGenericFont_fantasy;
|
|
|
|
else if (aGeneric.LowerCaseEqualsLiteral("monospace")) *aID = kGenericFont_monospace;
|
|
|
|
}
|