LCOV - code coverage report
Current view: directory - layout/generic - nsTextFrameUtils.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 119 0 0.0 %
Date: 2012-06-02 Functions: 5 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  * ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Novell code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Novell Corporation.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2006
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   robert@ocallahan.org
      23                 :  *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsTextFrameUtils.h"
      40                 : 
      41                 : #include "nsContentUtils.h"
      42                 : #include "nsIWordBreaker.h"
      43                 : #include "gfxFont.h"
      44                 : #include "nsUnicharUtils.h"
      45                 : #include "nsBidiUtils.h"
      46                 : 
      47                 : // XXX TODO implement transform of backslash to yen that nsTextTransform does
      48                 : // when requested by PresContext->LanguageSpecificTransformType(). Do it with
      49                 : // a new factory type that just munges the input stream. But first, check
      50                 : // that we really still need this, it's only enabled via a hidden pref
      51                 : // which defaults false...
      52                 : 
      53                 : #define UNICODE_ZWSP 0x200B
      54                 :   
      55               0 : static bool IsDiscardable(PRUnichar ch, PRUint32* aFlags)
      56                 : {
      57                 :   // Unlike IS_DISCARDABLE, we don't discard \r. \r will be ignored by gfxTextRun
      58                 :   // and discarding it would force us to copy text in many cases of preformatted
      59                 :   // text containing \r\n.
      60               0 :   if (ch == CH_SHY) {
      61               0 :     *aFlags |= nsTextFrameUtils::TEXT_HAS_SHY;
      62               0 :     return true;
      63                 :   }
      64               0 :   if ((ch & 0xFF00) != 0x2000) {
      65                 :     // Not a Bidi control character
      66               0 :     return false;
      67                 :   }
      68               0 :   return IS_BIDI_CONTROL_CHAR(ch);
      69                 : }
      70                 : 
      71               0 : static bool IsDiscardable(PRUint8 ch, PRUint32* aFlags)
      72                 : {
      73               0 :   if (ch == CH_SHY) {
      74               0 :     *aFlags |= nsTextFrameUtils::TEXT_HAS_SHY;
      75               0 :     return true;
      76                 :   }
      77               0 :   return false;
      78                 : }
      79                 : 
      80                 : PRUnichar*
      81               0 : nsTextFrameUtils::TransformText(const PRUnichar* aText, PRUint32 aLength,
      82                 :                                 PRUnichar* aOutput,
      83                 :                                 CompressionMode aCompression,
      84                 :                                 PRUint8* aIncomingFlags,
      85                 :                                 gfxSkipCharsBuilder* aSkipChars,
      86                 :                                 PRUint32* aAnalysisFlags)
      87                 : {
      88               0 :   PRUint32 flags = 0;
      89               0 :   PRUnichar* outputStart = aOutput;
      90                 : 
      91               0 :   bool lastCharArabic = false;
      92                 : 
      93               0 :   if (aCompression == COMPRESS_NONE) {
      94                 :     // Skip discardables.
      95                 :     PRUint32 i;
      96               0 :     for (i = 0; i < aLength; ++i) {
      97               0 :       PRUnichar ch = *aText++;
      98               0 :       if (IsDiscardable(ch, &flags)) {
      99               0 :         aSkipChars->SkipChar();
     100                 :       } else {
     101               0 :         aSkipChars->KeepChar();
     102               0 :         if (ch == '\t') {
     103               0 :           flags |= TEXT_HAS_TAB;
     104               0 :         } else if (ch != ' ' && ch != '\n') {
     105                 :           // we already know it's not a tab from the previous check
     106               0 :           lastCharArabic = IS_ARABIC_CHAR(ch);
     107                 :         }
     108               0 :         *aOutput++ = ch;
     109                 :       }
     110                 :     }
     111               0 :     if (lastCharArabic) {
     112               0 :       *aIncomingFlags |= INCOMING_ARABICCHAR;
     113                 :     } else {
     114               0 :       *aIncomingFlags &= ~INCOMING_ARABICCHAR;
     115                 :     }
     116               0 :     *aIncomingFlags &= ~INCOMING_WHITESPACE;
     117                 :   } else {
     118               0 :     bool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0;
     119                 :     PRUint32 i;
     120               0 :     for (i = 0; i < aLength; ++i) {
     121               0 :       PRUnichar ch = *aText++;
     122                 :       bool nowInWhitespace;
     123               0 :       if (ch == ' ' &&
     124                 :           (i + 1 >= aLength ||
     125               0 :            !IsSpaceCombiningSequenceTail(aText, aLength - (i + 1)))) {
     126               0 :         nowInWhitespace = true;
     127               0 :       } else if (ch == '\n' && aCompression == COMPRESS_WHITESPACE_NEWLINE) {
     128               0 :         if (i > 0 && IS_CJ_CHAR(aText[-1]) &&
     129               0 :             i + 1 < aLength && IS_CJ_CHAR(aText[1])) {
     130                 :           // Discard newlines between CJK chars.
     131                 :           // XXX this really requires more context to get right!
     132               0 :           aSkipChars->SkipChar();
     133               0 :           continue;
     134                 :         }
     135               0 :         nowInWhitespace = true;
     136                 :       } else {
     137               0 :         nowInWhitespace = ch == '\t';
     138                 :       }
     139                 : 
     140               0 :       if (!nowInWhitespace) {
     141               0 :         if (IsDiscardable(ch, &flags)) {
     142               0 :           aSkipChars->SkipChar();
     143               0 :           nowInWhitespace = inWhitespace;
     144                 :         } else {
     145               0 :           *aOutput++ = ch;
     146               0 :           aSkipChars->KeepChar();
     147               0 :           lastCharArabic = IS_ARABIC_CHAR(ch);
     148                 :         }
     149                 :       } else {
     150               0 :         if (inWhitespace) {
     151               0 :           aSkipChars->SkipChar();
     152                 :         } else {
     153               0 :           if (ch != ' ') {
     154               0 :             flags |= TEXT_WAS_TRANSFORMED;
     155                 :           }
     156               0 :           *aOutput++ = ' ';
     157               0 :           aSkipChars->KeepChar();
     158                 :         }
     159                 :       }
     160               0 :       inWhitespace = nowInWhitespace;
     161                 :     }
     162               0 :     if (lastCharArabic) {
     163               0 :       *aIncomingFlags |= INCOMING_ARABICCHAR;
     164                 :     } else {
     165               0 :       *aIncomingFlags &= ~INCOMING_ARABICCHAR;
     166                 :     }
     167               0 :     if (inWhitespace) {
     168               0 :       *aIncomingFlags |= INCOMING_WHITESPACE;
     169                 :     } else {
     170               0 :       *aIncomingFlags &= ~INCOMING_WHITESPACE;
     171                 :     }
     172                 :   }
     173                 : 
     174               0 :   if (outputStart + aLength != aOutput) {
     175               0 :     flags |= TEXT_WAS_TRANSFORMED;
     176                 :   }
     177               0 :   *aAnalysisFlags = flags;
     178               0 :   return aOutput;
     179                 : }
     180                 : 
     181                 : PRUint8*
     182               0 : nsTextFrameUtils::TransformText(const PRUint8* aText, PRUint32 aLength,
     183                 :                                 PRUint8* aOutput,
     184                 :                                 CompressionMode aCompression,
     185                 :                                 PRUint8* aIncomingFlags,
     186                 :                                 gfxSkipCharsBuilder* aSkipChars,
     187                 :                                 PRUint32* aAnalysisFlags)
     188                 : {
     189               0 :   PRUint32 flags = 0;
     190               0 :   PRUint8* outputStart = aOutput;
     191                 : 
     192               0 :   if (aCompression == COMPRESS_NONE) {
     193                 :     // Skip discardables.
     194                 :     PRUint32 i;
     195               0 :     for (i = 0; i < aLength; ++i) {
     196               0 :       PRUint8 ch = *aText++;
     197               0 :       if (IsDiscardable(ch, &flags)) {
     198               0 :         aSkipChars->SkipChar();
     199                 :       } else {
     200               0 :         aSkipChars->KeepChar();
     201               0 :         if (ch == '\t') {
     202               0 :           flags |= TEXT_HAS_TAB;
     203                 :         }
     204               0 :         *aOutput++ = ch;
     205                 :       }
     206                 :     }
     207               0 :     *aIncomingFlags &= ~(INCOMING_ARABICCHAR | INCOMING_WHITESPACE);
     208                 :   } else {
     209               0 :     bool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0;
     210                 :     PRUint32 i;
     211               0 :     for (i = 0; i < aLength; ++i) {
     212               0 :       PRUint8 ch = *aText++;
     213                 :       bool nowInWhitespace = ch == ' ' || ch == '\t' ||
     214               0 :         (ch == '\n' && aCompression == COMPRESS_WHITESPACE_NEWLINE);
     215               0 :       if (!nowInWhitespace) {
     216               0 :         if (IsDiscardable(ch, &flags)) {
     217               0 :           aSkipChars->SkipChar();
     218               0 :           nowInWhitespace = inWhitespace;
     219                 :         } else {
     220               0 :           *aOutput++ = ch;
     221               0 :           aSkipChars->KeepChar();
     222                 :         }
     223                 :       } else {
     224               0 :         if (inWhitespace) {
     225               0 :           aSkipChars->SkipChar();
     226                 :         } else {
     227               0 :           if (ch != ' ') {
     228               0 :             flags |= TEXT_WAS_TRANSFORMED;
     229                 :           }
     230               0 :           *aOutput++ = ' ';
     231               0 :           aSkipChars->KeepChar();
     232                 :         }
     233                 :       }
     234               0 :       inWhitespace = nowInWhitespace;
     235                 :     }
     236               0 :     *aIncomingFlags &= ~INCOMING_ARABICCHAR;
     237               0 :     if (inWhitespace) {
     238               0 :       *aIncomingFlags |= INCOMING_WHITESPACE;
     239                 :     } else {
     240               0 :       *aIncomingFlags &= ~INCOMING_WHITESPACE;
     241                 :     }
     242                 :   }
     243                 : 
     244               0 :   if (outputStart + aLength != aOutput) {
     245               0 :     flags |= TEXT_WAS_TRANSFORMED;
     246                 :   }
     247               0 :   *aAnalysisFlags = flags;
     248               0 :   return aOutput;
     249                 : }
     250                 : 
     251               0 : bool nsSkipCharsRunIterator::NextRun() {
     252               0 :   do {
     253               0 :     if (mRunLength) {
     254               0 :       mIterator.AdvanceOriginal(mRunLength);
     255               0 :       NS_ASSERTION(mRunLength > 0, "No characters in run (initial length too large?)");
     256               0 :       if (!mSkipped || mLengthIncludesSkipped) {
     257               0 :         mRemainingLength -= mRunLength;
     258                 :       }
     259                 :     }
     260               0 :     if (!mRemainingLength)
     261               0 :       return false;
     262                 :     PRInt32 length;
     263               0 :     mSkipped = mIterator.IsOriginalCharSkipped(&length);
     264               0 :     mRunLength = NS_MIN(length, mRemainingLength);
     265               0 :   } while (!mVisitSkipped && mSkipped);
     266                 : 
     267               0 :   return true;
     268                 : }

Generated by: LCOV version 1.7