Bug 715513 - Implement text in the new 2D API's Cairo backend. r=jrmuizel
authorJoe Drew <joe@drew.ca>
Tue, 10 Jan 2012 13:26:59 -0500
changeset 84197 603df6854a5296c095df575bafd5f4353770d1ee
parent 84196 7349c6b4ac7f856f12b606894872c526e8ffae28
child 84198 b6f547939cfbb675b01ace20fc6482e3a8e348f9
push id4781
push userjdrew@mozilla.com
push dateWed, 11 Jan 2012 03:41:41 +0000
treeherdermozilla-inbound@603df6854a52 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs715513
milestone12.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 715513 - Implement text in the new 2D API's Cairo backend. r=jrmuizel
gfx/2d/DrawTargetCairo.cpp
gfx/2d/Factory.cpp
gfx/2d/Makefile.in
gfx/2d/ScaledFontCairo.cpp
gfx/2d/ScaledFontCairo.h
gfx/2d/Types.h
gfx/thebes/gfxFont.h
gfx/thebes/gfxPlatform.cpp
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -34,16 +34,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "DrawTargetCairo.h"
 
 #include "SourceSurfaceCairo.h"
 #include "PathCairo.h"
 #include "HelpersCairo.h"
+#include "ScaledFontCairo.h"
 
 #include "cairo.h"
 
 #include "Blur.h"
 
 #ifdef CAIRO_HAS_QUARTZ_SURFACE
 #include "cairo-quartz.h"
 #include <ApplicationServices/ApplicationServices.h>
@@ -584,16 +585,36 @@ DrawTargetCairo::Fill(const Path *aPath,
 
 void
 DrawTargetCairo::FillGlyphs(ScaledFont *aFont,
                             const GlyphBuffer &aBuffer,
                             const Pattern &aPattern,
                             const DrawOptions &aOptions)
 {
   AutoPrepareForDrawing prep(this, mContext);
+
+  if (aFont->GetType() != FONT_CAIRO)
+    return;
+
+  ScaledFontCairo* scaledFont = static_cast<ScaledFontCairo*>(aFont);
+  cairo_set_scaled_font(mContext, scaledFont->GetCairoScaledFont());
+
+  cairo_pattern_t* pat = GfxPatternToCairoPattern(aPattern, aOptions.mAlpha);
+  cairo_set_source(mContext, pat);
+  cairo_pattern_destroy(pat);
+
+  // Convert our GlyphBuffer into an array of Cairo glyphs.
+  std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
+  for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
+    glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
+    glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
+    glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
+  }
+
+  cairo_show_glyphs(mContext, &glyphs[0], aBuffer.mNumGlyphs);
 }
 
 void
 DrawTargetCairo::Mask(const Pattern &aSource,
                       const Pattern &aMask,
                       const DrawOptions &aOptions /* = DrawOptions() */)
 {
   AutoPrepareForDrawing prep(this, mContext);
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -34,16 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "2D.h"
 
 #ifdef USE_CAIRO
 #include "DrawTargetCairo.h"
+#include "ScaledFontCairo.h"
 #endif
 
 #ifdef USE_SKIA
 #include "DrawTargetSkia.h"
 #ifdef XP_MACOSX
 #include "ScaledFontMac.h"
 #endif
 #ifdef WIN32
@@ -134,16 +135,20 @@ Factory::CreateScaledFontForNativeFont(c
       return new ScaledFontWin(static_cast<gfxGDIFont*>(aNativeFont.mFont), aSize);
     }
 #endif
   case NATIVE_FONT_SKIA_FONT_FACE:
     {
       return new ScaledFontSkia(static_cast<gfxFont*>(aNativeFont.mFont), aSize);
     }
 #endif
+  case NATIVE_FONT_CAIRO_FONT_FACE:
+    {
+      return new ScaledFontCairo(static_cast<gfxFont*>(aNativeFont.mFont));
+    }
   default:
     gfxWarning() << "Invalid native font type specified.";
     return NULL;
   }
 }
 
 #ifdef WIN32
 TemporaryRef<DrawTarget>
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -63,16 +63,17 @@ EXPORTS_mozilla/gfx	= \
         Rect.h \
         Types.h \
 	$(NULL)
 
 CPPSRCS	= \
 	Factory.cpp \
         Matrix.cpp \
         DrawTargetCairo.cpp \
