00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SkScalerContext_DEFINED
00018 #define SkScalerContext_DEFINED
00019
00020 #include "SkMask.h"
00021 #include "SkMatrix.h"
00022 #include "SkPaint.h"
00023 #include "SkPath.h"
00024 #include "SkPoint.h"
00025
00026 class SkDescriptor;
00027 class SkMaskFilter;
00028 class SkPathEffect;
00029 class SkRasterizer;
00030
00031
00032 #define MASK_FORMAT_JUST_ADVANCE (0xFF)
00033
00034 struct SkGlyph {
00035 void* fImage;
00036 SkPath* fPath;
00037 SkFixed fAdvanceX, fAdvanceY;
00038
00039 uint32_t fID;
00040 uint16_t fWidth, fHeight;
00041 int16_t fTop, fLeft;
00042
00043 uint8_t fMaskFormat;
00044 int8_t fRsbDelta, fLsbDelta;
00045
00046 unsigned rowBytes() const {
00047 unsigned rb = fWidth;
00048 if (SkMask::kBW_Format == fMaskFormat) {
00049 rb = (rb + 7) >> 3;
00050 } else {
00051 rb = SkAlign4(rb);
00052 }
00053 return rb;
00054 }
00055
00056 bool isJustAdvance() const {
00057 return MASK_FORMAT_JUST_ADVANCE == fMaskFormat;
00058 }
00059
00060 bool isFullMetrics() const {
00061 return MASK_FORMAT_JUST_ADVANCE != fMaskFormat;
00062 }
00063
00064 uint16_t getGlyphID() const {
00065 return ID2Code(fID);
00066 }
00067
00068 unsigned getGlyphID(unsigned baseGlyphCount) const {
00069 unsigned code = ID2Code(fID);
00070 SkASSERT(code >= baseGlyphCount);
00071 return code - baseGlyphCount;
00072 }
00073
00074 unsigned getSubX() const {
00075 return ID2SubX(fID);
00076 }
00077
00078 SkFixed getSubXFixed() const {
00079 return SubToFixed(ID2SubX(fID));
00080 }
00081
00082 SkFixed getSubYFixed() const {
00083 return SubToFixed(ID2SubY(fID));
00084 }
00085
00086 size_t computeImageSize() const;
00087
00092 void zeroMetrics();
00093
00094 enum {
00095 kSubBits = 2,
00096 kSubMask = ((1 << kSubBits) - 1),
00097 kSubShift = 24,
00098 kCodeMask = ((1 << kSubShift) - 1),
00099
00100 kSubShiftX = kSubBits,
00101 kSubShiftY = 0
00102 };
00103
00104 static unsigned ID2Code(uint32_t id) {
00105 return id & kCodeMask;
00106 }
00107
00108 static unsigned ID2SubX(uint32_t id) {
00109 return id >> (kSubShift + kSubShiftX);
00110 }
00111
00112 static unsigned ID2SubY(uint32_t id) {
00113 return (id >> (kSubShift + kSubShiftY)) & kSubMask;
00114 }
00115
00116 static unsigned FixedToSub(SkFixed n) {
00117 return (n >> (16 - kSubBits)) & kSubMask;
00118 }
00119
00120 static SkFixed SubToFixed(unsigned sub) {
00121 SkASSERT(sub <= kSubMask);
00122 return sub << (16 - kSubBits);
00123 }
00124
00125 static uint32_t MakeID(unsigned code) {
00126 return code;
00127 }
00128
00129 static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) {
00130 SkASSERT(code <= kCodeMask);
00131 x = FixedToSub(x);
00132 y = FixedToSub(y);
00133 return (x << (kSubShift + kSubShiftX)) |
00134 (y << (kSubShift + kSubShiftY)) |
00135 code;
00136 }
00137
00138 void toMask(SkMask* mask) const;
00139
00143 void expandA8ToLCD() const;
00144 };
00145
00146 class SkScalerContext {
00147 public:
00148 enum Flags {
00149 kFrameAndFill_Flag = 0x01,
00150 kDevKernText_Flag = 0x02,
00151 kGammaForBlack_Flag = 0x04,
00152 kGammaForWhite_Flag = 0x08,
00153
00154
00155 kHintingBit1_Flag = 0x10,
00156 kHintingBit2_Flag = 0x20,
00157 };
00158 private:
00159 enum {
00160 kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag
00161 };
00162 public:
00163 struct Rec {
00164 uint32_t fFontID;
00165 SkScalar fTextSize, fPreScaleX, fPreSkewX;
00166 SkScalar fPost2x2[2][2];
00167 SkScalar fFrameWidth, fMiterLimit;
00168 bool fSubpixelPositioning;
00169 uint8_t fMaskFormat;
00170 uint8_t fStrokeJoin;
00171 uint8_t fFlags;
00172
00173 void getMatrixFrom2x2(SkMatrix*) const;
00174 void getLocalMatrix(SkMatrix*) const;
00175 void getSingleMatrix(SkMatrix*) const;
00176
00177 SkPaint::Hinting getHinting() const {
00178 return static_cast<SkPaint::Hinting>((fFlags & kHintingMask) >> 4);
00179 }
00180
00181 void setHinting(SkPaint::Hinting hinting) {
00182 fFlags = (fFlags & ~kHintingMask) | (hinting << 4);
00183 }
00184
00185 SkMask::Format getFormat() const {
00186 return static_cast<SkMask::Format>(fMaskFormat);
00187 }
00188
00189 bool isLCD() const {
00190 return SkMask::FormatIsLCD(this->getFormat());
00191 }
00192 };
00193
00194 SkScalerContext(const SkDescriptor* desc);
00195 virtual ~SkScalerContext();
00196
00197
00198 void setBaseGlyphCount(unsigned baseGlyphCount) {
00199 fBaseGlyphCount = baseGlyphCount;
00200 }
00201
00207 uint16_t charToGlyphID(SkUnichar uni);
00208
00209 unsigned getGlyphCount() const { return this->generateGlyphCount(); }
00210 void getAdvance(SkGlyph*);
00211 void getMetrics(SkGlyph*);
00212 void getImage(const SkGlyph&);
00213 void getPath(const SkGlyph&, SkPath*);
00214 void getFontMetrics(SkPaint::FontMetrics* mX,
00215 SkPaint::FontMetrics* mY);
00216
00217 static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec);
00218 static SkScalerContext* Create(const SkDescriptor*);
00219
00220 protected:
00221 Rec fRec;
00222 unsigned fBaseGlyphCount;
00223
00224 virtual unsigned generateGlyphCount() const = 0;
00225 virtual uint16_t generateCharToGlyph(SkUnichar) = 0;
00226 virtual void generateAdvance(SkGlyph*) = 0;
00227 virtual void generateMetrics(SkGlyph*) = 0;
00228 virtual void generateImage(const SkGlyph&) = 0;
00229 virtual void generatePath(const SkGlyph&, SkPath*) = 0;
00230 virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
00231 SkPaint::FontMetrics* mY) = 0;
00232
00233 private:
00234 SkPathEffect* fPathEffect;
00235 SkMaskFilter* fMaskFilter;
00236 SkRasterizer* fRasterizer;
00237 SkScalar fDevFrameWidth;
00238
00239 void internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
00240 SkPath* devPath, SkMatrix* fillToDevMatrix);
00241
00242
00243 SkScalerContext* getNextContext();
00244
00245
00246
00247 SkScalerContext* getGlyphContext(const SkGlyph& glyph);
00248
00249
00250 SkScalerContext* fNextContext;
00251 };
00252
00253 #define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c')
00254 #define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e')
00255 #define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f')
00256 #define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't')
00257
00258 #endif
00259