author | Nicholas Nethercote <nnethercote@mozilla.com> |
Tue, 15 Dec 2015 13:56:40 -0800 | |
changeset 278265 | d7bca841b053dd36e56365c94e9c1bd8f5d6a15c |
parent 278264 | 2474921deb87a3e31d1ed9dac11b8d2eee8790e5 |
child 278266 | 7ad3f98c4c65b94b8576eeecd3a6685c13777358 |
push id | 29847 |
push user | cbook@mozilla.com |
push date | Mon, 04 Jan 2016 10:55:44 +0000 |
treeherder | autoland@0771c5eab32f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jfkthame |
bugs | 1232822 |
milestone | 46.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/thebes/gfxContext.cpp +++ b/gfx/thebes/gfxContext.cpp @@ -1291,91 +1291,8 @@ gfxContext::PushNewDT(gfxContentType con Save(); CurrentState().drawTarget = newDT; CurrentState().deviceOffset = clipBounds.TopLeft(); mDT = newDT; } -/** - * Work out whether cairo will snap inter-glyph spacing to pixels. - * - * Layout does not align text to pixel boundaries, so, with font drawing - * backends that snap glyph positions to pixels, it is important that - * inter-glyph spacing within words is always an integer number of pixels. - * This ensures that the drawing backend snaps all of the word's glyphs in the - * same direction and so inter-glyph spacing remains the same. - */ -void -gfxContext::GetRoundOffsetsToPixels(bool *aRoundX, bool *aRoundY) -{ - *aRoundX = false; - // 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 (CurrentMatrix().HasNonTranslation()) { - *aRoundY = false; - return; - } - - // All raster backends snap glyphs to pixels vertically. - // Print backends set CAIRO_HINT_METRICS_OFF. - *aRoundY = true; - - cairo_t *cr = gfxContext::RefCairo(GetDrawTarget()); - 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) { - *aRoundX = true; // default to the same as the fallback path below - return; - } - - // Sometimes hint metrics gets set for us, most notably for printing. - 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); - - switch (hint_metrics) { - case CAIRO_HINT_METRICS_OFF: - *aRoundY = false; - return; - 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; - } - 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; - } - break; - default: - break; - } - break; - case CAIRO_HINT_METRICS_ON: - break; - } - *aRoundX = true; -}
--- a/gfx/thebes/gfxContext.h +++ b/gfx/thebes/gfxContext.h @@ -440,19 +440,16 @@ public: void PushGroupAndCopyBackground(gfxContentType content = gfxContentType::COLOR, mozilla::gfx::Float aOpacity = 1.0f, mozilla::gfx::SourceSurface* aMask = nullptr, const mozilla::gfx::Matrix& aMaskTransform = mozilla::gfx::Matrix()); void PopGroupAndBlend(); mozilla::gfx::Point GetDeviceOffset() const; - // Work out whether cairo will snap inter-glyph spacing to pixels. - void GetRoundOffsetsToPixels(bool *aRoundX, bool *aRoundY); - #ifdef MOZ_DUMP_PAINTING /** * Debug functions to encode the current surface as a PNG and export it. */ /** * Writes a binary PNG file. */
--- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -544,16 +544,100 @@ gfxFontShaper::MergeFontFeatures( if (mergedFeatures.Count() != 0) { for (auto iter = mergedFeatures.Iter(); !iter.Done(); iter.Next()) { aHandleFeature(iter.Key(), iter.Data(), aHandleFeatureData); } } } +// Work out whether cairo will snap inter-glyph spacing to pixels. +// +// Layout does not align text to pixel boundaries, so, with font drawing +// backends that snap glyph positions to pixels, it is important that +// inter-glyph spacing within words is always an integer number of pixels. +// This ensures that the drawing backend snaps all of the word's glyphs in the +// same direction and so inter-glyph spacing remains the same. +// +/* static */ void +gfxFontShaper::GetRoundOffsetsToPixels(DrawTarget* aDrawTarget, + bool* aRoundX, bool* aRoundY) +{ + *aRoundX = false; + // 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()) { + *aRoundY = false; + return; + } + + // All raster backends snap glyphs to pixels vertically. + // Print backends set CAIRO_HINT_METRICS_OFF. + *aRoundY = true; + + cairo_t* cr = gfxContext::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) { + *aRoundX = true; // default to the same as the fallback path below + return; + } + + // Sometimes hint metrics gets set for us, most notably for printing. + 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); + + switch (hint_metrics) { + case CAIRO_HINT_METRICS_OFF: + *aRoundY = false; + return; + 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; + } + 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; + } + break; + default: + break; + } + break; + case CAIRO_HINT_METRICS_ON: + break; + } + *aRoundX = true; +} + void gfxShapedText::SetupClusterBoundaries(uint32_t aOffset, const char16_t *aString, uint32_t aLength) { CompressedGlyph *glyphs = GetCharacterGlyphs() + aOffset; gfxTextRun::CompressedGlyph extendCluster;
--- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -607,16 +607,18 @@ protected: * Platform-specific implementations designed to interface to platform * shaping APIs such as Uniscribe or CoreText may rely on features of a * specific font subclass to access native font references * (such as CTFont, HFONT, DWriteFont, etc). */ class gfxFontShaper { public: + typedef mozilla::gfx::DrawTarget DrawTarget; + explicit gfxFontShaper(gfxFont *aFont) : mFont(aFont) { NS_ASSERTION(aFont, "shaper requires a valid font!"); } virtual ~gfxFontShaper() { } @@ -639,16 +641,20 @@ public: bool aDisableLigatures, const nsAString& aFamilyName, bool aAddSmallCaps, void (*aHandleFeature)(const uint32_t&, uint32_t&, void*), void* aHandleFeatureData); protected: + // Work out whether cairo will snap inter-glyph spacing to pixels. + static void GetRoundOffsetsToPixels(DrawTarget* aDrawTarget, + bool* aRoundX, bool* aRoundY); + // the font this shaper is working with. The font owns a nsAutoPtr reference // to this object, and will destroy it before it dies. Thus, mFont will always // be valid. gfxFont* MOZ_NON_OWNING_REF mFont; }; /*
--- a/gfx/thebes/gfxGraphiteShaper.cpp +++ b/gfx/thebes/gfxGraphiteShaper.cpp @@ -263,19 +263,18 @@ gfxGraphiteShaper::SetGlyphsFromSegment( ++clusters[cIndex].nGlyphs; // extend cluster if necessary to reach the glyph's "after" index if (clusters[cIndex].baseChar + clusters[cIndex].nChars < after + 1) { clusters[cIndex].nChars = after + 1 - clusters[cIndex].baseChar; } } - bool roundX; - bool roundY; - aContext->GetRoundOffsetsToPixels(&roundX, &roundY); + bool roundX, roundY; + GetRoundOffsetsToPixels(aContext->GetDrawTarget(), &roundX, &roundY); gfxShapedText::CompressedGlyph *charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset; // now put glyphs into the textrun, one cluster at a time for (uint32_t i = 0; i <= cIndex; ++i) { const Cluster& c = clusters[i];
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp +++ b/gfx/thebes/gfxHarfBuzzShaper.cpp @@ -1612,22 +1612,22 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxC if (loc < wordLength) { charToGlyph[loc] = i; } } int32_t glyphStart = 0; // looking for a clump that starts at this glyph int32_t charStart = 0; // and this char index within the range of the run - bool roundI; - bool roundB; + bool roundI, roundB; + DrawTarget* drawTarget = aContext->GetDrawTarget(); if (aVertical) { - aContext->GetRoundOffsetsToPixels(&roundB, &roundI); + GetRoundOffsetsToPixels(drawTarget, &roundB, &roundI); } else { - aContext->GetRoundOffsetsToPixels(&roundI, &roundB); + GetRoundOffsetsToPixels(drawTarget, &roundI, &roundB); } int32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit(); gfxShapedText::CompressedGlyph *charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset; // factor to convert 16.16 fixed-point pixels to app units // (only used if not rounding)