gfx/2d/ScaledFontBase.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     6 #include "ScaledFontBase.h"
     8 #ifdef USE_SKIA
     9 #include "PathSkia.h"
    10 #include "skia/SkEmptyShader.h"
    11 #include "skia/SkPaint.h"
    12 #endif
    14 #ifdef USE_CAIRO
    15 #include "PathCairo.h"
    16 #include "DrawTargetCairo.h"
    17 #include "HelpersCairo.h"
    18 #endif
    20 #include <vector>
    21 #include <cmath>
    23 using namespace std;
    25 namespace mozilla {
    26 namespace gfx {
    28 ScaledFontBase::~ScaledFontBase()
    29 {
    30 #ifdef USE_SKIA
    31   SkSafeUnref(mTypeface);
    32 #endif
    33 #ifdef USE_CAIRO_SCALED_FONT
    34   cairo_scaled_font_destroy(mScaledFont);
    35 #endif
    36 }
    38 ScaledFontBase::ScaledFontBase(Float aSize)
    39   : mSize(aSize)
    40 {
    41 #ifdef USE_SKIA
    42   mTypeface = nullptr;
    43 #endif
    44 #ifdef USE_CAIRO_SCALED_FONT
    45   mScaledFont = nullptr;
    46 #endif
    47 }
    49 #ifdef USE_SKIA
    50 SkPath
    51 ScaledFontBase::GetSkiaPathForGlyphs(const GlyphBuffer &aBuffer)
    52 {
    53   SkTypeface *typeFace = GetSkTypeface();
    54   MOZ_ASSERT(typeFace);
    56   SkPaint paint;
    57   paint.setTypeface(typeFace);
    58   paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    59   paint.setTextSize(SkFloatToScalar(mSize));
    61   std::vector<uint16_t> indices;
    62   std::vector<SkPoint> offsets;
    63   indices.resize(aBuffer.mNumGlyphs);
    64   offsets.resize(aBuffer.mNumGlyphs);
    66   for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
    67     indices[i] = aBuffer.mGlyphs[i].mIndex;
    68     offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x);
    69     offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y);
    70   }
    72   SkPath path;
    73   paint.getPosTextPath(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), &path);
    74   return path;
    75 }
    76 #endif
    78 TemporaryRef<Path>
    79 ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
    80 {
    81 #ifdef USE_SKIA
    82   if (aTarget->GetType() == BackendType::SKIA) {
    83     SkPath path = GetSkiaPathForGlyphs(aBuffer);
    84     return new PathSkia(path, FillRule::FILL_WINDING);
    85   }
    86 #endif
    87 #ifdef USE_CAIRO
    88   if (aTarget->GetType() == BackendType::CAIRO) {
    89     MOZ_ASSERT(mScaledFont);
    91     DrawTarget *dt = const_cast<DrawTarget*>(aTarget);
    92     cairo_t *ctx = static_cast<cairo_t*>(dt->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
    94     bool isNewContext = !ctx;
    95     if (!ctx) {
    96       ctx = cairo_create(DrawTargetCairo::GetDummySurface());
    97       cairo_matrix_t mat;
    98       GfxMatrixToCairoMatrix(aTarget->GetTransform(), mat);
    99       cairo_set_matrix(ctx, &mat);
   100     }
   102     cairo_set_scaled_font(ctx, mScaledFont);
   104     // Convert our GlyphBuffer into an array of Cairo glyphs.
   105     std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
   106     for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
   107       glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
   108       glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
   109       glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
   110     }
   112     cairo_new_path(ctx);
   114     cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
   116     RefPtr<PathCairo> newPath = new PathCairo(ctx);
   117     if (isNewContext) {
   118       cairo_destroy(ctx);
   119     }
   121     return newPath;
   122   }
   123 #endif
   124   return nullptr;
   125 }
   127 void
   128 ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint)
   129 {
   130 #ifdef USE_SKIA
   131   if (aBackendType == BackendType::SKIA) {
   132     PathBuilderSkia *builder = static_cast<PathBuilderSkia*>(aBuilder);
   133     builder->AppendPath(GetSkiaPathForGlyphs(aBuffer));
   134     return;
   135   }
   136 #endif
   137 #ifdef USE_CAIRO
   138   if (aBackendType == BackendType::CAIRO) {
   139     MOZ_ASSERT(mScaledFont);
   141     PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder);
   142     cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface());
   144     if (aTransformHint) {
   145       cairo_matrix_t mat;
   146       GfxMatrixToCairoMatrix(*aTransformHint, mat);
   147       cairo_set_matrix(ctx, &mat);
   148     }
   150     // Convert our GlyphBuffer into an array of Cairo glyphs.
   151     std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
   152     for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
   153       glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
   154       glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
   155       glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
   156     }
   158     cairo_set_scaled_font(ctx, mScaledFont);
   159     cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
   161     RefPtr<PathCairo> cairoPath = new PathCairo(ctx);
   162     cairo_destroy(ctx);
   164     cairoPath->AppendPathToBuilder(builder);
   165     return;
   166   }
   167 #endif
   169   MOZ_CRASH("The specified backend type is not supported by CopyGlyphsToBuilder");
   170 }
   172 #ifdef USE_CAIRO_SCALED_FONT
   173 void
   174 ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
   175 {
   176   MOZ_ASSERT(!mScaledFont);
   178   if (font == mScaledFont)
   179     return;
   181   if (mScaledFont)
   182     cairo_scaled_font_destroy(mScaledFont);
   184   mScaledFont = font;
   185   cairo_scaled_font_reference(mScaledFont);
   186 }
   187 #endif
   189 }
   190 }

mercurial