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

Side by Side Diff: Source/core/css/CSSFontSelector.cpp

Issue 18375005: [oilpan] Move CSSFontFace and CSSSegmentedFontFace to the managed heap (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/css/CSSFontSelector.h ('k') | Source/core/css/CSSSegmentedFontFace.h » ('j') | 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 (C) 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 traitsMask |= FontVariantSmallCapsMask; 188 traitsMask |= FontVariantSmallCapsMask;
189 break; 189 break;
190 default: 190 default:
191 break; 191 break;
192 } 192 }
193 } 193 }
194 } else 194 } else
195 traitsMask |= FontVariantMask; 195 traitsMask |= FontVariantMask;
196 196
197 // Each item in the src property's list is a single CSSFontFaceSource. Put t hem all into a CSSFontFace. 197 // Each item in the src property's list is a single CSSFontFaceSource. Put t hem all into a CSSFontFace.
198 RefPtr<CSSFontFace> fontFace; 198 Handle<CSSFontFace> fontFace;
199 199
200 int srcLength = srcList->length(); 200 int srcLength = srcList->length();
201 201
202 bool foundSVGFont = false; 202 bool foundSVGFont = false;
203 203
204 for (int i = 0; i < srcLength; i++) { 204 for (int i = 0; i < srcLength; i++) {
205 // An item in the list either specifies a string (local font name) or a URL (remote font to download). 205 // An item in the list either specifies a string (local font name) or a URL (remote font to download).
206 CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->i temWithoutBoundsCheck(i)); 206 CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->i temWithoutBoundsCheck(i));
207 OwnPtr<CSSFontFaceSource> source; 207 OwnPtr<CSSFontFaceSource> source;
208 208
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 familyName = pictographFamily; 285 familyName = pictographFamily;
286 break; 286 break;
287 default: 287 default:
288 break; 288 break;
289 } 289 }
290 } 290 }
291 291
292 if (familyName.isEmpty()) 292 if (familyName.isEmpty())
293 continue; 293 continue;
294 294
295 OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add (familyName, nullptr).iterator->value; 295 // FIXME(oilpan): This is dangerous because the below 'new' can trigger a GC and
296 // some finalizer can get rid of the collection from m_fontFaces.
297 // Then subsequent access to familyFontFaces causes use-after-free.
298 // We should move the collection to the managed heap.
299 CSSFontFaceVectorCollection* familyFontFaces = m_fontFaces.add(familyNam e, nullptr).iterator->value.get();
296 if (!familyFontFaces) { 300 if (!familyFontFaces) {
297 familyFontFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >); 301 familyFontFaces = new CSSFontFaceVectorCollection;
302 m_fontFaces.set(familyName, adoptPtr(familyFontFaces));
298 303
299 ASSERT(!m_locallyInstalledFontFaces.contains(familyName)); 304 ASSERT(!m_locallyInstalledFontFaces.contains(familyName));
300 305
301 Vector<unsigned> locallyInstalledFontsTraitsMasks; 306 Vector<unsigned> locallyInstalledFontsTraitsMasks;
302 fontCache()->getTraitsInFamily(familyName, locallyInstalledFontsTrai tsMasks); 307 fontCache()->getTraitsInFamily(familyName, locallyInstalledFontsTrai tsMasks);
303 if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsM asks.size()) { 308 if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsM asks.size()) {
304 OwnPtr<Vector<RefPtr<CSSFontFace> > > familyLocallyInstalledFace s = adoptPtr(new Vector<RefPtr<CSSFontFace> >); 309 OwnPtr<CSSFontFaceVectorCollection> familyLocallyInstalledFaces = adoptPtr(new CSSFontFaceVectorCollection);
305 310
306 for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) { 311 for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) {
307 RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace:: create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), nullptr , true); 312 HandleScope scope;
313 Handle<CSSFontFace> locallyInstalledFontFace = CSSFontFace:: create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), nullptr , true);
308 locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFace Source(familyName))); 314 locallyInstalledFontFace->addSource(adoptPtr(new CSSFontFace Source(familyName)));
309 ASSERT(locallyInstalledFontFace->isValid()); 315 ASSERT(locallyInstalledFontFace->isValid());
310 familyLocallyInstalledFaces->append(locallyInstalledFontFace ); 316 (*familyLocallyInstalledFaces)->append(locallyInstalledFontF ace);
311 } 317 }
312 318
313 m_locallyInstalledFontFaces.set(familyName, familyLocallyInstall edFaces.release()); 319 m_locallyInstalledFontFaces.set(familyName, familyLocallyInstall edFaces.release());
314 } 320 }
315 } 321 }
316 322
317 familyFontFaces->append(fontFace); 323 (*familyFontFaces)->append(fontFace);
318 324
319 ++m_version; 325 ++m_version;
320 } 326 }
321 } 327 }
322 328
323 void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* clien t) 329 void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* clien t)
324 { 330 {
325 m_clients.add(client); 331 m_clients.add(client);
326 } 332 }
327 333
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 genericFamily = settings->standardFontFamily(script); 391 genericFamily = settings->standardFontFamily(script);
386 392
387 if (!genericFamily.isEmpty()) 393 if (!genericFamily.isEmpty())
388 return fontCache()->getCachedFontData(fontDescription, genericFamily); 394 return fontCache()->getCachedFontData(fontDescription, genericFamily);
389 395
390 return 0; 396 return 0;
391 } 397 }
392 398
393 static FontTraitsMask desiredTraitsMaskForComparison; 399 static FontTraitsMask desiredTraitsMaskForComparison;
394 400
395 static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second) 401 static inline bool compareFontFaces(Handle<CSSFontFace> first, Handle<CSSFontFac e> second)
396 { 402 {
397 FontTraitsMask firstTraitsMask = first->traitsMask(); 403 FontTraitsMask firstTraitsMask = first->traitsMask();
398 FontTraitsMask secondTraitsMask = second->traitsMask(); 404 FontTraitsMask secondTraitsMask = second->traitsMask();
399 405
400 bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMaskForComparis on & FontVariantMask; 406 bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMaskForComparis on & FontVariantMask;
401 bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMaskForCompar ison & FontVariantMask; 407 bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMaskForCompar ison & FontVariantMask;
402 408
403 if (firstHasDesiredVariant != secondHasDesiredVariant) 409 if (firstHasDesiredVariant != secondHasDesiredVariant)
404 return firstHasDesiredVariant; 410 return firstHasDesiredVariant;
405 411
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDes cription, const AtomicString& familyName) 481 PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDes cription, const AtomicString& familyName)
476 { 482 {
477 if (m_fontFaces.isEmpty()) { 483 if (m_fontFaces.isEmpty()) {
478 if (familyName.startsWith("-webkit-")) 484 if (familyName.startsWith("-webkit-"))
479 return fontDataForGenericFamily(m_document, fontDescription, familyN ame); 485 return fontDataForGenericFamily(m_document, fontDescription, familyN ame);
480 if (fontDescription.genericFamily() == FontDescription::StandardFamily & & !fontDescription.isSpecifiedFont()) 486 if (fontDescription.genericFamily() == FontDescription::StandardFamily & & !fontDescription.isSpecifiedFont())
481 return fontDataForGenericFamily(m_document, fontDescription, "-webki t-standard"); 487 return fontDataForGenericFamily(m_document, fontDescription, "-webki t-standard");
482 return 0; 488 return 0;
483 } 489 }
484 490
485 CSSSegmentedFontFace* face = getFontFace(fontDescription, familyName); 491 Handle<CSSSegmentedFontFace> face = getFontFace(fontDescription, familyName) ;
486 // If no face was found, then return 0 and let the OS come up with its best match for the name. 492 // If no face was found, then return 0 and let the OS come up with its best match for the name.
487 if (!face) { 493 if (!face) {
488 // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our 494 // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
489 // settings. 495 // settings.
490 if (fontDescription.genericFamily() == FontDescription::StandardFamily & & !fontDescription.isSpecifiedFont()) 496 if (fontDescription.genericFamily() == FontDescription::StandardFamily & & !fontDescription.isSpecifiedFont())
491 return fontDataForGenericFamily(m_document, fontDescription, "-webki t-standard"); 497 return fontDataForGenericFamily(m_document, fontDescription, "-webki t-standard");
492 return fontDataForGenericFamily(m_document, fontDescription, familyName) ; 498 return fontDataForGenericFamily(m_document, fontDescription, familyName) ;
493 } 499 }
494 500
495 // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over. 501 // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
496 return face->getFontData(fontDescription); 502 return face->getFontData(fontDescription);
497 } 503 }
498 504
499 CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDe scription, const AtomicString& family) 505 Result<CSSSegmentedFontFace> CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
500 { 506 {
501 Vector<RefPtr<CSSFontFace> >* familyFontFaces = m_fontFaces.get(family); 507 CSSFontFaceVectorCollection* familyFontFaces = m_fontFaces.get(family);
502 if (!familyFontFaces || familyFontFaces->isEmpty()) 508 if (!familyFontFaces || (*familyFontFaces)->isEmpty())
503 return 0; 509 return nullptr;
504 510
505 OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFace Cache = m_fonts.add(family, nullptr).iterator->value; 511 // FIXME(oilpan): This is dangerous because the below 'new' can trigger a GC and
506 if (!segmentedFontFaceCache) 512 // some finalizer can get rid of the hashmap from m_fonts.
507 segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmen tedFontFace> >); 513 // Then subsequent access to segmentedFontFaceCache causes use-after-free.
514 // We should move the hashmap to the managed heap.
515 HashMap<unsigned, Persistent<CSSSegmentedFontFace> >* segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value.get();
516 if (!segmentedFontFaceCache) {
517 segmentedFontFaceCache = new HashMap<unsigned, Persistent<CSSSegmentedFo ntFace> >;
518 m_fonts.set(family, adoptPtr(segmentedFontFaceCache));
519 }
508 520
509 FontTraitsMask traitsMask = fontDescription.traitsMask(); 521 FontTraitsMask traitsMask = fontDescription.traitsMask();
510 522
511 RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value; 523 Handle<CSSSegmentedFontFace> face = segmentedFontFaceCache->add(traitsMask, nullptr).iterator->value;
512 if (!face) { 524 if (face)
513 face = CSSSegmentedFontFace::create(this); 525 return face;
514 526
515 // Collect all matching faces and sort them in order of preference. 527 face = CSSSegmentedFontFace::create(this);
516 Vector<CSSFontFace*, 32> candidateFontFaces; 528 segmentedFontFaceCache->set(traitsMask, face);
517 for (int i = familyFontFaces->size() - 1; i >= 0; --i) { 529
518 CSSFontFace* candidate = familyFontFaces->at(i).get(); 530 // Collect all matching faces and sort them in order of preference.
531 Vector<Handle<CSSFontFace>, 32> candidateFontFaces;
haraken 2013/07/03 12:03:23 This is wrong. Handles in the vector are freed in
Mads Ager (google) 2013/07/03 12:18:38 Yes, good catch.
532 for (int i = (*familyFontFaces)->size() - 1; i >= 0; --i) {
533 HandleScope scope;
534 Handle<CSSFontFace> candidate = (*familyFontFaces)->at(i);
535 unsigned candidateTraitsMask = candidate->traitsMask();
536 if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontSt yleNormalMask))
537 continue;
538 if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & Font VariantNormalMask))
539 continue;
540 #if ENABLE(SVG_FONTS)
541 // For SVG Fonts that specify that they only support the "normal" varian t, we will assume they are incapable
542 // of small-caps synthesis and just ignore the font face as a candidate.
543 if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSmallC apsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask))
544 continue;
545 #endif
546 candidateFontFaces.append(candidate);
547 }
548
549 CSSFontFaceVectorCollection* familyLocallyInstalledFontFaces = m_locallyInst alledFontFaces.get(family);
550 if (familyLocallyInstalledFontFaces) {
551 unsigned numLocallyInstalledFontFaces = (*familyLocallyInstalledFontFace s)->size();
552 for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) {
553 Handle<CSSFontFace> candidate = (*familyLocallyInstalledFontFaces)-> at(i);
519 unsigned candidateTraitsMask = candidate->traitsMask(); 554 unsigned candidateTraitsMask = candidate->traitsMask();
520 if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & Fo ntStyleNormalMask)) 555 if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & Fo ntStyleNormalMask))
521 continue; 556 continue;
522 if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask)) 557 if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
523 continue; 558 continue;
524 #if ENABLE(SVG_FONTS)
525 // For SVG Fonts that specify that they only support the "normal" va riant, we will assume they are incapable
526 // of small-caps synthesis and just ignore the font face as a candid ate.
527 if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSm allCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask))
528 continue;
529 #endif
530 candidateFontFaces.append(candidate); 559 candidateFontFaces.append(candidate);
531 } 560 }
561 }
532 562
533 if (Vector<RefPtr<CSSFontFace> >* familyLocallyInstalledFontFaces = m_lo callyInstalledFontFaces.get(family)) { 563 desiredTraitsMaskForComparison = traitsMask;
534 unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFa ces->size(); 564 stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFon tFaces);
535 for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) { 565 unsigned numCandidates = candidateFontFaces.size();
536 CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i). get(); 566 for (unsigned i = 0; i < numCandidates; ++i)
537 unsigned candidateTraitsMask = candidate->traitsMask(); 567 face->appendFontFace(candidateFontFaces[i]);
538 if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask)) 568 return face;
539 continue;
540 if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMas k & FontVariantNormalMask))
541 continue;
542 candidateFontFaces.append(candidate);
543 }
544 }
545
546 desiredTraitsMaskForComparison = traitsMask;
547 stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compar eFontFaces);
548 unsigned numCandidates = candidateFontFaces.size();
549 for (unsigned i = 0; i < numCandidates; ++i)
550 face->appendFontFace(candidateFontFaces[i]);
551 }
552 return face.get();
553 } 569 }
554 570
555 void CSSFontSelector::clearDocument() 571 void CSSFontSelector::clearDocument()
556 { 572 {
557 if (!m_document) { 573 if (!m_document) {
558 ASSERT(!m_beginLoadingTimer.isActive()); 574 ASSERT(!m_beginLoadingTimer.isActive());
559 ASSERT(m_fontsToBeginLoading.isEmpty()); 575 ASSERT(m_fontsToBeginLoading.isEmpty());
560 return; 576 return;
561 } 577 }
562 578
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 618 }
603 // Ensure that if the request count reaches zero, the frame loader will know about it. 619 // Ensure that if the request count reaches zero, the frame loader will know about it.
604 cachedResourceLoader->loadDone(0); 620 cachedResourceLoader->loadDone(0);
605 // New font loads may be triggered by layout after the document load is comp lete but before we have dispatched 621 // New font loads may be triggered by layout after the document load is comp lete but before we have dispatched
606 // didFinishLoading for the frame. Make sure the delegate is always dispatch ed by checking explicitly. 622 // didFinishLoading for the frame. Make sure the delegate is always dispatch ed by checking explicitly.
607 if (m_document && m_document->frame()) 623 if (m_document && m_document->frame())
608 m_document->frame()->loader()->checkLoadComplete(); 624 m_document->frame()->loader()->checkLoadComplete();
609 } 625 }
610 626
611 } 627 }
OLDNEW
« no previous file with comments | « Source/core/css/CSSFontSelector.h ('k') | Source/core/css/CSSSegmentedFontFace.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698