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.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "ScaledFontBase.h"
michael@0 7
michael@0 8 #ifdef USE_SKIA
michael@0 9 #include "PathSkia.h"
michael@0 10 #include "skia/SkEmptyShader.h"
michael@0 11 #include "skia/SkPaint.h"
michael@0 12 #endif
michael@0 13
michael@0 14 #ifdef USE_CAIRO
michael@0 15 #include "PathCairo.h"
michael@0 16 #include "DrawTargetCairo.h"
michael@0 17 #include "HelpersCairo.h"
michael@0 18 #endif
michael@0 19
michael@0 20 #include <vector>
michael@0 21 #include <cmath>
michael@0 22
michael@0 23 using namespace std;
michael@0 24
michael@0 25 namespace mozilla {
michael@0 26 namespace gfx {
michael@0 27
michael@0 28 ScaledFontBase::~ScaledFontBase()
michael@0 29 {
michael@0 30 #ifdef USE_SKIA
michael@0 31 SkSafeUnref(mTypeface);
michael@0 32 #endif
michael@0 33 #ifdef USE_CAIRO_SCALED_FONT
michael@0 34 cairo_scaled_font_destroy(mScaledFont);
michael@0 35 #endif
michael@0 36 }
michael@0 37
michael@0 38 ScaledFontBase::ScaledFontBase(Float aSize)
michael@0 39 : mSize(aSize)
michael@0 40 {
michael@0 41 #ifdef USE_SKIA
michael@0 42 mTypeface = nullptr;
michael@0 43 #endif
michael@0 44 #ifdef USE_CAIRO_SCALED_FONT
michael@0 45 mScaledFont = nullptr;
michael@0 46 #endif
michael@0 47 }
michael@0 48
michael@0 49 #ifdef USE_SKIA
michael@0 50 SkPath
michael@0 51 ScaledFontBase::GetSkiaPathForGlyphs(const GlyphBuffer &aBuffer)
michael@0 52 {
michael@0 53 SkTypeface *typeFace = GetSkTypeface();
michael@0 54 MOZ_ASSERT(typeFace);
michael@0 55
michael@0 56 SkPaint paint;
michael@0 57 paint.setTypeface(typeFace);
michael@0 58 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
michael@0 59 paint.setTextSize(SkFloatToScalar(mSize));
michael@0 60
michael@0 61 std::vector<uint16_t> indices;
michael@0 62 std::vector<SkPoint> offsets;
michael@0 63 indices.resize(aBuffer.mNumGlyphs);
michael@0 64 offsets.resize(aBuffer.mNumGlyphs);
michael@0 65
michael@0 66 for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
michael@0 67 indices[i] = aBuffer.mGlyphs[i].mIndex;
michael@0 68 offsets[i].fX = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.x);
michael@0 69 offsets[i].fY = SkFloatToScalar(aBuffer.mGlyphs[i].mPosition.y);
michael@0 70 }
michael@0 71
michael@0 72 SkPath path;
michael@0 73 paint.getPosTextPath(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), &path);
michael@0 74 return path;
michael@0 75 }
michael@0 76 #endif
michael@0 77
michael@0 78 TemporaryRef<Path>
michael@0 79 ScaledFontBase::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
michael@0 80 {
michael@0 81 #ifdef USE_SKIA
michael@0 82 if (aTarget->GetType() == BackendType::SKIA) {
michael@0 83 SkPath path = GetSkiaPathForGlyphs(aBuffer);
michael@0 84 return new PathSkia(path, FillRule::FILL_WINDING);
michael@0 85 }
michael@0 86 #endif
michael@0 87 #ifdef USE_CAIRO
michael@0 88 if (aTarget->GetType() == BackendType::CAIRO) {
michael@0 89 MOZ_ASSERT(mScaledFont);
michael@0 90
michael@0 91 DrawTarget *dt = const_cast<DrawTarget*>(aTarget);
michael@0 92 cairo_t *ctx = static_cast<cairo_t*>(dt->GetNativeSurface(NativeSurfaceType::CAIRO_CONTEXT));
michael@0 93
michael@0 94 bool isNewContext = !ctx;
michael@0 95 if (!ctx) {
michael@0 96 ctx = cairo_create(DrawTargetCairo::GetDummySurface());
michael@0 97 cairo_matrix_t mat;
michael@0 98 GfxMatrixToCairoMatrix(aTarget->GetTransform(), mat);
michael@0 99 cairo_set_matrix(ctx, &mat);
michael@0 100 }
michael@0 101
michael@0 102 cairo_set_scaled_font(ctx, mScaledFont);
michael@0 103
michael@0 104 // Convert our GlyphBuffer into an array of Cairo glyphs.
michael@0 105 std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
michael@0 106 for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
michael@0 107 glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
michael@0 108 glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
michael@0 109 glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
michael@0 110 }
michael@0 111
michael@0 112 cairo_new_path(ctx);
michael@0 113
michael@0 114 cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
michael@0 115
michael@0 116 RefPtr<PathCairo> newPath = new PathCairo(ctx);
michael@0 117 if (isNewContext) {
michael@0 118 cairo_destroy(ctx);
michael@0 119 }
michael@0 120
michael@0 121 return newPath;
michael@0 122 }
michael@0 123 #endif
michael@0 124 return nullptr;
michael@0 125 }
michael@0 126
michael@0 127 void
michael@0 128 ScaledFontBase::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint)
michael@0 129 {
michael@0 130 #ifdef USE_SKIA
michael@0 131 if (aBackendType == BackendType::SKIA) {
michael@0 132 PathBuilderSkia *builder = static_cast<PathBuilderSkia*>(aBuilder);
michael@0 133 builder->AppendPath(GetSkiaPathForGlyphs(aBuffer));
michael@0 134 return;
michael@0 135 }
michael@0 136 #endif
michael@0 137 #ifdef USE_CAIRO
michael@0 138 if (aBackendType == BackendType::CAIRO) {
michael@0 139 MOZ_ASSERT(mScaledFont);
michael@0 140
michael@0 141 PathBuilderCairo* builder = static_cast<PathBuilderCairo*>(aBuilder);
michael@0 142 cairo_t *ctx = cairo_create(DrawTargetCairo::GetDummySurface());
michael@0 143
michael@0 144 if (aTransformHint) {
michael@0 145 cairo_matrix_t mat;
michael@0 146 GfxMatrixToCairoMatrix(*aTransformHint, mat);
michael@0 147 cairo_set_matrix(ctx, &mat);
michael@0 148 }
michael@0 149
michael@0 150 // Convert our GlyphBuffer into an array of Cairo glyphs.
michael@0 151 std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
michael@0 152 for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
michael@0 153 glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
michael@0 154 glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
michael@0 155 glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
michael@0 156 }
michael@0 157
michael@0 158 cairo_set_scaled_font(ctx, mScaledFont);
michael@0 159 cairo_glyph_path(ctx, &glyphs[0], aBuffer.mNumGlyphs);
michael@0 160
michael@0 161 RefPtr<PathCairo> cairoPath = new PathCairo(ctx);
michael@0 162 cairo_destroy(ctx);
michael@0 163
michael@0 164 cairoPath->AppendPathToBuilder(builder);
michael@0 165 return;
michael@0 166 }
michael@0 167 #endif
michael@0 168
michael@0 169 MOZ_CRASH("The specified backend type is not supported by CopyGlyphsToBuilder");
michael@0 170 }
michael@0 171
michael@0 172 #ifdef USE_CAIRO_SCALED_FONT
michael@0 173 void
michael@0 174 ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
michael@0 175 {
michael@0 176 MOZ_ASSERT(!mScaledFont);
michael@0 177
michael@0 178 if (font == mScaledFont)
michael@0 179 return;
michael@0 180
michael@0 181 if (mScaledFont)
michael@0 182 cairo_scaled_font_destroy(mScaledFont);
michael@0 183
michael@0 184 mScaledFont = font;
michael@0 185 cairo_scaled_font_reference(mScaledFont);
michael@0 186 }
michael@0 187 #endif
michael@0 188
michael@0 189 }
michael@0 190 }

mercurial