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
111
112
113
114
115
116
117
118
119
120
121
122
123
|
// Copyright (c) 2009 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 "chrome/common/gfx/chrome_canvas.h"
#include <pango/pango.h>
#include "base/gfx/rect.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/common/gfx/chrome_font.h"
namespace {
// Returns a new pango font, free with pango_font_description_free().
PangoFontDescription* PangoFontFromChromeFont(const ChromeFont& chrome_font) {
ChromeFont font = chrome_font; // Copy so we can call non-const methods.
PangoFontDescription* pfd = pango_font_description_new();
pango_font_description_set_family(pfd, WideToUTF8(font.FontName()).c_str());
pango_font_description_set_size(pfd, font.FontSize() * PANGO_SCALE);
switch (font.style()) {
case ChromeFont::NORMAL:
// Nothing to do, should already be PANGO_STYLE_NORMAL.
break;
case ChromeFont::BOLD:
pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
break;
case ChromeFont::ITALIC:
pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC);
break;
case ChromeFont::UNDERLINED:
// TODO(deanm): How to do underlined? Where do we use it? Probably have
// to paint it ourselves, see pango_font_metrics_get_underline_position.
break;
}
return pfd;
}
} // namespace
ChromeCanvas::ChromeCanvas(int width, int height, bool is_opaque)
: skia::PlatformCanvasLinux(width, height, is_opaque) {
}
ChromeCanvas::ChromeCanvas() : skia::PlatformCanvasLinux() {
}
ChromeCanvas::~ChromeCanvas() {
}
// static
void ChromeCanvas::SizeStringInt(const std::wstring& text,
const ChromeFont& font,
int* width, int* height, int flags) {
NOTIMPLEMENTED();
}
void ChromeCanvas::ApplySkiaMatrixToCairoContext(cairo_t* cr) {
const SkMatrix& skia_matrix = getTotalMatrix();
cairo_matrix_t cairo_matrix;
cairo_matrix_init(&cairo_matrix,
SkScalarToFloat(skia_matrix.getScaleX()),
SkScalarToFloat(skia_matrix.getSkewY()),
SkScalarToFloat(skia_matrix.getSkewX()),
SkScalarToFloat(skia_matrix.getScaleY()),
SkScalarToFloat(skia_matrix.getTranslateX()),
SkScalarToFloat(skia_matrix.getTranslateY()));
cairo_set_matrix(cr, &cairo_matrix);
}
void ChromeCanvas::DrawStringInt(const std::wstring& text,
const ChromeFont& font,
const SkColor& color, int x, int y, int w,
int h, int flags) {
cairo_surface_t* surface = beginPlatformPaint();
cairo_t* cr = cairo_create(surface);
// We're going to draw onto the surface directly. This circumvents the matrix
// installed by Skia. Apply the matrix from skia to cairo so they align and
// we draw at the right place.
ApplySkiaMatrixToCairoContext(cr);
PangoLayout* layout = pango_cairo_create_layout(cr);
cairo_set_source_rgb(cr,
SkColorGetR(color) / 255.0,
SkColorGetG(color) / 255.0,
SkColorGetB(color) / 255.0);
// TODO(deanm): Implement the rest of the ChromeCanvas flags.
if (!(flags & ChromeCanvas::NO_ELLIPSIS))
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
pango_layout_set_width(layout, w * PANGO_SCALE);
pango_layout_set_height(layout, h * PANGO_SCALE);
std::string utf8 = WideToUTF8(text);
pango_layout_set_text(layout, utf8.data(), utf8.size());
PangoFontDescription* desc = PangoFontFromChromeFont(font);
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
int width, height;
pango_layout_get_size(layout, &width, &height);
if (flags & ChromeCanvas::TEXT_VALIGN_TOP) {
// Cairo should draw from the top left corner already.
} else if (flags & ChromeCanvas::TEXT_VALIGN_BOTTOM) {
y = y + (h - (height / PANGO_SCALE));
} else {
// Vertically centered.
y = y + ((h - (height / PANGO_SCALE)) / 2);
}
cairo_move_to(cr, x, y);
pango_cairo_show_layout(cr, layout);
g_object_unref(layout);
cairo_destroy(cr);
// NOTE: beginPlatformPaint returned its surface, we shouldn't destroy it.
}
|