Bug 761890 (was 746883); bug fixing Skia fonts; r=gw280
authorNicholas Cameron <ncameron@mozilla.com>
Thu, 26 Apr 2012 10:04:35 +1200
changeset 96681 856142f345119d90be2e73e127303e5a8c854bcf
parent 96680 c2539605ff4957b9cc6b3210990273da44885978
child 96682 e3af4396672dc74d87431709d357c05b6a842fa1
push id22934
push useremorley@mozilla.com
push dateFri, 15 Jun 2012 12:37:14 +0000
treeherdermozilla-central@892f95753777 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw280
bugs761890, 746883
milestone16.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
Bug 761890 (was 746883); bug fixing Skia fonts; r=gw280
gfx/2d/DrawTargetSkia.cpp
gfx/2d/ScaledFontDWrite.cpp
gfx/skia/patches/0013-Bug-761890-fonts.patch
gfx/skia/patches/README
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -437,16 +437,17 @@ DrawTargetSkia::FillRect(const Rect &aRe
 
 void
 DrawTargetSkia::Stroke(const Path *aPath,
                        const Pattern &aPattern,
                        const StrokeOptions &aStrokeOptions,
                        const DrawOptions &aOptions)
 {
   MarkChanged();
+  MOZ_ASSERT(aPath, "Null path");
   if (aPath->GetBackendType() != BACKEND_SKIA) {
     return;
   }
 
   const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
 
 
   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
@@ -509,17 +510,19 @@ DrawTargetSkia::Fill(const Path *aPath,
 
 void
 DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
                            const GlyphBuffer &aBuffer,
                            const Pattern &aPattern,
                            const DrawOptions &aOptions,
                            const GlyphRenderingOptions*)
 {
-  if (aFont->GetType() != FONT_MAC && aFont->GetType() != FONT_SKIA) {
+  if (aFont->GetType() != FONT_MAC &&
+      aFont->GetType() != FONT_SKIA &&
+      aFont->GetType() != FONT_GDI) {
     return;
   }
 
   MarkChanged();
 
   ScaledFontBase* skiaFont = static_cast<ScaledFontBase*>(aFont);
 
   AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
--- a/gfx/2d/ScaledFontDWrite.cpp
+++ b/gfx/2d/ScaledFontDWrite.cpp
@@ -1,26 +1,28 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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 "ScaledFontDWrite.h"
 #include "PathD2D.h"
+#include "Logging.h"
 
 #include <vector>
 
 namespace mozilla {
 namespace gfx {
 
 TemporaryRef<Path>
 ScaledFontDWrite::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
 {
   if (aTarget->GetType() != BACKEND_DIRECT2D) {
     // For now we only support Direct2D.
+    gfxWarning() << "Attempt to use Direct Write font with non-Direct2D backend";
     return NULL;
   }
 
   RefPtr<PathBuilder> pathBuilder = aTarget->CreatePathBuilder();
 
   PathBuilderD2D *pathBuilderD2D =
     static_cast<PathBuilderD2D*>(pathBuilder.get());
 
new file mode 100644
--- /dev/null
+++ b/gfx/skia/patches/0013-Bug-761890-fonts.patch
@@ -0,0 +1,162 @@
+# HG changeset patch
+# User Nicholas Cameron <ncameron@mozilla.com>
+# Date 1337146927 -43200
+# Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821
+# Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8
+Bug 746883; changes to the Skia library. r=gw280
+
+diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h
+--- a/gfx/skia/include/core/SkDraw.h
++++ b/gfx/skia/include/core/SkDraw.h
+@@ -125,23 +125,24 @@ public:
+ #endif
+ };
+ 
+ class SkGlyphCache;
+ 
+ class SkTextToPathIter {
+ public:
+     SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
+-                     bool applyStrokeAndPathEffects);
++                     bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true);
+     ~SkTextToPathIter();
+ 
+     const SkPaint&  getPaint() const { return fPaint; }
+     SkScalar        getPathScale() const { return fScale; }
+ 
+     const SkPath*   next(SkScalar* xpos);   //!< returns nil when there are no more paths
++    bool            nextWithWhitespace(const SkPath** path, SkScalar* xpos);   //!< returns false when there are no more paths
+ 
+ private:
+     SkGlyphCache*   fCache;
+     SkPaint         fPaint;
+     SkScalar        fScale;
+     SkFixed         fPrevAdvance;
+     const char*     fText;
+     const char*     fStop;
+diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp
+--- a/gfx/skia/src/core/SkPaint.cpp
++++ b/gfx/skia/src/core/SkPaint.cpp
+@@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void*
+                              const SkPoint pos[], SkPath* path) const {
+     SkASSERT(length == 0 || textData != NULL);
+ 
+     const char* text = (const char*)textData;
+     if (text == NULL || length == 0 || path == NULL) {
+         return;
+     }
+ 
+-    SkTextToPathIter    iter(text, length, *this, false);
++    SkTextToPathIter    iter(text, length, *this, false, false);
+     SkMatrix            matrix;
+     SkPoint             prevPos;
+     prevPos.set(0, 0);
+ 
+     matrix.setScale(iter.getPathScale(), iter.getPathScale());
+     path->reset();
+ 
+     unsigned int    i = 0;
+     const SkPath*   iterPath;
+-    while ((iterPath = iter.next(NULL)) != NULL) {
+-        matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
+-        path->addPath(*iterPath, matrix);
+-        prevPos = pos[i];
++    while (iter.nextWithWhitespace(&iterPath, NULL)) {
++        if (iterPath) {
++            matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
++            path->addPath(*iterPath, matrix);
++            prevPos = pos[i];
++        }
+         i++;
+     }
+ }
+ 
+ static void add_flattenable(SkDescriptor* desc, uint32_t tag,
+                             SkFlattenableWriteBuffer* buffer) {
+     buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
+ }
+@@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun
+ 
+ static bool has_thick_frame(const SkPaint& paint) {
+     return  paint.getStrokeWidth() > 0 &&
+             paint.getStyle() != SkPaint::kFill_Style;
+ }
+ 
+ SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
+                                     const SkPaint& paint,
+-                                    bool applyStrokeAndPathEffects)
++                                    bool applyStrokeAndPathEffects,
++                                    bool useCanonicalTextSize)
+                                     : fPaint(paint) {
+     fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
+                                                 true);
+ 
+     fPaint.setLinearText(true);
+     fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
+ 
+     if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
+         applyStrokeAndPathEffects = false;
+     }
+ 
+     // can't use our canonical size if we need to apply patheffects
+-    if (fPaint.getPathEffect() == NULL) {
++    if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) {
+         fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
+         fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
+         if (has_thick_frame(fPaint)) {
+             fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
+         }
+     } else {
+         fScale = SK_Scalar1;
+     }
+@@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons
+     fXYIndex = paint.isVerticalText() ? 1 : 0;
+ }
+ 
+ SkTextToPathIter::~SkTextToPathIter() {
+     SkGlyphCache::AttachCache(fCache);
+ }
+ 
+ const SkPath* SkTextToPathIter::next(SkScalar* xpos) {
+-    while (fText < fStop) {
++    const SkPath* result;
++    while (nextWithWhitespace(&result, xpos)) {
++        if (result) {
++            if (xpos) {
++                *xpos = fXPos;
++            }
++            return result;
++        }
++    }
++    return NULL;
++}
++
++bool SkTextToPathIter::nextWithWhitespace(const SkPath** path, SkScalar* xpos) {
++    if (fText < fStop) {
+         const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
+ 
+         fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
+         fPrevAdvance = advance(glyph, fXYIndex);   // + fPaint.getTextTracking();
+ 
+         if (glyph.fWidth) {
+             if (xpos) {
+                 *xpos = fXPos;
+             }
+-            return fCache->findPath(glyph);
++            *path = fCache->findPath(glyph);
++            return true;
++        } else {
++            *path = NULL;
++            return true;
+         }
+     }
+-    return NULL;
++    return false;
+ }
+ 
+ ///////////////////////////////////////////////////////////////////////////////
+ 
+ bool SkPaint::nothingToDraw() const {
+     if (fLooper) {
+         return false;
+     }
--- a/gfx/skia/patches/README
+++ b/gfx/skia/patches/README
@@ -10,8 +10,9 @@ 0004-Bug-722011-Fix-trailing-commas-in-e
 0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch
 0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch
 0007-Bug-719872-Old-Android-FontHost.patch
 0008-Bug-687188-Skia-radial-gradients.patch
 0009-Bug-755869-FreeBSD-Hurd.patch
 0010-Bug-689069-ARM-Opts.patch
 0011-Bug-719575-Fix-clang-build.patch
 0012-Bug-759683-make-ssse3-conditional.patch
+0013-Bug-761890-fonts.patch