2010-02-26 09:36:07 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
|
|
* ***** 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 Foundation code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Bas Schouten <bschouten@mozilla.com>
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either 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 ***** */
|
|
|
|
|
|
|
|
#ifndef GFX_DWRITEFONTLIST_H
|
|
|
|
#define GFX_DWRITEFONTLIST_H
|
|
|
|
|
|
|
|
#include "gfxDWriteCommon.h"
|
|
|
|
|
|
|
|
#include "gfxFont.h"
|
|
|
|
#include "gfxUserFontSet.h"
|
|
|
|
#include "cairo-win32.h"
|
|
|
|
|
|
|
|
#include "gfxPlatformFontList.h"
|
2011-06-03 08:31:08 +04:00
|
|
|
#include "gfxPlatform.h"
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gfxDWriteFontFamily is a class that describes one of the fonts on the
|
|
|
|
* users system. It holds each gfxDWriteFontEntry (maps more directly to
|
|
|
|
* a font face) which holds font type, charset info and character map info.
|
|
|
|
*/
|
|
|
|
class gfxDWriteFontEntry;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Class representing directwrite font family.
|
|
|
|
*/
|
|
|
|
class gfxDWriteFontFamily : public gfxFontFamily
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Constructs a new DWriteFont Family.
|
|
|
|
*
|
|
|
|
* \param aName Name identifying the family
|
|
|
|
* \param aFamily IDWriteFontFamily object representing the directwrite
|
|
|
|
* family object.
|
|
|
|
*/
|
|
|
|
gfxDWriteFontFamily(const nsAString& aName,
|
2011-06-03 08:31:07 +04:00
|
|
|
IDWriteFontFamily *aFamily)
|
|
|
|
: gfxFontFamily(aName), mDWFamily(aFamily), mForceGDIClassic(false) {}
|
2010-02-26 09:36:07 +03:00
|
|
|
virtual ~gfxDWriteFontFamily();
|
|
|
|
|
|
|
|
virtual void FindStyleVariations();
|
|
|
|
|
2011-06-03 08:31:07 +04:00
|
|
|
virtual void LocalizedName(nsAString& aLocalizedName);
|
|
|
|
|
|
|
|
void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
protected:
|
|
|
|
/** This font family's directwrite fontfamily object */
|
|
|
|
nsRefPtr<IDWriteFontFamily> mDWFamily;
|
2011-06-03 08:31:07 +04:00
|
|
|
bool mForceGDIClassic;
|
2010-02-26 09:36:07 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Class representing DirectWrite FontEntry (a unique font style/family)
|
|
|
|
*/
|
|
|
|
class gfxDWriteFontEntry : public gfxFontEntry
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Constructs a font entry.
|
|
|
|
*
|
|
|
|
* \param aFaceName The name of the corresponding font face.
|
|
|
|
* \param aFont DirectWrite font object
|
|
|
|
*/
|
|
|
|
gfxDWriteFontEntry(const nsAString& aFaceName,
|
|
|
|
IDWriteFont *aFont)
|
2011-06-03 08:31:07 +04:00
|
|
|
: gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nsnull),
|
|
|
|
mForceGDIClassic(false)
|
2010-02-26 09:36:07 +03:00
|
|
|
{
|
|
|
|
mItalic = (aFont->GetStyle() == DWRITE_FONT_STYLE_ITALIC ||
|
|
|
|
aFont->GetStyle() == DWRITE_FONT_STYLE_OBLIQUE);
|
|
|
|
mStretch = FontStretchFromDWriteStretch(aFont->GetStretch());
|
2011-06-02 16:56:50 +04:00
|
|
|
PRUint16 weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100);
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
weight = NS_MAX<PRUint16>(100, weight);
|
|
|
|
weight = NS_MIN<PRUint16>(900, weight);
|
|
|
|
mWeight = weight;
|
2011-01-25 12:17:18 +03:00
|
|
|
|
|
|
|
mIsCJK = UNINITIALIZED_VALUE;
|
2010-02-26 09:36:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a font entry using a font. But with custom font values.
|
|
|
|
* This is used for creating correct font entries for @font-face with local
|
|
|
|
* font source.
|
|
|
|
*
|
|
|
|
* \param aFaceName The name of the corresponding font face.
|
|
|
|
* \param aFont DirectWrite font object
|
|
|
|
* \param aWeight Weight of the font
|
|
|
|
* \param aStretch Stretch of the font
|
|
|
|
* \param aItalic True if italic
|
|
|
|
*/
|
|
|
|
gfxDWriteFontEntry(const nsAString& aFaceName,
|
|
|
|
IDWriteFont *aFont,
|
|
|
|
PRUint16 aWeight,
|
|
|
|
PRInt16 aStretch,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aItalic)
|
2011-06-03 08:31:07 +04:00
|
|
|
: gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nsnull),
|
|
|
|
mForceGDIClassic(false)
|
2010-02-26 09:36:07 +03:00
|
|
|
{
|
|
|
|
mWeight = aWeight;
|
|
|
|
mStretch = aStretch;
|
|
|
|
mItalic = aItalic;
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsUserFont = true;
|
|
|
|
mIsLocalUserFont = true;
|
2011-01-25 12:17:18 +03:00
|
|
|
mIsCJK = UNINITIALIZED_VALUE;
|
2010-02-26 09:36:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a font entry using a font file.
|
|
|
|
*
|
|
|
|
* \param aFaceName The name of the corresponding font face.
|
|
|
|
* \param aFontFile DirectWrite fontfile object
|
|
|
|
* \param aWeight Weight of the font
|
|
|
|
* \param aStretch Stretch of the font
|
|
|
|
* \param aItalic True if italic
|
|
|
|
*/
|
|
|
|
gfxDWriteFontEntry(const nsAString& aFaceName,
|
|
|
|
IDWriteFontFile *aFontFile,
|
|
|
|
PRUint16 aWeight,
|
|
|
|
PRInt16 aStretch,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aItalic)
|
2011-06-03 08:31:07 +04:00
|
|
|
: gfxFontEntry(aFaceName), mFont(nsnull), mFontFile(aFontFile),
|
|
|
|
mForceGDIClassic(false)
|
2010-02-26 09:36:07 +03:00
|
|
|
{
|
|
|
|
mWeight = aWeight;
|
|
|
|
mStretch = aStretch;
|
|
|
|
mItalic = aItalic;
|
2011-10-17 18:59:28 +04:00
|
|
|
mIsUserFont = true;
|
2011-01-25 12:17:18 +03:00
|
|
|
mIsCJK = UNINITIALIZED_VALUE;
|
2010-02-26 09:36:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~gfxDWriteFontEntry();
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
virtual bool IsSymbolFont();
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
virtual nsresult GetFontTable(PRUint32 aTableTag,
|
2011-01-07 07:45:10 +03:00
|
|
|
FallibleTArray<PRUint8>& aBuffer);
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
nsresult ReadCMAP();
|
2011-01-25 12:17:18 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool IsCJKFont();
|
2011-01-25 12:17:18 +03:00
|
|
|
|
2011-06-03 08:31:07 +04:00
|
|
|
void SetForceGDIClassic(bool aForce) { mForceGDIClassic = aForce; }
|
|
|
|
bool GetForceGDIClassic() { return mForceGDIClassic; }
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
protected:
|
|
|
|
friend class gfxDWriteFont;
|
|
|
|
friend class gfxDWriteFontList;
|
|
|
|
|
|
|
|
virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool aNeedsBold);
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
nsresult CreateFontFace(
|
|
|
|
IDWriteFontFace **aFontFace,
|
|
|
|
DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE);
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont);
|
2011-01-21 19:44:32 +03:00
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
/**
|
|
|
|
* A fontentry only needs to have either of these. If it has both only
|
|
|
|
* the IDWriteFont will be used.
|
|
|
|
*/
|
|
|
|
nsRefPtr<IDWriteFont> mFont;
|
|
|
|
nsRefPtr<IDWriteFontFile> mFontFile;
|
|
|
|
DWRITE_FONT_FACE_TYPE mFaceType;
|
2011-01-25 12:17:18 +03:00
|
|
|
|
2011-06-03 08:31:07 +04:00
|
|
|
PRInt8 mIsCJK;
|
|
|
|
bool mForceGDIClassic;
|
2010-02-26 09:36:07 +03:00
|
|
|
};
|
|
|
|
|
2012-03-09 06:05:55 +04:00
|
|
|
// custom text renderer used to determine the fallback font for a given char
|
|
|
|
class FontFallbackRenderer : public IDWriteTextRenderer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FontFallbackRenderer(IDWriteFactory *aFactory)
|
|
|
|
: mRefCount(0)
|
|
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
hr = aFactory->GetSystemFontCollection(getter_AddRefs(mSystemFonts));
|
|
|
|
NS_ASSERTION(SUCCEEDED(hr), "GetSystemFontCollection failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
~FontFallbackRenderer()
|
|
|
|
{}
|
|
|
|
|
|
|
|
// IDWriteTextRenderer methods
|
|
|
|
IFACEMETHOD(DrawGlyphRun)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
FLOAT baselineOriginX,
|
|
|
|
FLOAT baselineOriginY,
|
|
|
|
DWRITE_MEASURING_MODE measuringMode,
|
|
|
|
__in DWRITE_GLYPH_RUN const* glyphRun,
|
|
|
|
__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
|
|
|
|
__maybenull IUnknown* clientDrawingEffect
|
|
|
|
);
|
|
|
|
|
|
|
|
IFACEMETHOD(DrawUnderline)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
FLOAT baselineOriginX,
|
|
|
|
FLOAT baselineOriginY,
|
|
|
|
__in DWRITE_UNDERLINE const* underline,
|
|
|
|
__maybenull IUnknown* clientDrawingEffect
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IFACEMETHOD(DrawStrikethrough)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
FLOAT baselineOriginX,
|
|
|
|
FLOAT baselineOriginY,
|
|
|
|
__in DWRITE_STRIKETHROUGH const* strikethrough,
|
|
|
|
__maybenull IUnknown* clientDrawingEffect
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IFACEMETHOD(DrawInlineObject)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
FLOAT originX,
|
|
|
|
FLOAT originY,
|
|
|
|
IDWriteInlineObject* inlineObject,
|
|
|
|
BOOL isSideways,
|
|
|
|
BOOL isRightToLeft,
|
|
|
|
__maybenull IUnknown* clientDrawingEffect
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// IDWritePixelSnapping methods
|
|
|
|
|
|
|
|
IFACEMETHOD(IsPixelSnappingDisabled)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
__out BOOL* isDisabled
|
|
|
|
)
|
|
|
|
{
|
|
|
|
*isDisabled = FALSE;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
IFACEMETHOD(GetCurrentTransform)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
__out DWRITE_MATRIX* transform
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
|
|
|
|
*transform = ident;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
IFACEMETHOD(GetPixelsPerDip)(
|
|
|
|
__maybenull void* clientDrawingContext,
|
|
|
|
__out FLOAT* pixelsPerDip
|
|
|
|
)
|
|
|
|
{
|
|
|
|
*pixelsPerDip = 1.0f;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// IUnknown methods
|
|
|
|
|
|
|
|
IFACEMETHOD_(unsigned long, AddRef) ()
|
|
|
|
{
|
|
|
|
return InterlockedIncrement(&mRefCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
IFACEMETHOD_(unsigned long, Release) ()
|
|
|
|
{
|
|
|
|
unsigned long newCount = InterlockedDecrement(&mRefCount);
|
|
|
|
if (newCount == 0)
|
|
|
|
{
|
|
|
|
delete this;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return newCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
IFACEMETHOD(QueryInterface) (IID const& riid, void** ppvObject)
|
|
|
|
{
|
|
|
|
if (__uuidof(IDWriteTextRenderer) == riid) {
|
|
|
|
*ppvObject = this;
|
|
|
|
} else if (__uuidof(IDWritePixelSnapping) == riid) {
|
|
|
|
*ppvObject = this;
|
|
|
|
} else if (__uuidof(IUnknown) == riid) {
|
|
|
|
*ppvObject = this;
|
|
|
|
} else {
|
|
|
|
*ppvObject = NULL;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->AddRef();
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsString& FallbackFamilyName() { return mFamilyName; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
unsigned long mRefCount;
|
|
|
|
nsRefPtr<IDWriteFontCollection> mSystemFonts;
|
|
|
|
nsString mFamilyName;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
class gfxDWriteFontList : public gfxPlatformFontList {
|
|
|
|
public:
|
|
|
|
gfxDWriteFontList();
|
|
|
|
|
|
|
|
static gfxDWriteFontList* PlatformFontList() {
|
|
|
|
return static_cast<gfxDWriteFontList*>(sPlatformFontList);
|
|
|
|
}
|
|
|
|
|
2010-11-08 14:02:27 +03:00
|
|
|
// initialize font lists
|
|
|
|
virtual nsresult InitFontList();
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
virtual gfxFontEntry* GetDefaultFont(const gfxFontStyle* aStyle,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool& aNeedsBold);
|
2010-02-26 09:36:07 +03:00
|
|
|
|
|
|
|
virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
|
|
|
const nsAString& aFontName);
|
|
|
|
|
|
|
|
virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
|
|
|
const PRUint8 *aFontData,
|
|
|
|
PRUint32 aLength);
|
2010-03-03 09:57:43 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
virtual bool ResolveFontName(const nsAString& aFontName,
|
2010-03-03 09:57:43 +03:00
|
|
|
nsAString& aResolvedFontName);
|
2010-02-26 09:36:07 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool GetStandardFamilyName(const nsAString& aFontName,
|
2010-02-28 10:27:22 +03:00
|
|
|
nsAString& aFamilyName);
|
|
|
|
|
2011-01-21 19:44:32 +03:00
|
|
|
IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; }
|
2011-09-29 10:19:26 +04:00
|
|
|
bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
|
2011-01-21 19:44:32 +03:00
|
|
|
|
2011-01-21 19:44:33 +03:00
|
|
|
virtual gfxFontFamily* FindFamily(const nsAString& aFamily);
|
|
|
|
|
2011-04-13 11:28:34 +04:00
|
|
|
virtual void GetFontFamilyList(nsTArray<nsRefPtr<gfxFontFamily> >& aFamilyArray);
|
|
|
|
|
2011-06-03 08:31:08 +04:00
|
|
|
gfxFloat GetForceGDIClassicMaxFontSize() { return mForceGDIClassicMaxFontSize; }
|
|
|
|
|
2010-02-26 09:36:07 +03:00
|
|
|
private:
|
|
|
|
friend class gfxDWriteFontFamily;
|
|
|
|
|
2010-03-03 09:57:43 +03:00
|
|
|
nsresult GetFontSubstitutes();
|
|
|
|
|
2011-03-24 23:11:38 +03:00
|
|
|
void GetDirectWriteSubstitutes();
|
|
|
|
|
2012-03-09 06:05:55 +04:00
|
|
|
// search fonts system-wide for a given character, null otherwise
|
|
|
|
virtual gfxFontEntry* GlobalFontFallback(const PRUint32 aCh,
|
|
|
|
PRInt32 aRunScript,
|
|
|
|
const gfxFontStyle* aMatchStyle,
|
|
|
|
PRUint32& aCmapCount);
|
|
|
|
|
|
|
|
virtual bool UsesSystemFallback() { return true; }
|
|
|
|
|
2010-03-03 09:57:43 +03:00
|
|
|
/**
|
|
|
|
* Fonts listed in the registry as substitutes but for which no actual
|
|
|
|
* font family is found.
|
|
|
|
*/
|
2010-02-26 09:36:07 +03:00
|
|
|
nsTArray<nsString> mNonExistingFonts;
|
2010-03-03 09:57:43 +03:00
|
|
|
|
|
|
|
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<gfxFontFamily> > FontTable;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Table of font substitutes, we grab this from the registry to get
|
|
|
|
* alternative font names.
|
|
|
|
*/
|
|
|
|
FontTable mFontSubstitutes;
|
2011-01-21 19:44:32 +03:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mInitialized;
|
2011-01-21 19:44:33 +03:00
|
|
|
virtual nsresult DelayedInitFontList();
|
|
|
|
|
2011-06-03 08:31:08 +04:00
|
|
|
gfxFloat mForceGDIClassicMaxFontSize;
|
|
|
|
|
2011-01-21 19:44:32 +03:00
|
|
|
// whether to use GDI font table access routines
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mGDIFontTableAccess;
|
2011-01-21 19:44:32 +03:00
|
|
|
nsRefPtr<IDWriteGdiInterop> mGDIInterop;
|
2012-03-09 06:05:55 +04:00
|
|
|
|
|
|
|
nsRefPtr<FontFallbackRenderer> mFallbackRenderer;
|
|
|
|
nsRefPtr<IDWriteTextFormat> mFallbackFormat;
|
2010-02-26 09:36:07 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* GFX_DWRITEFONTLIST_H */
|