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