ScaledFontFreeType.cpp (4512B)
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 "ScaledFontFreeType.h" 8 #include "UnscaledFontFreeType.h" 9 #include "NativeFontResourceFreeType.h" 10 #include "Logging.h" 11 #include "mozilla/StaticPrefs_gfx.h" 12 #include "mozilla/webrender/WebRenderTypes.h" 13 14 #include "skia/include/ports/SkTypeface_cairo.h" 15 16 #include FT_MULTIPLE_MASTERS_H 17 18 namespace mozilla { 19 namespace gfx { 20 21 ScaledFontFreeType::ScaledFontFreeType( 22 RefPtr<SharedFTFace>&& aFace, const RefPtr<UnscaledFont>& aUnscaledFont, 23 Float aSize, bool aApplySyntheticBold) 24 : ScaledFontBase(aUnscaledFont, aSize), 25 mFace(std::move(aFace)), 26 mApplySyntheticBold(aApplySyntheticBold) {} 27 28 bool ScaledFontFreeType::UseSubpixelPosition() const { 29 return !MOZ_UNLIKELY( 30 StaticPrefs:: 31 gfx_text_subpixel_position_force_disabled_AtStartup()) && 32 FT_IS_SCALABLE(mFace->GetFace()); 33 } 34 35 SkTypeface* ScaledFontFreeType::CreateSkTypeface() { 36 return SkCreateTypefaceFromCairoFTFont(mFace->GetFace(), mFace.get()); 37 } 38 39 void ScaledFontFreeType::SetupSkFontDrawOptions(SkFont& aFont) { 40 aFont.setSubpixel(UseSubpixelPosition()); 41 42 if (mApplySyntheticBold) { 43 aFont.setEmbolden(true); 44 } 45 46 aFont.setEmbeddedBitmaps(true); 47 } 48 49 bool ScaledFontFreeType::MayUseBitmaps() { 50 return !FT_IS_SCALABLE(mFace->GetFace()); 51 } 52 53 cairo_font_face_t* ScaledFontFreeType::CreateCairoFontFace( 54 cairo_font_options_t* aFontOptions) { 55 cairo_font_options_set_hint_metrics(aFontOptions, CAIRO_HINT_METRICS_OFF); 56 57 int loadFlags = FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING; 58 if (mFace->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) { 59 loadFlags &= ~FT_LOAD_NO_AUTOHINT; 60 } 61 62 unsigned int synthFlags = 0; 63 if (mApplySyntheticBold) { 64 synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD; 65 } 66 67 return cairo_ft_font_face_create_for_ft_face(mFace->GetFace(), loadFlags, 68 synthFlags, mFace.get()); 69 } 70 71 bool ScaledFontFreeType::GetFontInstanceData(FontInstanceDataOutput aCb, 72 void* aBaton) { 73 std::vector<FontVariation> variations; 74 if (HasVariationSettings()) { 75 UnscaledFontFreeType::GetVariationSettingsFromFace(&variations, 76 mFace->GetFace()); 77 } 78 79 InstanceData instance(this); 80 aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance), 81 variations.data(), variations.size(), aBaton); 82 return true; 83 } 84 85 bool ScaledFontFreeType::GetWRFontInstanceOptions( 86 Maybe<wr::FontInstanceOptions>* aOutOptions, 87 Maybe<wr::FontInstancePlatformOptions>* aOutPlatformOptions, 88 std::vector<FontVariation>* aOutVariations) { 89 wr::FontInstanceOptions options = {}; 90 options.render_mode = wr::FontRenderMode::Alpha; 91 options.flags = wr::FontInstanceFlags{0}; 92 if (UseSubpixelPosition()) { 93 options.flags |= wr::FontInstanceFlags::SUBPIXEL_POSITION; 94 } 95 options.flags |= wr::FontInstanceFlags::EMBEDDED_BITMAPS; 96 options.synthetic_italics = 97 wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle()); 98 99 if (mApplySyntheticBold) { 100 options.flags |= wr::FontInstanceFlags::SYNTHETIC_BOLD; 101 } 102 103 wr::FontInstancePlatformOptions platformOptions; 104 platformOptions.lcd_filter = wr::FontLCDFilter::None; 105 platformOptions.hinting = wr::FontHinting::None; 106 107 *aOutOptions = Some(options); 108 *aOutPlatformOptions = Some(platformOptions); 109 110 if (HasVariationSettings()) { 111 UnscaledFontFreeType::GetVariationSettingsFromFace(aOutVariations, 112 mFace->GetFace()); 113 } 114 115 return true; 116 } 117 118 ScaledFontFreeType::InstanceData::InstanceData( 119 const wr::FontInstanceOptions* aOptions, 120 const wr::FontInstancePlatformOptions* aPlatformOptions) 121 : mApplySyntheticBold(false) { 122 if (aOptions) { 123 if (aOptions->flags & wr::FontInstanceFlags::SYNTHETIC_BOLD) { 124 mApplySyntheticBold = true; 125 } 126 } 127 } 128 129 bool ScaledFontFreeType::HasVariationSettings() { 130 // Check if the FT face has been cloned. 131 return mFace && 132 mFace->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS && 133 mFace != 134 static_cast<UnscaledFontFreeType*>(mUnscaledFont.get())->GetFace(); 135 } 136 137 } // namespace gfx 138 } // namespace mozilla