aboutsummaryrefslogtreecommitdiffstats
path: root/include/core
diff options
context:
space:
mode:
Diffstat (limited to 'include/core')
-rw-r--r--include/core/SkFontHost.h46
-rw-r--r--include/core/SkMask.h50
-rw-r--r--include/core/SkPaint.h56
-rw-r--r--include/core/SkScalerContext.h41
-rw-r--r--include/core/SkUserConfig.h1
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.