LCOV - code coverage report
Current view: top level - layout/style - nsFontFaceUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 64 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : // vim:cindent:ts=2:et:sw=2:
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsFontFaceUtils.h"
       8             : 
       9             : #include "gfxUserFontSet.h"
      10             : #include "nsFontMetrics.h"
      11             : #include "nsIFrame.h"
      12             : #include "nsLayoutUtils.h"
      13             : #include "nsPlaceholderFrame.h"
      14             : #include "nsTArray.h"
      15             : #include "SVGTextFrame.h"
      16             : 
      17             : static bool
      18           0 : StyleContextContainsFont(nsStyleContext* aStyleContext,
      19             :                          const gfxUserFontSet* aUserFontSet,
      20             :                          const gfxUserFontEntry* aFont)
      21             : {
      22             :   // if the font is null, simply check to see whether fontlist includes
      23             :   // downloadable fonts
      24           0 :   if (!aFont) {
      25             :     const mozilla::FontFamilyList& fontlist =
      26           0 :       aStyleContext->StyleFont()->mFont.fontlist;
      27           0 :     return aUserFontSet->ContainsUserFontSetFonts(fontlist);
      28             :   }
      29             : 
      30             :   // first, check if the family name is in the fontlist
      31           0 :   const nsString& familyName = aFont->FamilyName();
      32           0 :   if (!aStyleContext->StyleFont()->mFont.fontlist.Contains(familyName)) {
      33           0 :     return false;
      34             :   }
      35             : 
      36             :   // family name is in the fontlist, check to see if the font group
      37             :   // associated with the frame includes the specific userfont
      38             :   RefPtr<nsFontMetrics> fm =
      39           0 :     nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext, 1.0f);
      40             : 
      41           0 :   if (fm->GetThebesFontGroup()->ContainsUserFont(aFont)) {
      42           0 :     return true;
      43             :   }
      44             : 
      45           0 :   return false;
      46             : }
      47             : 
      48             : static bool
      49           0 : FrameUsesFont(nsIFrame* aFrame, const gfxUserFontEntry* aFont)
      50             : {
      51             :   // check the style context of the frame
      52           0 :   gfxUserFontSet* ufs = aFrame->PresContext()->GetUserFontSet();
      53           0 :   if (StyleContextContainsFont(aFrame->StyleContext(), ufs, aFont)) {
      54           0 :     return true;
      55             :   }
      56             : 
      57             :   // check additional style contexts
      58           0 :   int32_t contextIndex = 0;
      59           0 :   for (nsStyleContext* extraContext;
      60           0 :        (extraContext = aFrame->GetAdditionalStyleContext(contextIndex));
      61             :        ++contextIndex) {
      62           0 :     if (StyleContextContainsFont(extraContext, ufs, aFont)) {
      63           0 :       return true;
      64             :     }
      65             :   }
      66             : 
      67           0 :   return false;
      68             : }
      69             : 
      70             : static void
      71           0 : ScheduleReflow(nsIPresShell* aShell, nsIFrame* aFrame)
      72             : {
      73           0 :   nsIFrame* f = aFrame;
      74           0 :   if (f->IsFrameOfType(nsIFrame::eSVG) || nsSVGUtils::IsInSVGTextSubtree(f)) {
      75             :     // SVG frames (and the non-SVG descendants of an SVGTextFrame) need special
      76             :     // reflow handling.  We need to search upwards for the first displayed
      77             :     // nsSVGOuterSVGFrame or non-SVG frame, which is the frame we can call
      78             :     // FrameNeedsReflow on.  (This logic is based on
      79             :     // nsSVGUtils::ScheduleReflowSVG and
      80             :     // SVGTextFrame::ScheduleReflowSVGNonDisplayText.)
      81           0 :     if (f->GetStateBits() & NS_FRAME_IS_NONDISPLAY) {
      82           0 :       while (f) {
      83           0 :         if (!(f->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
      84           0 :           if (NS_SUBTREE_DIRTY(f)) {
      85             :             // This is a displayed frame, so if it is already dirty, we
      86             :             // will be reflowed soon anyway.  No need to call
      87             :             // FrameNeedsReflow again, then.
      88           0 :             return;
      89             :           }
      90           0 :           if (f->GetStateBits() & NS_STATE_IS_OUTER_SVG ||
      91           0 :               !(f->IsFrameOfType(nsIFrame::eSVG) ||
      92           0 :                 nsSVGUtils::IsInSVGTextSubtree(f))) {
      93           0 :             break;
      94             :           }
      95           0 :           f->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
      96             :         }
      97           0 :         f = f->GetParent();
      98             :       }
      99           0 :       MOZ_ASSERT(f, "should have found an ancestor frame to reflow");
     100             :     }
     101             :   }
     102             : 
     103           0 :   aShell->FrameNeedsReflow(f, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
     104             : }
     105             : 
     106             : /* static */ void
     107           0 : nsFontFaceUtils::MarkDirtyForFontChange(nsIFrame* aSubtreeRoot,
     108             :                                         const gfxUserFontEntry* aFont)
     109             : {
     110           0 :   AutoTArray<nsIFrame*, 4> subtrees;
     111           0 :   subtrees.AppendElement(aSubtreeRoot);
     112             : 
     113           0 :   nsIPresShell* ps = aSubtreeRoot->PresContext()->PresShell();
     114             : 
     115             :   // check descendants, iterating over subtrees that may include
     116             :   // additional subtrees associated with placeholders
     117           0 :   do {
     118           0 :     nsIFrame* subtreeRoot = subtrees.ElementAt(subtrees.Length() - 1);
     119           0 :     subtrees.RemoveElementAt(subtrees.Length() - 1);
     120             : 
     121             :     // Check all descendants to see if they use the font
     122           0 :     AutoTArray<nsIFrame*, 32> stack;
     123           0 :     stack.AppendElement(subtreeRoot);
     124             : 
     125           0 :     do {
     126           0 :       nsIFrame* f = stack.ElementAt(stack.Length() - 1);
     127           0 :       stack.RemoveElementAt(stack.Length() - 1);
     128             : 
     129             :       // if this frame uses the font, mark its descendants dirty
     130             :       // and skip checking its children
     131           0 :       if (FrameUsesFont(f, aFont)) {
     132           0 :         ScheduleReflow(ps, f);
     133             :       } else {
     134           0 :         if (f->IsPlaceholderFrame()) {
     135           0 :           nsIFrame* oof = nsPlaceholderFrame::GetRealFrameForPlaceholder(f);
     136           0 :           if (!nsLayoutUtils::IsProperAncestorFrame(subtreeRoot, oof)) {
     137             :             // We have another distinct subtree we need to mark.
     138           0 :             subtrees.AppendElement(oof);
     139             :           }
     140             :         }
     141             : 
     142           0 :         nsIFrame::ChildListIterator lists(f);
     143           0 :         for (; !lists.IsDone(); lists.Next()) {
     144           0 :           nsFrameList::Enumerator childFrames(lists.CurrentList());
     145           0 :           for (; !childFrames.AtEnd(); childFrames.Next()) {
     146           0 :             nsIFrame* kid = childFrames.get();
     147           0 :             stack.AppendElement(kid);
     148             :           }
     149             :         }
     150             :       }
     151           0 :     } while (!stack.IsEmpty());
     152           0 :   } while (!subtrees.IsEmpty());
     153           0 : }

Generated by: LCOV version 1.13