Bug 1156742 Part 19: Implement GetFontFileData for ScaledFontWin. r=bas

This commit is contained in:
Bob Owen 2015-12-21 20:33:14 +00:00
parent 9425bbddb9
commit ff49466165
5 changed files with 147 additions and 1 deletions

86
gfx/2d/AutoHelpersWin.h Normal file
View File

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_gfx_AutoHelpersWin_h
#define mozilla_gfx_AutoHelpersWin_h
#include <windows.h>
namespace mozilla {
namespace gfx {
// Get the global device context, and auto-release it on destruction.
class AutoDC
{
public:
AutoDC() {
mDC = ::GetDC(nullptr);
}
~AutoDC() {
::ReleaseDC(nullptr, mDC);
}
HDC GetDC() {
return mDC;
}
private:
HDC mDC;
};
// Select a font into the given DC, and auto-restore.
class AutoSelectFont
{
public:
AutoSelectFont(HDC aDC, LOGFONTW *aLogFont)
: mOwnsFont(false)
{
mFont = ::CreateFontIndirectW(aLogFont);
if (mFont) {
mOwnsFont = true;
mDC = aDC;
mOldFont = (HFONT)::SelectObject(aDC, mFont);
} else {
mOldFont = nullptr;
}
}
AutoSelectFont(HDC aDC, HFONT aFont)
: mOwnsFont(false)
{
mDC = aDC;
mFont = aFont;
mOldFont = (HFONT)::SelectObject(aDC, aFont);
}
~AutoSelectFont() {
if (mOldFont) {
::SelectObject(mDC, mOldFont);
if (mOwnsFont) {
::DeleteObject(mFont);
}
}
}
bool IsValid() const {
return mFont != nullptr;
}
HFONT GetFont() const {
return mFont;
}
private:
HDC mDC;
HFONT mFont;
HFONT mOldFont;
bool mOwnsFont;
};
} // gfx
} // mozilla
#endif // mozilla_gfx_AutoHelpersWin_h

View File

@ -1404,6 +1404,12 @@ RecordedScaledFontCreation::PlayEvent(Translator *aTranslator) const
void
RecordedScaledFontCreation::RecordToStream(std::ostream &aStream) const
{
if (!mGetFontFileDataSucceeded) {
gfxWarning()
<< "Unable to record ScaledFont creation as no data was retrieved.";
return;
}
WriteElement(aStream, mRefPtr);
WriteElement(aStream, mIndex);
WriteElement(aStream, mGlyphSize);

View File

@ -947,7 +947,7 @@ public:
RecordedScaledFontCreation(ReferencePtr aRefPtr, ScaledFont *aScaledFont)
: RecordedEvent(SCALEDFONTCREATION), mRefPtr(aRefPtr), mData(nullptr)
{
aScaledFont->GetFontFileData(&FontDataProc, this);
mGetFontFileDataSucceeded = aScaledFont->GetFontFileData(&FontDataProc, this);
}
~RecordedScaledFontCreation();
@ -970,6 +970,7 @@ private:
uint32_t mSize;
Float mGlyphSize;
uint32_t mIndex;
bool mGetFontFileDataSucceeded = false;
MOZ_IMPLICIT RecordedScaledFontCreation(std::istream &aStream);
};

View File

@ -6,6 +6,7 @@
#include "ScaledFontWin.h"
#include "ScaledFontBase.h"
#include "AutoHelpersWin.h"
#include "Logging.h"
#include "SFNTData.h"
@ -77,6 +78,55 @@ ScaledFontWin::ScaledFontWin(uint8_t* aFontData, uint32_t aFontDataLength,
}
bool
ScaledFontWin::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton)
{
AutoDC dc;
AutoSelectFont font(dc.GetDC(), &mLogFont);
// Check for a font collection first.
uint32_t table = 0x66637474; // 'ttcf'
uint32_t tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
if (tableSize == GDI_ERROR) {
// Try as if just a single font.
table = 0;
tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
if (tableSize == GDI_ERROR) {
return false;
}
}
UniquePtr<uint8_t[]> fontData(new uint8_t[tableSize]);
uint32_t sizeGot =
::GetFontData(dc.GetDC(), table, 0, fontData.get(), tableSize);
if (sizeGot != tableSize) {
return false;
}
// If it's a font collection then attempt to get the index.
uint32_t index = 0;
if (table != 0) {
UniquePtr<SFNTData> sfntData = SFNTData::Create(fontData.get(),
tableSize);
if (!sfntData) {
gfxWarning() << "Failed to create SFNTData for GetFontFileData.";
return false;
}
// We cast here because for VS2015 char16_t != wchar_t, even though they are
// both 16 bit.
if (!sfntData->GetIndexForU16Name(
reinterpret_cast<char16_t*>(mLogFont.lfFaceName), &index)) {
gfxWarning() << "Failed to get index for face name.";
return false;
}
}
aDataCallback(fontData.get(), tableSize, index, mSize, aBaton);
return true;
}
#ifdef USE_SKIA
SkTypeface* ScaledFontWin::GetSkTypeface()
{

View File

@ -24,6 +24,9 @@ public:
Float aGlyphSize);
virtual FontType GetType() const { return FontType::GDI; }
bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton) override;
#ifdef USE_SKIA
virtual SkTypeface* GetSkTypeface();
#endif