diff options
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkFontHost.h | 46 | ||||
-rw-r--r-- | include/core/SkMask.h | 50 | ||||
-rw-r--r-- | include/core/SkPaint.h | 56 | ||||
-rw-r--r-- | include/core/SkScalerContext.h | 41 | ||||
-rw-r--r-- | include/core/SkUserConfig.h | 1 |
5 files changed, 175 insertions, 19 deletions
diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h index 03ebfc7..5a49146 100644 --- a/include/core/SkFontHost.h +++ b/include/core/SkFontHost.h @@ -131,6 +131,20 @@ public: /////////////////////////////////////////////////////////////////////////// + /** Given a filled-out rec, the fonthost may decide to modify it to reflect + what the host is actually capable of fulfilling. For example, if the + rec is requesting a level of hinting that, for this host, maps some + other level (e.g. kFull -> kNormal), it should update the rec to reflect + what will actually be done. This is an optimization so that the font + cache does not contain different recs (i.e. keys) that in reality map to + the same output. + + A lazy (but valid) fonthost can do nothing in its FilterRec routine. + */ + static void FilterRec(SkScalerContext::Rec* rec); + + /////////////////////////////////////////////////////////////////////////// + /** Return the number of tables in the font */ static int CountTables(SkFontID); @@ -187,6 +201,38 @@ public: white (table[1]) gamma tables. */ static void GetGammaTables(const uint8_t* tables[2]); + + /////////////////////////////////////////////////////////////////////////// + + /** LCDs either have their color elements arranged horizontally or + vertically. When rendering subpixel glyphs we need to know which way + round they are. + + Note, if you change this after startup, you'll need to flush the glyph + cache because it'll have the wrong type of masks cached. + */ + enum LCDOrientation { + kHorizontal_LCDOrientation = 0, //!< this is the default + kVertical_LCDOrientation = 1, + }; + + static void SetSubpixelOrientation(LCDOrientation orientation); + static LCDOrientation GetSubpixelOrientation(); + + /** LCD color elements can vary in order. For subpixel text we need to know + the order which the LCDs uses so that the color fringes are in the + correct place. + + Note, if you change this after startup, you'll need to flush the glyph + cache because it'll have the wrong type of masks cached. + */ + enum LCDOrder { + kRGB_LCDOrder = 0, //!< this is the default + kBGR_LCDOrder = 1, + }; + + static void SetSubpixelOrder(LCDOrder order); + static LCDOrder GetSubpixelOrder(); }; #endif diff --git a/include/core/SkMask.h b/include/core/SkMask.h index b72a5c5..6cbf37a 100644 --- a/include/core/SkMask.h +++ b/include/core/SkMask.h @@ -28,11 +28,28 @@ struct SkMask { kBW_Format, //!< 1bit per pixel mask (e.g. monochrome) kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing) k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add - kLCD_Format //!< 3 bytes/pixel: r/g/b + + /* The LCD formats look like this in memory: + + First, there's an A8 plane which contains the average alpha value for + each pixel. Because of this, the LCD formats can be passed directly + to functions which expect an A8 and everything will just work. + + After that in memory, there's a bitmap of 32-bit values which have + been RGB order corrected for the current screen (based on the + settings in SkFontHost at the time of renderering). The alpha value + for each pixel is the maximum of the three alpha values. + + kHorizontalLCD_Format has an extra column of pixels on the left and right + edges. kVerticalLCD_Format has an extra row at the top and bottom. + */ + + kHorizontalLCD_Format, //!< 4 bytes/pixel: a/r/g/b + kVerticalLCD_Format, //!< 4 bytes/pixel: a/r/g/b }; - + enum { - kCountMaskFormats = kLCD_Format + 1 + kCountMaskFormats = kVerticalLCD_Format + 1 }; uint8_t* fImage; @@ -78,6 +95,29 @@ struct SkMask { return fImage + x - fBounds.fLeft + (y - fBounds.fTop) * fRowBytes; } + /** Return an address into the 32-bit plane of an LCD or VerticalLCD mask + for the given position. + */ + const uint32_t* getAddrLCD(int x, int y) const { + SkASSERT(fFormat == kHorizontalLCD_Format || fFormat == kVerticalLCD_Format); + SkASSERT(fBounds.contains(x, y)); + SkASSERT(fImage != NULL); + + return reinterpret_cast<const uint32_t*>(fImage + SkAlign4(fRowBytes * fBounds.height())) + + x - fBounds.fLeft + (y - fBounds.fTop) * rowWordsLCD(); + } + + /** Return the number of 32-bit words in a row of the 32-bit plane of an + LCD or VerticalLCD mask. + */ + unsigned rowWordsLCD() const { + SkASSERT(fFormat == kHorizontalLCD_Format || fFormat == kVerticalLCD_Format); + if (fFormat == kHorizontalLCD_Format) + return fBounds.width() + 2; + else + return fBounds.width(); + } + static uint8_t* AllocImage(size_t bytes); static void FreeImage(void* image); @@ -86,6 +126,10 @@ struct SkMask { kJustRenderImage_CreateMode, //!< render into preallocate mask kComputeBoundsAndRenderImage_CreateMode //!< compute bounds, alloc image and render into it }; + + static bool FormatIsLCD(Format fm) { + return kHorizontalLCD_Format == fm || kVerticalLCD_Format == fm; + } }; #endif diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 5a01cd6..ed60a20 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -69,6 +69,33 @@ public: */ void reset(); + /** Specifies the level of hinting to be performed. These names are taken + from the Gnome/Cairo names for the same. They are translated into + Freetype concepts the same as in cairo-ft-font.c: + kNo_Hinting -> FT_LOAD_NO_HINTING + kSlight_Hinting -> FT_LOAD_TARGET_LIGHT + kNormal_Hinting -> <default, no option> + kFull_Hinting -> <same as kNormalHinting, unless we are rendering + subpixel glyphs, in which case TARGET_LCD or + TARGET_LCD_V is used> + */ + enum Hinting { + kNo_Hinting = 0, + kSlight_Hinting = 1, + kNormal_Hinting = 2, //!< this is the default + kFull_Hinting = 3, + }; + + Hinting getHinting() const + { + return static_cast<Hinting>(fHinting); + } + + void setHinting(Hinting hintingLevel) + { + fHinting = hintingLevel; + } + /** Specifies the bit values that are stored in the paint's flags. */ enum Flags { @@ -79,10 +106,13 @@ public: kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text kLinearText_Flag = 0x40, //!< mask to enable linear-text - kSubpixelText_Flag = 0x80, //!< mask to enable subpixel-text + kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning kDevKernText_Flag = 0x100, //!< mask to enable device kerning text + kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering + // when adding extra flags, note that the fFlags member is specified + // with a bit-width and you'll have to expand it. - kAllFlags = 0x1FF + kAllFlags = 0x3FF }; /** Return the paint's flags. Use the Flag enum to test flag values. @@ -143,12 +173,23 @@ public: return SkToBool(this->getFlags() & kSubpixelText_Flag); } - /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag bit - @param subpixelText true to set the subpixelText bit in the paint's - flags, false to clear it. + /** Helper for setFlags(), setting or clearing the kSubpixelText_Flag + bit @param subpixelText true to set the subpixelText bit in the paint's flags, + false to clear it. */ void setSubpixelText(bool subpixelText); - + + bool isLCDRenderText() const + { + return SkToBool(this->getFlags() & kLCDRenderText_Flag); + } + + /** Helper for setFlags(), setting or clearing the kLCDRenderText_Flag bit + @param subpixelRender true to set the subpixelRenderText bit in the paint's flags, + false to clear it. + */ + void setLCDRenderText(bool subpixelRender); + /** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set @return true if the underlineText bit is set in the paint's flags. */ @@ -749,12 +790,13 @@ private: SkColor fColor; SkScalar fWidth; SkScalar fMiterLimit; - unsigned fFlags : 9; + unsigned fFlags : 10; unsigned fTextAlign : 2; unsigned fCapType : 2; unsigned fJoinType : 2; unsigned fStyle : 2; unsigned fTextEncoding : 2; // 3 values + unsigned fHinting : 2; SkDrawCacheProc getDrawCacheProc() const; SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index b06a443..29c28f7 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -136,34 +136,59 @@ 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 Hints { - kNo_Hints, - kSubpixel_Hints, - kNormal_Hints - }; 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 + kGammaForWhite_Flag = 0x08, // illegal to set both Gamma flags + // together, these two flags resulting in a two bit value which matches + // up with the SkPaint::Hinting enum. + kHintingBit1_Flag = 0x10, + kHintingBit2_Flag = 0x20, + }; +private: + enum { + kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag }; +public: struct Rec { uint32_t fFontID; SkScalar fTextSize, fPreScaleX, fPreSkewX; SkScalar fPost2x2[2][2]; SkScalar fFrameWidth, fMiterLimit; - uint8_t fHints; + bool fSubpixelPositioning; uint8_t fMaskFormat; uint8_t fStrokeJoin; uint8_t fFlags; - + void getMatrixFrom2x2(SkMatrix*) const; void getLocalMatrix(SkMatrix*) const; void getSingleMatrix(SkMatrix*) const; + + SkPaint::Hinting getHinting() const { + return static_cast<SkPaint::Hinting>((fFlags & kHintingMask) >> 4); + } + + void setHinting(SkPaint::Hinting hinting) { + fFlags = (fFlags & ~kHintingMask) | (hinting << 4); + } + + SkMask::Format getFormat() const { + return static_cast<SkMask::Format>(fMaskFormat); + } + + bool isLCD() const { + return SkMask::FormatIsLCD(this->getFormat()); + } }; SkScalerContext(const SkDescriptor* desc); diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h index e5528cc..a72aa1a 100644 --- a/include/core/SkUserConfig.h +++ b/include/core/SkUserConfig.h @@ -135,7 +135,6 @@ void Android_SkDebugf(const char* file, int line, const char* function, const char* format, ...); - /* If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST which will run additional self-tests at startup. These can take a long time, so this flag is optional. |