Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: ui/gfx/harfbuzz_font_skia.cc

Issue 2716213002: ui: Fix cc/paint skia type mismatches (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/harfbuzz_font_skia.h" 5 #include "ui/gfx/harfbuzz_font_skia.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <limits> 10 #include <limits>
(...skipping 15 matching lines...) Expand all
26 // Maps from code points to glyph indices in a font. 26 // Maps from code points to glyph indices in a font.
27 typedef std::map<uint32_t, uint16_t> GlyphCache; 27 typedef std::map<uint32_t, uint16_t> GlyphCache;
28 28
29 typedef std::pair<HarfBuzzFace, GlyphCache> FaceCache; 29 typedef std::pair<HarfBuzzFace, GlyphCache> FaceCache;
30 30
31 // Font data provider for HarfBuzz using Skia. Copied from Blink. 31 // Font data provider for HarfBuzz using Skia. Copied from Blink.
32 // TODO(ckocagil): Eliminate the duplication. http://crbug.com/368375 32 // TODO(ckocagil): Eliminate the duplication. http://crbug.com/368375
33 struct FontData { 33 struct FontData {
34 FontData(GlyphCache* glyph_cache) : glyph_cache_(glyph_cache) {} 34 FontData(GlyphCache* glyph_cache) : glyph_cache_(glyph_cache) {}
35 35
36 SkPaint paint_; 36 cc::PaintFlags flags_;
37 GlyphCache* glyph_cache_; 37 GlyphCache* glyph_cache_;
38 }; 38 };
39 39
40 // Deletes the object at the given pointer after casting it to the given type. 40 // Deletes the object at the given pointer after casting it to the given type.
41 template<typename Type> 41 template<typename Type>
42 void DeleteByType(void* data) { 42 void DeleteByType(void* data) {
43 Type* typed_data = reinterpret_cast<Type*>(data); 43 Type* typed_data = reinterpret_cast<Type*>(data);
44 delete typed_data; 44 delete typed_data;
45 } 45 }
46 46
47 template<typename Type> 47 template<typename Type>
48 void DeleteArrayByType(void* data) { 48 void DeleteArrayByType(void* data) {
49 Type* typed_data = reinterpret_cast<Type*>(data); 49 Type* typed_data = reinterpret_cast<Type*>(data);
50 delete[] typed_data; 50 delete[] typed_data;
51 } 51 }
52 52
53 // Outputs the |width| and |extents| of the glyph with index |codepoint| in 53 // Outputs the |width| and |extents| of the glyph with index |codepoint| in
54 // |paint|'s font. 54 // |paint|'s font.
55 void GetGlyphWidthAndExtents(SkPaint* paint, 55 void GetGlyphWidthAndExtents(cc::PaintFlags* flags,
56 hb_codepoint_t codepoint, 56 hb_codepoint_t codepoint,
57 hb_position_t* width, 57 hb_position_t* width,
58 hb_glyph_extents_t* extents) { 58 hb_glyph_extents_t* extents) {
59 SkPaint paint(cc::ToSkPaint(*flags));
60
59 DCHECK_LE(codepoint, std::numeric_limits<uint16_t>::max()); 61 DCHECK_LE(codepoint, std::numeric_limits<uint16_t>::max());
60 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); 62 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
61 63
62 SkScalar sk_width; 64 SkScalar sk_width;
63 SkRect sk_bounds; 65 SkRect sk_bounds;
64 uint16_t glyph = static_cast<uint16_t>(codepoint); 66 uint16_t glyph = static_cast<uint16_t>(codepoint);
65 67
66 paint->getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds); 68 paint.getTextWidths(&glyph, sizeof(glyph), &sk_width, &sk_bounds);
67 if (width) 69 if (width)
68 *width = SkiaScalarToHarfBuzzUnits(sk_width); 70 *width = SkiaScalarToHarfBuzzUnits(sk_width);
69 if (extents) { 71 if (extents) {
70 // Invert y-axis because Skia is y-grows-down but we set up HarfBuzz to be 72 // Invert y-axis because Skia is y-grows-down but we set up HarfBuzz to be
71 // y-grows-up. 73 // y-grows-up.
72 extents->x_bearing = SkiaScalarToHarfBuzzUnits(sk_bounds.fLeft); 74 extents->x_bearing = SkiaScalarToHarfBuzzUnits(sk_bounds.fLeft);
73 extents->y_bearing = SkiaScalarToHarfBuzzUnits(-sk_bounds.fTop); 75 extents->y_bearing = SkiaScalarToHarfBuzzUnits(-sk_bounds.fTop);
74 extents->width = SkiaScalarToHarfBuzzUnits(sk_bounds.width()); 76 extents->width = SkiaScalarToHarfBuzzUnits(sk_bounds.width());
75 extents->height = SkiaScalarToHarfBuzzUnits(-sk_bounds.height()); 77 extents->height = SkiaScalarToHarfBuzzUnits(-sk_bounds.height());
76 } 78 }
77 } 79 }
78 80
79 // Writes the |glyph| index for the given |unicode| code point. Returns whether 81 // Writes the |glyph| index for the given |unicode| code point. Returns whether
80 // the glyph exists, i.e. it is not a missing glyph. 82 // the glyph exists, i.e. it is not a missing glyph.
81 hb_bool_t GetGlyph(hb_font_t* font, 83 hb_bool_t GetGlyph(hb_font_t* font,
82 void* data, 84 void* data,
83 hb_codepoint_t unicode, 85 hb_codepoint_t unicode,
84 hb_codepoint_t variation_selector, 86 hb_codepoint_t variation_selector,
85 hb_codepoint_t* glyph, 87 hb_codepoint_t* glyph,
86 void* user_data) { 88 void* user_data) {
87 FontData* font_data = reinterpret_cast<FontData*>(data); 89 FontData* font_data = reinterpret_cast<FontData*>(data);
88 GlyphCache* cache = font_data->glyph_cache_; 90 GlyphCache* cache = font_data->glyph_cache_;
89 91
90 bool exists = cache->count(unicode) != 0; 92 bool exists = cache->count(unicode) != 0;
91 if (!exists) { 93 if (!exists) {
92 SkPaint* paint = &font_data->paint_; 94 font_data->flags_.setTextEncoding(cc::PaintFlags::kUTF32_TextEncoding);
93 paint->setTextEncoding(SkPaint::kUTF32_TextEncoding); 95 SkPaint paint(cc::ToSkPaint(font_data->flags_));
enne (OOO) 2017/02/27 01:56:21 Similar to my comments on https://codereview.chrom
94 paint->textToGlyphs(&unicode, sizeof(hb_codepoint_t), &(*cache)[unicode]); 96 paint.textToGlyphs(&unicode, sizeof(hb_codepoint_t), &(*cache)[unicode]);
95 } 97 }
96 *glyph = (*cache)[unicode]; 98 *glyph = (*cache)[unicode];
97 return !!*glyph; 99 return !!*glyph;
98 } 100 }
99 101
100 // Returns the horizontal advance value of the |glyph|. 102 // Returns the horizontal advance value of the |glyph|.
101 hb_position_t GetGlyphHorizontalAdvance(hb_font_t* font, 103 hb_position_t GetGlyphHorizontalAdvance(hb_font_t* font,
102 void* data, 104 void* data,
103 hb_codepoint_t glyph, 105 hb_codepoint_t glyph,
104 void* user_data) { 106 void* user_data) {
105 FontData* font_data = reinterpret_cast<FontData*>(data); 107 FontData* font_data = reinterpret_cast<FontData*>(data);
106 hb_position_t advance = 0; 108 hb_position_t advance = 0;
107 109
108 GetGlyphWidthAndExtents(&font_data->paint_, glyph, &advance, 0); 110 GetGlyphWidthAndExtents(&font_data->flags_, glyph, &advance, 0);
109 return advance; 111 return advance;
110 } 112 }
111 113
112 hb_bool_t GetGlyphHorizontalOrigin(hb_font_t* font, 114 hb_bool_t GetGlyphHorizontalOrigin(hb_font_t* font,
113 void* data, 115 void* data,
114 hb_codepoint_t glyph, 116 hb_codepoint_t glyph,
115 hb_position_t* x, 117 hb_position_t* x,
116 hb_position_t* y, 118 hb_position_t* y,
117 void* user_data) { 119 void* user_data) {
118 // Just return true, like the HarfBuzz-FreeType implementation. 120 // Just return true, like the HarfBuzz-FreeType implementation.
119 return true; 121 return true;
120 } 122 }
121 123
122 hb_position_t GetGlyphKerning(FontData* font_data, 124 hb_position_t GetGlyphKerning(FontData* font_data,
123 hb_codepoint_t first_glyph, 125 hb_codepoint_t first_glyph,
124 hb_codepoint_t second_glyph) { 126 hb_codepoint_t second_glyph) {
125 SkTypeface* typeface = font_data->paint_.getTypeface(); 127 SkTypeface* typeface = font_data->flags_.getTypeface();
126 const uint16_t glyphs[2] = { static_cast<uint16_t>(first_glyph), 128 const uint16_t glyphs[2] = { static_cast<uint16_t>(first_glyph),
127 static_cast<uint16_t>(second_glyph) }; 129 static_cast<uint16_t>(second_glyph) };
128 int32_t kerning_adjustments[1] = { 0 }; 130 int32_t kerning_adjustments[1] = { 0 };
129 131
130 if (!typeface->getKerningPairAdjustments(glyphs, 2, kerning_adjustments)) 132 if (!typeface->getKerningPairAdjustments(glyphs, 2, kerning_adjustments))
131 return 0; 133 return 0;
132 134
133 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); 135 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm());
134 SkScalar size = font_data->paint_.getTextSize(); 136 SkScalar size = font_data->flags_.getTextSize();
135 return SkiaScalarToHarfBuzzUnits(SkIntToScalar(kerning_adjustments[0]) * 137 return SkiaScalarToHarfBuzzUnits(SkIntToScalar(kerning_adjustments[0]) *
136 size / upm); 138 size / upm);
137 } 139 }
138 140
139 hb_position_t GetGlyphHorizontalKerning(hb_font_t* font, 141 hb_position_t GetGlyphHorizontalKerning(hb_font_t* font,
140 void* data, 142 void* data,
141 hb_codepoint_t left_glyph, 143 hb_codepoint_t left_glyph,
142 hb_codepoint_t right_glyph, 144 hb_codepoint_t right_glyph,
143 void* user_data) { 145 void* user_data) {
144 FontData* font_data = reinterpret_cast<FontData*>(data); 146 FontData* font_data = reinterpret_cast<FontData*>(data);
145 if (font_data->paint_.isVerticalText()) { 147 if (font_data->flags_.isVerticalText()) {
146 // We don't support cross-stream kerning. 148 // We don't support cross-stream kerning.
147 return 0; 149 return 0;
148 } 150 }
149 151
150 return GetGlyphKerning(font_data, left_glyph, right_glyph); 152 return GetGlyphKerning(font_data, left_glyph, right_glyph);
151 } 153 }
152 154
153 hb_position_t GetGlyphVerticalKerning(hb_font_t* font, 155 hb_position_t GetGlyphVerticalKerning(hb_font_t* font,
154 void* data, 156 void* data,
155 hb_codepoint_t top_glyph, 157 hb_codepoint_t top_glyph,
156 hb_codepoint_t bottom_glyph, 158 hb_codepoint_t bottom_glyph,
157 void* user_data) { 159 void* user_data) {
158 FontData* font_data = reinterpret_cast<FontData*>(data); 160 FontData* font_data = reinterpret_cast<FontData*>(data);
159 if (!font_data->paint_.isVerticalText()) { 161 if (!font_data->flags_.isVerticalText()) {
160 // We don't support cross-stream kerning. 162 // We don't support cross-stream kerning.
161 return 0; 163 return 0;
162 } 164 }
163 165
164 return GetGlyphKerning(font_data, top_glyph, bottom_glyph); 166 return GetGlyphKerning(font_data, top_glyph, bottom_glyph);
165 } 167 }
166 168
167 // Writes the |extents| of |glyph|. 169 // Writes the |extents| of |glyph|.
168 hb_bool_t GetGlyphExtents(hb_font_t* font, 170 hb_bool_t GetGlyphExtents(hb_font_t* font,
169 void* data, 171 void* data,
170 hb_codepoint_t glyph, 172 hb_codepoint_t glyph,
171 hb_glyph_extents_t* extents, 173 hb_glyph_extents_t* extents,
172 void* user_data) { 174 void* user_data) {
173 FontData* font_data = reinterpret_cast<FontData*>(data); 175 FontData* font_data = reinterpret_cast<FontData*>(data);
174 176
175 GetGlyphWidthAndExtents(&font_data->paint_, glyph, 0, extents); 177 GetGlyphWidthAndExtents(&font_data->flags_, glyph, 0, extents);
176 return true; 178 return true;
177 } 179 }
178 180
179 class FontFuncs { 181 class FontFuncs {
180 public: 182 public:
181 FontFuncs() : font_funcs_(hb_font_funcs_create()) { 183 FontFuncs() : font_funcs_(hb_font_funcs_create()) {
182 hb_font_funcs_set_glyph_func(font_funcs_, GetGlyph, 0, 0); 184 hb_font_funcs_set_glyph_func(font_funcs_, GetGlyph, 0, 0);
183 hb_font_funcs_set_glyph_h_advance_func( 185 hb_font_funcs_set_glyph_h_advance_func(
184 font_funcs_, GetGlyphHorizontalAdvance, 0, 0); 186 font_funcs_, GetGlyphHorizontalAdvance, 0, 0);
185 hb_font_funcs_set_glyph_h_kerning_func( 187 hb_font_funcs_set_glyph_h_kerning_func(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 static std::map<SkFontID, FaceCache> face_caches; 269 static std::map<SkFontID, FaceCache> face_caches;
268 270
269 FaceCache* face_cache = &face_caches[skia_face->uniqueID()]; 271 FaceCache* face_cache = &face_caches[skia_face->uniqueID()];
270 if (face_cache->first.get() == NULL) 272 if (face_cache->first.get() == NULL)
271 face_cache->first.Init(skia_face.get()); 273 face_cache->first.Init(skia_face.get());
272 274
273 hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get()); 275 hb_font_t* harfbuzz_font = hb_font_create(face_cache->first.get());
274 const int scale = SkiaScalarToHarfBuzzUnits(text_size); 276 const int scale = SkiaScalarToHarfBuzzUnits(text_size);
275 hb_font_set_scale(harfbuzz_font, scale, scale); 277 hb_font_set_scale(harfbuzz_font, scale, scale);
276 FontData* hb_font_data = new FontData(&face_cache->second); 278 FontData* hb_font_data = new FontData(&face_cache->second);
277 hb_font_data->paint_.setTypeface(std::move(skia_face)); 279 hb_font_data->flags_.setTypeface(std::move(skia_face));
278 hb_font_data->paint_.setTextSize(text_size); 280 hb_font_data->flags_.setTextSize(text_size);
279 // TODO(ckocagil): Do we need to update these params later? 281 // TODO(ckocagil): Do we need to update these params later?
280 internal::ApplyRenderParams(params, subpixel_rendering_suppressed, 282 internal::ApplyRenderParams(params, subpixel_rendering_suppressed,
281 &hb_font_data->paint_); 283 &hb_font_data->flags_);
282 hb_font_set_funcs(harfbuzz_font, g_font_funcs.Get().get(), hb_font_data, 284 hb_font_set_funcs(harfbuzz_font, g_font_funcs.Get().get(), hb_font_data,
283 DeleteByType<FontData>); 285 DeleteByType<FontData>);
284 hb_font_make_immutable(harfbuzz_font); 286 hb_font_make_immutable(harfbuzz_font);
285 return harfbuzz_font; 287 return harfbuzz_font;
286 } 288 }
287 289
288 } // namespace gfx 290 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698