зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1547063 - Use FreeType metrics directly instead of querying Cairo. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D44497 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1ad0ba9769
Коммит
0d6ebe2503
|
@ -1748,7 +1748,8 @@ class GFX2D_API Factory {
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
static already_AddRefed<ScaledFont> CreateScaledFontForFreeTypeFont(
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace);
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
|
||||
bool aApplySyntheticBold = false);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -642,9 +642,10 @@ already_AddRefed<ScaledFont> Factory::CreateScaledFontForFontconfigFont(
|
|||
#ifdef MOZ_WIDGET_ANDROID
|
||||
already_AddRefed<ScaledFont> Factory::CreateScaledFontForFreeTypeFont(
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace) {
|
||||
return MakeAndAddRef<ScaledFontFreeType>(aScaledFont, std::move(aFace),
|
||||
aUnscaledFont, aSize);
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace> aFace,
|
||||
bool aApplySyntheticBold) {
|
||||
return MakeAndAddRef<ScaledFontFreeType>(
|
||||
aScaledFont, std::move(aFace), aUnscaledFont, aSize, aApplySyntheticBold);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -98,12 +98,6 @@ ScaledFontFontconfig::InstanceData::InstanceData(
|
|||
embolden) {
|
||||
mFlags |= EMBOLDEN;
|
||||
}
|
||||
FcBool vertical;
|
||||
if (FcPatternGetBool(aPattern, FC_VERTICAL_LAYOUT, 0, &vertical) ==
|
||||
FcResultMatch &&
|
||||
vertical) {
|
||||
mFlags |= VERTICAL_LAYOUT;
|
||||
}
|
||||
|
||||
cairo_font_options_t* fontOptions = cairo_font_options_create();
|
||||
cairo_scaled_font_get_font_options(aScaledFont, fontOptions);
|
||||
|
@ -221,9 +215,6 @@ ScaledFontFontconfig::InstanceData::InstanceData(
|
|||
if (aOptions->flags & wr::FontInstanceFlags_SYNTHETIC_BOLD) {
|
||||
mFlags |= EMBOLDEN;
|
||||
}
|
||||
if (aOptions->flags & wr::FontInstanceFlags_VERTICAL_LAYOUT) {
|
||||
mFlags |= VERTICAL_LAYOUT;
|
||||
}
|
||||
if (aOptions->render_mode == wr::FontRenderMode::Subpixel) {
|
||||
mAntialias = AntialiasMode::SUBPIXEL;
|
||||
if (aOptions->flags & wr::FontInstanceFlags_SUBPIXEL_BGR) {
|
||||
|
@ -339,9 +330,6 @@ void ScaledFontFontconfig::InstanceData::SetupFontOptions(
|
|||
if (mFlags & AUTOHINT) {
|
||||
loadFlags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
}
|
||||
if (mFlags & VERTICAL_LAYOUT) {
|
||||
loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||
}
|
||||
if (mFlags & EMBOLDEN) {
|
||||
synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD;
|
||||
}
|
||||
|
@ -386,9 +374,6 @@ bool ScaledFontFontconfig::GetWRFontInstanceOptions(
|
|||
if (mInstanceData.mFlags & InstanceData::EMBOLDEN) {
|
||||
options.flags |= wr::FontInstanceFlags_SYNTHETIC_BOLD;
|
||||
}
|
||||
if (mInstanceData.mFlags & InstanceData::VERTICAL_LAYOUT) {
|
||||
options.flags |= wr::FontInstanceFlags_VERTICAL_LAYOUT;
|
||||
}
|
||||
if (mInstanceData.mFlags & InstanceData::EMBEDDED_BITMAP) {
|
||||
options.flags |= wr::FontInstanceFlags_EMBEDDED_BITMAPS;
|
||||
}
|
||||
|
|
|
@ -53,10 +53,9 @@ class ScaledFontFontconfig : public ScaledFontBase {
|
|||
AUTOHINT = 1 << 0,
|
||||
EMBEDDED_BITMAP = 1 << 1,
|
||||
EMBOLDEN = 1 << 2,
|
||||
VERTICAL_LAYOUT = 1 << 3,
|
||||
HINT_METRICS = 1 << 4,
|
||||
LCD_VERTICAL = 1 << 5,
|
||||
SUBPIXEL_BGR = 1 << 6,
|
||||
HINT_METRICS = 1 << 3,
|
||||
LCD_VERTICAL = 1 << 4,
|
||||
SUBPIXEL_BGR = 1 << 5,
|
||||
};
|
||||
|
||||
InstanceData(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern);
|
||||
|
|
|
@ -25,8 +25,11 @@ namespace gfx {
|
|||
// which is a requirement when we consider runtime switchable backends and so on
|
||||
ScaledFontFreeType::ScaledFontFreeType(
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFace,
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize)
|
||||
: ScaledFontBase(aUnscaledFont, aSize), mFace(std::move(aFace)) {
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
|
||||
bool aApplySyntheticBold)
|
||||
: ScaledFontBase(aUnscaledFont, aSize),
|
||||
mFace(std::move(aFace)),
|
||||
mApplySyntheticBold(aApplySyntheticBold) {
|
||||
SetCairoScaledFont(aScaledFont);
|
||||
}
|
||||
|
||||
|
@ -39,6 +42,10 @@ void ScaledFontFreeType::SetupSkFontDrawOptions(SkFont& aFont) {
|
|||
// SkFontHost_cairo does not support subpixel text positioning
|
||||
aFont.setSubpixel(false);
|
||||
|
||||
if (mApplySyntheticBold) {
|
||||
aFont.setEmbolden(true);
|
||||
}
|
||||
|
||||
aFont.setEmbeddedBitmaps(true);
|
||||
}
|
||||
#endif
|
||||
|
@ -51,7 +58,9 @@ bool ScaledFontFreeType::GetFontInstanceData(FontInstanceDataOutput aCb,
|
|||
mFace->GetFace());
|
||||
}
|
||||
|
||||
aCb(nullptr, 0, variations.data(), variations.size(), aBaton);
|
||||
InstanceData instance(this);
|
||||
aCb(reinterpret_cast<uint8_t*>(&instance), sizeof(instance),
|
||||
variations.data(), variations.size(), aBaton);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,6 +78,10 @@ bool ScaledFontFreeType::GetWRFontInstanceOptions(
|
|||
options.synthetic_italics =
|
||||
wr::DegreesToSyntheticItalics(GetSyntheticObliqueAngle());
|
||||
|
||||
if (mApplySyntheticBold) {
|
||||
options.flags |= wr::FontInstanceFlags_SYNTHETIC_BOLD;
|
||||
}
|
||||
|
||||
wr::FontInstancePlatformOptions platformOptions;
|
||||
platformOptions.lcd_filter = wr::FontLCDFilter::None;
|
||||
platformOptions.hinting = wr::FontHinting::None;
|
||||
|
@ -84,10 +97,28 @@ bool ScaledFontFreeType::GetWRFontInstanceOptions(
|
|||
return true;
|
||||
}
|
||||
|
||||
ScaledFontFreeType::InstanceData::InstanceData(
|
||||
const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions)
|
||||
: mApplySyntheticBold(false) {
|
||||
if (aOptions) {
|
||||
if (aOptions->flags & wr::FontInstanceFlags_SYNTHETIC_BOLD) {
|
||||
mApplySyntheticBold = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont> UnscaledFontFreeType::CreateScaledFont(
|
||||
Float aGlyphSize, const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength, const FontVariation* aVariations,
|
||||
uint32_t aNumVariations) {
|
||||
if (aInstanceDataLength < sizeof(ScaledFontFreeType::InstanceData)) {
|
||||
gfxWarning() << "FreeType scaled font instance data is truncated.";
|
||||
return nullptr;
|
||||
}
|
||||
const ScaledFontFreeType::InstanceData& instanceData =
|
||||
*reinterpret_cast<const ScaledFontFreeType::InstanceData*>(aInstanceData);
|
||||
|
||||
RefPtr<SharedFTFace> face(InitFace());
|
||||
if (!face) {
|
||||
gfxWarning() << "Attempted to deserialize FreeType scaled font without "
|
||||
|
@ -138,14 +169,24 @@ already_AddRefed<ScaledFont> UnscaledFontFreeType::CreateScaledFont(
|
|||
ApplyVariationsToFace(aVariations, aNumVariations, face->GetFace());
|
||||
}
|
||||
|
||||
RefPtr<ScaledFontFreeType> scaledFont = new ScaledFontFreeType(
|
||||
cairoScaledFont, std::move(face), this, aGlyphSize);
|
||||
RefPtr<ScaledFontFreeType> scaledFont =
|
||||
new ScaledFontFreeType(cairoScaledFont, std::move(face), this, aGlyphSize,
|
||||
instanceData.mApplySyntheticBold);
|
||||
|
||||
cairo_scaled_font_destroy(cairoScaledFont);
|
||||
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont> UnscaledFontFreeType::CreateScaledFontFromWRFont(
|
||||
Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions,
|
||||
const FontVariation* aVariations, uint32_t aNumVariations) {
|
||||
ScaledFontFreeType::InstanceData instanceData(aOptions, aPlatformOptions);
|
||||
return CreateScaledFont(aGlyphSize, reinterpret_cast<uint8_t*>(&instanceData),
|
||||
sizeof(instanceData), aVariations, aNumVariations);
|
||||
}
|
||||
|
||||
bool ScaledFontFreeType::HasVariationSettings() {
|
||||
// Check if the FT face has been cloned.
|
||||
return mFace &&
|
||||
|
|
|
@ -14,13 +14,16 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class UnscaledFontFreeType;
|
||||
|
||||
class ScaledFontFreeType : public ScaledFontBase {
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontFreeType, override)
|
||||
|
||||
ScaledFontFreeType(cairo_scaled_font_t* aScaledFont,
|
||||
RefPtr<SharedFTFace>&& aFace,
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
|
||||
const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize,
|
||||
bool aApplySyntheticBold = false);
|
||||
|
||||
FontType GetType() const override { return FontType::FREETYPE; }
|
||||
|
||||
|
@ -43,7 +46,21 @@ class ScaledFontFreeType : public ScaledFontBase {
|
|||
bool HasVariationSettings() override;
|
||||
|
||||
private:
|
||||
friend UnscaledFontFreeType;
|
||||
|
||||
RefPtr<SharedFTFace> mFace;
|
||||
|
||||
bool mApplySyntheticBold;
|
||||
|
||||
struct InstanceData {
|
||||
explicit InstanceData(ScaledFontFreeType* aScaledFont)
|
||||
: mApplySyntheticBold(aScaledFont->mApplySyntheticBold) {}
|
||||
|
||||
InstanceData(const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions);
|
||||
|
||||
bool mApplySyntheticBold;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -48,6 +48,11 @@ class UnscaledFontFreeType : public UnscaledFont {
|
|||
Float aGlyphSize, const uint8_t* aInstanceData,
|
||||
uint32_t aInstanceDataLength, const FontVariation* aVariations,
|
||||
uint32_t aNumVariations) override;
|
||||
|
||||
already_AddRefed<ScaledFont> CreateScaledFontFromWRFont(
|
||||
Float aGlyphSize, const wr::FontInstanceOptions* aOptions,
|
||||
const wr::FontInstancePlatformOptions* aPlatformOptions,
|
||||
const FontVariation* aVariations, uint32_t aNumVariations) override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
|
|
@ -471,17 +471,6 @@ bool gfxDWriteFont::HasBitmapStrikeForSize(uint32_t aSize) {
|
|||
|
||||
uint32_t gfxDWriteFont::GetSpaceGlyph() { return mSpaceGlyph; }
|
||||
|
||||
bool gfxDWriteFont::SetupCairoFont(DrawTarget* aDrawTarget) {
|
||||
cairo_scaled_font_t* scaledFont = InitCairoScaledFont();
|
||||
if (cairo_scaled_font_status(scaledFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return false;
|
||||
}
|
||||
cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), scaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gfxDWriteFont::IsValid() const { return mFontFace != nullptr; }
|
||||
|
||||
IDWriteFontFace* gfxDWriteFont::GetFontFace() { return mFontFace.get(); }
|
||||
|
@ -578,7 +567,7 @@ int32_t gfxDWriteFont::GetGlyphWidth(uint16_t aGID) {
|
|||
return width;
|
||||
}
|
||||
|
||||
bool gfxDWriteFont::GetForceGDIClassic() {
|
||||
bool gfxDWriteFont::GetForceGDIClassic() const {
|
||||
return static_cast<gfxDWriteFontEntry*>(mFontEntry.get())
|
||||
->GetForceGDIClassic() &&
|
||||
cairo_dwrite_get_cleartype_rendering_mode() < 0 &&
|
||||
|
@ -587,7 +576,7 @@ bool gfxDWriteFont::GetForceGDIClassic() {
|
|||
}
|
||||
|
||||
DWRITE_MEASURING_MODE
|
||||
gfxDWriteFont::GetMeasuringMode() {
|
||||
gfxDWriteFont::GetMeasuringMode() const {
|
||||
return GetForceGDIClassic()
|
||||
? DWRITE_MEASURING_MODE_GDI_CLASSIC
|
||||
: gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode();
|
||||
|
@ -701,3 +690,12 @@ already_AddRefed<ScaledFont> gfxDWriteFont::GetScaledFont(
|
|||
RefPtr<ScaledFont> scaledFont(mAzureScaledFont);
|
||||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
bool gfxDWriteFont::ShouldRoundXOffset(cairo_t* aCairo) const {
|
||||
// show_glyphs is implemented on the font and so is used for all Cairo
|
||||
// surface types; however, it may pixel-snap depending on the dwrite
|
||||
// rendering mode
|
||||
return GetForceGDIClassic() ||
|
||||
gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode() !=
|
||||
DWRITE_MEASURING_MODE_NATURAL;
|
||||
}
|
||||
|
|
|
@ -40,8 +40,6 @@ class gfxDWriteFont : public gfxFont {
|
|||
|
||||
uint32_t GetSpaceGlyph() override;
|
||||
|
||||
bool SetupCairoFont(DrawTarget* aDrawTarget) override;
|
||||
|
||||
bool AllowSubpixelAA() override { return mAllowManualShowGlyphs; }
|
||||
|
||||
bool IsValid() const;
|
||||
|
@ -69,6 +67,8 @@ class gfxDWriteFont : public gfxFont {
|
|||
already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
|
||||
mozilla::gfx::DrawTarget* aTarget) override;
|
||||
|
||||
bool ShouldRoundXOffset(cairo_t* aCairo) const override;
|
||||
|
||||
protected:
|
||||
cairo_scaled_font_t* InitCairoScaledFont();
|
||||
|
||||
|
@ -84,8 +84,8 @@ class gfxDWriteFont : public gfxFont {
|
|||
|
||||
gfxFloat MeasureGlyphWidth(uint16_t aGlyph);
|
||||
|
||||
DWRITE_MEASURING_MODE GetMeasuringMode();
|
||||
bool GetForceGDIClassic();
|
||||
DWRITE_MEASURING_MODE GetMeasuringMode() const;
|
||||
bool GetForceGDIClassic() const;
|
||||
|
||||
RefPtr<IDWriteFontFace> mFontFace;
|
||||
RefPtr<IDWriteFontFace1> mFontFace1; // may be unavailable on older DWrite
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include FT_ADVANCES_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
|
||||
#ifndef FT_LOAD_COLOR
|
||||
# define FT_LOAD_COLOR (1L << 20)
|
||||
#endif
|
||||
#ifndef FT_FACE_FLAG_COLOR
|
||||
# define FT_FACE_FLAG_COLOR (1L << 14)
|
||||
#endif
|
||||
|
@ -27,18 +30,15 @@ gfxFT2FontBase::gfxFT2FontBase(
|
|||
const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
|
||||
cairo_scaled_font_t* aScaledFont,
|
||||
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
|
||||
const gfxFontStyle* aFontStyle, gfxFloat aAdjustedSize)
|
||||
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden)
|
||||
: gfxFont(aUnscaledFont, aFontEntry, aFontStyle, kAntialiasDefault,
|
||||
aScaledFont),
|
||||
mFTFace(std::move(aFTFace)),
|
||||
mSpaceGlyph(0) {
|
||||
mEmbolden = aFontStyle->NeedsSyntheticBold(aFontEntry);
|
||||
|
||||
mSpaceGlyph(0),
|
||||
mFTLoadFlags(aLoadFlags | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH |
|
||||
FT_LOAD_COLOR),
|
||||
mEmbolden(aEmbolden) {
|
||||
cairo_scaled_font_reference(mScaledFont);
|
||||
|
||||
mAdjustedSize = aAdjustedSize;
|
||||
|
||||
InitMetrics();
|
||||
}
|
||||
|
||||
gfxFT2FontBase::~gfxFT2FontBase() { cairo_scaled_font_destroy(mScaledFont); }
|
||||
|
@ -114,22 +114,6 @@ uint32_t gfxFT2FontBase::GetGlyph(uint32_t aCharCode) {
|
|||
return slot->mGlyphIndex;
|
||||
}
|
||||
|
||||
void gfxFT2FontBase::GetGlyphExtents(uint32_t aGlyph,
|
||||
cairo_text_extents_t* aExtents) {
|
||||
MOZ_ASSERT(aExtents != nullptr, "aExtents must not be NULL");
|
||||
|
||||
cairo_glyph_t glyphs[1];
|
||||
glyphs[0].index = aGlyph;
|
||||
glyphs[0].x = 0.0;
|
||||
glyphs[0].y = 0.0;
|
||||
// cairo does some caching for us here but perhaps a small gain could be
|
||||
// made by caching more. It is usually only the advance that is needed,
|
||||
// so caching only the advance could allow many requests to be cached with
|
||||
// little memory use. Ideally this cache would be merged with
|
||||
// gfxGlyphExtents.
|
||||
cairo_scaled_font_glyph_extents(GetCairoScaledFont(), glyphs, 1, aExtents);
|
||||
}
|
||||
|
||||
// aScale is intended for a 16.16 x/y_scale of an FT_Size_Metrics
|
||||
static inline FT_Long ScaleRoundDesignUnits(FT_Short aDesignMetric,
|
||||
FT_Fixed aScale) {
|
||||
|
@ -159,13 +143,18 @@ static void SnapLineToPixels(gfxFloat& aOffset, gfxFloat& aSize) {
|
|||
* The return value is the glyph id of that glyph or zero if no such glyph
|
||||
* exists. aExtents is only set when this returns a non-zero glyph id.
|
||||
*/
|
||||
uint32_t gfxFT2FontBase::GetCharExtents(char aChar,
|
||||
cairo_text_extents_t* aExtents) {
|
||||
uint32_t gfxFT2FontBase::GetCharExtents(char aChar, gfxFloat* aWidth,
|
||||
gfxFloat* aHeight) {
|
||||
FT_UInt gid = GetGlyph(aChar);
|
||||
if (gid) {
|
||||
GetGlyphExtents(gid, aExtents);
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
if (gid && GetFTGlyphExtents(gid, &width, &height)) {
|
||||
*aWidth = FLOAT_FROM_16_16(width);
|
||||
*aHeight = FLOAT_FROM_26_6(height);
|
||||
return gid;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return gid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,16 +165,13 @@ uint32_t gfxFT2FontBase::GetCharExtents(char aChar,
|
|||
*/
|
||||
uint32_t gfxFT2FontBase::GetCharWidth(char aChar, gfxFloat* aWidth) {
|
||||
FT_UInt gid = GetGlyph(aChar);
|
||||
if (gid) {
|
||||
int32_t width;
|
||||
if (!GetFTGlyphAdvance(gid, &width)) {
|
||||
cairo_text_extents_t extents;
|
||||
GetGlyphExtents(gid, &extents);
|
||||
width = NS_lround(0x10000 * extents.x_advance);
|
||||
}
|
||||
int32_t width;
|
||||
if (gid && GetFTGlyphExtents(gid, &width)) {
|
||||
*aWidth = FLOAT_FROM_16_16(width);
|
||||
return gid;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return gid;
|
||||
}
|
||||
|
||||
void gfxFT2FontBase::InitMetrics() {
|
||||
|
@ -395,14 +381,15 @@ void gfxFT2FontBase::InitMetrics() {
|
|||
// hinting, but maybe the x extents are not quite right in some fancy
|
||||
// script fonts. CSS 2.1 suggests possibly using the height of an "o",
|
||||
// which would have a more consistent glyph across fonts.
|
||||
cairo_text_extents_t extents;
|
||||
if (GetCharExtents('x', &extents) && extents.y_bearing < 0.0) {
|
||||
mMetrics.xHeight = -extents.y_bearing;
|
||||
mMetrics.aveCharWidth = std::max(mMetrics.aveCharWidth, extents.x_advance);
|
||||
gfxFloat xWidth;
|
||||
gfxFloat xHeight;
|
||||
if (GetCharExtents('x', &xWidth, &xHeight) && xHeight < 0.0) {
|
||||
mMetrics.xHeight = -xHeight;
|
||||
mMetrics.aveCharWidth = std::max(mMetrics.aveCharWidth, xWidth);
|
||||
}
|
||||
|
||||
if (GetCharExtents('H', &extents) && extents.y_bearing < 0.0) {
|
||||
mMetrics.capHeight = -extents.y_bearing;
|
||||
if (GetCharExtents('H', &xWidth, &xHeight) && xHeight < 0.0) {
|
||||
mMetrics.capHeight = -xHeight;
|
||||
}
|
||||
|
||||
mMetrics.aveCharWidth = std::max(mMetrics.aveCharWidth, mMetrics.zeroWidth);
|
||||
|
@ -479,7 +466,27 @@ uint32_t gfxFT2FontBase::GetGlyph(uint32_t unicode,
|
|||
return GetGlyph(unicode);
|
||||
}
|
||||
|
||||
bool gfxFT2FontBase::GetFTGlyphAdvance(uint16_t aGID, int32_t* aAdvance) {
|
||||
FT_Fixed gfxFT2FontBase::GetEmboldenAdvance(FT_Face aFace, FT_Fixed aAdvance) {
|
||||
// If freetype emboldening is being used, and it's not a zero-width glyph,
|
||||
// adjust the advance to account for the increased width.
|
||||
if (!mEmbolden || !aAdvance) {
|
||||
return 0;
|
||||
}
|
||||
// This is the embolden "strength" used by FT_GlyphSlot_Embolden,
|
||||
// converted from 26.6 to 16.16
|
||||
FT_Fixed strength =
|
||||
FT_MulFix(aFace->units_per_EM, aFace->size->metrics.y_scale) / 24;
|
||||
if (aFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||
strength &= -64;
|
||||
if (!strength) {
|
||||
strength = 64;
|
||||
}
|
||||
}
|
||||
return strength << 10;
|
||||
}
|
||||
|
||||
bool gfxFT2FontBase::GetFTGlyphExtents(uint16_t aGID, int32_t* aAdvance,
|
||||
int32_t* aHeight) {
|
||||
gfxFT2LockedFace face(this);
|
||||
MOZ_ASSERT(face.get());
|
||||
if (!face.get()) {
|
||||
|
@ -488,23 +495,7 @@ bool gfxFT2FontBase::GetFTGlyphAdvance(uint16_t aGID, int32_t* aAdvance) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Due to bugs like 1435234 and 1440938, we currently prefer to fall back
|
||||
// to reading the advance from cairo extents, unless we're dealing with
|
||||
// a variation font (for which cairo metrics may be wrong, due to FreeType
|
||||
// bug 52683).
|
||||
if (!(face.get()->face_flags & FT_FACE_FLAG_SCALABLE) ||
|
||||
!(face.get()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hinting = gfxPlatform::GetPlatform()->FontHintingEnabled();
|
||||
int32_t flags =
|
||||
hinting ? FT_LOAD_ADVANCE_ONLY
|
||||
: FT_LOAD_ADVANCE_ONLY | FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
|
||||
if (face.get()->face_flags & FT_FACE_FLAG_TRICKY) {
|
||||
flags &= ~FT_LOAD_NO_AUTOHINT;
|
||||
}
|
||||
FT_Error ftError = Factory::LoadFTGlyph(face.get(), aGID, flags);
|
||||
FT_Error ftError = Factory::LoadFTGlyph(face.get(), aGID, mFTLoadFlags);
|
||||
if (ftError != FT_Err_Ok) {
|
||||
// FT_Face was somehow broken/invalid? Don't try to access glyph slot.
|
||||
// This probably shouldn't happen, but does: see bug 1440938.
|
||||
|
@ -512,27 +503,31 @@ bool gfxFT2FontBase::GetFTGlyphAdvance(uint16_t aGID, int32_t* aAdvance) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool hintMetrics = ShouldHintMetrics();
|
||||
|
||||
// Due to freetype bug 52683 we MUST use the linearHoriAdvance field when
|
||||
// dealing with a variation font. (And other fonts would have returned
|
||||
// earlier, so only variation fonts currently reach here.)
|
||||
FT_Fixed advance = face.get()->glyph->linearHoriAdvance;
|
||||
|
||||
// If freetype emboldening is being used, and it's not a zero-width glyph,
|
||||
// adjust the advance to account for the increased width.
|
||||
if (mEmbolden && advance > 0) {
|
||||
// This is the embolden "strength" used by FT_GlyphSlot_Embolden,
|
||||
// converted from 26.6 to 16.16
|
||||
FT_Fixed strength =
|
||||
1024 *
|
||||
FT_MulFix(face.get()->units_per_EM, face.get()->size->metrics.y_scale) /
|
||||
24;
|
||||
advance += strength;
|
||||
// dealing with a variation font; also use it for scalable fonts when not
|
||||
// applying hinting. Otherwise, prefer hinted width from glyph->advance.x.
|
||||
FT_Fixed advance;
|
||||
if (face.get()->glyph->format == FT_GLYPH_FORMAT_OUTLINE &&
|
||||
(!hintMetrics || FT_HAS_MULTIPLE_MASTERS(face.get()))) {
|
||||
advance = face.get()->glyph->linearHoriAdvance;
|
||||
} else {
|
||||
advance = face.get()->glyph->advance.x << 10; // convert 26.6 to 16.16
|
||||
}
|
||||
advance += GetEmboldenAdvance(face.get(), advance);
|
||||
if (hintMetrics && (mFTLoadFlags & FT_LOAD_NO_HINTING)) {
|
||||
advance = (advance + 0x8000) & 0xffff0000u;
|
||||
}
|
||||
*aAdvance = advance;
|
||||
|
||||
// Round the 16.16 fixed-point value to whole pixels for better consistency
|
||||
// with how cairo renders the glyphs.
|
||||
*aAdvance = (advance + 0x8000) & 0xffff0000u;
|
||||
|
||||
if (aHeight) {
|
||||
FT_F26Dot6 height = -face.get()->glyph->metrics.horiBearingY;
|
||||
if (hintMetrics && (mFTLoadFlags & FT_LOAD_NO_HINTING)) {
|
||||
height &= -64;
|
||||
}
|
||||
*aHeight = height;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -547,53 +542,14 @@ int32_t gfxFT2FontBase::GetGlyphWidth(uint16_t aGID) {
|
|||
return width;
|
||||
}
|
||||
|
||||
if (!GetFTGlyphAdvance(aGID, &width)) {
|
||||
cairo_text_extents_t extents;
|
||||
GetGlyphExtents(aGID, &extents);
|
||||
width = NS_lround(0x10000 * extents.x_advance);
|
||||
if (!GetFTGlyphExtents(aGID, &width)) {
|
||||
width = 0;
|
||||
}
|
||||
mGlyphWidths->Put(aGID, width);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
bool gfxFT2FontBase::SetupCairoFont(DrawTarget* aDrawTarget) {
|
||||
// The scaled font ctm is not relevant right here because
|
||||
// cairo_set_scaled_font does not record the scaled font itself, but
|
||||
// merely the font_face, font_matrix, font_options. The scaled_font used
|
||||
// for the target can be different from the scaled_font passed to
|
||||
// cairo_set_scaled_font. (Unfortunately we have measured only for an
|
||||
// identity ctm.)
|
||||
cairo_scaled_font_t* cairoFont = GetCairoScaledFont();
|
||||
|
||||
if (cairo_scaled_font_status(cairoFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return false;
|
||||
}
|
||||
// Thoughts on which font_options to set on the context:
|
||||
//
|
||||
// cairoFont has been created for screen rendering.
|
||||
//
|
||||
// When the context is being used for screen rendering, we should set
|
||||
// font_options such that the same scaled_font gets used (when the ctm is
|
||||
// the same). The use of explicit font_options recorded in
|
||||
// CreateScaledFont ensures that this will happen.
|
||||
//
|
||||
// XXXkt: For pdf and ps surfaces, I don't know whether it's better to
|
||||
// remove surface-specific options, or try to draw with the same
|
||||
// scaled_font that was used to measure. As the same font_face is being
|
||||
// used, its font_options will often override some values anyway (unless
|
||||
// perhaps we remove those from the FcPattern at face creation).
|
||||
//
|
||||
// I can't see any significant difference in printing, irrespective of
|
||||
// what is set here. It's too late to change things here as measuring has
|
||||
// already taken place. We should really be measuring with a different
|
||||
// font for pdf and ps surfaces (bug 403513).
|
||||
cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), cairoFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
// For variation fonts, figure out the variation coordinates to be applied
|
||||
// for each axis, in freetype's order (which may not match the order of
|
||||
// axes in mStyle.variationSettings, so we need to search by axis tag).
|
||||
|
|
|
@ -20,11 +20,10 @@ class gfxFT2FontBase : public gfxFont {
|
|||
const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
|
||||
cairo_scaled_font_t* aScaledFont,
|
||||
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, gfxFontEntry* aFontEntry,
|
||||
const gfxFontStyle* aFontStyle, gfxFloat aAdjustedSize = 0.0);
|
||||
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
|
||||
virtual ~gfxFT2FontBase();
|
||||
|
||||
uint32_t GetGlyph(uint32_t aCharCode);
|
||||
void GetGlyphExtents(uint32_t aGlyph, cairo_text_extents_t* aExtents);
|
||||
uint32_t GetSpaceGlyph() override;
|
||||
bool ProvidesGetGlyph() const override { return true; }
|
||||
virtual uint32_t GetGlyph(uint32_t unicode,
|
||||
|
@ -32,8 +31,6 @@ class gfxFT2FontBase : public gfxFont {
|
|||
bool ProvidesGlyphWidths() const override { return true; }
|
||||
int32_t GetGlyphWidth(uint16_t aGID) override;
|
||||
|
||||
bool SetupCairoFont(DrawTarget* aDrawTarget) override;
|
||||
|
||||
FontType GetType() const override { return FONT_TYPE_FT2; }
|
||||
|
||||
static void SetupVarCoords(FT_MM_Var* aMMVar,
|
||||
|
@ -44,23 +41,24 @@ class gfxFT2FontBase : public gfxFont {
|
|||
void UnlockFTFace();
|
||||
|
||||
private:
|
||||
uint32_t GetCharExtents(char aChar, cairo_text_extents_t* aExtents);
|
||||
uint32_t GetCharExtents(char aChar, gfxFloat* aWidth, gfxFloat* aHeight);
|
||||
uint32_t GetCharWidth(char aChar, gfxFloat* aWidth);
|
||||
|
||||
// Get advance of a single glyph from FreeType, and return true;
|
||||
// or return false if we should fall back to getting the glyph
|
||||
// extents from cairo instead.
|
||||
bool GetFTGlyphAdvance(uint16_t aGID, int32_t* aWidth);
|
||||
|
||||
void InitMetrics();
|
||||
// Get advance (and optionally height) of a single glyph from FreeType,
|
||||
// and return true, or return false if we failed.
|
||||
bool GetFTGlyphExtents(uint16_t aGID, int32_t* aWidth,
|
||||
int32_t* aHeight = nullptr);
|
||||
|
||||
protected:
|
||||
void InitMetrics();
|
||||
const Metrics& GetHorizontalMetrics() override;
|
||||
FT_Fixed GetEmboldenAdvance(FT_Face aFace, FT_Fixed aAdvance);
|
||||
|
||||
RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
|
||||
|
||||
uint32_t mSpaceGlyph;
|
||||
Metrics mMetrics;
|
||||
int mFTLoadFlags;
|
||||
bool mEmbolden;
|
||||
|
||||
// For variation/multiple-master fonts, this will be an array of the values
|
||||
|
|
|
@ -145,15 +145,25 @@ FTUserFontData* FT2FontEntry::GetUserFontData() {
|
|||
*/
|
||||
|
||||
cairo_scaled_font_t* FT2FontEntry::CreateScaledFont(
|
||||
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFace) {
|
||||
int flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
|
||||
? FT_LOAD_DEFAULT
|
||||
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
|
||||
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFace, int* aOutLoadFlags,
|
||||
unsigned int* aOutSynthFlags) {
|
||||
int loadFlags = gfxPlatform::GetPlatform()->FontHintingEnabled()
|
||||
? FT_LOAD_DEFAULT
|
||||
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
|
||||
if (aFace->GetFace()->face_flags & FT_FACE_FLAG_TRICKY) {
|
||||
flags &= ~FT_LOAD_NO_AUTOHINT;
|
||||
loadFlags &= ~FT_LOAD_NO_AUTOHINT;
|
||||
}
|
||||
|
||||
unsigned int synthFlags = 0;
|
||||
if (aStyle->NeedsSyntheticBold(this)) {
|
||||
synthFlags |= CAIRO_FT_SYNTHESIZE_BOLD;
|
||||
}
|
||||
|
||||
*aOutLoadFlags = loadFlags;
|
||||
*aOutSynthFlags = synthFlags;
|
||||
|
||||
cairo_font_face_t* cairoFace = cairo_ft_font_face_create_for_ft_face(
|
||||
aFace->GetFace(), flags, 0, aFace.get());
|
||||
aFace->GetFace(), loadFlags, synthFlags, aFace.get());
|
||||
if (!cairoFace) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -230,7 +240,10 @@ gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aStyle) {
|
|||
}
|
||||
}
|
||||
|
||||
cairo_scaled_font_t* scaledFont = CreateScaledFont(aStyle, face);
|
||||
int loadFlags;
|
||||
unsigned int synthFlags;
|
||||
cairo_scaled_font_t* scaledFont =
|
||||
CreateScaledFont(aStyle, face, &loadFlags, &synthFlags);
|
||||
if (!scaledFont) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -245,7 +258,8 @@ gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle* aStyle) {
|
|||
}
|
||||
|
||||
gfxFont* font =
|
||||
new gfxFT2Font(unscaledFont, scaledFont, std::move(face), this, aStyle);
|
||||
new gfxFT2Font(unscaledFont, scaledFont, std::move(face), this, aStyle,
|
||||
loadFlags, (synthFlags & CAIRO_FT_SYNTHESIZE_BOLD) != 0);
|
||||
cairo_scaled_font_destroy(scaledFont);
|
||||
return font;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ class FT2FontEntry : public gfxFontEntry {
|
|||
// Create a cairo_scaled_font for this face, with the given style.
|
||||
// This may fail and return null, so caller must be prepared to handle this.
|
||||
cairo_scaled_font_t* CreateScaledFont(
|
||||
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFace);
|
||||
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFace,
|
||||
int* aOutLoadFlags, unsigned int* aOutSynthFlags);
|
||||
|
||||
nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
|
||||
|
||||
|
|
|
@ -155,14 +155,14 @@ void gfxFT2Font::AddRange(const char16_t* aText, uint32_t aOffset,
|
|||
gfxFT2Font::gfxFT2Font(const RefPtr<UnscaledFontFreeType>& aUnscaledFont,
|
||||
cairo_scaled_font_t* aCairoFont,
|
||||
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
|
||||
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle)
|
||||
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
|
||||
int aLoadFlags, bool aEmbolden)
|
||||
: gfxFT2FontBase(aUnscaledFont, aCairoFont, std::move(aFTFace), aFontEntry,
|
||||
aFontStyle),
|
||||
aFontStyle, aLoadFlags, aEmbolden),
|
||||
mCharGlyphCache(32) {
|
||||
NS_ASSERTION(mFontEntry,
|
||||
"Unable to find font entry for font. Something is whack.");
|
||||
// TODO: use FreeType emboldening instead of multi-strike?
|
||||
mApplySyntheticBold = aFontStyle->NeedsSyntheticBold(aFontEntry);
|
||||
InitMetrics();
|
||||
}
|
||||
|
||||
gfxFT2Font::~gfxFT2Font() {}
|
||||
|
@ -170,7 +170,8 @@ gfxFT2Font::~gfxFT2Font() {}
|
|||
already_AddRefed<ScaledFont> gfxFT2Font::GetScaledFont(DrawTarget* aTarget) {
|
||||
if (!mAzureScaledFont) {
|
||||
mAzureScaledFont = Factory::CreateScaledFontForFreeTypeFont(
|
||||
GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace);
|
||||
GetUnscaledFont(), GetAdjustedSize(), GetCairoScaledFont(), mFTFace,
|
||||
GetStyle()->NeedsSyntheticBold(GetFontEntry()));
|
||||
InitializeScaledFont();
|
||||
}
|
||||
|
||||
|
@ -178,6 +179,10 @@ already_AddRefed<ScaledFont> gfxFT2Font::GetScaledFont(DrawTarget* aTarget) {
|
|||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
bool gfxFT2Font::ShouldHintMetrics() const {
|
||||
return !gfxPlatform::GetPlatform()->RequiresLinearZoom();
|
||||
}
|
||||
|
||||
void gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch,
|
||||
CachedGlyphData* gd) {
|
||||
if (!face->charmap || (face->charmap->encoding != FT_ENCODING_UNICODE &&
|
||||
|
@ -198,13 +203,7 @@ void gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch,
|
|||
return;
|
||||
}
|
||||
|
||||
FT_Int32 flags = gfxPlatform::GetPlatform()->FontHintingEnabled()
|
||||
? FT_LOAD_DEFAULT
|
||||
: (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
|
||||
if (face->face_flags & FT_FACE_FLAG_TRICKY) {
|
||||
flags &= ~FT_LOAD_NO_AUTOHINT;
|
||||
}
|
||||
FT_Error err = Factory::LoadFTGlyph(face, gid, flags);
|
||||
FT_Error err = Factory::LoadFTGlyph(face, gid, mFTLoadFlags);
|
||||
|
||||
if (err) {
|
||||
// hmm, this is weird, we failed to load a glyph that we had?
|
||||
|
@ -217,7 +216,8 @@ void gfxFT2Font::FillGlyphDataForChar(FT_Face face, uint32_t ch,
|
|||
gd->glyphIndex = gid;
|
||||
gd->lsbDelta = face->glyph->lsb_delta;
|
||||
gd->rsbDelta = face->glyph->rsb_delta;
|
||||
gd->xAdvance = face->glyph->advance.x;
|
||||
gd->xAdvance =
|
||||
face->glyph->advance.x + GetEmboldenAdvance(face, face->glyph->advance.x);
|
||||
}
|
||||
|
||||
void gfxFT2Font::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
||||
|
|
|
@ -22,7 +22,8 @@ class gfxFT2Font : public gfxFT2FontBase {
|
|||
gfxFT2Font(const RefPtr<mozilla::gfx::UnscaledFontFreeType>& aUnscaledFont,
|
||||
cairo_scaled_font_t* aCairoFont,
|
||||
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace,
|
||||
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle);
|
||||
FT2FontEntry* aFontEntry, const gfxFontStyle* aFontStyle,
|
||||
int aLoadFlags, bool aEmbolden);
|
||||
virtual ~gfxFT2Font();
|
||||
|
||||
FT2FontEntry* GetFontEntry();
|
||||
|
@ -30,6 +31,8 @@ class gfxFT2Font : public gfxFT2FontBase {
|
|||
already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
|
||||
DrawTarget* aTarget) override;
|
||||
|
||||
bool ShouldHintMetrics() const override;
|
||||
|
||||
void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const override;
|
||||
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
|
|
|
@ -527,11 +527,12 @@ double gfxFontconfigFontEntry::GetAspect() {
|
|||
|
||||
static void PrepareFontOptions(FcPattern* aPattern,
|
||||
cairo_font_options_t* aFontOptions,
|
||||
int* aOutLoadFlags,
|
||||
int* aOutLoadFlags, int* aOutLoadTarget,
|
||||
unsigned int* aOutSynthFlags) {
|
||||
NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions");
|
||||
|
||||
int loadFlags = FT_LOAD_DEFAULT;
|
||||
int loadTarget = 0;
|
||||
unsigned int synthFlags = 0;
|
||||
|
||||
// xxx - taken from the gfxFontconfigFonts code, needs to be reviewed
|
||||
|
@ -543,8 +544,8 @@ static void PrepareFontOptions(FcPattern* aPattern,
|
|||
}
|
||||
|
||||
// Font options are set explicitly here to improve cairo's caching
|
||||
// behavior and to record the relevant parts of the pattern for
|
||||
// SetupCairoFont (so that the pattern can be released).
|
||||
// behavior and to record the relevant parts of the pattern so that
|
||||
// the pattern can be released.
|
||||
//
|
||||
// Most font_options have already been set as defaults on the FcPattern
|
||||
// with cairo_ft_font_options_substitute(), then user and system
|
||||
|
@ -611,29 +612,28 @@ static void PrepareFontOptions(FcPattern* aPattern,
|
|||
}
|
||||
|
||||
cairo_hint_style_t hint_style;
|
||||
if (printing || !hinting) {
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
} else {
|
||||
int fc_hintstyle;
|
||||
if (FcPatternGetInteger(aPattern, FC_HINT_STYLE, 0, &fc_hintstyle) !=
|
||||
FcResultMatch) {
|
||||
fc_hintstyle = FC_HINT_FULL;
|
||||
}
|
||||
switch (fc_hintstyle) {
|
||||
case FC_HINT_NONE:
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
break;
|
||||
case FC_HINT_SLIGHT:
|
||||
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||
break;
|
||||
case FC_HINT_MEDIUM:
|
||||
default: // This fallback mirrors _get_pattern_ft_options in cairo.
|
||||
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||
break;
|
||||
case FC_HINT_FULL:
|
||||
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||
break;
|
||||
}
|
||||
int fc_hintstyle = FC_HINT_NONE;
|
||||
if ((!printing || hinting) &&
|
||||
FcPatternGetInteger(aPattern, FC_HINT_STYLE, 0, &fc_hintstyle) !=
|
||||
FcResultMatch) {
|
||||
fc_hintstyle = FC_HINT_FULL;
|
||||
}
|
||||
switch (fc_hintstyle) {
|
||||
case FC_HINT_NONE:
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
loadTarget = FT_LOAD_NO_HINTING;
|
||||
break;
|
||||
case FC_HINT_SLIGHT:
|
||||
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||
loadTarget = FT_LOAD_TARGET_LIGHT;
|
||||
break;
|
||||
case FC_HINT_MEDIUM:
|
||||
default: // This fallback mirrors _get_pattern_ft_options in cairo.
|
||||
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||
break;
|
||||
case FC_HINT_FULL:
|
||||
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||
break;
|
||||
}
|
||||
cairo_font_options_set_hint_style(aFontOptions, hint_style);
|
||||
|
||||
|
@ -676,10 +676,19 @@ static void PrepareFontOptions(FcPattern* aPattern,
|
|||
cairo_antialias_t antialias;
|
||||
if (!fc_antialias) {
|
||||
antialias = CAIRO_ANTIALIAS_NONE;
|
||||
if (fc_hintstyle != FC_HINT_NONE) {
|
||||
loadTarget = FT_LOAD_TARGET_MONO;
|
||||
}
|
||||
loadTarget |= FT_LOAD_MONOCHROME;
|
||||
} else if (rgba == FC_RGBA_NONE) {
|
||||
antialias = CAIRO_ANTIALIAS_GRAY;
|
||||
} else {
|
||||
antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||
if (fc_hintstyle == FC_HINT_FULL) {
|
||||
loadTarget = rgba == FC_RGBA_VRGB || rgba == FC_RGBA_VBGR
|
||||
? FT_LOAD_TARGET_LCD_V
|
||||
: FT_LOAD_TARGET_LCD;
|
||||
}
|
||||
}
|
||||
cairo_font_options_set_antialias(aFontOptions, antialias);
|
||||
|
||||
|
@ -719,13 +728,6 @@ static void PrepareFontOptions(FcPattern* aPattern,
|
|||
loadFlags |= FT_LOAD_FORCE_AUTOHINT;
|
||||
}
|
||||
|
||||
FcBool vertical;
|
||||
if (FcPatternGetBool(aPattern, FC_VERTICAL_LAYOUT, 0, &vertical) ==
|
||||
FcResultMatch &&
|
||||
vertical) {
|
||||
loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||
}
|
||||
|
||||
FcBool embolden;
|
||||
if (FcPatternGetBool(aPattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch &&
|
||||
embolden) {
|
||||
|
@ -733,12 +735,14 @@ static void PrepareFontOptions(FcPattern* aPattern,
|
|||
}
|
||||
|
||||
*aOutLoadFlags = loadFlags;
|
||||
*aOutLoadTarget = loadTarget;
|
||||
*aOutSynthFlags = synthFlags;
|
||||
}
|
||||
|
||||
cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
|
||||
FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
|
||||
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFTFace) {
|
||||
const gfxFontStyle* aStyle, RefPtr<SharedFTFace> aFTFace,
|
||||
int* aOutLoadFlags, unsigned int* aOutSynthFlags) {
|
||||
if (aStyle->NeedsSyntheticBold(this)) {
|
||||
FcPatternAddBool(aRenderPattern, FC_EMBOLDEN, FcTrue);
|
||||
}
|
||||
|
@ -762,8 +766,13 @@ cairo_scaled_font_t* gfxFontconfigFontEntry::CreateScaledFont(
|
|||
|
||||
cairo_font_options_t* fontOptions = cairo_font_options_create();
|
||||
int loadFlags;
|
||||
int loadTarget;
|
||||
unsigned int synthFlags;
|
||||
PrepareFontOptions(aRenderPattern, fontOptions, &loadFlags, &synthFlags);
|
||||
PrepareFontOptions(aRenderPattern, fontOptions, &loadFlags, &loadTarget,
|
||||
&synthFlags);
|
||||
|
||||
*aOutLoadFlags = loadFlags | loadTarget;
|
||||
*aOutSynthFlags = synthFlags;
|
||||
|
||||
cairo_font_face_t* face = cairo_ft_font_face_create_for_ft_face(
|
||||
aFTFace->GetFace(), loadFlags, synthFlags, aFTFace.get());
|
||||
|
@ -960,8 +969,10 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
cairo_scaled_font_t* scaledFont =
|
||||
CreateScaledFont(renderPattern, size, aFontStyle, face);
|
||||
int loadFlags;
|
||||
unsigned int synthFlags;
|
||||
cairo_scaled_font_t* scaledFont = CreateScaledFont(
|
||||
renderPattern, size, aFontStyle, face, &loadFlags, &synthFlags);
|
||||
|
||||
std::string file;
|
||||
int index = 0;
|
||||
|
@ -986,9 +997,9 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
|
|||
mUnscaledFontCache.Add(unscaledFont);
|
||||
}
|
||||
|
||||
gfxFont* newFont =
|
||||
new gfxFontconfigFont(unscaledFont, scaledFont, std::move(face),
|
||||
renderPattern, size, this, aFontStyle);
|
||||
gfxFont* newFont = new gfxFontconfigFont(
|
||||
unscaledFont, scaledFont, std::move(face), renderPattern, size, this,
|
||||
aFontStyle, loadFlags, (synthFlags & CAIRO_FT_SYNTHESIZE_BOLD) != 0);
|
||||
cairo_scaled_font_destroy(scaledFont);
|
||||
|
||||
return newFont;
|
||||
|
@ -1345,10 +1356,12 @@ gfxFontconfigFont::gfxFontconfigFont(
|
|||
const RefPtr<UnscaledFontFontconfig>& aUnscaledFont,
|
||||
cairo_scaled_font_t* aScaledFont, RefPtr<SharedFTFace>&& aFTFace,
|
||||
FcPattern* aPattern, gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
|
||||
const gfxFontStyle* aFontStyle)
|
||||
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden)
|
||||
: gfxFT2FontBase(aUnscaledFont, aScaledFont, std::move(aFTFace), aFontEntry,
|
||||
aFontStyle, aAdjustedSize),
|
||||
aFontStyle, aLoadFlags, aEmbolden),
|
||||
mPattern(aPattern) {
|
||||
mAdjustedSize = aAdjustedSize;
|
||||
InitMetrics();
|
||||
}
|
||||
|
||||
gfxFontconfigFont::~gfxFontconfigFont() {}
|
||||
|
@ -1366,6 +1379,10 @@ already_AddRefed<ScaledFont> gfxFontconfigFont::GetScaledFont(
|
|||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
bool gfxFontconfigFont::ShouldHintMetrics() const {
|
||||
return !GetStyle()->printerFont;
|
||||
}
|
||||
|
||||
gfxFcPlatformFontList::gfxFcPlatformFontList()
|
||||
: mLocalNames(64),
|
||||
mGenericMappings(32),
|
||||
|
|
|
@ -103,7 +103,8 @@ class gfxFontconfigFontEntry : public gfxFontEntry {
|
|||
// helper method for creating cairo font from pattern
|
||||
cairo_scaled_font_t* CreateScaledFont(
|
||||
FcPattern* aRenderPattern, gfxFloat aAdjustedSize,
|
||||
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFTFace);
|
||||
const gfxFontStyle* aStyle, RefPtr<mozilla::gfx::SharedFTFace> aFTFace,
|
||||
int* aOutLoadFlags, unsigned int* aOutSynthFlags);
|
||||
|
||||
// override to pull data from FTFace
|
||||
virtual nsresult CopyFontTable(uint32_t aTableTag,
|
||||
|
@ -209,7 +210,7 @@ class gfxFontconfigFont : public gfxFT2FontBase {
|
|||
cairo_scaled_font_t* aScaledFont,
|
||||
RefPtr<mozilla::gfx::SharedFTFace>&& aFTFace, FcPattern* aPattern,
|
||||
gfxFloat aAdjustedSize, gfxFontEntry* aFontEntry,
|
||||
const gfxFontStyle* aFontStyle);
|
||||
const gfxFontStyle* aFontStyle, int aLoadFlags, bool aEmbolden);
|
||||
|
||||
FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
|
||||
virtual FcPattern* GetPattern() const { return mPattern; }
|
||||
|
@ -217,6 +218,8 @@ class gfxFontconfigFont : public gfxFT2FontBase {
|
|||
virtual already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
|
||||
DrawTarget* aTarget) override;
|
||||
|
||||
bool ShouldHintMetrics() const override;
|
||||
|
||||
private:
|
||||
virtual ~gfxFontconfigFont();
|
||||
|
||||
|
|
|
@ -822,95 +822,45 @@ gfxFont::~gfxFont() {
|
|||
//
|
||||
gfxFont::RoundingFlags gfxFont::GetRoundOffsetsToPixels(
|
||||
DrawTarget* aDrawTarget) {
|
||||
RoundingFlags result = RoundingFlags(0);
|
||||
|
||||
// Could do something fancy here for ScaleFactors of
|
||||
// AxisAlignedTransforms, but we leave things simple.
|
||||
// Not much point rounding if a matrix will mess things up anyway.
|
||||
// Also return false for non-cairo contexts.
|
||||
if (aDrawTarget->GetTransform().HasNonTranslation()) {
|
||||
return result;
|
||||
// Also check if the font already knows hint metrics is off...
|
||||
if (aDrawTarget->GetTransform().HasNonTranslation() || !ShouldHintMetrics()) {
|
||||
return RoundingFlags(0);
|
||||
}
|
||||
|
||||
// All raster backends snap glyphs to pixels vertically.
|
||||
// Print backends set CAIRO_HINT_METRICS_OFF.
|
||||
result |= RoundingFlags::kRoundY;
|
||||
cairo_t* cr = nullptr;
|
||||
if (aDrawTarget->GetBackendType() == BackendType::CAIRO) {
|
||||
cr = static_cast<cairo_t*>(
|
||||
aDrawTarget->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
|
||||
cairo_surface_t* target = cairo_get_target(cr);
|
||||
|
||||
// If we can't set up the cairo font, bail out.
|
||||
if (!SetupCairoFont(aDrawTarget)) {
|
||||
return result;
|
||||
// Check whether the cairo surface's font options hint metrics.
|
||||
cairo_font_options_t* fontOptions = cairo_font_options_create();
|
||||
cairo_surface_get_font_options(target, fontOptions);
|
||||
cairo_hint_metrics_t hintMetrics =
|
||||
cairo_font_options_get_hint_metrics(fontOptions);
|
||||
cairo_font_options_destroy(fontOptions);
|
||||
|
||||
switch (hintMetrics) {
|
||||
case CAIRO_HINT_METRICS_OFF:
|
||||
return RoundingFlags(0);
|
||||
case CAIRO_HINT_METRICS_ON:
|
||||
return RoundingFlags::kRoundX | RoundingFlags::kRoundY;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_t* cr = gfxFont::RefCairo(aDrawTarget);
|
||||
cairo_scaled_font_t* scaled_font = cairo_get_scaled_font(cr);
|
||||
|
||||
// bug 1198921 - this sometimes fails under Windows for whatver reason
|
||||
NS_ASSERTION(scaled_font,
|
||||
"null cairo scaled font should never be returned "
|
||||
"by cairo_get_scaled_font");
|
||||
if (!scaled_font) {
|
||||
result |= RoundingFlags::kRoundX; // default to the same as the fallback
|
||||
// path below
|
||||
return result;
|
||||
if (ShouldRoundXOffset(cr)) {
|
||||
return RoundingFlags::kRoundX | RoundingFlags::kRoundY;
|
||||
} else {
|
||||
return RoundingFlags::kRoundY;
|
||||
}
|
||||
|
||||
// Sometimes hint metrics gets set for us, most notably for printing.
|
||||
#ifdef MOZ_TREE_CAIRO
|
||||
cairo_hint_metrics_t hint_metrics =
|
||||
cairo_scaled_font_get_hint_metrics(scaled_font);
|
||||
#else
|
||||
cairo_font_options_t* font_options = cairo_font_options_create();
|
||||
cairo_scaled_font_get_font_options(scaled_font, font_options);
|
||||
cairo_hint_metrics_t hint_metrics =
|
||||
cairo_font_options_get_hint_metrics(font_options);
|
||||
cairo_font_options_destroy(font_options);
|
||||
#endif
|
||||
|
||||
switch (hint_metrics) {
|
||||
case CAIRO_HINT_METRICS_OFF:
|
||||
result &= ~RoundingFlags::kRoundY;
|
||||
return result;
|
||||
case CAIRO_HINT_METRICS_DEFAULT:
|
||||
// Here we mimic what cairo surface/font backends do. Printing
|
||||
// surfaces have already been handled by hint_metrics. The
|
||||
// fallback show_glyphs implementation composites pixel-aligned
|
||||
// glyph surfaces, so we just pick surface/font combinations that
|
||||
// override this.
|
||||
switch (cairo_scaled_font_get_type(scaled_font)) {
|
||||
#if CAIRO_HAS_DWRITE_FONT // dwrite backend is not in std cairo releases yet
|
||||
case CAIRO_FONT_TYPE_DWRITE:
|
||||
// show_glyphs is implemented on the font and so is used for
|
||||
// all surface types; however, it may pixel-snap depending on
|
||||
// the dwrite rendering mode
|
||||
if (!cairo_dwrite_scaled_font_get_force_GDI_classic(scaled_font) &&
|
||||
gfxWindowsPlatform::GetPlatform()->DWriteMeasuringMode() ==
|
||||
DWRITE_MEASURING_MODE_NATURAL) {
|
||||
return result;
|
||||
}
|
||||
MOZ_FALLTHROUGH;
|
||||
#endif
|
||||
case CAIRO_FONT_TYPE_QUARTZ:
|
||||
// Quartz surfaces implement show_glyphs for Quartz fonts
|
||||
if (cairo_surface_get_type(cairo_get_target(cr)) ==
|
||||
CAIRO_SURFACE_TYPE_QUARTZ) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CAIRO_HINT_METRICS_ON:
|
||||
break;
|
||||
}
|
||||
result |= RoundingFlags::kRoundX;
|
||||
return result;
|
||||
}
|
||||
|
||||
gfxFloat gfxFont::GetGlyphHAdvance(DrawTarget* aDrawTarget, uint16_t aGID) {
|
||||
if (!SetupCairoFont(aDrawTarget)) {
|
||||
return 0;
|
||||
}
|
||||
if (ProvidesGlyphWidths()) {
|
||||
return GetGlyphWidth(aGID) / 65536.0;
|
||||
}
|
||||
|
@ -3396,38 +3346,6 @@ gfxFont* gfxFont::GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel) {
|
|||
return fe->FindOrMakeFont(&style, mUnicodeRangeMap);
|
||||
}
|
||||
|
||||
static void DestroyRefCairo(void* aData) {
|
||||
cairo_t* refCairo = static_cast<cairo_t*>(aData);
|
||||
MOZ_ASSERT(refCairo);
|
||||
cairo_destroy(refCairo);
|
||||
}
|
||||
|
||||
/* static */
|
||||
cairo_t* gfxFont::RefCairo(DrawTarget* aDT) {
|
||||
// DrawTargets that don't use a Cairo backend can be given a 1x1 "reference"
|
||||
// |cairo_t*|, stored in the DrawTarget's user data, for doing font-related
|
||||
// operations.
|
||||
static UserDataKey sRefCairo;
|
||||
|
||||
cairo_t* refCairo = nullptr;
|
||||
if (aDT->GetBackendType() == BackendType::CAIRO) {
|
||||
refCairo = static_cast<cairo_t*>(
|
||||
aDT->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
|
||||
if (refCairo) {
|
||||
return refCairo;
|
||||
}
|
||||
}
|
||||
|
||||
refCairo = static_cast<cairo_t*>(aDT->GetUserData(&sRefCairo));
|
||||
if (!refCairo) {
|
||||
refCairo = cairo_create(
|
||||
gfxPlatform::GetPlatform()->ScreenReferenceSurface()->CairoSurface());
|
||||
aDT->AddUserData(&sRefCairo, refCairo, DestroyRefCairo);
|
||||
}
|
||||
|
||||
return refCairo;
|
||||
}
|
||||
|
||||
gfxGlyphExtents* gfxFont::GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit) {
|
||||
uint32_t i, count = mGlyphExtentsArray.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
|
|
@ -1520,6 +1520,9 @@ class gfxFont {
|
|||
// when rendering to the given drawTarget.
|
||||
RoundingFlags GetRoundOffsetsToPixels(DrawTarget* aDrawTarget);
|
||||
|
||||
virtual bool ShouldHintMetrics() const { return true; }
|
||||
virtual bool ShouldRoundXOffset(cairo_t* aCairo) const { return true; }
|
||||
|
||||
// Font metrics
|
||||
struct Metrics {
|
||||
gfxFloat capHeight;
|
||||
|
@ -1686,13 +1689,9 @@ class gfxFont {
|
|||
|
||||
gfxGlyphExtents* GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit);
|
||||
|
||||
// You need to call SetupCairoFont on aDrawTarget just before calling this.
|
||||
void SetupGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphID,
|
||||
bool aNeedTight, gfxGlyphExtents* aExtents);
|
||||
|
||||
// This is called by the default Draw() implementation above.
|
||||
virtual bool SetupCairoFont(DrawTarget* aDrawTarget) = 0;
|
||||
|
||||
virtual bool AllowSubpixelAA() { return true; }
|
||||
|
||||
bool IsSyntheticBold() const { return mApplySyntheticBold; }
|
||||
|
@ -1862,11 +1861,6 @@ class gfxFont {
|
|||
// glyphs. This does not add a reference to the returned font.
|
||||
gfxFont* GetSubSuperscriptFont(int32_t aAppUnitsPerDevPixel);
|
||||
|
||||
/**
|
||||
* Return the reference cairo_t object from aDT.
|
||||
*/
|
||||
static cairo_t* RefCairo(mozilla::gfx::DrawTarget* aDT);
|
||||
|
||||
protected:
|
||||
virtual const Metrics& GetHorizontalMetrics() = 0;
|
||||
|
||||
|
|
|
@ -88,14 +88,6 @@ bool gfxGDIFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
return false;
|
||||
}
|
||||
|
||||
// Ensure the cairo font is set up, so there's no risk it'll fall back to
|
||||
// creating a "toy" font internally (see bug 544617).
|
||||
// We must check that this succeeded, otherwise we risk cairo creating the
|
||||
// wrong kind of font internally as a fallback (bug 744480).
|
||||
if (!SetupCairoFont(aDrawTarget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return gfxFont::ShapeText(aDrawTarget, aText, aOffset, aLength, aScript,
|
||||
aVertical, aRounding, aShapedText);
|
||||
}
|
||||
|
@ -104,17 +96,6 @@ const gfxFont::Metrics& gfxGDIFont::GetHorizontalMetrics() { return *mMetrics; }
|
|||
|
||||
uint32_t gfxGDIFont::GetSpaceGlyph() { return mSpaceGlyph; }
|
||||
|
||||
bool gfxGDIFont::SetupCairoFont(DrawTarget* aDrawTarget) {
|
||||
if (!mScaledFont ||
|
||||
cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return false;
|
||||
}
|
||||
cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), mScaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont> gfxGDIFont::GetScaledFont(DrawTarget* aTarget) {
|
||||
if (!mAzureScaledFont) {
|
||||
NativeFont nativeFont;
|
||||
|
|
|
@ -30,8 +30,6 @@ class gfxGDIFont : public gfxFont {
|
|||
/* overrides for the pure virtual methods in gfxFont */
|
||||
uint32_t GetSpaceGlyph() override;
|
||||
|
||||
bool SetupCairoFont(DrawTarget* aDrawTarget) override;
|
||||
|
||||
already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
|
||||
DrawTarget* aTarget) override;
|
||||
|
||||
|
|
|
@ -47,13 +47,11 @@ bool gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (aFont->SetupCairoFont(aDrawTarget)) {
|
||||
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
|
||||
++gGlyphExtentsSetupLazyTight;
|
||||
++gGlyphExtentsSetupLazyTight;
|
||||
#endif
|
||||
aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
|
||||
entry = mTightGlyphExtents.GetEntry(aGlyphID);
|
||||
}
|
||||
aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
|
||||
entry = mTightGlyphExtents.GetEntry(aGlyphID);
|
||||
if (!entry) {
|
||||
NS_WARNING("Could not get glyph extents");
|
||||
return false;
|
||||
|
|
|
@ -80,11 +80,6 @@ bool gfxGraphiteShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
// some font back-ends require this in order to get proper hinted metrics
|
||||
if (!mFont->SetupCairoFont(aDrawTarget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gfxFontStyle* style = mFont->GetStyle();
|
||||
|
||||
if (!mGrFont) {
|
||||
|
|
|
@ -1319,11 +1319,6 @@ bool gfxHarfBuzzShaper::ShapeText(DrawTarget* aDrawTarget,
|
|||
uint32_t aLength, Script aScript,
|
||||
bool aVertical, RoundingFlags aRounding,
|
||||
gfxShapedText* aShapedText) {
|
||||
// some font back-ends require this in order to get proper hinted metrics
|
||||
if (!mFont->SetupCairoFont(aDrawTarget)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mUseVerticalPresentationForms = false;
|
||||
|
||||
if (!Initialize()) {
|
||||
|
|
|
@ -230,16 +230,6 @@ bool gfxMacFont::ShapeText(DrawTarget* aDrawTarget, const char16_t* aText,
|
|||
aVertical, aRounding, aShapedText);
|
||||
}
|
||||
|
||||
bool gfxMacFont::SetupCairoFont(DrawTarget* aDrawTarget) {
|
||||
if (cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
|
||||
// Don't cairo_set_scaled_font as that would propagate the error to
|
||||
// the cairo_t, precluding any further drawing.
|
||||
return false;
|
||||
}
|
||||
cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget), mScaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
gfxFont::RunMetrics gfxMacFont::Measure(const gfxTextRun* aTextRun,
|
||||
uint32_t aStart, uint32_t aEnd,
|
||||
BoundingBoxType aBoundingBoxType,
|
||||
|
@ -581,6 +571,12 @@ already_AddRefed<ScaledFont> gfxMacFont::GetScaledFont(DrawTarget* aTarget) {
|
|||
return scaledFont.forget();
|
||||
}
|
||||
|
||||
bool gfxMacFont::ShouldRoundXOffset(cairo_t* aCairo) const {
|
||||
// Quartz surfaces implement show_glyphs for Quartz fonts
|
||||
return aCairo && cairo_surface_get_type(cairo_get_target(aCairo)) !=
|
||||
CAIRO_SURFACE_TYPE_QUARTZ;
|
||||
}
|
||||
|
||||
void gfxMacFont::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const {
|
||||
gfxFont::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
|
|
|
@ -27,8 +27,6 @@ class gfxMacFont : public gfxFont {
|
|||
/* overrides for the pure virtual methods in gfxFont */
|
||||
uint32_t GetSpaceGlyph() override { return mSpaceGlyph; }
|
||||
|
||||
bool SetupCairoFont(DrawTarget* aDrawTarget) override;
|
||||
|
||||
/* override Measure to add padding for antialiasing */
|
||||
RunMetrics Measure(const gfxTextRun* aTextRun, uint32_t aStart, uint32_t aEnd,
|
||||
BoundingBoxType aBoundingBoxType, DrawTarget* aDrawTargetForTightBoundingBox,
|
||||
|
@ -46,6 +44,8 @@ class gfxMacFont : public gfxFont {
|
|||
already_AddRefed<mozilla::gfx::ScaledFont> GetScaledFont(
|
||||
mozilla::gfx::DrawTarget* aTarget) override;
|
||||
|
||||
bool ShouldRoundXOffset(cairo_t* aCairo) const override;
|
||||
|
||||
void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const override;
|
||||
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
|
||||
|
|
|
@ -16,7 +16,7 @@ use freetype::freetype::{FT_Fixed, FT_Matrix, FT_Set_Transform, FT_String, FT_UL
|
|||
use freetype::freetype::{FT_Err_Unimplemented_Feature};
|
||||
use freetype::freetype::{FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_FORCE_AUTOHINT};
|
||||
use freetype::freetype::{FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH, FT_LOAD_NO_AUTOHINT};
|
||||
use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING, FT_LOAD_VERTICAL_LAYOUT};
|
||||
use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING};
|
||||
use freetype::freetype::{FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES};
|
||||
use freetype::freetype::{FT_FACE_FLAG_MULTIPLE_MASTERS};
|
||||
use freetype::succeeded;
|
||||
|
@ -415,9 +415,6 @@ impl FontContext {
|
|||
if !font.flags.contains(FontInstanceFlags::EMBEDDED_BITMAPS) {
|
||||
load_flags |= FT_LOAD_NO_BITMAP;
|
||||
}
|
||||
if font.flags.contains(FontInstanceFlags::VERTICAL_LAYOUT) {
|
||||
load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||
}
|
||||
|
||||
load_flags |= FT_LOAD_COLOR;
|
||||
load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
|
||||
|
|
Загрузка…
Ссылка в новой задаче