LCOV - code coverage report
Current view: directory - gfx/skia/include/core - SkScalerContext.h (source / functions) Found Hit Coverage
Test: app.info Lines: 71 0 0.0 %
Date: 2012-06-02 Functions: 23 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #ifndef SkScalerContext_DEFINED
      11                 : #define SkScalerContext_DEFINED
      12                 : 
      13                 : #include "SkMask.h"
      14                 : #include "SkMatrix.h"
      15                 : #include "SkPaint.h"
      16                 : #include "SkPath.h"
      17                 : #include "SkPoint.h"
      18                 : 
      19                 : class SkDescriptor;
      20                 : class SkMaskFilter;
      21                 : class SkPathEffect;
      22                 : class SkRasterizer;
      23                 : 
      24                 : // needs to be != to any valid SkMask::Format
      25                 : #define MASK_FORMAT_UNKNOWN         (0xFF)
      26                 : #define MASK_FORMAT_JUST_ADVANCE    MASK_FORMAT_UNKNOWN
      27                 : 
      28                 : #define kMaxGlyphWidth (1<<13)
      29                 : 
      30                 : struct SkGlyph {
      31                 :     void*       fImage;
      32                 :     SkPath*     fPath;
      33                 :     SkFixed     fAdvanceX, fAdvanceY;
      34                 : 
      35                 :     uint32_t    fID;
      36                 :     uint16_t    fWidth, fHeight;
      37                 :     int16_t     fTop, fLeft;
      38                 : 
      39                 :     uint8_t     fMaskFormat;
      40                 :     int8_t      fRsbDelta, fLsbDelta;  // used by auto-kerning
      41                 : 
      42               0 :     void init(uint32_t id) {
      43               0 :         fID             = id;
      44               0 :         fImage          = NULL;
      45               0 :         fPath           = NULL;
      46               0 :         fMaskFormat     = MASK_FORMAT_UNKNOWN;
      47               0 :     }
      48                 : 
      49                 :     /**
      50                 :      *  Compute the rowbytes for the specified width and mask-format.
      51                 :      */
      52               0 :     static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) {
      53               0 :         unsigned rb = width;
      54               0 :         if (SkMask::kBW_Format == format) {
      55               0 :             rb = (rb + 7) >> 3;
      56               0 :                 } else if (SkMask::kARGB32_Format == format ||
      57                 :                    SkMask::kLCD32_Format == format)
      58                 :         {
      59               0 :                         rb <<= 2;
      60               0 :                 } else if (SkMask::kLCD16_Format == format) {
      61               0 :                         rb = SkAlign4(rb << 1);
      62                 :         } else {
      63               0 :             rb = SkAlign4(rb);
      64                 :         }
      65               0 :         return rb;
      66                 :     }
      67                 : 
      68               0 :     unsigned rowBytes() const {
      69               0 :         return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat);
      70                 :     }
      71                 : 
      72               0 :     bool isJustAdvance() const {
      73               0 :         return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
      74                 :     }
      75                 : 
      76               0 :     bool isFullMetrics() const {
      77               0 :         return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
      78                 :     }
      79                 : 
      80               0 :     uint16_t getGlyphID() const {
      81               0 :         return ID2Code(fID);
      82                 :     }
      83                 : 
      84               0 :     unsigned getGlyphID(unsigned baseGlyphCount) const {
      85               0 :         unsigned code = ID2Code(fID);
      86               0 :         SkASSERT(code >= baseGlyphCount);
      87               0 :         return code - baseGlyphCount;
      88                 :     }
      89                 : 
      90                 :     unsigned getSubX() const {
      91                 :         return ID2SubX(fID);
      92                 :     }
      93                 : 
      94               0 :     SkFixed getSubXFixed() const {
      95               0 :         return SubToFixed(ID2SubX(fID));
      96                 :     }
      97                 : 
      98               0 :     SkFixed getSubYFixed() const {
      99               0 :         return SubToFixed(ID2SubY(fID));
     100                 :     }
     101                 : 
     102                 :     size_t computeImageSize() const;
     103                 : 
     104                 :     /** Call this to set all of the metrics fields to 0 (e.g. if the scaler
     105                 :         encounters an error measuring a glyph). Note: this does not alter the
     106                 :         fImage, fPath, fID, fMaskFormat fields.
     107                 :      */
     108                 :     void zeroMetrics();
     109                 : 
     110                 :     enum {
     111                 :         kSubBits = 2,
     112                 :         kSubMask = ((1 << kSubBits) - 1),
     113                 :         kSubShift = 24, // must be large enough for glyphs and unichars
     114                 :         kCodeMask = ((1 << kSubShift) - 1),
     115                 :         // relative offsets for X and Y subpixel bits
     116                 :         kSubShiftX = kSubBits,
     117                 :         kSubShiftY = 0
     118                 :     };
     119                 : 
     120               0 :     static unsigned ID2Code(uint32_t id) {
     121               0 :         return id & kCodeMask;
     122                 :     }
     123                 : 
     124               0 :     static unsigned ID2SubX(uint32_t id) {
     125               0 :         return id >> (kSubShift + kSubShiftX);
     126                 :     }
     127                 : 
     128               0 :     static unsigned ID2SubY(uint32_t id) {
     129               0 :         return (id >> (kSubShift + kSubShiftY)) & kSubMask;
     130                 :     }
     131                 : 
     132               0 :     static unsigned FixedToSub(SkFixed n) {
     133               0 :         return (n >> (16 - kSubBits)) & kSubMask;
     134                 :     }
     135                 : 
     136               0 :     static SkFixed SubToFixed(unsigned sub) {
     137               0 :         SkASSERT(sub <= kSubMask);
     138               0 :         return sub << (16 - kSubBits);
     139                 :     }
     140                 : 
     141               0 :     static uint32_t MakeID(unsigned code) {
     142               0 :         return code;
     143                 :     }
     144                 : 
     145               0 :     static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
     146               0 :         SkASSERT(code <= kCodeMask);
     147               0 :         x = FixedToSub(x);
     148               0 :         y = FixedToSub(y);
     149                 :         return (x << (kSubShift + kSubShiftX)) |
     150                 :                (y << (kSubShift + kSubShiftY)) |
     151               0 :                code;
     152                 :     }
     153                 : 
     154                 :     void toMask(SkMask* mask) const;
     155                 : };
     156                 : 
     157                 : class SkScalerContext {
     158                 : public:
     159                 :     enum Flags {
     160                 :         kFrameAndFill_Flag        = 0x0001,
     161                 :         kDevKernText_Flag         = 0x0002,
     162                 :         kEmbeddedBitmapText_Flag  = 0x0004,
     163                 :         kEmbolden_Flag            = 0x0008,
     164                 :         kSubpixelPositioning_Flag = 0x0010,
     165                 :         kAutohinting_Flag         = 0x0020,
     166                 :         kVertical_Flag            = 0x0040,
     167                 : 
     168                 :         // together, these two flags resulting in a two bit value which matches
     169                 :         // up with the SkPaint::Hinting enum.
     170                 :         kHinting_Shift            = 7, // to shift into the other flags above
     171                 :         kHintingBit1_Flag         = 0x0080,
     172                 :         kHintingBit2_Flag         = 0x0100,
     173                 : 
     174                 :         // these should only ever be set if fMaskFormat is LCD16 or LCD32
     175                 :         kLCD_Vertical_Flag        = 0x0200,    // else Horizontal
     176                 :         kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
     177                 : 
     178                 :         // luminance : 0 for black text, kLuminance_Max for white text
     179                 :         kLuminance_Shift          = 11, // to shift into the other flags above
     180                 :         kLuminance_Bits           = 3  // ensure Flags doesn't exceed 16bits
     181                 :     };
     182                 :     
     183                 :     // computed values
     184                 :     enum {
     185                 :         kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
     186                 :         kLuminance_Max  = (1 << kLuminance_Bits) - 1,
     187                 :         kLuminance_Mask = kLuminance_Max << kLuminance_Shift
     188                 :     };
     189                 : 
     190                 :     struct Rec {
     191                 :         uint32_t    fOrigFontID;
     192                 :         uint32_t    fFontID;
     193                 :         SkScalar    fTextSize, fPreScaleX, fPreSkewX;
     194                 :         SkScalar    fPost2x2[2][2];
     195                 :         SkScalar    fFrameWidth, fMiterLimit;
     196                 :         uint8_t     fMaskFormat;
     197                 :         uint8_t     fStrokeJoin;
     198                 :         uint16_t    fFlags;
     199                 :         // Warning: when adding members note that the size of this structure
     200                 :         // must be a multiple of 4. SkDescriptor requires that its arguments be
     201                 :         // multiples of four and this structure is put in an SkDescriptor in
     202                 :         // SkPaint::MakeRec.
     203                 : 
     204                 :         void    getMatrixFrom2x2(SkMatrix*) const;
     205                 :         void    getLocalMatrix(SkMatrix*) const;
     206                 :         void    getSingleMatrix(SkMatrix*) const;
     207                 : 
     208               0 :         SkPaint::Hinting getHinting() const {
     209               0 :             unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift;
     210               0 :             return static_cast<SkPaint::Hinting>(hint);
     211                 :         }
     212                 : 
     213               0 :         void setHinting(SkPaint::Hinting hinting) {
     214               0 :             fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
     215               0 :         }
     216                 : 
     217               0 :         unsigned getLuminanceBits() const {
     218               0 :             return (fFlags & kLuminance_Mask) >> kLuminance_Shift;
     219                 :         }
     220                 :         
     221               0 :         void setLuminanceBits(unsigned lum) {
     222               0 :             SkASSERT(lum <= kLuminance_Max);
     223               0 :             fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift);
     224               0 :         }
     225                 : 
     226               0 :         U8CPU getLuminanceByte() const {
     227                 :             SkASSERT(3 == kLuminance_Bits);
     228               0 :             unsigned lum = this->getLuminanceBits();
     229               0 :             lum |= (lum << kLuminance_Bits);
     230               0 :             lum |= (lum << kLuminance_Bits*2);
     231               0 :             return lum >> (4*kLuminance_Bits - 8);
     232                 :         }
     233                 : 
     234                 :         SkMask::Format getFormat() const {
     235                 :             return static_cast<SkMask::Format>(fMaskFormat);
     236                 :         }
     237                 :     };
     238                 : 
     239                 :     SkScalerContext(const SkDescriptor* desc);
     240                 :     virtual ~SkScalerContext();
     241                 : 
     242                 :     SkMask::Format getMaskFormat() const {
     243                 :         return (SkMask::Format)fRec.fMaskFormat;
     244                 :     }
     245                 : 
     246                 :     bool isSubpixel() const {
     247                 :         return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
     248                 :     }
     249                 :     
     250                 :     // remember our glyph offset/base
     251               0 :     void setBaseGlyphCount(unsigned baseGlyphCount) {
     252               0 :         fBaseGlyphCount = baseGlyphCount;
     253               0 :     }
     254                 : 
     255                 :     /** Return the corresponding glyph for the specified unichar. Since contexts
     256                 :         may be chained (under the hood), the glyphID that is returned may in
     257                 :         fact correspond to a different font/context. In that case, we use the
     258                 :         base-glyph-count to know how to translate back into local glyph space.
     259                 :      */
     260                 :     uint16_t charToGlyphID(SkUnichar uni);
     261                 : 
     262                 :     /** Map the glyphID to its glyph index, and then to its char code. Unmapped
     263                 :         glyphs return zero.
     264                 :     */
     265                 :     SkUnichar glyphIDToChar(uint16_t glyphID);
     266                 : 
     267               0 :     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
     268                 :     void        getAdvance(SkGlyph*);
     269                 :     void        getMetrics(SkGlyph*);
     270                 :     void        getImage(const SkGlyph&);
     271                 :     void        getPath(const SkGlyph&, SkPath*);
     272                 :     void        getFontMetrics(SkPaint::FontMetrics* mX,
     273                 :                                SkPaint::FontMetrics* mY);
     274                 : 
     275                 :     static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
     276                 :     static SkScalerContext* Create(const SkDescriptor*);
     277                 : 
     278                 : protected:
     279                 :     Rec         fRec;
     280                 :     unsigned    fBaseGlyphCount;
     281                 : 
     282                 :     virtual unsigned generateGlyphCount() = 0;
     283                 :     virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
     284                 :     virtual void generateAdvance(SkGlyph*) = 0;
     285                 :     virtual void generateMetrics(SkGlyph*) = 0;
     286                 :     virtual void generateImage(const SkGlyph&) = 0;
     287                 :     virtual void generatePath(const SkGlyph&, SkPath*) = 0;
     288                 :     virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
     289                 :                                      SkPaint::FontMetrics* mY) = 0;
     290                 :     // default impl returns 0, indicating failure.
     291                 :     virtual SkUnichar generateGlyphToChar(uint16_t);
     292                 : 
     293                 :     void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
     294                 : 
     295                 : private:
     296                 :     SkPathEffect*   fPathEffect;
     297                 :     SkMaskFilter*   fMaskFilter;
     298                 :     SkRasterizer*   fRasterizer;
     299                 :     SkScalar        fDevFrameWidth;
     300                 : 
     301                 :     // if this is set, we draw the image from a path, rather than
     302                 :     // calling generateImage.
     303                 :     bool fGenerateImageFromPath;
     304                 : 
     305                 :     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
     306                 :                          SkPath* devPath, SkMatrix* fillToDevMatrix);
     307                 : 
     308                 :     // return the next context, treating fNextContext as a cache of the answer
     309                 :     SkScalerContext* getNextContext();
     310                 : 
     311                 :     // returns the right context from our link-list for this glyph. If no match
     312                 :     // is found, just returns the original context (this)
     313                 :     SkScalerContext* getGlyphContext(const SkGlyph& glyph);
     314                 : 
     315                 :     // link-list of context, to handle missing chars. null-terminated.
     316                 :     SkScalerContext* fNextContext;
     317                 : };
     318                 : 
     319                 : #define kRec_SkDescriptorTag            SkSetFourByteTag('s', 'r', 'e', 'c')
     320                 : #define kPathEffect_SkDescriptorTag     SkSetFourByteTag('p', 't', 'h', 'e')
     321                 : #define kMaskFilter_SkDescriptorTag     SkSetFourByteTag('m', 's', 'k', 'f')
     322                 : #define kRasterizer_SkDescriptorTag     SkSetFourByteTag('r', 'a', 's', 't')
     323                 : 
     324                 : ///////////////////////////////////////////////////////////////////////////////
     325                 : 
     326                 : enum SkAxisAlignment {
     327                 :     kNone_SkAxisAlignment,
     328                 :     kX_SkAxisAlignment,
     329                 :     kY_SkAxisAlignment
     330                 : };
     331                 : 
     332                 : /**
     333                 :  *  Return the axis (if any) that the baseline for horizontal text will land on
     334                 :  *  after running through the specified matrix.
     335                 :  *
     336                 :  *  As an example, the identity matrix will return kX_SkAxisAlignment
     337                 :  */
     338                 : SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix);
     339                 : 
     340                 : #endif
     341                 : 

Generated by: LCOV version 1.7