gfx/skia/trunk/src/core/SkScalerContext.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 #ifndef SkScalerContext_DEFINED
     9 #define SkScalerContext_DEFINED
    11 #include "SkMask.h"
    12 #include "SkMaskGamma.h"
    13 #include "SkMatrix.h"
    14 #include "SkPaint.h"
    15 #include "SkTypeface.h"
    17 #ifdef SK_BUILD_FOR_ANDROID
    18     #include "SkPaintOptionsAndroid.h"
    19 #endif
    21 struct SkGlyph;
    22 class SkDescriptor;
    23 class SkMaskFilter;
    24 class SkPathEffect;
    25 class SkRasterizer;
    27 /*
    28  *  To allow this to be forward-declared, it must be its own typename, rather
    29  *  than a nested struct inside SkScalerContext (where it started).
    30  */
    31 struct SkScalerContextRec {
    32     uint32_t    fOrigFontID;
    33     uint32_t    fFontID;
    34     SkScalar    fTextSize, fPreScaleX, fPreSkewX;
    35     SkScalar    fPost2x2[2][2];
    36     SkScalar    fFrameWidth, fMiterLimit;
    38     //These describe the parameters to create (uniquely identify) the pre-blend.
    39     uint32_t    fLumBits;
    40     uint8_t     fDeviceGamma; //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
    41     uint8_t     fPaintGamma;  //2.6, (0.0, 4.0) gamma, 0.0 for sRGB
    42     uint8_t     fContrast;    //0.8+1, [0.0, 1.0] artificial contrast
    43     uint8_t     fReservedAlign;
    45     SkScalar getDeviceGamma() const {
    46         return SkIntToScalar(fDeviceGamma) / (1 << 6);
    47     }
    48     void setDeviceGamma(SkScalar dg) {
    49         SkASSERT(0 <= dg && dg < SkIntToScalar(4));
    50         fDeviceGamma = SkScalarFloorToInt(dg * (1 << 6));
    51     }
    53     SkScalar getPaintGamma() const {
    54         return SkIntToScalar(fPaintGamma) / (1 << 6);
    55     }
    56     void setPaintGamma(SkScalar pg) {
    57         SkASSERT(0 <= pg && pg < SkIntToScalar(4));
    58         fPaintGamma = SkScalarFloorToInt(pg * (1 << 6));
    59     }
    61     SkScalar getContrast() const {
    62         return SkIntToScalar(fContrast) / ((1 << 8) - 1);
    63     }
    64     void setContrast(SkScalar c) {
    65         SkASSERT(0 <= c && c <= SK_Scalar1);
    66         fContrast = SkScalarRoundToInt(c * ((1 << 8) - 1));
    67     }
    69     /**
    70      *  Causes the luminance color and contrast to be ignored, and the
    71      *  paint and device gamma to be effectively 1.0.
    72      */
    73     void ignorePreBlend() {
    74         setLuminanceColor(SK_ColorTRANSPARENT);
    75         setPaintGamma(SK_Scalar1);
    76         setDeviceGamma(SK_Scalar1);
    77         setContrast(0);
    78     }
    80     uint8_t     fMaskFormat;
    81     uint8_t     fStrokeJoin;
    82     uint16_t    fFlags;
    83     // Warning: when adding members note that the size of this structure
    84     // must be a multiple of 4. SkDescriptor requires that its arguments be
    85     // multiples of four and this structure is put in an SkDescriptor in
    86     // SkPaint::MakeRec.
    88     void    getMatrixFrom2x2(SkMatrix*) const;
    89     void    getLocalMatrix(SkMatrix*) const;
    90     void    getSingleMatrix(SkMatrix*) const;
    92     inline SkPaint::Hinting getHinting() const;
    93     inline void setHinting(SkPaint::Hinting);
    95     SkMask::Format getFormat() const {
    96         return static_cast<SkMask::Format>(fMaskFormat);
    97     }
    99     SkColor getLuminanceColor() const {
   100         return fLumBits;
   101     }
   103     void setLuminanceColor(SkColor c) {
   104         fLumBits = c;
   105     }
   106 };
   108 //The following typedef hides from the rest of the implementation the number of
   109 //most significant bits to consider when creating mask gamma tables. Two bits
   110 //per channel was chosen as a balance between fidelity (more bits) and cache
   111 //sizes (fewer bits). Three bits per channel was chosen when #303942; (used by
   112 //the Chrome UI) turned out too green.
   113 typedef SkTMaskGamma<3, 3, 3> SkMaskGamma;
   115 class SkScalerContext {
   116 public:
   117     typedef SkScalerContextRec Rec;
   119     enum Flags {
   120         kFrameAndFill_Flag        = 0x0001,
   121         kDevKernText_Flag         = 0x0002,
   122         kEmbeddedBitmapText_Flag  = 0x0004,
   123         kEmbolden_Flag            = 0x0008,
   124         kSubpixelPositioning_Flag = 0x0010,
   125         kForceAutohinting_Flag    = 0x0020,  // Use auto instead of bytcode hinting if hinting.
   126         kVertical_Flag            = 0x0040,
   128         // together, these two flags resulting in a two bit value which matches
   129         // up with the SkPaint::Hinting enum.
   130         kHinting_Shift            = 7, // to shift into the other flags above
   131         kHintingBit1_Flag         = 0x0080,
   132         kHintingBit2_Flag         = 0x0100,
   134         // Pixel geometry information.
   135         // only meaningful if fMaskFormat is LCD16 or LCD32
   136         kLCD_Vertical_Flag        = 0x0200,    // else Horizontal
   137         kLCD_BGROrder_Flag        = 0x0400,    // else RGB order
   139         // Generate A8 from LCD source (for GDI and CoreGraphics).
   140         // only meaningful if fMaskFormat is kA8
   141         kGenA8FromLCD_Flag        = 0x0800, // could be 0x200 (bit meaning dependent on fMaskFormat)
   142     };
   144     // computed values
   145     enum {
   146         kHinting_Mask   = kHintingBit1_Flag | kHintingBit2_Flag,
   147     };
   150     SkScalerContext(SkTypeface*, const SkDescriptor*);
   151     virtual ~SkScalerContext();
   153     SkTypeface* getTypeface() const { return fTypeface.get(); }
   155     SkMask::Format getMaskFormat() const {
   156         return (SkMask::Format)fRec.fMaskFormat;
   157     }
   159     bool isSubpixel() const {
   160         return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
   161     }
   163     // remember our glyph offset/base
   164     void setBaseGlyphCount(unsigned baseGlyphCount) {
   165         fBaseGlyphCount = baseGlyphCount;
   166     }
   168     /** Return the corresponding glyph for the specified unichar. Since contexts
   169         may be chained (under the hood), the glyphID that is returned may in
   170         fact correspond to a different font/context. In that case, we use the
   171         base-glyph-count to know how to translate back into local glyph space.
   172      */
   173     uint16_t charToGlyphID(SkUnichar uni);
   175     /** Map the glyphID to its glyph index, and then to its char code. Unmapped
   176         glyphs return zero.
   177     */
   178     SkUnichar glyphIDToChar(uint16_t glyphID);
   180     unsigned    getGlyphCount() { return this->generateGlyphCount(); }
   181     void        getAdvance(SkGlyph*);
   182     void        getMetrics(SkGlyph*);
   183     void        getImage(const SkGlyph&);
   184     void        getPath(const SkGlyph&, SkPath*);
   185     void        getFontMetrics(SkPaint::FontMetrics*);
   187 #ifdef SK_BUILD_FOR_ANDROID
   188     unsigned getBaseGlyphCount(SkUnichar charCode);
   190     // This function must be public for SkTypeface_android.h, but should not be
   191     // called by other callers
   192     SkFontID findTypefaceIdForChar(SkUnichar uni);
   193 #endif
   195     static inline void MakeRec(const SkPaint&, const SkDeviceProperties* deviceProperties,
   196                                const SkMatrix*, Rec* rec);
   197     static inline void PostMakeRec(const SkPaint&, Rec*);
   199     static SkMaskGamma::PreBlend GetMaskPreBlend(const Rec& rec);
   201 protected:
   202     Rec         fRec;
   203     unsigned    fBaseGlyphCount;
   205     /** Generates the contents of glyph.fAdvanceX and glyph.fAdvanceY.
   206      *  May call getMetrics if that would be just as fast.
   207      */
   208     virtual void generateAdvance(SkGlyph* glyph) = 0;
   210     /** Generates the contents of glyph.fWidth, fHeight, fTop, fLeft,
   211      *  as well as fAdvanceX and fAdvanceY if not already set.
   212      *
   213      *  TODO: fMaskFormat is set by getMetrics later; cannot be set here.
   214      */
   215     virtual void generateMetrics(SkGlyph* glyph) = 0;
   217     /** Generates the contents of glyph.fImage.
   218      *  When called, glyph.fImage will be pointing to a pre-allocated,
   219      *  uninitialized region of memory of size glyph.computeImageSize().
   220      *  This method may change glyph.fMaskFormat if the new image size is
   221      *  less than or equal to the old image size.
   222      *
   223      *  Because glyph.computeImageSize() will determine the size of fImage,
   224      *  generateMetrics will be called before generateImage.
   225      */
   226     virtual void generateImage(const SkGlyph& glyph) = 0;
   228     /** Sets the passed path to the glyph outline.
   229      *  If this cannot be done the path is set to empty;
   230      *  this is indistinguishable from a glyph with an empty path.
   231      *  This does not set glyph.fPath.
   232      *
   233      *  TODO: path is always glyph.fPath, no reason to pass separately.
   234      */
   235     virtual void generatePath(const SkGlyph& glyph, SkPath* path) = 0;
   237     /** Retrieves font metrics.
   238      *  TODO: there is now a vertical bit, no need for two parameters.
   239      */
   240     virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
   241                                      SkPaint::FontMetrics* mY) = 0;
   243     /** Returns the number of glyphs in the font. */
   244     virtual unsigned generateGlyphCount() = 0;
   246     /** Returns the glyph id for the given unichar.
   247      *  If there is no 1:1 mapping from the unichar to a glyph id, returns 0.
   248      */
   249     virtual uint16_t generateCharToGlyph(SkUnichar unichar) = 0;
   251     /** Returns the unichar for the given glyph id.
   252      *  If there is no 1:1 mapping from the glyph id to a unichar, returns 0.
   253      *  The default implementation always returns 0, indicating failure.
   254      */
   255     virtual SkUnichar generateGlyphToChar(uint16_t glyphId);
   257     void forceGenerateImageFromPath() { fGenerateImageFromPath = true; }
   259 private:
   260     // never null
   261     SkAutoTUnref<SkTypeface> fTypeface;
   263 #ifdef SK_BUILD_FOR_ANDROID
   264     SkPaintOptionsAndroid fPaintOptionsAndroid;
   265 #endif
   267     // optional object, which may be null
   268     SkPathEffect*   fPathEffect;
   269     SkMaskFilter*   fMaskFilter;
   270     SkRasterizer*   fRasterizer;
   272     // if this is set, we draw the image from a path, rather than
   273     // calling generateImage.
   274     bool fGenerateImageFromPath;
   276     void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
   277                          SkPath* devPath, SkMatrix* fillToDevMatrix);
   279     // Return the context associated with the next logical typeface, or NULL if
   280     // there are no more entries in the fallback chain.
   281     SkScalerContext* allocNextContext() const;
   283     // return the next context, treating fNextContext as a cache of the answer
   284     SkScalerContext* getNextContext();
   286     // returns the right context from our link-list for this glyph. If no match
   287     // is found, just returns the original context (this)
   288     SkScalerContext* getGlyphContext(const SkGlyph& glyph);
   290     // returns the right context from our link-list for this char. If no match
   291     // is found it returns NULL. If a match is found then the glyphID param is
   292     // set to the glyphID that maps to the provided char.
   293     SkScalerContext* getContextFromChar(SkUnichar uni, uint16_t* glyphID);
   295     // link-list of context, to handle missing chars. null-terminated.
   296     SkScalerContext* fNextContext;
   298     // SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
   299 protected:
   300     // Visible to subclasses so that generateImage can apply the pre-blend directly.
   301     const SkMaskGamma::PreBlend fPreBlend;
   302 private:
   303     // When there is a filter, previous steps must create a linear mask
   304     // and the pre-blend applied as a final step.
   305     const SkMaskGamma::PreBlend fPreBlendForFilter;
   306 };
   308 #define kRec_SkDescriptorTag            SkSetFourByteTag('s', 'r', 'e', 'c')
   309 #define kPathEffect_SkDescriptorTag     SkSetFourByteTag('p', 't', 'h', 'e')
   310 #define kMaskFilter_SkDescriptorTag     SkSetFourByteTag('m', 's', 'k', 'f')
   311 #define kRasterizer_SkDescriptorTag     SkSetFourByteTag('r', 'a', 's', 't')
   312 #ifdef SK_BUILD_FOR_ANDROID
   313 #define kAndroidOpts_SkDescriptorTag    SkSetFourByteTag('a', 'n', 'd', 'r')
   314 #endif
   316 ///////////////////////////////////////////////////////////////////////////////
   318 enum SkAxisAlignment {
   319     kNone_SkAxisAlignment,
   320     kX_SkAxisAlignment,
   321     kY_SkAxisAlignment
   322 };
   324 /**
   325  *  Return the axis (if any) that the baseline for horizontal text will land on
   326  *  after running through the specified matrix.
   327  *
   328  *  As an example, the identity matrix will return kX_SkAxisAlignment
   329  */
   330 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix);
   332 ///////////////////////////////////////////////////////////////////////////////
   334 SkPaint::Hinting SkScalerContextRec::getHinting() const {
   335     unsigned hint = (fFlags & SkScalerContext::kHinting_Mask) >>
   336                                             SkScalerContext::kHinting_Shift;
   337     return static_cast<SkPaint::Hinting>(hint);
   338 }
   340 void SkScalerContextRec::setHinting(SkPaint::Hinting hinting) {
   341     fFlags = (fFlags & ~SkScalerContext::kHinting_Mask) |
   342                                 (hinting << SkScalerContext::kHinting_Shift);
   343 }
   346 #endif

mercurial