SkScalerContext.h revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef SkScalerContext_DEFINED 18#define SkScalerContext_DEFINED 19 20#include "SkMask.h" 21#include "SkMatrix.h" 22#include "SkPaint.h" 23#include "SkPath.h" 24#include "SkPoint.h" 25 26class SkDescriptor; 27class SkMaskFilter; 28class SkPathEffect; 29class SkRasterizer; 30 31// needs to be != to any valid SkMask::Format 32#define MASK_FORMAT_JUST_ADVANCE (0xFF) 33 34struct SkGlyph { 35 void* fImage; 36 SkPath* fPath; 37 SkFixed fAdvanceX, fAdvanceY; 38 39 uint32_t fID; 40 uint16_t fWidth, fHeight; 41 int16_t fTop, fLeft; 42 43 uint8_t fMaskFormat; 44 int8_t fRsbDelta, fLsbDelta; // used by auto-kerning 45 46 unsigned rowBytes() const { 47 unsigned rb = fWidth; 48 if (SkMask::kBW_Format == fMaskFormat) { 49 rb = (rb + 7) >> 3; 50 } else { 51 rb = SkAlign4(rb); 52 } 53 return rb; 54 } 55 56 bool isJustAdvance() const { 57 return MASK_FORMAT_JUST_ADVANCE == fMaskFormat; 58 } 59 60 bool isFullMetrics() const { 61 return MASK_FORMAT_JUST_ADVANCE != fMaskFormat; 62 } 63 64 uint16_t getGlyphID() const { 65 return ID2Code(fID); 66 } 67 68 unsigned getGlyphID(unsigned baseGlyphCount) const { 69 unsigned code = ID2Code(fID); 70 SkASSERT(code >= baseGlyphCount); 71 return code - baseGlyphCount; 72 } 73 74 unsigned getSubX() const { 75 return ID2SubX(fID); 76 } 77 78 SkFixed getSubXFixed() const { 79 return SubToFixed(ID2SubX(fID)); 80 } 81 82 SkFixed getSubYFixed() const { 83 return SubToFixed(ID2SubY(fID)); 84 } 85 86 size_t computeImageSize() const; 87 88 /** Call this to set all of the metrics fields to 0 (e.g. if the scaler 89 encounters an error measuring a glyph). Note: this does not alter the 90 fImage, fPath, fID, fMaskFormat fields. 91 */ 92 void zeroMetrics(); 93 94 enum { 95 kSubBits = 2, 96 kSubMask = ((1 << kSubBits) - 1), 97 kSubShift = 24, // must be large enough for glyphs and unichars 98 kCodeMask = ((1 << kSubShift) - 1), 99 // relative offsets for X and Y subpixel bits 100 kSubShiftX = kSubBits, 101 kSubShiftY = 0 102 }; 103 104 static unsigned ID2Code(uint32_t id) { 105 return id & kCodeMask; 106 } 107 108 static unsigned ID2SubX(uint32_t id) { 109 return id >> (kSubShift + kSubShiftX); 110 } 111 112 static unsigned ID2SubY(uint32_t id) { 113 return (id >> (kSubShift + kSubShiftY)) & kSubMask; 114 } 115 116 static unsigned FixedToSub(SkFixed n) { 117 return (n >> (16 - kSubBits)) & kSubMask; 118 } 119 120 static SkFixed SubToFixed(unsigned sub) { 121 SkASSERT(sub <= kSubMask); 122 return sub << (16 - kSubBits); 123 } 124 125 static uint32_t MakeID(unsigned code) { 126 return code; 127 } 128 129 static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) { 130 SkASSERT(code <= kCodeMask); 131 x = FixedToSub(x); 132 y = FixedToSub(y); 133 return (x << (kSubShift + kSubShiftX)) | 134 (y << (kSubShift + kSubShiftY)) | 135 code; 136 } 137 138 void toMask(SkMask* mask) const; 139}; 140 141class SkScalerContext { 142public: 143 enum Hints { 144 kNo_Hints, 145 kSubpixel_Hints, 146 kNormal_Hints 147 }; 148 enum Flags { 149 kFrameAndFill_Flag = 0x01, 150 kDevKernText_Flag = 0x02, 151 kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags 152 kGammaForWhite_Flag = 0x08 // illegal to set both Gamma flags 153 }; 154 struct Rec { 155 uint32_t fFontID; 156 SkScalar fTextSize, fPreScaleX, fPreSkewX; 157 SkScalar fPost2x2[2][2]; 158 SkScalar fFrameWidth, fMiterLimit; 159 uint8_t fHints; 160 uint8_t fMaskFormat; 161 uint8_t fStrokeJoin; 162 uint8_t fFlags; 163 164 void getMatrixFrom2x2(SkMatrix*) const; 165 void getLocalMatrix(SkMatrix*) const; 166 void getSingleMatrix(SkMatrix*) const; 167 }; 168 169 SkScalerContext(const SkDescriptor* desc); 170 virtual ~SkScalerContext(); 171 172 void setBaseGlyphCount(unsigned baseGlyphCount) { 173 fBaseGlyphCount = baseGlyphCount; 174 } 175 176 uint16_t charToGlyphID(SkUnichar uni); 177 178 unsigned getGlyphCount() const { return this->generateGlyphCount(); } 179 void getAdvance(SkGlyph*); 180 void getMetrics(SkGlyph*); 181 void getImage(const SkGlyph&); 182 void getPath(const SkGlyph&, SkPath*); 183 void getFontMetrics(SkPaint::FontMetrics* mX, 184 SkPaint::FontMetrics* mY); 185 186 static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec); 187 static SkScalerContext* Create(const SkDescriptor*); 188 189protected: 190 Rec fRec; 191 unsigned fBaseGlyphCount; 192 193 virtual unsigned generateGlyphCount() const = 0; 194 virtual uint16_t generateCharToGlyph(SkUnichar) = 0; 195 virtual void generateAdvance(SkGlyph*) = 0; 196 virtual void generateMetrics(SkGlyph*) = 0; 197 virtual void generateImage(const SkGlyph&) = 0; 198 virtual void generatePath(const SkGlyph&, SkPath*) = 0; 199 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, 200 SkPaint::FontMetrics* mY) = 0; 201 202private: 203 SkPathEffect* fPathEffect; 204 SkMaskFilter* fMaskFilter; 205 SkRasterizer* fRasterizer; 206 SkScalar fDevFrameWidth; 207 208 void internalGetPath(const SkGlyph& glyph, SkPath* fillPath, 209 SkPath* devPath, SkMatrix* fillToDevMatrix); 210 211 mutable SkScalerContext* fAuxScalerContext; 212 213 SkScalerContext* getGlyphContext(const SkGlyph& glyph) const; 214 215 // return loaded fAuxScalerContext or NULL 216 SkScalerContext* loadAuxContext() const; 217}; 218 219#define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c') 220#define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e') 221#define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f') 222#define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't') 223 224#endif 225 226