362 lines
9.7 KiB
C++
362 lines
9.7 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
|
*
|
|
* 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 Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
|
*/
|
|
|
|
#include "nsFontRetrieverService.h"
|
|
#include <windows.h>
|
|
|
|
#include "nsFont.h"
|
|
#include "nsVoidArray.h"
|
|
#include "nsFontSizeIterator.h"
|
|
|
|
NS_IMPL_ADDREF(nsFontRetrieverService)
|
|
NS_IMPL_RELEASE(nsFontRetrieverService)
|
|
|
|
|
|
//----------------------------------------------------------
|
|
nsFontRetrieverService::nsFontRetrieverService()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
|
|
mFontList = nsnull;
|
|
mSizeIter = nsnull;
|
|
mNameIterInx = 0;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
nsFontRetrieverService::~nsFontRetrieverService()
|
|
{
|
|
if (nsnull != mFontList) {
|
|
for (PRInt32 i=0;i<mFontList->Count();i++) {
|
|
FontInfo * font = (FontInfo *)mFontList->ElementAt(i);
|
|
if (font->mSizes) {
|
|
delete font->mSizes;
|
|
}
|
|
delete font;
|
|
}
|
|
delete mFontList;
|
|
}
|
|
NS_IF_RELEASE(mSizeIter);
|
|
}
|
|
|
|
/**
|
|
* @param aIID The name of the class implementing the method
|
|
* @param _classiiddef The name of the #define symbol that defines the IID
|
|
* for the class (e.g. NS_ISUPPORTS_IID)
|
|
*
|
|
*/
|
|
nsresult nsFontRetrieverService::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
|
{
|
|
|
|
if (NULL == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
nsresult rv = NS_NOINTERFACE;
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIFontRetrieverService))) {
|
|
*aInstancePtr = (void*) ((nsIFontRetrieverService*)this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIFontNameIterator))) {
|
|
*aInstancePtr = (void*) ((nsIFontNameIterator*)this);
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------
|
|
//-- nsIFontRetrieverService
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::CreateFontNameIterator( nsIFontNameIterator** aIterator )
|
|
{
|
|
if (nsnull == aIterator) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (nsnull == mFontList) {
|
|
LoadFontList();
|
|
}
|
|
*aIterator = this;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::CreateFontSizeIterator( const nsString &aFontName,
|
|
nsIFontSizeIterator** aIterator )
|
|
{
|
|
// cache current value in case someone else externally is using it
|
|
PRInt32 saveIterInx = mNameIterInx;
|
|
|
|
PRBool found = PR_FALSE;
|
|
Reset();
|
|
do {
|
|
nsAutoString name;
|
|
Get(&name);
|
|
if (name.Equals(aFontName)) {
|
|
found = PR_TRUE;
|
|
break;
|
|
}
|
|
} while (Advance() == NS_OK);
|
|
|
|
if (found) {
|
|
if (nsnull == mSizeIter) {
|
|
mSizeIter = new nsFontSizeIterator();
|
|
}
|
|
NS_ASSERTION( nsnull != mSizeIter, "nsFontSizeIterator instance pointer is null");
|
|
|
|
*aIterator = (nsIFontSizeIterator *)mSizeIter;
|
|
NS_ADDREF(mSizeIter);
|
|
|
|
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
|
|
mSizeIter->SetFontInfo(fontInfo);
|
|
mNameIterInx = saveIterInx;
|
|
return NS_OK;
|
|
}
|
|
mNameIterInx = saveIterInx;
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
//-- nsIFontNameIterator
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::Reset()
|
|
{
|
|
mNameIterInx = 0;
|
|
return NS_OK;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::Get( nsString* aFontName )
|
|
{
|
|
if (mNameIterInx < mFontList->Count()) {
|
|
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
|
|
*aFontName = fontInfo->mName;
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::Advance()
|
|
{
|
|
if (mNameIterInx < mFontList->Count()-1) {
|
|
mNameIterInx++;
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
static int CALLBACK MyEnumFontFamProc(ENUMLOGFONT FAR *lpelf,
|
|
NEWTEXTMETRIC FAR *lpntm,
|
|
unsigned long fontType,
|
|
LPARAM lParam)
|
|
{
|
|
FontInfo * font = (FontInfo *)lParam;
|
|
|
|
////printf(" sizes-> %d\n", lpelf->elfLogFont.lfHeight);
|
|
LOGFONT ourLogFont; // Local copy of the LOGFONT structure.
|
|
memcpy(&ourLogFont, (const void *)&lpelf->elfLogFont, sizeof LOGFONT); // Make the copy
|
|
//printf("Size: %d", ourLogFont.lfHeight);
|
|
|
|
if (fontType & TRUETYPE_FONTTYPE) {
|
|
//printf("TRUETYPE_FONTTYPE;");
|
|
font->mIsScalable = PR_TRUE;
|
|
return 1;
|
|
} else if (fontType & RASTER_FONTTYPE) {
|
|
//printf("RASTER_FONTTYPE;");
|
|
if (nsnull == font->mSizes ) {
|
|
font->mSizes = new nsVoidArray();
|
|
}
|
|
} else if (fontType & DEVICE_FONTTYPE) {
|
|
//printf("DEVICE_FONTTYPE;");
|
|
//if (nsnull == font->mSizes ) {
|
|
// font->mSizes = new nsVoidArray();
|
|
//}
|
|
} else {
|
|
//printf("VECTOR_FONTTYPE;");
|
|
font->mIsScalable = PR_TRUE;
|
|
}
|
|
|
|
if (nsnull != font->mSizes) {
|
|
font->mSizes->AppendElement((void *)ourLogFont.lfHeight);
|
|
}
|
|
|
|
#if 0
|
|
if (ourLogFont.lfCharSet != ANSI_CHARSET)
|
|
//printf("FNT_NONANSI;");
|
|
else
|
|
//printf("FNT_ANSI;");
|
|
|
|
//
|
|
// We also need to set the family type (we use it for filtering)
|
|
//
|
|
switch (ourLogFont.lfPitchAndFamily & 0xF0)
|
|
{
|
|
case FF_SWISS:
|
|
//printf("FNT_SANSSERIF;");
|
|
break;
|
|
|
|
case FF_ROMAN:
|
|
//printf("FNT_SERIF;");
|
|
break;
|
|
|
|
case FF_MODERN:
|
|
//printf("FNT_MODERN;");
|
|
break;
|
|
|
|
case FF_SCRIPT:
|
|
//printf("FNT_SCRIPT;");
|
|
break;
|
|
|
|
default:
|
|
//printf("FNT_OTHER;");
|
|
break;
|
|
}
|
|
#endif
|
|
//printf("\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// int CALLBACK EnumerateMyFonts
|
|
//
|
|
// This function is called as a result of the call to EnumFontFamiliesEx
|
|
// in CFViewerView::OnInitialUpdate(), once for every type face in the
|
|
// system.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
static int CALLBACK EnumerateMyFonts(ENUMLOGFONTEX *lpLogFontEx,
|
|
NEWTEXTMETRICEX *lpMetricsEx,
|
|
int fontType,
|
|
LPARAM lParam)
|
|
{
|
|
nsVoidArray * fontList = (nsVoidArray *)lParam;
|
|
|
|
/*printf("%s [%s][%s][%s]", lpLogFontEx->elfLogFont.lfFaceName,
|
|
lpLogFontEx->elfFullName,
|
|
lpLogFontEx->elfStyle,
|
|
lpLogFontEx->elfScript
|
|
); */
|
|
LOGFONT ourLogFont; // Local copy of the LOGFONT structure.
|
|
memcpy(&ourLogFont, (const void *)&lpLogFontEx->elfLogFont, sizeof LOGFONT); // Make the copy
|
|
//printf("Size: %d\n", ourLogFont.lfHeight);
|
|
|
|
FontInfo * font = new FontInfo();
|
|
font->mName = (char *)lpLogFontEx->elfLogFont.lfFaceName; // XXX I18N ?
|
|
font->mIsScalable = PR_FALSE;
|
|
font->mSizes = nsnull;
|
|
|
|
|
|
fontList->AppendElement(font);
|
|
|
|
HDC myDC = ::GetDC(NULL); // Get the old style DC handle
|
|
::EnumFontFamilies(myDC, lpLogFontEx->elfLogFont.lfFaceName, (FONTENUMPROC)&MyEnumFontFamProc, (LPARAM)font);
|
|
::ReleaseDC(NULL, myDC);
|
|
|
|
|
|
return (1);
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::LoadFontList()
|
|
{
|
|
if (nsnull == mFontList) {
|
|
mFontList = new nsVoidArray();
|
|
if (nsnull == mFontList) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|
|
|
|
LOGFONT myLogFont; // Our font structure
|
|
HDC myDC; // Our device context
|
|
|
|
|
|
// Here is a partial list CHAR_SETS
|
|
/*
|
|
ANSI_CHARSET
|
|
DEFAULT_CHARSET
|
|
SYMBOL_CHARSET
|
|
SHIFTJIS_CHARSET
|
|
GB2312_CHARSET
|
|
HANGEUL_CHARSET
|
|
CHINESEBIG5_CHARSET
|
|
OEM_CHARSET
|
|
*/
|
|
|
|
myDC = ::GetDC(NULL); // Get the old style DC handle
|
|
|
|
// Font search parms (find all)
|
|
myLogFont.lfCharSet = ANSI_CHARSET;
|
|
myLogFont.lfFaceName[0] = 0;
|
|
myLogFont.lfPitchAndFamily = 0;
|
|
|
|
// Force the calls to EnumerateMyFonts
|
|
::EnumFontFamiliesEx(myDC, &myLogFont, (FONTENUMPROC)&EnumerateMyFonts, (LPARAM)mFontList, (DWORD)0);
|
|
|
|
myLogFont.lfCharSet = SYMBOL_CHARSET;
|
|
::EnumFontFamiliesEx(myDC, &myLogFont, (FONTENUMPROC)&EnumerateMyFonts, (LPARAM)mFontList, (DWORD)0);
|
|
|
|
::ReleaseDC(NULL, myDC);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------
|
|
NS_IMETHODIMP nsFontRetrieverService::IsFontScalable( const nsString &aFontName, PRBool* aResult )
|
|
{
|
|
// cache current value in case someone else externally is using it
|
|
PRInt32 saveIterInx = mNameIterInx;
|
|
|
|
PRBool found = PR_FALSE;
|
|
Reset();
|
|
do {
|
|
nsAutoString name;
|
|
Get(&name);
|
|
if (name.Equals(aFontName)) {
|
|
found = PR_TRUE;
|
|
break;
|
|
}
|
|
} while (Advance() == NS_OK);
|
|
|
|
if (found) {
|
|
FontInfo * fontInfo = (FontInfo *)mFontList->ElementAt(mNameIterInx);
|
|
*aResult = fontInfo->mIsScalable;
|
|
mNameIterInx = saveIterInx;
|
|
return NS_OK;
|
|
}
|
|
mNameIterInx = saveIterInx;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|