+        ScaledFontCairo.cpp \
         SourceSurfaceCairo.cpp \
         PathCairo.cpp \
         Blur.cpp \
         $(NULL)
 
 
 DEFINES += -DMOZ_GFX -DUSE_CAIRO
 
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontCairo.cpp
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ScaledFontCairo.h"
+
+#include "cairo.h"
+
+#include "PathCairo.h"
+#include "gfxFont.h"
+
+#include <vector>
+
+using namespace std;
+
+namespace mozilla {
+namespace gfx {
+
+ScaledFontCairo::ScaledFontCairo(gfxFont* aFont)
+{
+  mScaledFont = aFont->GetCairoScaledFont();
+  cairo_scaled_font_reference(mScaledFont);
+}
+
+ScaledFontCairo::~ScaledFontCairo()
+{
+  cairo_scaled_font_destroy(mScaledFont);
+}
+
+TemporaryRef<Path>
+ScaledFontCairo::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
+{
+  if (aTarget->GetType() != BACKEND_CAIRO) {
+    return NULL;
+  }
+
+  RefPtr<PathBuilder> builder_iface = aTarget->CreatePathBuilder();
+  PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(builder_iface.get());
+
+  // Manually build the path for the PathBuilder.
+  RefPtr<CairoPathContext> context = builder->GetPathContext();
+
+  cairo_set_scaled_font(*context, mScaledFont);
+
+  // Convert our GlyphBuffer into an array of Cairo glyphs.
+  std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
+  for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
+    glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
+    glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
+    glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
+  }
+
+  cairo_glyph_path(*context, &glyphs[0], aBuffer.mNumGlyphs);
+
+  return builder->Finish();
+}
+
+cairo_scaled_font_t*
+ScaledFontCairo::GetCairoScaledFont()
+{
+  return mScaledFont;
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/ScaledFontCairo.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Corporation code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_GFX_SCALEDFONTCAIRO_H_
+#define MOZILLA_GFX_SCALEDFONTCAIRO_H_
+
+#include "2D.h"
+
+class gfxFont;
+typedef struct _cairo_scaled_font cairo_scaled_font_t;
+
+namespace mozilla {
+namespace gfx {
+
+class ScaledFontCairo : public ScaledFont
+{
+public:
+  ScaledFontCairo(gfxFont* aFont);
+  virtual ~ScaledFontCairo();
+
+  virtual FontType GetType() const { return FONT_CAIRO; }
+
+  virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
+
+  cairo_scaled_font_t* GetCairoScaledFont();
+
+private:
+  cairo_scaled_font_t* mScaledFont;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_SCALEDFONTCAIRO_H_ */
--- a/gfx/2d/Types.h
+++ b/gfx/2d/Types.h
@@ -74,31 +74,33 @@ enum BackendType
   BACKEND_SKIA
 };
 
 enum FontType
 {
   FONT_DWRITE,
   FONT_GDI,
   FONT_MAC,
-  FONT_SKIA
+  FONT_SKIA,
+  FONT_CAIRO
 };
 
 enum NativeSurfaceType
 {
   NATIVE_SURFACE_D3D10_TEXTURE,
   NATIVE_SURFACE_CAIRO_SURFACE
 };
 
 enum NativeFontType
 {
   NATIVE_FONT_DWRITE_FONT_FACE,
   NATIVE_FONT_GDI_FONT_FACE,
   NATIVE_FONT_MAC_FONT_FACE,
-  NATIVE_FONT_SKIA_FONT_FACE
+  NATIVE_FONT_SKIA_FONT_FACE,
+  NATIVE_FONT_CAIRO_FONT_FACE
 };
 
 enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
 enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
 enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
 enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
 enum Snapping { SNAP_NONE, SNAP_ALIGNED };
 enum Filter { FILTER_LINEAR, FILTER_POINT };
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1123,16 +1123,18 @@ public:
             // outside the hinted outline.
             // Also NOTE: it is relatively expensive to request this,
             // as it does not use cached glyph extents in the font.
     } BoundingBoxType;
 
     const nsString& GetName() const { return mFontEntry->Name(); }
     const gfxFontStyle *GetStyle() const { return &mStyle; }
 
+    cairo_scaled_font_t* GetCairoScaledFont() { return mScaledFont; }
+
     virtual gfxFont* CopyWithAntialiasOption(AntialiasOption anAAOption) {
         // platforms where this actually matters should override
         return nsnull;
     }
 
     virtual gfxFloat GetAdjustedSize() {
         return mAdjustedSize > 0.0 ? mAdjustedSize : mStyle.size;
     }
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -511,17 +511,23 @@ gfxPlatform::GetSourceSurfaceForSurface(
   aSurface->SetData(&kSourceSurface, srcBuffer, SourceBufferDestroy);
 
   return srcBuffer;
 }
 
 RefPtr<ScaledFont>
 gfxPlatform::GetScaledFontForFont(gfxFont *aFont)
 {
-  return NULL;
+  NativeFont nativeFont;
+  nativeFont.mType = NATIVE_FONT_CAIRO_FONT_FACE;
+  nativeFont.mFont = aFont;
+  RefPtr<ScaledFont> scaledFont =
+    Factory::CreateScaledFontForNativeFont(nativeFont,
+                                           aFont->GetAdjustedSize());
+  return scaledFont;
 }
 
 cairo_user_data_key_t kDrawSourceSurface;
 static void
 DataSourceSurfaceDestroy(void *dataSourceSurface)
 {
       static_cast<DataSourceSurface*>(dataSourceSurface)->Release();
 }