1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/glue/plugins/pepper_private2.h"
#include "skia/ext/platform_canvas.h"
#include "ppapi/c/pp_point.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/dev/ppb_font_dev.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkTemplates.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "webkit/glue/plugins/pepper_image_data.h"
#include "webkit/glue/plugins/pepper_var.h"
namespace pepper {
bool Private2::DrawGlyphs(PP_Resource pp_image_data,
const PP_FontDescription_Dev* font_desc,
uint32_t color,
PP_Point position,
PP_Rect clip,
float transformation[3][3],
uint32_t glyph_count,
uint16_t glyph_indices[],
PP_Point glyph_advances[]) {
scoped_refptr<ImageData> image_resource(
Resource::GetAs<ImageData>(pp_image_data));
if (!image_resource.get())
return false;
ImageDataAutoMapper mapper(image_resource);
if (!mapper.is_valid())
return false;
// Set up the typeface.
scoped_refptr<StringVar> face_name(StringVar::FromPPVar(font_desc->face));
if (!face_name)
return false;
int style = SkTypeface::kNormal;
if (font_desc->weight >= PP_FONTWEIGHT_BOLD)
style |= SkTypeface::kBold;
if (font_desc->italic)
style |= SkTypeface::kItalic;
SkTypeface* typeface =
SkTypeface::CreateFromName(face_name->value().c_str(),
static_cast<SkTypeface::Style>(style));
if (!typeface)
return false;
// Set up the canvas.
SkCanvas* canvas = image_resource->mapped_canvas();
canvas->save();
// Clip is applied in pixels before the transform.
SkRect clip_rect = { clip.point.x, clip.point.y,
clip.point.x + clip.size.width,
clip.point.y + clip.size.height };
canvas->clipRect(clip_rect);
// -- Do not return early below this. The canvas needs restoring and the
// typeface will leak if it's not assigned to the paint (it's refcounted and
// the refcount is currently 0).
// Convert & set the matrix.
SkMatrix matrix;
matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(transformation[0][0]));
matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(transformation[0][1]));
matrix.set(SkMatrix::kMTransX, SkFloatToScalar(transformation[0][2]));
matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(transformation[1][0]));
matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(transformation[1][1]));
matrix.set(SkMatrix::kMTransY, SkFloatToScalar(transformation[1][2]));
matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(transformation[2][0]));
matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(transformation[2][1]));
matrix.set(SkMatrix::kMPersp2, SkFloatToScalar(transformation[2][2]));
canvas->concat(matrix);
SkPaint paint;
paint.setColor(color);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setAntiAlias(true);
paint.setHinting(SkPaint::kFull_Hinting);
paint.setTextSize(SkIntToScalar(font_desc->size));
paint.setTypeface(typeface); // Takes a ref and manages lifetime.
paint.setSubpixelText(true);
paint.setLCDRenderText(true);
SkScalar x = SkIntToScalar(position.x);
SkScalar y = SkIntToScalar(position.y);
// Build up the skia advances.
SkAutoSTMalloc<32, SkPoint> storage(glyph_count);
SkPoint* sk_positions = storage.get();
for (uint32_t i = 0; i < glyph_count; i++) {
sk_positions[i].set(x, y);
x += SkFloatToScalar(glyph_advances[i].x);
y += SkFloatToScalar(glyph_advances[i].y);
}
canvas->drawPosText(glyph_indices, glyph_count * 2, sk_positions, paint);
canvas->restore();
return true;
}
} // namespace pepper
|