summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/pepper_private2_linux.cc
blob: ed2c04a6c3424b05d17f1c4ad8fe70d33fbb8603 (plain)
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