LCOV - code coverage report
Current view: top level - gfx/2d - ScaledFontBase.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 19 136 14.0 %
Date: 2017-07-14 16:53:18 Functions: 4 12 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "ScaledFontBase.h"
       7             : 
       8             : #include "gfxPrefs.h"
       9             : 
      10             : #ifdef USE_SKIA
      11             : #include "PathSkia.h"
      12             : #include "skia/include/core/SkPaint.h"
      13             : #endif
      14             : 
      15             : #ifdef USE_CAIRO
      16             : #include "PathCairo.h"
      17             : #include "DrawTargetCairo.h"
      18             : #include "HelpersCairo.h"
      19             : #endif
      20             : 
      21             : #include <vector>
      22             : #include <cmath>
      23             : 
      24             : using namespace std;
      25             : 
      26             : namespace mozilla {
      27             : namespace gfx {
      28             : 
      29             : uint32_t UnscaledFont::sDeletionCounter = 0;
      30             : 
      31           0 : UnscaledFont::~UnscaledFont()
      32             : {
      33           0 :   sDeletionCounter++;
      34           0 : }
      35             : 
      36             : AntialiasMode
      37          21 : ScaledFont::GetDefaultAAMode()
      38             : {
      39          21 :   if (gfxPrefs::DisableAllTextAA()) {
      40           0 :     return AntialiasMode::NONE;
      41             :   }
      42             : 
      43          21 :   return AntialiasMode::DEFAULT;
      44             : }
      45             : 
      46          42 : ScaledFontBase::~ScaledFontBase()
      47             : {
      48             : #ifdef USE_SKIA
      49          21 :   SkSafeUnref(mTypeface);
      50             : #endif
      51             : #ifdef USE_CAIRO_SCALED_FONT
      52          21 :   cairo_scaled_font_destroy(mScaledFont);
      53             : #endif
      54          21 : }
      55             : 
      56          21 : ScaledFontBase::ScaledFontBase(const RefPtr<UnscaledFont>& aUnscaledFont,
      57          21 :                                Float aSize)
      58             :   : ScaledFont(aUnscaledFont)
      59          21 :   , mSize(aSize)
      60             : {
      61             : #ifdef USE_SKIA
      62          21 :   mTypeface = nullptr;
      63             : #endif
      64             : #ifdef USE_CAIRO_SCALED_FONT
      65          21 :   mScaledFont = nullptr;
      66             : #endif
      67          21 : }
      68             : 
      69             : #ifdef USE_CAIRO_SCALED_FONT
      70             : bool
      71           0 : ScaledFontBase::PopulateCairoScaledFont()
      72             : {
      73           0 :   cairo_font_face_t* cairoFontFace = GetCairoFontFace();
      74           0 :   if (!cairoFontFace) {
      75           0 :     return false;
      76             :   }
      77             : 
      78             :   cairo_matrix_t sizeMatrix;
      79             :   cairo_matrix_t identityMatrix;
      80             : 
      81           0 :   cairo_matrix_init_scale(&sizeMatrix, mSize, mSize);
      82           0 :   cairo_matrix_init_identity(&identityMatrix);
      83             : 
      84           0 :   cairo_font_options_t *fontOptions = cairo_font_options_create();
      85             : 
      86           0 :   mScaledFont = cairo_scaled_font_create(cairoFontFace, &sizeMatrix,
      87             :     &identityMatrix, fontOptions);
      88             : 
      89           0 :   cairo_font_options_destroy(fontOptions);
      90           0 :   cairo_font_face_destroy(cairoFontFace);
      91             : 
      92           0 :   return (cairo_scaled_font_status(mScaledFont) == CAIRO_STATUS_SUCCESS);
      93             : }
      94             : #endif
      95             : 
      96             : #ifdef USE_SKIA
      97             : SkPath
      98           0 : ScaledFontBase::GetSkiaPathForGlyphs(const GlyphBuffer &aBuffer)
      99             : {
     100           0 :   SkTypeface *typeFace = GetSkTypeface();
     101           0 :   MOZ_ASSERT(typeFace);
     102             : 
     103           0 :   SkPaint paint;
     104           0 :   paint.setTypeface(sk_ref_sp(typeFace));
     105           0 :   paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
     106           0 :   paint.setTextSize(SkFloatToScalar(mSize));
     107             : 
     108           0 :   std::vector<uint16_t> indices;
     109           0 :   std::vector<SkPoint> offsets;
     110           0 :   indices.resize(aBuffer.mNumGlyphs);
     111           0 :   offsets.resize(aBuffer.mNumGlyphs);
     112             : 
     113           0 :   for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
     114           0 :     indices[i] = aBuffer.mGlyphs[i].mIndex;
     115           0 :     offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x);
     116           0 :     offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y);
     117             :   }
     118             : 
     119           0 :   SkPath path;
     120           0 :   paint.getPosTextPath(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), &path);
     121           0 :   return path;
     122             : }
     123             : #endif
     124             : 
     125             : already_AddRefed<Path>
     126           0 : ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
     127             : {
     128             : #ifdef USE_SKIA
     129           0 :   if (aTarget->GetBackendType() == BackendType::SKIA) {
     130           0 :     SkPath path = GetSkiaPathForGlyphs(aBuffer);
     131           0 :     return MakeAndAddRef<PathSkia>(path, FillRule::FILL_WINDING);
     132             :   }
     133             : #endif
     134             : #ifdef USE_CAIRO
     135           0 :   if (aTarget->GetBackendType() == BackendType::CAIRO) {
     136           0 :     MOZ_ASSERT(mScaledFont);
     137             : 
     138           0 :     DrawTarget *dt = const_cast<DrawTarget*>(aTarget);
     139           0 :     cairo_t *ctx = static_cast<cairo_t*>(dt->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
     140             : 
     141           0 :     bool isNewContext = !ctx;
     142           0 :     if (!ctx) {
     143           0 :       ctx = cairo_create(DrawTargetCairo::GetDummySurface());
     144             :       cairo_matrix_t mat;
     145           0 :       GfxMatrixToCairoMatrix(aTarget->GetTransform(), mat);
     146           0 :       cairo_set_matrix(ctx, &mat);
     147             :     }
     148             : 
     149           0 :     cairo_set_scaled_font(ctx, mScaledFont);
     150             : 
     151             :     // Convert our GlyphBuffer into an array of Cairo glyphs.
     152           0 :     std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
     153           0 :     for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
     154           0 :       glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
     155           0 :       glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
     156           0 :       glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
     157             :     }
     158             : 
     159           0 :     cairo_new_path(ctx);
     160             : 
     161           0 :     cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
     162             : 
     163           0 :     RefPtr<PathCairo> newPath = new PathCairo(ctx);
     164           0 :     if (isNewContext) {
     165           0 :       cairo_destroy(ctx);
     166             :     }
     167             : 
     168           0 :     return newPath.forget();
     169             :   }
     170             : #endif
     171             : #ifdef USE_SKIA
     172           0 :   RefPtr<PathBuilder> builder = aTarget->CreatePathBuilder();
     173           0 :   SkPath skPath = GetSkiaPathForGlyphs(aBuffer);
     174           0 :   RefPtr<Path> path = MakeAndAddRef<PathSkia>(skPath, FillRule::FILL_WINDING);
     175           0 :   path->StreamToSink(builder);
     176           0 :   return builder->Finish();
     177             : #endif
     178             : }
     179             : 
     180             : void
     181           0 : ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint)
     182             : {
     183           0 :   BackendType backendType = aBuilder->GetBackendType();
     184             : #ifdef USE_SKIA
     185           0 :   if (backendType == BackendType::SKIA) {
     186           0 :     PathBuilderSkia *builder = static_cast<PathBuilderSkia*>(aBuilder);
     187           0 :     builder->AppendPath(GetSkiaPathForGlyphs(aBuffer));
     188           0 :     return;
     189             :   }
     190             : #endif
     191             : #ifdef USE_CAIRO
     192           0 :   if (backendType == BackendType::CAIRO) {
     193           0 :     MOZ_ASSERT(mScaledFont);
     194             : 
     195           0 :     PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder);
     196           0 :     cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface());
     197             : 
     198           0 :     if (aTransformHint) {
     199             :       cairo_matrix_t mat;
     200           0 :       GfxMatrixToCairoMatrix(*aTransformHint, mat);
     201           0 :       cairo_set_matrix(ctx, &mat);
     202             :     }
     203             : 
     204             :     // Convert our GlyphBuffer into an array of Cairo glyphs.
     205           0 :     std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
     206           0 :     for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
     207           0 :       glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
     208           0 :       glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
     209           0 :       glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
     210             :     }
     211             : 
     212           0 :     cairo_set_scaled_font(ctx, mScaledFont);
     213           0 :     cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
     214             : 
     215           0 :     RefPtr<PathCairo> cairoPath = new PathCairo(ctx);
     216           0 :     cairo_destroy(ctx);
     217             : 
     218           0 :     cairoPath->AppendPathToBuilder(builder);
     219           0 :     return;
     220             :   }
     221           0 :   if (backendType == BackendType::RECORDING) {
     222           0 :     SkPath skPath = GetSkiaPathForGlyphs(aBuffer);
     223           0 :     RefPtr<Path> path = MakeAndAddRef<PathSkia>(skPath, FillRule::FILL_WINDING);
     224           0 :     path->StreamToSink(aBuilder);
     225           0 :     return;
     226             :   }
     227           0 :   MOZ_ASSERT(false, "Path not being copied");
     228             : #endif
     229             : }
     230             : 
     231             : void
     232           0 : ScaledFontBase::GetGlyphDesignMetrics(const uint16_t* aGlyphs, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics)
     233             : {
     234             : #ifdef USE_CAIRO_SCALED_FONT
     235           0 :   if (mScaledFont) {
     236           0 :     for (uint32_t i = 0; i < aNumGlyphs; i++) {
     237             :       cairo_glyph_t glyph;
     238             :       cairo_text_extents_t extents;
     239           0 :       glyph.index = aGlyphs[i];
     240           0 :       glyph.x = 0;
     241           0 :       glyph.y = 0;
     242             : 
     243           0 :       cairo_scaled_font_glyph_extents(mScaledFont, &glyph, 1, &extents);
     244             : 
     245           0 :       aGlyphMetrics[i].mXBearing = extents.x_bearing;
     246           0 :       aGlyphMetrics[i].mXAdvance = extents.x_advance;
     247           0 :       aGlyphMetrics[i].mYBearing = extents.y_bearing;
     248           0 :       aGlyphMetrics[i].mYAdvance = extents.y_advance;
     249           0 :       aGlyphMetrics[i].mWidth = extents.width;
     250           0 :       aGlyphMetrics[i].mHeight = extents.height;
     251             : 
     252           0 :       cairo_font_options_t *options = cairo_font_options_create();
     253           0 :       cairo_scaled_font_get_font_options(mScaledFont, options);
     254             : 
     255           0 :       if (cairo_font_options_get_antialias(options) != CAIRO_ANTIALIAS_NONE) {
     256           0 :         if (cairo_scaled_font_get_type(mScaledFont) == CAIRO_FONT_TYPE_WIN32) {
     257           0 :           if (aGlyphMetrics[i].mWidth > 0 && aGlyphMetrics[i].mHeight > 0) {
     258           0 :             aGlyphMetrics[i].mWidth -= 3.0f;
     259           0 :             aGlyphMetrics[i].mXBearing += 1.0f;
     260             :           }
     261             :         }
     262             : #if defined(MOZ2D_HAS_MOZ_CAIRO) && defined(CAIRO_HAS_DWRITE_FONT)
     263             :         else if (cairo_scaled_font_get_type(mScaledFont) == CAIRO_FONT_TYPE_DWRITE) {
     264             :           if (aGlyphMetrics[i].mWidth > 0 && aGlyphMetrics[i].mHeight > 0) {
     265             :             aGlyphMetrics[i].mWidth -= 2.0f;
     266             :             aGlyphMetrics[i].mXBearing += 1.0f;
     267             :           }
     268             :         }
     269             : #endif
     270             :       }
     271           0 :       cairo_font_options_destroy(options);
     272             :     }
     273             : 
     274             :   }
     275             : #endif
     276             : 
     277             :   // Don't know how to get the glyph metrics...
     278           0 :   MOZ_CRASH("The specific backend type is not supported for GetGlyphDesignMetrics.");
     279             : }
     280             : 
     281             : 
     282             : #ifdef USE_CAIRO_SCALED_FONT
     283             : void
     284          21 : ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
     285             : {
     286          21 :   MOZ_ASSERT(!mScaledFont);
     287             : 
     288          21 :   if (font == mScaledFont)
     289           0 :     return;
     290             : 
     291          21 :   if (mScaledFont)
     292           0 :     cairo_scaled_font_destroy(mScaledFont);
     293             : 
     294          21 :   mScaledFont = font;
     295          21 :   cairo_scaled_font_reference(mScaledFont);
     296             : }
     297             : #endif
     298             : 
     299             : } // namespace gfx
     300             : } // namespace mozilla

Generated by: LCOV version 1.13