diff options
Diffstat (limited to 'include/core/SkScalerContext.h')
-rw-r--r-- | include/core/SkScalerContext.h | 125 |
1 files changed, 84 insertions, 41 deletions
diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index cbbbdf0..e7dd7d4 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -1,19 +1,12 @@ + /* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright 2006 The Android Open Source Project * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + #ifndef SkScalerContext_DEFINED #define SkScalerContext_DEFINED @@ -60,7 +53,9 @@ struct SkGlyph { unsigned rb = width; if (SkMask::kBW_Format == format) { rb = (rb + 7) >> 3; - } else if (SkMask::kARGB32_Format == format) { + } else if (SkMask::kARGB32_Format == format || + SkMask::kLCD32_Format == format) + { rb <<= 2; } else if (SkMask::kLCD16_Format == format) { rb = SkAlign4(rb << 1); @@ -157,37 +152,41 @@ struct SkGlyph { } void toMask(SkMask* mask) const; - - /** Given a glyph which is has a mask format of LCD or VerticalLCD, take - the A8 plane in fImage and produce a valid LCD plane from it. - */ - void expandA8ToLCD() const; }; class SkScalerContext { public: enum Flags { - kFrameAndFill_Flag = 0x01, - kDevKernText_Flag = 0x02, - kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags - kGammaForWhite_Flag = 0x08, // illegal to set both Gamma flags + kFrameAndFill_Flag = 0x0001, + kDevKernText_Flag = 0x0002, + kEmbeddedBitmapText_Flag = 0x0004, + kEmbolden_Flag = 0x0008, + kSubpixelPositioning_Flag = 0x0010, + kAutohinting_Flag = 0x0020, + kVertical_Flag = 0x0040, + // together, these two flags resulting in a two bit value which matches // up with the SkPaint::Hinting enum. - kHintingBit1_Flag = 0x10, - kHintingBit2_Flag = 0x20, - kEmbeddedBitmapText_Flag = 0x40, - kEmbolden_Flag = 0x80, - kSubpixelPositioning_Flag = 0x100, - kAutohinting_Flag = 0x200, - // these should only ever be set if fMaskFormat is LCD - kLCD_Vertical_Flag = 0x400, // else Horizontal - kLCD_BGROrder_Flag = 0x800, // else RGB order + kHinting_Shift = 7, // to shift into the other flags above + kHintingBit1_Flag = 0x0080, + kHintingBit2_Flag = 0x0100, + + // these should only ever be set if fMaskFormat is LCD16 or LCD32 + kLCD_Vertical_Flag = 0x0200, // else Horizontal + kLCD_BGROrder_Flag = 0x0400, // else RGB order + + // luminance : 0 for black text, kLuminance_Max for white text + kLuminance_Shift = 11, // to shift into the other flags above + kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits }; -private: + + // computed values enum { - kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag + kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, + kLuminance_Max = (1 << kLuminance_Bits) - 1, + kLuminance_Mask = kLuminance_Max << kLuminance_Shift, }; -public: + struct Rec { uint32_t fOrigFontID; uint32_t fFontID; @@ -207,19 +206,33 @@ public: void getSingleMatrix(SkMatrix*) const; SkPaint::Hinting getHinting() const { - return static_cast<SkPaint::Hinting>((fFlags & kHintingMask) >> 4); + unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift; + return static_cast<SkPaint::Hinting>(hint); } void setHinting(SkPaint::Hinting hinting) { - fFlags = (fFlags & ~kHintingMask) | (hinting << 4); + fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift); } - SkMask::Format getFormat() const { - return static_cast<SkMask::Format>(fMaskFormat); + unsigned getLuminanceBits() const { + return (fFlags & kLuminance_Mask) >> kLuminance_Shift; + } + + void setLuminanceBits(unsigned lum) { + SkASSERT(lum <= kLuminance_Max); + fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift); } - bool isLCD() const { - return SkMask::FormatIsLCD(this->getFormat()); + U8CPU getLuminanceByte() const { + SkASSERT(3 == kLuminance_Bits); + unsigned lum = this->getLuminanceBits(); + lum |= (lum << kLuminance_Bits); + lum |= (lum << kLuminance_Bits*2); + return lum >> (4*kLuminance_Bits - 8); + } + + SkMask::Format getFormat() const { + return static_cast<SkMask::Format>(fMaskFormat); } }; @@ -230,6 +243,10 @@ public: return (SkMask::Format)fRec.fMaskFormat; } + bool isSubpixel() const { + return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag); + } + // remember our glyph offset/base void setBaseGlyphCount(unsigned baseGlyphCount) { fBaseGlyphCount = baseGlyphCount; @@ -240,7 +257,7 @@ public: fact correspond to a different font/context. In that case, we use the base-glyph-count to know how to translate back into local glyph space. */ - uint16_t charToGlyphID(SkUnichar uni); + uint16_t charToGlyphID(SkUnichar uni); /** Map the glyphID to its glyph index, and then to its char code. Unmapped glyphs return zero. @@ -255,6 +272,10 @@ public: void getFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY); +#ifdef SK_BUILD_FOR_ANDROID + unsigned getBaseGlyphCount(SkUnichar charCode); +#endif + static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec); static SkScalerContext* Create(const SkDescriptor*); @@ -273,12 +294,18 @@ protected: // default impl returns 0, indicating failure. virtual SkUnichar generateGlyphToChar(uint16_t); + void forceGenerateImageFromPath() { fGenerateImageFromPath = true; } + private: SkPathEffect* fPathEffect; SkMaskFilter* fMaskFilter; SkRasterizer* fRasterizer; SkScalar fDevFrameWidth; + // if this is set, we draw the image from a path, rather than + // calling generateImage. + bool fGenerateImageFromPath; + void internalGetPath(const SkGlyph& glyph, SkPath* fillPath, SkPath* devPath, SkMatrix* fillToDevMatrix); @@ -298,5 +325,21 @@ private: #define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f') #define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't') +/////////////////////////////////////////////////////////////////////////////// + +enum SkAxisAlignment { + kNone_SkAxisAlignment, + kX_SkAxisAlignment, + kY_SkAxisAlignment +}; + +/** + * Return the axis (if any) that the baseline for horizontal text will land on + * after running through the specified matrix. + * + * As an example, the identity matrix will return kX_SkAxisAlignment + */ +SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix); + #endif |