gfx/skia/trunk/src/views/SkTextBox.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2006 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkTextBox.h"
     9 #include "SkUtils.h"
    11 static inline int is_ws(int c)
    12 {
    13     return !((c - 1) >> 5);
    14 }
    16 static size_t linebreak(const char text[], const char stop[],
    17                         const SkPaint& paint, SkScalar margin,
    18                         size_t* trailing = NULL)
    19 {
    20     size_t lengthBreak = paint.breakText(text, stop - text, margin);
    22     //Check for white space or line breakers before the lengthBreak
    23     const char* start = text;
    24     const char* word_start = text;
    25     int prevWS = true;
    26     if (trailing) {
    27         *trailing = 0;
    28     }
    30     while (text < stop) {
    31         const char* prevText = text;
    32         SkUnichar uni = SkUTF8_NextUnichar(&text);
    33         int currWS = is_ws(uni);
    35         if (!currWS && prevWS) {
    36             word_start = prevText;
    37         }
    38         prevWS = currWS;
    40         if (text > start + lengthBreak) {
    41             if (currWS) {
    42                 // eat the rest of the whitespace
    43                 while (text < stop && is_ws(SkUTF8_ToUnichar(text))) {
    44                     text += SkUTF8_CountUTF8Bytes(text);
    45                 }
    46                 if (trailing) {
    47                     *trailing = text - prevText;
    48                 }
    49             } else {
    50                 // backup until a whitespace (or 1 char)
    51                 if (word_start == start) {
    52                     if (prevText > start) {
    53                         text = prevText;
    54                     }
    55                 } else {
    56                     text = word_start;
    57                 }
    58             }
    59             break;
    60         }
    62         if ('\n' == uni) {
    63             size_t ret = text - start;
    64             size_t lineBreakSize = 1;
    65             if (text < stop) {
    66                 uni = SkUTF8_NextUnichar(&text);
    67                 if ('\r' == uni) {
    68                     ret = text - start;
    69                     ++lineBreakSize;
    70                 }
    71             }
    72             if (trailing) {
    73                 *trailing = lineBreakSize;
    74             }
    75             return ret;
    76         }
    78         if ('\r' == uni) {
    79             size_t ret = text - start;
    80             size_t lineBreakSize = 1;
    81             if (text < stop) {
    82                 uni = SkUTF8_NextUnichar(&text);
    83                 if ('\n' == uni) {
    84                     ret = text - start;
    85                     ++lineBreakSize;
    86                 }
    87             }
    88             if (trailing) {
    89                 *trailing = lineBreakSize;
    90             }
    91             return ret;
    92         }
    93     }
    95     return text - start;
    96 }
    98 int SkTextLineBreaker::CountLines(const char text[], size_t len, const SkPaint& paint, SkScalar width)
    99 {
   100     const char* stop = text + len;
   101     int         count = 0;
   103     if (width > 0)
   104     {
   105         do {
   106             count += 1;
   107             text += linebreak(text, stop, paint, width);
   108         } while (text < stop);
   109     }
   110     return count;
   111 }
   113 //////////////////////////////////////////////////////////////////////////////
   115 SkTextBox::SkTextBox()
   116 {
   117     fBox.setEmpty();
   118     fSpacingMul = SK_Scalar1;
   119     fSpacingAdd = 0;
   120     fMode = kLineBreak_Mode;
   121     fSpacingAlign = kStart_SpacingAlign;
   122 }
   124 void SkTextBox::setMode(Mode mode)
   125 {
   126     SkASSERT((unsigned)mode < kModeCount);
   127     fMode = SkToU8(mode);
   128 }
   130 void SkTextBox::setSpacingAlign(SpacingAlign align)
   131 {
   132     SkASSERT((unsigned)align < kSpacingAlignCount);
   133     fSpacingAlign = SkToU8(align);
   134 }
   136 void SkTextBox::getBox(SkRect* box) const
   137 {
   138     if (box)
   139         *box = fBox;
   140 }
   142 void SkTextBox::setBox(const SkRect& box)
   143 {
   144     fBox = box;
   145 }
   147 void SkTextBox::setBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
   148 {
   149     fBox.set(left, top, right, bottom);
   150 }
   152 void SkTextBox::getSpacing(SkScalar* mul, SkScalar* add) const
   153 {
   154     if (mul)
   155         *mul = fSpacingMul;
   156     if (add)
   157         *add = fSpacingAdd;
   158 }
   160 void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
   161 {
   162     fSpacingMul = mul;
   163     fSpacingAdd = add;
   164 }
   166 /////////////////////////////////////////////////////////////////////////////////////////////
   168 void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint)
   169 {
   170     SkASSERT(canvas && &paint && (text || len == 0));
   172     SkScalar marginWidth = fBox.width();
   174     if (marginWidth <= 0 || len == 0)
   175         return;
   177     const char* textStop = text + len;
   179     SkScalar                x, y, scaledSpacing, height, fontHeight;
   180     SkPaint::FontMetrics    metrics;
   182     switch (paint.getTextAlign()) {
   183     case SkPaint::kLeft_Align:
   184         x = 0;
   185         break;
   186     case SkPaint::kCenter_Align:
   187         x = SkScalarHalf(marginWidth);
   188         break;
   189     default:
   190         x = marginWidth;
   191         break;
   192     }
   193     x += fBox.fLeft;
   195     fontHeight = paint.getFontMetrics(&metrics);
   196     scaledSpacing = SkScalarMul(fontHeight, fSpacingMul) + fSpacingAdd;
   197     height = fBox.height();
   199     //  compute Y position for first line
   200     {
   201         SkScalar textHeight = fontHeight;
   203         if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign)
   204         {
   205             int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
   206             SkASSERT(count > 0);
   207             textHeight += scaledSpacing * (count - 1);
   208         }
   210         switch (fSpacingAlign) {
   211         case kStart_SpacingAlign:
   212             y = 0;
   213             break;
   214         case kCenter_SpacingAlign:
   215             y = SkScalarHalf(height - textHeight);
   216             break;
   217         default:
   218             SkASSERT(fSpacingAlign == kEnd_SpacingAlign);
   219             y = height - textHeight;
   220             break;
   221         }
   222         y += fBox.fTop - metrics.fAscent;
   223     }
   225     for (;;)
   226     {
   227         size_t trailing;
   228         len = linebreak(text, textStop, paint, marginWidth, &trailing);
   229         if (y + metrics.fDescent + metrics.fLeading > 0)
   230             canvas->drawText(text, len - trailing, x, y, paint);
   231         text += len;
   232         if (text >= textStop)
   233             break;
   234         y += scaledSpacing;
   235         if (y + metrics.fAscent >= fBox.fBottom)
   236             break;
   237     }
   238 }
   240 ///////////////////////////////////////////////////////////////////////////////
   242 void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
   243     fText = text;
   244     fLen = len;
   245     fPaint = &paint;
   246 }
   248 void SkTextBox::draw(SkCanvas* canvas) {
   249     this->draw(canvas, fText, fLen, *fPaint);
   250 }
   252 int SkTextBox::countLines() const {
   253     return SkTextLineBreaker::CountLines(fText, fLen, *fPaint, fBox.width());
   254 }
   256 SkScalar SkTextBox::getTextHeight() const {
   257     SkScalar spacing = SkScalarMul(fPaint->getTextSize(), fSpacingMul) + fSpacingAdd;
   258     return this->countLines() * spacing;
   259 }

mercurial