DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Header

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */

#include "ScaledFontWin.h"
#include "UnscaledFontGDI.h"

#include "AutoHelpersWin.h"
#include "Logging.h"
#include "nsString.h"

#ifdef USE_SKIA
#include "skia/include/ports/SkTypeface_win.h"
#endif

#ifdef USE_CAIRO_SCALED_FONT
#include "cairo-win32.h"
#endif

#include "HelpersWinFonts.h"

namespace mozilla {
namespace gfx {

ScaledFontWin::ScaledFontWin(const LOGFONT* aFont,
                             const RefPtr<UnscaledFont>& aUnscaledFont,
                             Float aSize)
  : ScaledFontBase(aUnscaledFont, aSize)
  , mLogFont(*aFont)
{
}

bool
UnscaledFontGDI::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;
  }

  aDataCallback(fontData.get(), tableSize, 0, aBaton);
  return true;
}

bool
ScaledFontWin::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
{
  aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), nullptr, 0, aBaton);
  return true;
}

bool
UnscaledFontGDI::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton)
{
  aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), aBaton);
  return true;
}

bool
UnscaledFontGDI::GetFontDescriptor(FontDescriptorOutput aCb, void* aBaton)
{
  aCb(reinterpret_cast<uint8_t*>(&mLogFont), sizeof(mLogFont), 0, aBaton);
  return true;
}

already_AddRefed<UnscaledFont>
UnscaledFontGDI::CreateFromFontDescriptor(const uint8_t* aData, uint32_t aDataLength, uint32_t aIndex)
{
  if (aDataLength < sizeof(LOGFONT)) {
    gfxWarning() << "GDI font descriptor is truncated.";
    return nullptr;
  }

  const LOGFONT* logFont = reinterpret_cast<const LOGFONT*>(aData);
  RefPtr<UnscaledFont> unscaledFont = new UnscaledFontGDI(*logFont);
  return unscaledFont.forget();
}

already_AddRefed<ScaledFont>
UnscaledFontGDI::CreateScaledFont(Float aGlyphSize,
                                  const uint8_t* aInstanceData,
                                  uint32_t aInstanceDataLength,
                                  const FontVariation* aVariations,
                                  uint32_t aNumVariations)
{
  if (aInstanceDataLength < sizeof(LOGFONT)) {
    gfxWarning() << "GDI unscaled font instance data is truncated.";
    return nullptr;
  }

  NativeFont nativeFont;
  nativeFont.mType = NativeFontType::GDI_LOGFONT;
  nativeFont.mFont = (void*)aInstanceData;

  return Factory::CreateScaledFontForNativeFont(nativeFont, this, aGlyphSize);
}

AntialiasMode
ScaledFontWin::GetDefaultAAMode()
{
  return GetSystemDefaultAAMode();
}

#ifdef USE_SKIA
SkTypeface* ScaledFontWin::CreateSkTypeface()
{
  return SkCreateTypefaceFromLOGFONT(mLogFont);
}
#endif

#ifdef USE_CAIRO_SCALED_FONT
cairo_font_face_t*
ScaledFontWin::GetCairoFontFace()
{
  if (mLogFont.lfFaceName[0] == 0) {
    return nullptr;
  }
  return cairo_win32_font_face_create_for_logfontw(&mLogFont);
}
#endif

}
}