1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "ScaledFontWin.h"
8 #include "UnscaledFontGDI.h"
9
10 #include "AutoHelpersWin.h"
11 #include "Logging.h"
12 #include "nsString.h"
13
14 #ifdef USE_SKIA
15 # include "skia/include/ports/SkTypeface_win.h"
16 #endif
17
18 #ifdef USE_CAIRO_SCALED_FONT
19 # include "cairo-win32.h"
20 #endif
21
22 #include "HelpersWinFonts.h"
23
24 namespace mozilla {
25 namespace gfx {
26
ScaledFontWin(const LOGFONT * aFont,const RefPtr<UnscaledFont> & aUnscaledFont,Float aSize)27 ScaledFontWin::ScaledFontWin(const LOGFONT* aFont,
28 const RefPtr<UnscaledFont>& aUnscaledFont,
29 Float aSize)
30 : ScaledFontBase(aUnscaledFont, aSize), mLogFont(*aFont) {}
31
GetFontFileData(FontFileDataOutput aDataCallback,void * aBaton)32 bool UnscaledFontGDI::GetFontFileData(FontFileDataOutput aDataCallback,
33 void* aBaton) {
34 AutoDC dc;
35 AutoSelectFont font(dc.GetDC(), &mLogFont);
36
37 // Check for a font collection first.
38 uint32_t table = 0x66637474; // 'ttcf'
39 uint32_t tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
40 if (tableSize == GDI_ERROR) {
41 // Try as if just a single font.
42 table = 0;
43 tableSize = ::GetFontData(dc.GetDC(), table, 0, nullptr, 0);
44 if (tableSize == GDI_ERROR) {
45 return false;
46 }
47 }
48
49 UniquePtr<uint8_t[]> fontData(new uint8_t[tableSize]);
50
51 uint32_t sizeGot =
52 ::GetFontData(dc.GetDC(), table, 0, fontData.get(), tableSize);
53 if (sizeGot != tableSize) {
54 return false;
55 }
56
57 aDataCallback(fontData.get(), tableSize, 0, aBaton);
58 return true;
59 }
60
GetFontInstanceData(FontInstanceDataOutput aCb,void * aBaton)61 bool ScaledFontWin::GetFontInstanceData(FontInstanceDataOutput aCb,
62 void* aBaton) {
63 aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), nullptr, 0,
64 aBaton);
65 return true;
66 }
67
GetFontInstanceData(FontInstanceDataOutput aCb,void * aBaton)68 bool UnscaledFontGDI::GetFontInstanceData(FontInstanceDataOutput aCb,
69 void* aBaton) {
70 aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), aBaton);
71 return true;
72 }
73
GetFontDescriptor(FontDescriptorOutput aCb,void * aBaton)74 bool UnscaledFontGDI::GetFontDescriptor(FontDescriptorOutput aCb,
75 void* aBaton) {
76 // Because all the callers of this function are preparing a recorded
77 // event to be played back in another process, it's not helpful to ever
78 // return a font descriptor, since it isn't meaningful in another
79 // process. Those callers will always need to send full font data, and
80 // returning false here will ensure that that happens.
81 return false;
82 }
83
CreateFromFontDescriptor(const uint8_t * aData,uint32_t aDataLength,uint32_t aIndex)84 already_AddRefed<UnscaledFont> UnscaledFontGDI::CreateFromFontDescriptor(
85 const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex) {
86 if (aDataLength < sizeof(LOGFONT)) {
87 gfxWarning() << "GDI font descriptor is truncated.";
88 return nullptr;
89 }
90
91 const LOGFONT* logFont = reinterpret_cast<const LOGFONT*>(aData);
92 RefPtr<UnscaledFont> unscaledFont = new UnscaledFontGDI(*logFont);
93 return unscaledFont.forget();
94 }
95
CreateScaledFont(Float aGlyphSize,const uint8_t * aInstanceData,uint32_t aInstanceDataLength,const FontVariation * aVariations,uint32_t aNumVariations)96 already_AddRefed<ScaledFont> UnscaledFontGDI::CreateScaledFont(
97 Float aGlyphSize, const uint8_t* aInstanceData,
98 uint32_t aInstanceDataLength, const FontVariation* aVariations,
99 uint32_t aNumVariations) {
100 if (aInstanceDataLength < sizeof(LOGFONT)) {
101 gfxWarning() << "GDI unscaled font instance data is truncated.";
102 return nullptr;
103 }
104 return MakeAndAddRef<ScaledFontWin>(
105 reinterpret_cast<const LOGFONT*>(aInstanceData), this, aGlyphSize);
106 }
107
GetDefaultAAMode()108 AntialiasMode ScaledFontWin::GetDefaultAAMode() {
109 return GetSystemDefaultAAMode();
110 }
111
112 #ifdef USE_SKIA
CreateSkTypeface()113 SkTypeface* ScaledFontWin::CreateSkTypeface() {
114 return SkCreateTypefaceFromLOGFONT(mLogFont);
115 }
116 #endif
117
118 #ifdef USE_CAIRO_SCALED_FONT
CreateCairoFontFace(cairo_font_options_t * aFontOptions)119 cairo_font_face_t* ScaledFontWin::CreateCairoFontFace(
120 cairo_font_options_t* aFontOptions) {
121 if (mLogFont.lfFaceName[0] == 0) {
122 return nullptr;
123 }
124 return cairo_win32_font_face_create_for_logfontw(&mLogFont);
125 }
126 #endif
127
128 } // namespace gfx
129 } // namespace mozilla
130