epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 1 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 2 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 3 | * Copyright 2006 The Android Open Source Project |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 4 | * |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 7 | */ |
| 8 | |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 9 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 10 | #ifndef SkScalerContext_DEFINED |
| 11 | #define SkScalerContext_DEFINED |
| 12 | |
| 13 | #include "SkMask.h" |
| 14 | #include "SkMatrix.h" |
| 15 | #include "SkPaint.h" |
| 16 | #include "SkPath.h" |
| 17 | #include "SkPoint.h" |
| 18 | |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 19 | //#define SK_USE_COLOR_LUMINANCE |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 20 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 21 | class SkDescriptor; |
| 22 | class SkMaskFilter; |
| 23 | class SkPathEffect; |
| 24 | class SkRasterizer; |
| 25 | |
| 26 | // needs to be != to any valid SkMask::Format |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 27 | #define MASK_FORMAT_UNKNOWN (0xFF) |
| 28 | #define MASK_FORMAT_JUST_ADVANCE MASK_FORMAT_UNKNOWN |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 29 | |
scarybeasts@gmail.com | 17f694b | 2010-10-18 23:29:36 +0000 | [diff] [blame] | 30 | #define kMaxGlyphWidth (1<<13) |
| 31 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 32 | struct SkGlyph { |
| 33 | void* fImage; |
| 34 | SkPath* fPath; |
| 35 | SkFixed fAdvanceX, fAdvanceY; |
| 36 | |
| 37 | uint32_t fID; |
| 38 | uint16_t fWidth, fHeight; |
| 39 | int16_t fTop, fLeft; |
| 40 | |
| 41 | uint8_t fMaskFormat; |
| 42 | int8_t fRsbDelta, fLsbDelta; // used by auto-kerning |
reed@android.com | f2b98d6 | 2010-12-20 18:26:13 +0000 | [diff] [blame] | 43 | |
| 44 | void init(uint32_t id) { |
| 45 | fID = id; |
| 46 | fImage = NULL; |
| 47 | fPath = NULL; |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 48 | fMaskFormat = MASK_FORMAT_UNKNOWN; |
reed@android.com | f2b98d6 | 2010-12-20 18:26:13 +0000 | [diff] [blame] | 49 | } |
| 50 | |
reed@google.com | f88d676 | 2011-03-10 15:06:27 +0000 | [diff] [blame] | 51 | /** |
| 52 | * Compute the rowbytes for the specified width and mask-format. |
| 53 | */ |
| 54 | static unsigned ComputeRowBytes(unsigned width, SkMask::Format format) { |
| 55 | unsigned rb = width; |
| 56 | if (SkMask::kBW_Format == format) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 57 | rb = (rb + 7) >> 3; |
caryclark@google.com | 1eeaf0b | 2011-06-22 13:19:43 +0000 | [diff] [blame] | 58 | } else if (SkMask::kARGB32_Format == format || |
| 59 | SkMask::kLCD32_Format == format) |
| 60 | { |
reed@android.com | f2b98d6 | 2010-12-20 18:26:13 +0000 | [diff] [blame] | 61 | rb <<= 2; |
reed@google.com | f88d676 | 2011-03-10 15:06:27 +0000 | [diff] [blame] | 62 | } else if (SkMask::kLCD16_Format == format) { |
| 63 | rb = SkAlign4(rb << 1); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 64 | } else { |
| 65 | rb = SkAlign4(rb); |
| 66 | } |
| 67 | return rb; |
| 68 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 69 | |
reed@google.com | f88d676 | 2011-03-10 15:06:27 +0000 | [diff] [blame] | 70 | unsigned rowBytes() const { |
| 71 | return ComputeRowBytes(fWidth, (SkMask::Format)fMaskFormat); |
| 72 | } |
| 73 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 74 | bool isJustAdvance() const { |
| 75 | return MASK_FORMAT_JUST_ADVANCE == fMaskFormat; |
| 76 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 77 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 78 | bool isFullMetrics() const { |
| 79 | return MASK_FORMAT_JUST_ADVANCE != fMaskFormat; |
| 80 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 81 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 82 | uint16_t getGlyphID() const { |
| 83 | return ID2Code(fID); |
| 84 | } |
| 85 | |
| 86 | unsigned getGlyphID(unsigned baseGlyphCount) const { |
| 87 | unsigned code = ID2Code(fID); |
| 88 | SkASSERT(code >= baseGlyphCount); |
| 89 | return code - baseGlyphCount; |
| 90 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 91 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 92 | unsigned getSubX() const { |
| 93 | return ID2SubX(fID); |
| 94 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 95 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 96 | SkFixed getSubXFixed() const { |
| 97 | return SubToFixed(ID2SubX(fID)); |
| 98 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 99 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 100 | SkFixed getSubYFixed() const { |
| 101 | return SubToFixed(ID2SubY(fID)); |
| 102 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 103 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 104 | size_t computeImageSize() const; |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 105 | |
reed@android.com | 62900b4 | 2009-02-11 15:07:19 +0000 | [diff] [blame] | 106 | /** Call this to set all of the metrics fields to 0 (e.g. if the scaler |
| 107 | encounters an error measuring a glyph). Note: this does not alter the |
| 108 | fImage, fPath, fID, fMaskFormat fields. |
| 109 | */ |
| 110 | void zeroMetrics(); |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 111 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 112 | enum { |
| 113 | kSubBits = 2, |
| 114 | kSubMask = ((1 << kSubBits) - 1), |
| 115 | kSubShift = 24, // must be large enough for glyphs and unichars |
| 116 | kCodeMask = ((1 << kSubShift) - 1), |
| 117 | // relative offsets for X and Y subpixel bits |
| 118 | kSubShiftX = kSubBits, |
| 119 | kSubShiftY = 0 |
| 120 | }; |
| 121 | |
| 122 | static unsigned ID2Code(uint32_t id) { |
| 123 | return id & kCodeMask; |
| 124 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 125 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 126 | static unsigned ID2SubX(uint32_t id) { |
| 127 | return id >> (kSubShift + kSubShiftX); |
| 128 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 129 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 130 | static unsigned ID2SubY(uint32_t id) { |
| 131 | return (id >> (kSubShift + kSubShiftY)) & kSubMask; |
| 132 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 133 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 134 | static unsigned FixedToSub(SkFixed n) { |
| 135 | return (n >> (16 - kSubBits)) & kSubMask; |
| 136 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 137 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 138 | static SkFixed SubToFixed(unsigned sub) { |
| 139 | SkASSERT(sub <= kSubMask); |
| 140 | return sub << (16 - kSubBits); |
| 141 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 142 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 143 | static uint32_t MakeID(unsigned code) { |
| 144 | return code; |
| 145 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 146 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 147 | static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) { |
| 148 | SkASSERT(code <= kCodeMask); |
| 149 | x = FixedToSub(x); |
| 150 | y = FixedToSub(y); |
| 151 | return (x << (kSubShift + kSubShiftX)) | |
| 152 | (y << (kSubShift + kSubShiftY)) | |
| 153 | code; |
| 154 | } |
reed@google.com | d3b13bd | 2011-01-13 16:33:36 +0000 | [diff] [blame] | 155 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 156 | void toMask(SkMask* mask) const; |
| 157 | }; |
| 158 | |
| 159 | class SkScalerContext { |
| 160 | public: |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 161 | enum Flags { |
reed@google.com | b6bb5cb | 2011-11-21 19:32:29 +0000 | [diff] [blame] | 162 | kFrameAndFill_Flag = 0x0001, |
| 163 | kDevKernText_Flag = 0x0002, |
| 164 | kEmbeddedBitmapText_Flag = 0x0004, |
| 165 | kEmbolden_Flag = 0x0008, |
| 166 | kSubpixelPositioning_Flag = 0x0010, |
| 167 | kAutohinting_Flag = 0x0020, |
| 168 | kVertical_Flag = 0x0040, |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 169 | |
agl@chromium.org | 309485b | 2009-07-21 17:41:32 +0000 | [diff] [blame] | 170 | // together, these two flags resulting in a two bit value which matches |
| 171 | // up with the SkPaint::Hinting enum. |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 172 | kHinting_Shift = 7, // to shift into the other flags above |
reed@google.com | b6bb5cb | 2011-11-21 19:32:29 +0000 | [diff] [blame] | 173 | kHintingBit1_Flag = 0x0080, |
| 174 | kHintingBit2_Flag = 0x0100, |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 175 | |
reed@google.com | effc501 | 2011-06-27 16:44:46 +0000 | [diff] [blame] | 176 | // these should only ever be set if fMaskFormat is LCD16 or LCD32 |
reed@google.com | b6bb5cb | 2011-11-21 19:32:29 +0000 | [diff] [blame] | 177 | kLCD_Vertical_Flag = 0x0200, // else Horizontal |
| 178 | kLCD_BGROrder_Flag = 0x0400, // else RGB order |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 179 | |
reed@google.com | 8351aab | 2012-01-18 17:06:35 +0000 | [diff] [blame] | 180 | // Generate A8 from LCD source (for GDI), only meaningful if fMaskFormat is kA8 |
| 181 | // Perhaps we can store this (instead) in fMaskFormat, in hight bit? |
| 182 | kGenA8FromLCD_Flag = 0x0800, |
| 183 | |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 184 | #ifdef SK_USE_COLOR_LUMINANCE |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 185 | kLuminance_Bits = 3, |
| 186 | #else |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 187 | // luminance : 0 for black text, kLuminance_Max for white text |
reed@google.com | 8351aab | 2012-01-18 17:06:35 +0000 | [diff] [blame] | 188 | kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 189 | kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 190 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 191 | }; |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 192 | |
| 193 | // computed values |
reed@android.com | e2ca207 | 2009-07-27 16:39:38 +0000 | [diff] [blame] | 194 | enum { |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 195 | kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 196 | #ifdef SK_USE_COLOR_LUMINANCE |
| 197 | #else |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 198 | kLuminance_Max = (1 << kLuminance_Bits) - 1, |
| 199 | kLuminance_Mask = kLuminance_Max << kLuminance_Shift, |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 200 | #endif |
reed@android.com | e2ca207 | 2009-07-27 16:39:38 +0000 | [diff] [blame] | 201 | }; |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 202 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 203 | struct Rec { |
reed@google.com | 7d26c59 | 2011-06-13 13:01:10 +0000 | [diff] [blame] | 204 | uint32_t fOrigFontID; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 205 | uint32_t fFontID; |
| 206 | SkScalar fTextSize, fPreScaleX, fPreSkewX; |
| 207 | SkScalar fPost2x2[2][2]; |
| 208 | SkScalar fFrameWidth, fMiterLimit; |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 209 | #ifdef SK_USE_COLOR_LUMINANCE |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 210 | uint32_t fLumBits; |
| 211 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 212 | uint8_t fMaskFormat; |
| 213 | uint8_t fStrokeJoin; |
agl@chromium.org | a2c71cb | 2010-06-17 20:49:17 +0000 | [diff] [blame] | 214 | uint16_t fFlags; |
agl@chromium.org | 13c8558 | 2010-01-04 23:56:43 +0000 | [diff] [blame] | 215 | // Warning: when adding members note that the size of this structure |
| 216 | // must be a multiple of 4. SkDescriptor requires that its arguments be |
| 217 | // multiples of four and this structure is put in an SkDescriptor in |
| 218 | // SkPaint::MakeRec. |
agl@chromium.org | 309485b | 2009-07-21 17:41:32 +0000 | [diff] [blame] | 219 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 220 | void getMatrixFrom2x2(SkMatrix*) const; |
| 221 | void getLocalMatrix(SkMatrix*) const; |
| 222 | void getSingleMatrix(SkMatrix*) const; |
agl@chromium.org | 309485b | 2009-07-21 17:41:32 +0000 | [diff] [blame] | 223 | |
| 224 | SkPaint::Hinting getHinting() const { |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 225 | unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift; |
reed@google.com | f788feb | 2011-11-21 19:46:00 +0000 | [diff] [blame] | 226 | return static_cast<SkPaint::Hinting>(hint); |
agl@chromium.org | 309485b | 2009-07-21 17:41:32 +0000 | [diff] [blame] | 227 | } |
| 228 | |
| 229 | void setHinting(SkPaint::Hinting hinting) { |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 230 | fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift); |
| 231 | } |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 232 | |
| 233 | SkMask::Format getFormat() const { |
| 234 | return static_cast<SkMask::Format>(fMaskFormat); |
| 235 | } |
| 236 | |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 237 | #ifdef SK_USE_COLOR_LUMINANCE |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 238 | SkColor getLuminanceColor() const { |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 239 | return fLumBits; |
| 240 | } |
| 241 | |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 242 | void setLuminanceColor(SkColor c) { |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 243 | fLumBits = c; |
reed@google.com | e7a0a16 | 2012-02-07 21:25:33 +0000 | [diff] [blame] | 244 | } |
| 245 | #else |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 246 | unsigned getLuminanceBits() const { |
| 247 | return (fFlags & kLuminance_Mask) >> kLuminance_Shift; |
| 248 | } |
| 249 | |
| 250 | void setLuminanceBits(unsigned lum) { |
| 251 | SkASSERT(lum <= kLuminance_Max); |
| 252 | fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift); |
| 253 | } |
| 254 | |
| 255 | U8CPU getLuminanceByte() const { |
| 256 | SkASSERT(3 == kLuminance_Bits); |
| 257 | unsigned lum = this->getLuminanceBits(); |
| 258 | lum |= (lum << kLuminance_Bits); |
| 259 | lum |= (lum << kLuminance_Bits*2); |
| 260 | return lum >> (4*kLuminance_Bits - 8); |
agl@chromium.org | 309485b | 2009-07-21 17:41:32 +0000 | [diff] [blame] | 261 | } |
reed@google.com | ce6dbb6 | 2012-02-10 22:01:45 +0000 | [diff] [blame] | 262 | #endif |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 263 | }; |
| 264 | |
| 265 | SkScalerContext(const SkDescriptor* desc); |
| 266 | virtual ~SkScalerContext(); |
| 267 | |
reed@google.com | 98539c6 | 2011-03-15 15:40:16 +0000 | [diff] [blame] | 268 | SkMask::Format getMaskFormat() const { |
| 269 | return (SkMask::Format)fRec.fMaskFormat; |
| 270 | } |
| 271 | |
reed@google.com | abf00aa | 2012-01-03 19:43:20 +0000 | [diff] [blame] | 272 | bool isSubpixel() const { |
| 273 | return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag); |
| 274 | } |
| 275 | |
reed@android.com | a14ea0e | 2009-03-17 17:59:53 +0000 | [diff] [blame] | 276 | // remember our glyph offset/base |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 277 | void setBaseGlyphCount(unsigned baseGlyphCount) { |
| 278 | fBaseGlyphCount = baseGlyphCount; |
| 279 | } |
| 280 | |
reed@android.com | a14ea0e | 2009-03-17 17:59:53 +0000 | [diff] [blame] | 281 | /** Return the corresponding glyph for the specified unichar. Since contexts |
| 282 | may be chained (under the hood), the glyphID that is returned may in |
| 283 | fact correspond to a different font/context. In that case, we use the |
| 284 | base-glyph-count to know how to translate back into local glyph space. |
| 285 | */ |
reed@google.com | ffe49f5 | 2011-11-22 19:42:41 +0000 | [diff] [blame] | 286 | uint16_t charToGlyphID(SkUnichar uni); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 287 | |
reed@android.com | 9d3a985 | 2010-01-08 14:07:42 +0000 | [diff] [blame] | 288 | /** Map the glyphID to its glyph index, and then to its char code. Unmapped |
| 289 | glyphs return zero. |
| 290 | */ |
| 291 | SkUnichar glyphIDToChar(uint16_t glyphID); |
| 292 | |
ctguil@chromium.org | 0bc7bf5 | 2011-03-04 19:04:57 +0000 | [diff] [blame] | 293 | unsigned getGlyphCount() { return this->generateGlyphCount(); } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 294 | void getAdvance(SkGlyph*); |
| 295 | void getMetrics(SkGlyph*); |
| 296 | void getImage(const SkGlyph&); |
| 297 | void getPath(const SkGlyph&, SkPath*); |
| 298 | void getFontMetrics(SkPaint::FontMetrics* mX, |
| 299 | SkPaint::FontMetrics* mY); |
| 300 | |
djsollen@google.com | 60abb07 | 2012-02-15 18:49:15 +0000 | [diff] [blame^] | 301 | #ifdef SK_BUILD_FOR_ANDROID |
| 302 | unsigned getBaseGlyphCount(SkUnichar charCode); |
| 303 | #endif |
| 304 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 305 | static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec); |
| 306 | static SkScalerContext* Create(const SkDescriptor*); |
| 307 | |
| 308 | protected: |
| 309 | Rec fRec; |
| 310 | unsigned fBaseGlyphCount; |
| 311 | |
ctguil@chromium.org | 0bc7bf5 | 2011-03-04 19:04:57 +0000 | [diff] [blame] | 312 | virtual unsigned generateGlyphCount() = 0; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 313 | virtual uint16_t generateCharToGlyph(SkUnichar) = 0; |
| 314 | virtual void generateAdvance(SkGlyph*) = 0; |
| 315 | virtual void generateMetrics(SkGlyph*) = 0; |
| 316 | virtual void generateImage(const SkGlyph&) = 0; |
| 317 | virtual void generatePath(const SkGlyph&, SkPath*) = 0; |
| 318 | virtual void generateFontMetrics(SkPaint::FontMetrics* mX, |
| 319 | SkPaint::FontMetrics* mY) = 0; |
reed@android.com | 9d3a985 | 2010-01-08 14:07:42 +0000 | [diff] [blame] | 320 | // default impl returns 0, indicating failure. |
| 321 | virtual SkUnichar generateGlyphToChar(uint16_t); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 322 | |
reed@google.com | a767fa0 | 2011-08-05 21:40:26 +0000 | [diff] [blame] | 323 | void forceGenerateImageFromPath() { fGenerateImageFromPath = true; } |
| 324 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 325 | private: |
| 326 | SkPathEffect* fPathEffect; |
| 327 | SkMaskFilter* fMaskFilter; |
| 328 | SkRasterizer* fRasterizer; |
| 329 | SkScalar fDevFrameWidth; |
| 330 | |
reed@google.com | a767fa0 | 2011-08-05 21:40:26 +0000 | [diff] [blame] | 331 | // if this is set, we draw the image from a path, rather than |
| 332 | // calling generateImage. |
| 333 | bool fGenerateImageFromPath; |
| 334 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 335 | void internalGetPath(const SkGlyph& glyph, SkPath* fillPath, |
| 336 | SkPath* devPath, SkMatrix* fillToDevMatrix); |
| 337 | |
reed@android.com | a14ea0e | 2009-03-17 17:59:53 +0000 | [diff] [blame] | 338 | // return the next context, treating fNextContext as a cache of the answer |
| 339 | SkScalerContext* getNextContext(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 340 | |
reed@android.com | a14ea0e | 2009-03-17 17:59:53 +0000 | [diff] [blame] | 341 | // returns the right context from our link-list for this glyph. If no match |
| 342 | // is found, just returns the original context (this) |
| 343 | SkScalerContext* getGlyphContext(const SkGlyph& glyph); |
| 344 | |
| 345 | // link-list of context, to handle missing chars. null-terminated. |
| 346 | SkScalerContext* fNextContext; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 347 | }; |
| 348 | |
| 349 | #define kRec_SkDescriptorTag SkSetFourByteTag('s', 'r', 'e', 'c') |
| 350 | #define kPathEffect_SkDescriptorTag SkSetFourByteTag('p', 't', 'h', 'e') |
| 351 | #define kMaskFilter_SkDescriptorTag SkSetFourByteTag('m', 's', 'k', 'f') |
| 352 | #define kRasterizer_SkDescriptorTag SkSetFourByteTag('r', 'a', 's', 't') |
| 353 | |
reed@google.com | cb6ccdd | 2011-08-23 21:30:47 +0000 | [diff] [blame] | 354 | /////////////////////////////////////////////////////////////////////////////// |
| 355 | |
| 356 | enum SkAxisAlignment { |
| 357 | kNone_SkAxisAlignment, |
| 358 | kX_SkAxisAlignment, |
| 359 | kY_SkAxisAlignment |
| 360 | }; |
| 361 | |
| 362 | /** |
| 363 | * Return the axis (if any) that the baseline for horizontal text will land on |
| 364 | * after running through the specified matrix. |
| 365 | * |
| 366 | * As an example, the identity matrix will return kX_SkAxisAlignment |
| 367 | */ |
reed@google.com | 2e68478 | 2011-08-24 15:38:46 +0000 | [diff] [blame] | 368 | SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix); |
reed@google.com | cb6ccdd | 2011-08-23 21:30:47 +0000 | [diff] [blame] | 369 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 370 | #endif |
| 371 | |