зеркало из https://github.com/mozilla/pjs.git
Platform-specific bustage.
This commit is contained in:
Родитель
185c761605
Коммит
bf1256e906
|
@ -1,448 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */
|
||||
/* ***** 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):
|
||||
* Brian Stell <bstell@netscape.com>
|
||||
* Louie Zhao <louie.zhao@sun.com>
|
||||
*
|
||||
* 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 "gfx-config.h"
|
||||
#include "nsFT2FontNode.h"
|
||||
#include "nsFontDebug.h"
|
||||
|
||||
#if (!defined(MOZ_ENABLE_FREETYPE2))
|
||||
|
||||
void nsFT2FontNode::FreeGlobals() {}
|
||||
|
||||
nsresult nsFT2FontNode::InitGlobals()
|
||||
{
|
||||
FREETYPE_FONT_PRINTF(("freetype not compiled in"));
|
||||
NS_WARNING("freetype not compiled in");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsFT2FontNode::GetFontNames(const char* aPattern,
|
||||
nsFontNodeArray* aNodes) {}
|
||||
|
||||
#else
|
||||
|
||||
#include "nsFreeType.h"
|
||||
#include "nsFontFreeType.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsArray.h"
|
||||
|
||||
nsHashtable* nsFT2FontNode::mFreeTypeNodes = nsnull;
|
||||
PRBool nsFT2FontNode::sInited = PR_FALSE;
|
||||
nsIFontCatalogService* nsFT2FontNode::sFcs = nsnull;
|
||||
|
||||
void
|
||||
nsFT2FontNode::FreeGlobals()
|
||||
{
|
||||
NS_IF_RELEASE(sFcs);
|
||||
|
||||
if (mFreeTypeNodes) {
|
||||
mFreeTypeNodes->Reset(FreeNode, nsnull);
|
||||
delete mFreeTypeNodes;
|
||||
mFreeTypeNodes = nsnull;
|
||||
}
|
||||
sInited = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFT2FontNode::InitGlobals()
|
||||
{
|
||||
NS_ASSERTION(sInited==PR_FALSE,
|
||||
"nsFT2FontNode::InitGlobals called more than once");
|
||||
|
||||
sInited = PR_TRUE;
|
||||
|
||||
nsresult rv = ::CallGetService("@mozilla.org/gfx/xfontcatalogservice;1",
|
||||
&sFcs);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ERROR("Font Catalog Service init failed\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mFreeTypeNodes = new nsHashtable();
|
||||
if (!mFreeTypeNodes)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LoadNodeTable();
|
||||
WeightTableInitCorrection(nsFreeTypeFont::sLinearWeightTable,
|
||||
nsFreeType2::gAATTDarkTextMinValue,
|
||||
nsFreeType2::gAATTDarkTextGain);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsFT2FontNode::GetFontNames(const char* aPattern, nsFontNodeArray* aNodes)
|
||||
{
|
||||
int j;
|
||||
PRBool rslt;
|
||||
PRUint32 count, i;
|
||||
char *pattern, *foundry, *family, *charset, *encoding;
|
||||
const char *charSetName;
|
||||
nsFontNode *node;
|
||||
nsCOMPtr<nsIArray> arrayFC;
|
||||
nsCAutoString familyTmp, languageTmp;
|
||||
|
||||
FONT_CATALOG_PRINTF(("looking for FreeType font matching %s", aPattern));
|
||||
nsCAutoString patt(aPattern);
|
||||
ToLowerCase(patt);
|
||||
pattern = strdup(patt.get());
|
||||
NS_ASSERTION(pattern, "failed to copy pattern");
|
||||
if (!pattern)
|
||||
goto cleanup_and_return;
|
||||
|
||||
rslt = ParseXLFD(pattern, &foundry, &family, &charset, &encoding);
|
||||
if (!rslt)
|
||||
goto cleanup_and_return;
|
||||
|
||||
// unable to handle "name-charset-*"
|
||||
if (charset && !encoding) {
|
||||
goto cleanup_and_return;
|
||||
}
|
||||
|
||||
if (family)
|
||||
familyTmp.Assign(family);
|
||||
|
||||
sFcs->GetFontCatalogEntries(familyTmp, languageTmp, 0, 0, 0, 0,
|
||||
getter_AddRefs(arrayFC));
|
||||
if (!arrayFC)
|
||||
goto cleanup_and_return;
|
||||
arrayFC->GetLength(&count);
|
||||
for (i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsITrueTypeFontCatalogEntry> fce = do_QueryElementAt(arrayFC, i);
|
||||
if (!fce)
|
||||
continue;
|
||||
nsCAutoString foundryName, familyName;
|
||||
PRUint32 flags, codePageRange1, codePageRange2;
|
||||
PRUint16 weight, width;
|
||||
fce->GetFamilyName(familyName);
|
||||
fce->GetFlags(&flags);
|
||||
fce->GetWidth(&width);
|
||||
fce->GetWeight(&weight);
|
||||
fce->GetCodePageRange1(&codePageRange1);
|
||||
fce->GetCodePageRange2(&codePageRange2);
|
||||
if (!charset) { // get all encoding
|
||||
FONT_CATALOG_PRINTF(("found FreeType %s-%s-*-*", foundryName.get(),
|
||||
familyName.get()));
|
||||
for (j=0; j<32; j++) {
|
||||
unsigned long bit = 1 << j;
|
||||
if (bit & codePageRange1) {
|
||||
charSetName = nsFreeType2::GetRange1CharSetName(bit);
|
||||
NS_ASSERTION(charSetName, "failed to get charset name");
|
||||
if (!charSetName)
|
||||
continue;
|
||||
node = LoadNode(fce, charSetName, aNodes);
|
||||
}
|
||||
if (bit & codePageRange2) {
|
||||
charSetName = nsFreeType2::GetRange2CharSetName(bit);
|
||||
if (!charSetName)
|
||||
continue;
|
||||
LoadNode(fce, charSetName, aNodes);
|
||||
}
|
||||
}
|
||||
if (foundryName.IsEmpty() && !familyName.IsEmpty() && flags&FCE_FLAGS_SYMBOL) {
|
||||
// the "registry-encoding" is not used but LoadNode will fail without
|
||||
// some value for this
|
||||
LoadNode(fce, "symbol-fontspecific", aNodes);
|
||||
}
|
||||
}
|
||||
|
||||
if (charset && encoding) { // get this specific encoding
|
||||
PRUint32 cpr1_bits, cpr2_bits;
|
||||
nsCAutoString charsetName(charset);
|
||||
charsetName.Append('-');
|
||||
charsetName.Append(encoding);
|
||||
CharSetNameToCodeRangeBits(charsetName.get(), &cpr1_bits, &cpr2_bits);
|
||||
if (!(cpr1_bits & codePageRange1)
|
||||
&& !(cpr2_bits & codePageRange2))
|
||||
continue;
|
||||
FONT_CATALOG_PRINTF(("found FreeType -%s-%s-%s",
|
||||
familyName.get(),charset,encoding));
|
||||
LoadNode(fce, charsetName.get(), aNodes);
|
||||
}
|
||||
}
|
||||
|
||||
FREE_IF(pattern);
|
||||
return;
|
||||
|
||||
cleanup_and_return:
|
||||
FONT_CATALOG_PRINTF(("nsFT2FontNode::GetFontNames failed"));
|
||||
FREE_IF(pattern);
|
||||
return;
|
||||
}
|
||||
|
||||
nsFontNode*
|
||||
nsFT2FontNode::LoadNode(nsITrueTypeFontCatalogEntry *aFce,
|
||||
const char *aCharSetName,
|
||||
nsFontNodeArray* aNodes)
|
||||
{
|
||||
nsFontCharSetMap *charSetMap = GetCharSetMap(aCharSetName);
|
||||
if (!charSetMap->mInfo) {
|
||||
return nsnull;
|
||||
}
|
||||
nsCAutoString nodeName, familyName;
|
||||
aFce->GetVendorID(nodeName);
|
||||
aFce->GetFamilyName(familyName);
|
||||
|
||||
nodeName.Append('-');
|
||||
nodeName.Append(familyName);
|
||||
nodeName.Append('-');
|
||||
nodeName.Append(aCharSetName);
|
||||
nsCStringKey key(nodeName);
|
||||
nsFontNode* node = (nsFontNode*) mFreeTypeNodes->Get(&key);
|
||||
if (!node) {
|
||||
node = new nsFontNode;
|
||||
if (!node) {
|
||||
return nsnull;
|
||||
}
|
||||
mFreeTypeNodes->Put(&key, node);
|
||||
node->mName = nodeName;
|
||||
nsFontCharSetMap *charSetMap = GetCharSetMap(aCharSetName);
|
||||
node->mCharSetInfo = charSetMap->mInfo;
|
||||
}
|
||||
|
||||
PRInt64 styleFlags;
|
||||
PRUint16 fceWeight, fceWidth;
|
||||
aFce->GetStyleFlags(&styleFlags);
|
||||
aFce->GetWidth(&fceWidth);
|
||||
aFce->GetWeight(&fceWeight);
|
||||
|
||||
int styleIndex;
|
||||
if (styleFlags & FT_STYLE_FLAG_ITALIC)
|
||||
styleIndex = NS_FONT_STYLE_ITALIC;
|
||||
else
|
||||
styleIndex = NS_FONT_STYLE_NORMAL;
|
||||
nsFontStyle* style = node->mStyles[styleIndex];
|
||||
if (!style) {
|
||||
style = new nsFontStyle;
|
||||
if (!style) {
|
||||
return nsnull;
|
||||
}
|
||||
node->mStyles[styleIndex] = style;
|
||||
}
|
||||
|
||||
int weightIndex = WEIGHT_INDEX(fceWeight);
|
||||
nsFontWeight* weight = style->mWeights[weightIndex];
|
||||
if (!weight) {
|
||||
weight = new nsFontWeight;
|
||||
if (!weight) {
|
||||
return nsnull;
|
||||
}
|
||||
style->mWeights[weightIndex] = weight;
|
||||
}
|
||||
|
||||
nsFontStretch* stretch = weight->mStretches[fceWidth];
|
||||
if (!stretch) {
|
||||
stretch = new nsFontStretch;
|
||||
if (!stretch) {
|
||||
return nsnull;
|
||||
}
|
||||
weight->mStretches[fceWidth] = stretch;
|
||||
}
|
||||
if (!stretch->mFreeTypeFaceID) {
|
||||
stretch->mFreeTypeFaceID = aFce;
|
||||
}
|
||||
if (aNodes) {
|
||||
int i, n, found = 0;
|
||||
n = aNodes->Count();
|
||||
for (i=0; i<n; i++) {
|
||||
if (aNodes->GetElement(i) == node) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
aNodes->AppendElement(node);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsFT2FontNode::LoadNodeTable()
|
||||
{
|
||||
int j;
|
||||
nsCOMPtr<nsIArray> arrayFC;
|
||||
nsCAutoString family, language;
|
||||
sFcs->GetFontCatalogEntries(family, language, 0, 0, 0, 0,
|
||||
getter_AddRefs(arrayFC));
|
||||
if (!arrayFC)
|
||||
return PR_FALSE;
|
||||
PRUint32 count, i;
|
||||
arrayFC->GetLength(&count);
|
||||
for (i = 0; i < count; i++) {
|
||||
const char *charsetName;
|
||||
nsCOMPtr<nsITrueTypeFontCatalogEntry> fce = do_QueryElementAt(arrayFC, i);
|
||||
if (!fce)
|
||||
continue;
|
||||
PRUint32 flags, codePageRange1, codePageRange2;
|
||||
PRUint16 weight, width;
|
||||
fce->GetFlags(&flags);
|
||||
fce->GetWidth(&width);
|
||||
fce->GetWeight(&weight);
|
||||
fce->GetCodePageRange1(&codePageRange1);
|
||||
fce->GetCodePageRange2(&codePageRange2);
|
||||
if ((!flags&FCE_FLAGS_ISVALID)
|
||||
|| (weight < 100) || (weight > 900) || (width > 8))
|
||||
continue;
|
||||
for (j=0; j<32; j++) {
|
||||
unsigned long bit = 1 << j;
|
||||
if (!(bit & codePageRange1))
|
||||
continue;
|
||||
charsetName = nsFreeType2::GetRange1CharSetName(bit);
|
||||
NS_ASSERTION(charsetName, "failed to get charset name");
|
||||
if (!charsetName)
|
||||
continue;
|
||||
LoadNode(fce, charsetName, nsnull);
|
||||
}
|
||||
for (j=0; j<32; j++) {
|
||||
unsigned long bit = 1 << j;
|
||||
if (!(bit & codePageRange2))
|
||||
continue;
|
||||
charsetName = nsFreeType2::GetRange2CharSetName(bit);
|
||||
if (!charsetName)
|
||||
continue;
|
||||
LoadNode(fce, charsetName, nsnull);
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Parse XLFD
|
||||
// The input is a typical XLFD string.
|
||||
//
|
||||
// the XLFD entries look like this:
|
||||
// -adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1
|
||||
// -adobe-courier-medium-r-*-*-12-*-*-*-*-*-*-*
|
||||
//
|
||||
// the fields are:
|
||||
// -foundry-family-weight-slant-width-style-pixelsize-pointsize-
|
||||
// resolution_x-resolution_y-spacing-avg_width-registry-encoding
|
||||
//
|
||||
// see ftp://ftp.x.org/pub/R6.4/xc/doc/hardcopy/XLFD
|
||||
//
|
||||
PRBool
|
||||
nsFT2FontNode::ParseXLFD(char *aPattern, char** aFoundry, char** aFamily,
|
||||
char** aCharset, char** aEncoding)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
*aFoundry = nsnull;
|
||||
*aFamily = nsnull;
|
||||
*aCharset = nsnull;
|
||||
*aEncoding = nsnull;
|
||||
|
||||
// start of pattern
|
||||
p = aPattern;
|
||||
NS_ASSERTION(*p == '-',"garbled pattern: does not start with a '-'");
|
||||
if (*p++ != '-')
|
||||
return PR_FALSE;
|
||||
|
||||
// foundry
|
||||
NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern");
|
||||
if (!*p)
|
||||
return PR_FALSE;
|
||||
if (*p == '*')
|
||||
*aFoundry = nsnull;
|
||||
else
|
||||
*aFoundry = p;
|
||||
while (*p && (*p!='-'))
|
||||
p++;
|
||||
if (!*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of foundry");
|
||||
*p++ = '\0';
|
||||
|
||||
// family
|
||||
if (!*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
if (*p == '*')
|
||||
*aFamily = nsnull;
|
||||
else
|
||||
*aFamily = p;
|
||||
while (*p && (*p!='-'))
|
||||
p++;
|
||||
if (!*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of family");
|
||||
*p++ = '\0';
|
||||
|
||||
// skip forward to charset
|
||||
for (i=0; i<10; i++) {
|
||||
while (*p && (*p!='-'))
|
||||
p++;
|
||||
if (!*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
// charset
|
||||
NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern");
|
||||
if (!*p)
|
||||
return PR_FALSE;
|
||||
if (*p == '*')
|
||||
*aCharset = nsnull;
|
||||
else
|
||||
*aCharset = p;
|
||||
while (*p && (*p!='-'))
|
||||
p++;
|
||||
if (!*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
NS_ASSERTION(*p == '-',"garbled pattern: cannot find end of charset");
|
||||
*p++ = '\0';
|
||||
|
||||
// encoding
|
||||
NS_ASSERTION(*p,"garbled pattern: unexpected end of pattern");
|
||||
if (!*p)
|
||||
return PR_FALSE;
|
||||
if (*p == '*')
|
||||
*aEncoding = nsnull;
|
||||
else
|
||||
*aEncoding = p;
|
||||
while (*p && (*p!='-'))
|
||||
p++;
|
||||
if (*p)
|
||||
return PR_TRUE; // short XLFD
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Загрузка…
Ссылка в новой задаче