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

Side by Side Diff: src/core/SkTextBlob.cpp

Issue 858153007: Conservative blob bounds cleanup (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTextBlob.h" 8 #include "SkTextBlob.h"
9 9
10 #include "SkReadBuffer.h" 10 #include "SkReadBuffer.h"
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 299
300 SkTextBlobBuilder::~SkTextBlobBuilder() { 300 SkTextBlobBuilder::~SkTextBlobBuilder() {
301 if (NULL != fStorage.get()) { 301 if (NULL != fStorage.get()) {
302 // We are abandoning runs and must destruct the associated font data. 302 // We are abandoning runs and must destruct the associated font data.
303 // The easiest way to accomplish that is to use the blob destructor. 303 // The easiest way to accomplish that is to use the blob destructor.
304 build()->unref(); 304 build()->unref();
305 } 305 }
306 } 306 }
307 307
308 SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) { 308 SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) {
309 SkASSERT(SkTextBlob::kDefault_Positioning == run.positioning());
310
309 SkRect bounds; 311 SkRect bounds;
310 312 run.font().measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint16_t ), &bounds);
311 if (SkTextBlob::kDefault_Positioning == run.positioning()) {
312 run.font().measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint 16_t), &bounds);
313 return bounds;
f(malita) 2015/01/29 19:19:38 Previously missing the run offset here.
314 }
315
316 SkASSERT(SkTextBlob::kFull_Positioning == run.positioning() ||
317 SkTextBlob::kHorizontal_Positioning == run.positioning());
318
319 SkAutoSTArray<16, SkRect> glyphBounds(run.glyphCount());
320 run.font().getTextWidths(run.glyphBuffer(),
321 run.glyphCount() * sizeof(uint16_t),
322 NULL,
323 glyphBounds.get());
324
325 bounds = SkRect::MakeEmpty();
326 SkScalar* glyphPos = run.posBuffer();
327 for (unsigned i = 0; i < run.glyphCount(); ++i) {
328 if (SkTextBlob::kFull_Positioning == run.positioning()) {
329 // [ x, y, x, y... ]
330 glyphBounds[i].offset(glyphPos[0], glyphPos[1]);
331 SkASSERT(2 == SkTextBlob::ScalarsPerGlyph(run.positioning()));
332 glyphPos += 2;
333 } else {
334 // [ x, x, x... ], const y applied by runBounds.offset(run->offset() ) later.
335 glyphBounds[i].offset(glyphPos[0], 0);
336 SkASSERT(1 == SkTextBlob::ScalarsPerGlyph(run.positioning()));
337 glyphPos += 1;
338 }
339
340 bounds.join(glyphBounds[i]);
341 }
342
343 SkASSERT((void*)glyphPos <= SkTextBlob::RunRecord::Next(&run));
344 313
345 return bounds.makeOffset(run.offset().x(), run.offset().y()); 314 return bounds.makeOffset(run.offset().x(), run.offset().y());
346 } 315 }
347 316
348 SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run ) { 317 SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run ) {
349 const SkScalar* glyphPos = run.posBuffer();
350 int posScalars = SkTextBlob::ScalarsPerGlyph(run.positioning());
351
352 SkASSERT(1 == posScalars || 2 == posScalars);
353 SkASSERT(run.glyphCount() > 0); 318 SkASSERT(run.glyphCount() > 0);
354 SkASSERT((void*)(glyphPos + run.glyphCount() * posScalars) <= 319 SkASSERT(SkTextBlob::kFull_Positioning == run.positioning() ||
355 SkTextBlob::RunRecord::Next(&run)); 320 SkTextBlob::kHorizontal_Positioning == run.positioning());
356 321
357 // First, compute the glyph position bbox. 322 // First, compute the glyph position bbox.
358 SkRect bounds = SkRect::MakeXYWH(glyphPos[0], (2 == posScalars) ? glyphPos[1 ] : 0, 0, 0); 323 const SkScalar* glyphPos = run.posBuffer();
359 for (unsigned i = 1; i < run.glyphCount(); ++i) { 324 SkRect bounds = SkRect::MakeXYWH(glyphPos[0],
mtklein 2015/01/29 19:52:03 SkRect bounds; switch(..) { case H: SkScalar
f(malita) 2015/01/29 20:18:31 Done.
360 SkScalar xpos = glyphPos[i * posScalars]; 325 SkTextBlob::kFull_Positioning == run.positioning() ? glyphPos[1] : 0, 0, 0);
361 SkScalar ypos = (2 == posScalars) ? glyphPos[i * posScalars + 1] : 0; 326
362 bounds.growToInclude(xpos, ypos); 327 switch (run.positioning()) {
328 case SkTextBlob::kHorizontal_Positioning: {
329 SkASSERT((void*)(glyphPos + run.glyphCount()) <= SkTextBlob::RunRecord:: Next(&run));
330 for (unsigned i = 1; i < run.glyphCount(); ++i) {
331 SkScalar x = glyphPos[i];
332 bounds.fLeft = SkMinScalar(x, bounds.fLeft);
333 bounds.fRight = SkMaxScalar(x, bounds.fRight);
334 }
335 } break;
336 case SkTextBlob::kFull_Positioning: {
337 const SkPoint* glyphPosPts = reinterpret_cast<const SkPoint*>(glyphPos);
338 SkASSERT((void*)(glyphPosPts + run.glyphCount()) <= SkTextBlob::RunRecor d::Next(&run));
339 bounds.growToInclude(glyphPosPts + 1, run.glyphCount() - 1);
340 } break;
341 default:
342 SkFAIL("unsupported positioning mode");
363 } 343 }
364 344
365 // Expand by typeface glyph bounds. 345 // Expand by typeface glyph bounds.
366 const SkRect fontBounds = run.font().getFontBounds(); 346 const SkRect fontBounds = run.font().getFontBounds();
367 bounds.fLeft += fontBounds.left(); 347 bounds.fLeft += fontBounds.left();
368 bounds.fTop += fontBounds.top(); 348 bounds.fTop += fontBounds.top();
369 bounds.fRight += fontBounds.right(); 349 bounds.fRight += fontBounds.right();
370 bounds.fBottom += fontBounds.bottom(); 350 bounds.fBottom += fontBounds.bottom();
371 351
372 // Offset by run position. 352 // Offset by run position.
373 return bounds.makeOffset(run.offset().x(), run.offset().y()); 353 return bounds.makeOffset(run.offset().x(), run.offset().y());
374 } 354 }
375 355
376 void SkTextBlobBuilder::updateDeferredBounds() { 356 void SkTextBlobBuilder::updateDeferredBounds() {
377 SkASSERT(!fDeferredBounds || fRunCount > 0); 357 SkASSERT(!fDeferredBounds || fRunCount > 0);
378 358
379 if (!fDeferredBounds) { 359 if (!fDeferredBounds) {
380 return; 360 return;
381 } 361 }
382 362
383 SkASSERT(fLastRun >= sizeof(SkTextBlob)); 363 SkASSERT(fLastRun >= sizeof(SkTextBlob));
384 SkTextBlob::RunRecord* run = reinterpret_cast<SkTextBlob::RunRecord*>(fStora ge.get() + 364 SkTextBlob::RunRecord* run = reinterpret_cast<SkTextBlob::RunRecord*>(fStora ge.get() +
385 fLastR un); 365 fLastR un);
386 SkASSERT(SkPaint::kGlyphID_TextEncoding == run->font().getTextEncoding()); 366 SkASSERT(SkPaint::kGlyphID_TextEncoding == run->font().getTextEncoding());
387 367
388 SkRect runBounds; 368 // FIXME: we should also use conservative bounds for kDefault_Positioning.
389 #ifdef SK_SUPPORT_LEGACY_BLOB_BOUNDS 369 SkRect runBounds = SkTextBlob::kDefault_Positioning == run->positioning() ?
390 runBounds = TightRunBounds(*run); 370 TightRunBounds(*run) : ConservativeRunBounds(*run);
391 #else
392 // FIXME: conservative bounds for default positioning?
393 if (SkTextBlob::kDefault_Positioning == run->positioning()) {
394 runBounds = TightRunBounds(*run);
395 } else {
396 runBounds = ConservativeRunBounds(*run);
397 }
398 #endif
399
400 fBounds.join(runBounds); 371 fBounds.join(runBounds);
401 fDeferredBounds = false; 372 fDeferredBounds = false;
402 } 373 }
403 374
404 void SkTextBlobBuilder::reserve(size_t size) { 375 void SkTextBlobBuilder::reserve(size_t size) {
405 // We don't currently pre-allocate, but maybe someday... 376 // We don't currently pre-allocate, but maybe someday...
406 if (fStorageUsed + size <= fStorageSize) { 377 if (fStorageUsed + size <= fStorageSize) {
407 return; 378 return;
408 } 379 }
409 380
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 532
562 fStorageUsed = 0; 533 fStorageUsed = 0;
563 fStorageSize = 0; 534 fStorageSize = 0;
564 fRunCount = 0; 535 fRunCount = 0;
565 fLastRun = 0; 536 fLastRun = 0;
566 fBounds.setEmpty(); 537 fBounds.setEmpty();
567 538
568 return blob; 539 return blob;
569 } 540 }
570 541
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698