Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkScalerContext.cpp
1
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8
9
10 #include "SkScalerContext.h"
11 #include "SkColorPriv.h"
12 #include "SkDescriptor.h"
13 #include "SkDraw.h"
14 #include "SkFontHost.h"
15 #include "SkGlyph.h"
16 #include "SkMaskFilter.h"
17 #include "SkMaskGamma.h"
18 #include "SkReadBuffer.h"
19 #include "SkWriteBuffer.h"
20 #include "SkPathEffect.h"
21 #include "SkRasterizer.h"
22 #include "SkRasterClip.h"
23 #include "SkStroke.h"
24 #include "SkThread.h"
25
26 #ifdef SK_BUILD_FOR_ANDROID
27     #include "SkTypeface_android.h"
28 #endif
29
30 #define ComputeBWRowBytes(width)        (((unsigned)(width) + 7) >> 3)
31
32 void SkGlyph::toMask(SkMask* mask) const {
33     SkASSERT(mask);
34
35     mask->fImage = (uint8_t*)fImage;
36     mask->fBounds.set(fLeft, fTop, fLeft + fWidth, fTop + fHeight);
37     mask->fRowBytes = this->rowBytes();
38     mask->fFormat = static_cast<SkMask::Format>(fMaskFormat);
39 }
40
41 size_t SkGlyph::computeImageSize() const {
42     const size_t size = this->rowBytes() * fHeight;
43
44     switch (fMaskFormat) {
45         case SkMask::k3D_Format:
46             return 3 * size;
47         default:
48             return size;
49     }
50 }
51
52 void SkGlyph::zeroMetrics() {
53     fAdvanceX = 0;
54     fAdvanceY = 0;
55     fWidth    = 0;
56     fHeight   = 0;
57     fTop      = 0;
58     fLeft     = 0;
59     fRsbDelta = 0;
60     fLsbDelta = 0;
61 }
62
63 ///////////////////////////////////////////////////////////////////////////////
64
65 #ifdef SK_DEBUG
66     #define DUMP_RECx
67 #endif
68
69 static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag,
70                                        SkFlattenable::Type ft) {
71     SkFlattenable*  obj = NULL;
72     uint32_t        len;
73     const void*     data = desc->findEntry(tag, &len);
74
75     if (data) {
76         SkReadBuffer buffer(data, len);
77         obj = buffer.readFlattenable(ft);
78         SkASSERT(buffer.offset() == buffer.size());
79     }
80     return obj;
81 }
82
83 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc)
84     : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL)))
85
86     , fBaseGlyphCount(0)
87     , fTypeface(SkRef(typeface))
88     , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_SkDescriptorTag,
89                                              SkFlattenable::kSkPathEffect_Type)))
90     , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_SkDescriptorTag,
91                                              SkFlattenable::kSkMaskFilter_Type)))
92     , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_SkDescriptorTag,
93                                              SkFlattenable::kSkRasterizer_Type)))
94       // Initialize based on our settings. Subclasses can also force this.
95     , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL)
96
97     , fNextContext(NULL)
98
99     , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMaskPreBlend(fRec))
100     , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec)
101                                      : SkMaskGamma::PreBlend())
102 {
103 #ifdef DUMP_REC
104     desc->assertChecksum();
105     SkDebugf("SkScalerContext checksum %x count %d length %d\n",
106              desc->getChecksum(), desc->getCount(), desc->getLength());
107     SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n",
108         rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0],
109         rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]);
110     SkDebugf("  frame %g miter %g hints %d framefill %d format %d join %d\n",
111         rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill,
112         rec->fMaskFormat, rec->fStrokeJoin);
113     SkDebugf("  pathEffect %x maskFilter %x\n",
114              desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
115         desc->findEntry(kMaskFilter_SkDescriptorTag, NULL));
116 #endif
117 #ifdef SK_BUILD_FOR_ANDROID
118     uint32_t len;
119     const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len);
120     if (data) {
121         SkReadBuffer buffer(data, len);
122         fPaintOptionsAndroid.unflatten(buffer);
123         SkASSERT(buffer.offset() == buffer.size());
124     }
125 #endif
126 }
127
128 SkScalerContext::~SkScalerContext() {
129     SkDELETE(fNextContext);
130
131     SkSafeUnref(fPathEffect);
132     SkSafeUnref(fMaskFilter);
133     SkSafeUnref(fRasterizer);
134 }
135
136 // Return the context associated with the next logical typeface, or NULL if
137 // there are no more entries in the fallback chain.
138 SkScalerContext* SkScalerContext::allocNextContext() const {
139 #ifdef SK_BUILD_FOR_ANDROID
140     SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
141                                                        fRec.fOrigFontID,
142                                                        fPaintOptionsAndroid);
143     if (0 == newFace) {
144         return NULL;
145     }
146
147     SkAutoTUnref<SkTypeface> aur(newFace);
148     uint32_t newFontID = newFace->uniqueID();
149
150     SkWriteBuffer androidBuffer;
151     fPaintOptionsAndroid.flatten(androidBuffer);
152
153     SkAutoDescriptor    ad(sizeof(fRec) + androidBuffer.bytesWritten()
154                            + SkDescriptor::ComputeOverhead(2));
155     SkDescriptor*       desc = ad.getDesc();
156
157     desc->init();
158     SkScalerContext::Rec* newRec =
159     (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
160                                           sizeof(fRec), &fRec);
161     androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
162                                                androidBuffer.bytesWritten(), NULL));
163
164     newRec->fFontID = newFontID;
165     desc->computeChecksum();
166
167     return newFace->createScalerContext(desc);
168 #else
169     return NULL;
170 #endif
171 }
172
173 /*  Return the next context, creating it if its not already created, but return
174     NULL if the fonthost says there are no more fonts to fallback to.
175  */
176 SkScalerContext* SkScalerContext::getNextContext() {
177     SkScalerContext* next = fNextContext;
178     // if next is null, then either it isn't cached yet, or we're at the
179     // end of our possible chain
180     if (NULL == next) {
181         next = this->allocNextContext();
182         if (NULL == next) {
183             return NULL;
184         }
185         // next's base is our base + our local count
186         next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount());
187         // cache the answer
188         fNextContext = next;
189     }
190     return next;
191 }
192
193 SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
194     unsigned glyphID = glyph.getGlyphID();
195     SkScalerContext* ctx = this;
196     for (;;) {
197         unsigned count = ctx->getGlyphCount();
198         if (glyphID < count) {
199             break;
200         }
201         glyphID -= count;
202         ctx = ctx->getNextContext();
203         if (NULL == ctx) {
204 //            SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID());
205             // just return the original context (this)
206             return this;
207         }
208     }
209     return ctx;
210 }
211
212 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni,
213                                                      uint16_t* glyphID) {
214     SkScalerContext* ctx = this;
215     for (;;) {
216         const uint16_t glyph = ctx->generateCharToGlyph(uni);
217         if (glyph) {
218             if (NULL != glyphID) {
219                 *glyphID = glyph;
220             }
221             break;  // found it
222         }
223         ctx = ctx->getNextContext();
224         if (NULL == ctx) {
225             return NULL;
226         }
227     }
228     return ctx;
229 }
230
231 #ifdef SK_BUILD_FOR_ANDROID
232 SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
233     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
234     if (NULL != ctx) {
235         return ctx->fRec.fFontID;
236     } else {
237         return 0;
238     }
239 }
240
241 /*  This loops through all available fallback contexts (if needed) until it
242     finds some context that can handle the unichar and return it.
243
244     As this is somewhat expensive operation, it should only be done on the first
245     char of a run.
246  */
247 unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
248     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
249     if (NULL != ctx) {
250         return ctx->fBaseGlyphCount;
251     } else {
252         SkDEBUGF(("--- no context for char %x\n", uni));
253         return this->fBaseGlyphCount;
254     }
255 }
256 #endif
257
258 /*  This loops through all available fallback contexts (if needed) until it
259     finds some context that can handle the unichar. If all fail, returns 0
260  */
261 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
262
263     uint16_t tempID;
264     SkScalerContext* ctx = this->getContextFromChar(uni, &tempID);
265     if (NULL == ctx) {
266         return 0; // no more contexts, return missing glyph
267     }
268     // add the ctx's base, making glyphID unique for chain of contexts
269     unsigned glyphID = tempID + ctx->fBaseGlyphCount;
270     // check for overflow of 16bits, since our glyphID cannot exceed that
271     if (glyphID > 0xFFFF) {
272         glyphID = 0;
273     }
274     return SkToU16(glyphID);
275 }
276
277 SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) {
278     SkScalerContext* ctx = this;
279     unsigned rangeEnd = 0;
280     do {
281         unsigned rangeStart = rangeEnd;
282
283         rangeEnd += ctx->getGlyphCount();
284         if (rangeStart <= glyphID && glyphID < rangeEnd) {
285             return ctx->generateGlyphToChar(glyphID - rangeStart);
286         }
287         ctx = ctx->getNextContext();
288     } while (NULL != ctx);
289     return 0;
290 }
291
292 void SkScalerContext::getAdvance(SkGlyph* glyph) {
293     // mark us as just having a valid advance
294     glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE;
295     // we mark the format before making the call, in case the impl
296     // internally ends up calling its generateMetrics, which is OK
297     // albeit slower than strictly necessary
298     this->getGlyphContext(*glyph)->generateAdvance(glyph);
299 }
300
301 void SkScalerContext::getMetrics(SkGlyph* glyph) {
302     this->getGlyphContext(*glyph)->generateMetrics(glyph);
303
304     // for now we have separate cache entries for devkerning on and off
305     // in the future we might share caches, but make our measure/draw
306     // code make the distinction. Thus we zap the values if the caller
307     // has not asked for them.
308     if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) {
309         // no devkern, so zap the fields
310         glyph->fLsbDelta = glyph->fRsbDelta = 0;
311     }
312
313     // if either dimension is empty, zap the image bounds of the glyph
314     if (0 == glyph->fWidth || 0 == glyph->fHeight) {
315         glyph->fWidth   = 0;
316         glyph->fHeight  = 0;
317         glyph->fTop     = 0;
318         glyph->fLeft    = 0;
319         glyph->fMaskFormat = 0;
320         return;
321     }
322
323     if (fGenerateImageFromPath) {
324         SkPath      devPath, fillPath;
325         SkMatrix    fillToDevMatrix;
326
327         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
328
329         if (fRasterizer) {
330             SkMask  mask;
331
332             if (fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
333                                        fMaskFilter, &mask,
334                                        SkMask::kJustComputeBounds_CreateMode)) {
335                 glyph->fLeft    = mask.fBounds.fLeft;
336                 glyph->fTop     = mask.fBounds.fTop;
337                 glyph->fWidth   = SkToU16(mask.fBounds.width());
338                 glyph->fHeight  = SkToU16(mask.fBounds.height());
339             } else {
340                 goto SK_ERROR;
341             }
342         } else {
343             // just use devPath
344             SkIRect ir;
345             devPath.getBounds().roundOut(&ir);
346
347             if (ir.isEmpty() || !ir.is16Bit()) {
348                 goto SK_ERROR;
349             }
350             glyph->fLeft    = ir.fLeft;
351             glyph->fTop     = ir.fTop;
352             glyph->fWidth   = SkToU16(ir.width());
353             glyph->fHeight  = SkToU16(ir.height());
354
355             if (glyph->fWidth > 0) {
356                 switch (fRec.fMaskFormat) {
357                 case SkMask::kLCD16_Format:
358                 case SkMask::kLCD32_Format:
359                     glyph->fWidth += 2;
360                     glyph->fLeft -= 1;
361                     break;
362                 default:
363                     break;
364                 }
365             }
366         }
367     }
368
369     if (SkMask::kARGB32_Format != glyph->fMaskFormat) {
370         glyph->fMaskFormat = fRec.fMaskFormat;
371     }
372
373     // If we are going to create the mask, then we cannot keep the color
374     if ((fGenerateImageFromPath || fMaskFilter) &&
375             SkMask::kARGB32_Format == glyph->fMaskFormat) {
376         glyph->fMaskFormat = SkMask::kA8_Format;
377     }
378
379     if (fMaskFilter) {
380         SkMask      src, dst;
381         SkMatrix    matrix;
382
383         glyph->toMask(&src);
384         fRec.getMatrixFrom2x2(&matrix);
385
386         src.fImage = NULL;  // only want the bounds from the filter
387         if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) {
388             if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) {
389                 goto SK_ERROR;
390             }
391             SkASSERT(dst.fImage == NULL);
392             glyph->fLeft    = dst.fBounds.fLeft;
393             glyph->fTop     = dst.fBounds.fTop;
394             glyph->fWidth   = SkToU16(dst.fBounds.width());
395             glyph->fHeight  = SkToU16(dst.fBounds.height());
396             glyph->fMaskFormat = dst.fFormat;
397         }
398     }
399     return;
400
401 SK_ERROR:
402     // draw nothing 'cause we failed
403     glyph->fLeft    = 0;
404     glyph->fTop     = 0;
405     glyph->fWidth   = 0;
406     glyph->fHeight  = 0;
407     // put a valid value here, in case it was earlier set to
408     // MASK_FORMAT_JUST_ADVANCE
409     glyph->fMaskFormat = fRec.fMaskFormat;
410 }
411
412 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
413
414 static void applyLUTToA8Mask(const SkMask& mask, const uint8_t* lut) {
415     uint8_t* SK_RESTRICT dst = (uint8_t*)mask.fImage;
416     unsigned rowBytes = mask.fRowBytes;
417
418     for (int y = mask.fBounds.height() - 1; y >= 0; --y) {
419         for (int x = mask.fBounds.width() - 1; x >= 0; --x) {
420             dst[x] = lut[dst[x]];
421         }
422         dst += rowBytes;
423     }
424 }
425
426 template<bool APPLY_PREBLEND>
427 static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst,
428                            const SkMaskGamma::PreBlend& maskPreBlend) {
429 #define SAMPLES_PER_PIXEL 4
430 #define LCD_PER_PIXEL 3
431     SkASSERT(kAlpha_8_SkColorType == src.colorType());
432     SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
433
434     const int sample_width = src.width();
435     const int height = src.height();
436
437     uint16_t* dstP = (uint16_t*)dst.fImage;
438     size_t dstRB = dst.fRowBytes;
439     // An N tap FIR is defined by
440     // out[n] = coeff[0]*x[n] + coeff[1]*x[n-1] + ... + coeff[N]*x[n-N]
441     // or
442     // out[n] = sum(i, 0, N, coeff[i]*x[n-i])
443
444     // The strategy is to use one FIR (different coefficients) for each of r, g, and b.
445     // This means using every 4th FIR output value of each FIR and discarding the rest.
446     // The FIRs are aligned, and the coefficients reach 5 samples to each side of their 'center'.
447     // (For r and b this is technically incorrect, but the coeffs outside round to zero anyway.)
448
449     // These are in some fixed point repesentation.
450     // Adding up to more than one simulates ink spread.
451     // For implementation reasons, these should never add up to more than two.
452
453     // Coefficients determined by a gausian where 5 samples = 3 std deviations (0x110 'contrast').
454     // Calculated using tools/generate_fir_coeff.py
455     // With this one almost no fringing is ever seen, but it is imperceptibly blurry.
456     // The lcd smoothed text is almost imperceptibly different from gray,
457     // but is still sharper on small stems and small rounded corners than gray.
458     // This also seems to be about as wide as one can get and only have a three pixel kernel.
459     // TODO: caculate these at runtime so parameters can be adjusted (esp contrast).
460     static const unsigned int coefficients[LCD_PER_PIXEL][SAMPLES_PER_PIXEL*3] = {
461         //The red subpixel is centered inside the first sample (at 1/6 pixel), and is shifted.
462         { 0x03, 0x0b, 0x1c, 0x33,  0x40, 0x39, 0x24, 0x10,  0x05, 0x01, 0x00, 0x00, },
463         //The green subpixel is centered between two samples (at 1/2 pixel), so is symetric
464         { 0x00, 0x02, 0x08, 0x16,  0x2b, 0x3d, 0x3d, 0x2b,  0x16, 0x08, 0x02, 0x00, },
465         //The blue subpixel is centered inside the last sample (at 5/6 pixel), and is shifted.
466         { 0x00, 0x00, 0x01, 0x05,  0x10, 0x24, 0x39, 0x40,  0x33, 0x1c, 0x0b, 0x03, },
467     };
468
469     for (int y = 0; y < height; ++y) {
470         const uint8_t* srcP = src.getAddr8(0, y);
471
472         // TODO: this fir filter implementation is straight forward, but slow.
473         // It should be possible to make it much faster.
474         for (int sample_x = -4, pixel_x = 0; sample_x < sample_width + 4; sample_x += 4, ++pixel_x) {
475             int fir[LCD_PER_PIXEL] = { 0 };
476             for (int sample_index = SkMax32(0, sample_x - 4), coeff_index = sample_index - (sample_x - 4)
477                 ; sample_index < SkMin32(sample_x + 8, sample_width)
478                 ; ++sample_index, ++coeff_index)
479             {
480                 int sample_value = srcP[sample_index];
481                 for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
482                     fir[subpxl_index] += coefficients[subpxl_index][coeff_index] * sample_value;
483                 }
484             }
485             for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
486                 fir[subpxl_index] /= 0x100;
487                 fir[subpxl_index] = SkMin32(fir[subpxl_index], 255);
488             }
489
490             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(fir[0], maskPreBlend.fR);
491             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(fir[1], maskPreBlend.fG);
492             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(fir[2], maskPreBlend.fB);
493 #if SK_SHOW_TEXT_BLIT_COVERAGE
494             r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
495 #endif
496             dstP[pixel_x] = SkPack888ToRGB16(r, g, b);
497         }
498         dstP = (uint16_t*)((char*)dstP + dstRB);
499     }
500 }
501
502 template<bool APPLY_PREBLEND>
503 static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst,
504                            const SkMaskGamma::PreBlend& maskPreBlend) {
505     SkASSERT(kAlpha_8_SkColorType == src.colorType());
506     SkASSERT(SkMask::kLCD32_Format == dst.fFormat);
507
508     const int width = dst.fBounds.width();
509     const int height = dst.fBounds.height();
510     SkPMColor* dstP = (SkPMColor*)dst.fImage;
511     size_t dstRB = dst.fRowBytes;
512
513     for (int y = 0; y < height; ++y) {
514         const uint8_t* srcP = src.getAddr8(0, y);
515
516         // TODO: need to use fir filter here as well.
517         for (int x = 0; x < width; ++x) {
518             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fR);
519             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fG);
520             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fB);
521             dstP[x] = SkPackARGB32(0xFF, r, g, b);
522         }
523         dstP = (SkPMColor*)((char*)dstP + dstRB);
524     }
525 }
526
527 static inline int convert_8_to_1(unsigned byte) {
528     SkASSERT(byte <= 0xFF);
529     return byte >> 7;
530 }
531
532 static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
533     unsigned bits = 0;
534     for (int i = 0; i < 8; ++i) {
535         bits <<= 1;
536         bits |= convert_8_to_1(alpha[i]);
537     }
538     return SkToU8(bits);
539 }
540
541 static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
542     const int height = mask.fBounds.height();
543     const int width = mask.fBounds.width();
544     const int octs = width >> 3;
545     const int leftOverBits = width & 7;
546
547     uint8_t* dst = mask.fImage;
548     const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
549     SkASSERT(dstPad >= 0);
550
551     const int srcPad = srcRB - width;
552     SkASSERT(srcPad >= 0);
553
554     for (int y = 0; y < height; ++y) {
555         for (int i = 0; i < octs; ++i) {
556             *dst++ = pack_8_to_1(src);
557             src += 8;
558         }
559         if (leftOverBits > 0) {
560             unsigned bits = 0;
561             int shift = 7;
562             for (int i = 0; i < leftOverBits; ++i, --shift) {
563                 bits |= convert_8_to_1(*src++) << shift;
564             }
565             *dst++ = bits;
566         }
567         src += srcPad;
568         dst += dstPad;
569     }
570 }
571
572 static void generateMask(const SkMask& mask, const SkPath& path,
573                          const SkMaskGamma::PreBlend& maskPreBlend) {
574     SkPaint paint;
575
576     int srcW = mask.fBounds.width();
577     int srcH = mask.fBounds.height();
578     int dstW = srcW;
579     int dstH = srcH;
580     int dstRB = mask.fRowBytes;
581
582     SkMatrix matrix;
583     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
584                         -SkIntToScalar(mask.fBounds.fTop));
585
586     SkBitmap::Config config = SkBitmap::kA8_Config;
587     paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
588     switch (mask.fFormat) {
589         case SkMask::kBW_Format:
590             dstRB = 0;  // signals we need a copy
591             break;
592         case SkMask::kA8_Format:
593             break;
594         case SkMask::kLCD16_Format:
595         case SkMask::kLCD32_Format:
596             // TODO: trigger off LCD orientation
597             dstW = 4*dstW - 8;
598             matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
599                                 -SkIntToScalar(mask.fBounds.fTop));
600             matrix.postScale(SkIntToScalar(4), SK_Scalar1);
601             dstRB = 0;  // signals we need a copy
602             break;
603         default:
604             SkDEBUGFAIL("unexpected mask format");
605     }
606
607     SkRasterClip clip;
608     clip.setRect(SkIRect::MakeWH(dstW, dstH));
609
610     SkBitmap bm;
611     bm.setConfig(config, dstW, dstH, dstRB);
612
613     if (0 == dstRB) {
614         if (!bm.allocPixels()) {
615             // can't allocate offscreen, so empty the mask and return
616             sk_bzero(mask.fImage, mask.computeImageSize());
617             return;
618         }
619         bm.lockPixels();
620     } else {
621         bm.setPixels(mask.fImage);
622     }
623     sk_bzero(bm.getPixels(), bm.getSafeSize());
624
625     SkDraw  draw;
626     draw.fRC    = &clip;
627     draw.fClip  = &clip.bwRgn();
628     draw.fMatrix = &matrix;
629     draw.fBitmap = &bm;
630     draw.drawPath(path, paint);
631
632     switch (mask.fFormat) {
633         case SkMask::kBW_Format:
634             packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
635             break;
636         case SkMask::kA8_Format:
637             if (maskPreBlend.isApplicable()) {
638                 applyLUTToA8Mask(mask, maskPreBlend.fG);
639             }
640             break;
641         case SkMask::kLCD16_Format:
642             if (maskPreBlend.isApplicable()) {
643                 pack4xHToLCD16<true>(bm, mask, maskPreBlend);
644             } else {
645                 pack4xHToLCD16<false>(bm, mask, maskPreBlend);
646             }
647             break;
648         case SkMask::kLCD32_Format:
649             if (maskPreBlend.isApplicable()) {
650                 pack4xHToLCD32<true>(bm, mask, maskPreBlend);
651             } else {
652                 pack4xHToLCD32<false>(bm, mask, maskPreBlend);
653             }
654             break;
655         default:
656             break;
657     }
658 }
659
660 static void extract_alpha(const SkMask& dst,
661                           const SkPMColor* srcRow, size_t srcRB) {
662     int width = dst.fBounds.width();
663     int height = dst.fBounds.height();
664     int dstRB = dst.fRowBytes;
665     uint8_t* dstRow = dst.fImage;
666
667     for (int y = 0; y < height; ++y) {
668         for (int x = 0; x < width; ++x) {
669             dstRow[x] = SkGetPackedA32(srcRow[x]);
670         }
671         // zero any padding on each row
672         for (int x = width; x < dstRB; ++x) {
673             dstRow[x] = 0;
674         }
675         dstRow += dstRB;
676         srcRow = (const SkPMColor*)((const char*)srcRow + srcRB);
677     }
678 }
679
680 void SkScalerContext::getImage(const SkGlyph& origGlyph) {
681     const SkGlyph*  glyph = &origGlyph;
682     SkGlyph         tmpGlyph;
683
684     // in case we need to call generateImage on a mask-format that is different
685     // (i.e. larger) than what our caller allocated by looking at origGlyph.
686     SkAutoMalloc tmpGlyphImageStorage;
687
688     // If we are going to draw-from-path, then we cannot generate color, since
689     // the path only makes a mask. This case should have been caught up in
690     // generateMetrics().
691     SkASSERT(!fGenerateImageFromPath ||
692              SkMask::kARGB32_Format != origGlyph.fMaskFormat);
693
694     if (fMaskFilter) {   // restore the prefilter bounds
695         tmpGlyph.init(origGlyph.fID);
696
697         // need the original bounds, sans our maskfilter
698         SkMaskFilter* mf = fMaskFilter;
699         fMaskFilter = NULL;             // temp disable
700         this->getMetrics(&tmpGlyph);
701         fMaskFilter = mf;               // restore
702
703         // we need the prefilter bounds to be <= filter bounds
704         SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
705         SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
706
707         if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
708             tmpGlyph.fImage = origGlyph.fImage;
709         } else {
710             tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize());
711             tmpGlyph.fImage = tmpGlyphImageStorage.get();
712         }
713         glyph = &tmpGlyph;
714     }
715
716     if (fGenerateImageFromPath) {
717         SkPath      devPath, fillPath;
718         SkMatrix    fillToDevMatrix;
719         SkMask      mask;
720
721         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
722         glyph->toMask(&mask);
723
724         if (fRasterizer) {
725             mask.fFormat = SkMask::kA8_Format;
726             sk_bzero(glyph->fImage, mask.computeImageSize());
727
728             if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
729                                         fMaskFilter, &mask,
730                                         SkMask::kJustRenderImage_CreateMode)) {
731                 return;
732             }
733             if (fPreBlend.isApplicable()) {
734                 applyLUTToA8Mask(mask, fPreBlend.fG);
735             }
736         } else {
737             SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
738             generateMask(mask, devPath, fPreBlend);
739         }
740     } else {
741         this->getGlyphContext(*glyph)->generateImage(*glyph);
742     }
743
744     if (fMaskFilter) {
745         SkMask      srcM, dstM;
746         SkMatrix    matrix;
747
748         // the src glyph image shouldn't be 3D
749         SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
750
751         SkAutoSMalloc<32*32> a8storage;
752         glyph->toMask(&srcM);
753         if (SkMask::kARGB32_Format == srcM.fFormat) {
754             // now we need to extract the alpha-channel from the glyph's image
755             // and copy it into a temp buffer, and then point srcM at that temp.
756             srcM.fFormat = SkMask::kA8_Format;
757             srcM.fRowBytes = SkAlign4(srcM.fBounds.width());
758             size_t size = srcM.computeImageSize();
759             a8storage.reset(size);
760             srcM.fImage = (uint8_t*)a8storage.get();
761             extract_alpha(srcM,
762                           (const SkPMColor*)glyph->fImage, glyph->rowBytes());
763         }
764
765         fRec.getMatrixFrom2x2(&matrix);
766
767         if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) {
768             int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width());
769             int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height());
770             int dstRB = origGlyph.rowBytes();
771             int srcRB = dstM.fRowBytes;
772
773             const uint8_t* src = (const uint8_t*)dstM.fImage;
774             uint8_t* dst = (uint8_t*)origGlyph.fImage;
775
776             if (SkMask::k3D_Format == dstM.fFormat) {
777                 // we have to copy 3 times as much
778                 height *= 3;
779             }
780
781             // clean out our glyph, since it may be larger than dstM
782             //sk_bzero(dst, height * dstRB);
783
784             while (--height >= 0) {
785                 memcpy(dst, src, width);
786                 src += srcRB;
787                 dst += dstRB;
788             }
789             SkMask::FreeImage(dstM.fImage);
790
791             if (fPreBlendForFilter.isApplicable()) {
792                 applyLUTToA8Mask(srcM, fPreBlendForFilter.fG);
793             }
794         }
795     }
796 }
797
798 void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
799     this->internalGetPath(glyph, NULL, path, NULL);
800 }
801
802 void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) {
803     // All of this complexity should go away when we change generateFontMetrics
804     // to just take one parameter (since it knows if it is vertical or not)
805     SkPaint::FontMetrics* mx = NULL;
806     SkPaint::FontMetrics* my = NULL;
807     if (fRec.fFlags & kVertical_Flag) {
808         mx = fm;
809     } else {
810         my = fm;
811     }
812     this->generateFontMetrics(mx, my);
813 }
814
815 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
816     return 0;
817 }
818
819 ///////////////////////////////////////////////////////////////////////////////
820
821 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
822                                   SkPath* devPath, SkMatrix* fillToDevMatrix) {
823     SkPath  path;
824
825     this->getGlyphContext(glyph)->generatePath(glyph, &path);
826
827     if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
828         SkFixed dx = glyph.getSubXFixed();
829         SkFixed dy = glyph.getSubYFixed();
830         if (dx | dy) {
831             path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy));
832         }
833     }
834
835     if (fRec.fFrameWidth > 0 || fPathEffect != NULL) {
836         // need the path in user-space, with only the point-size applied
837         // so that our stroking and effects will operate the same way they
838         // would if the user had extracted the path themself, and then
839         // called drawPath
840         SkPath      localPath;
841         SkMatrix    matrix, inverse;
842
843         fRec.getMatrixFrom2x2(&matrix);
844         if (!matrix.invert(&inverse)) {
845             // assume fillPath and devPath are already empty.
846             return;
847         }
848         path.transform(inverse, &localPath);
849         // now localPath is only affected by the paint settings, and not the canvas matrix
850
851         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
852
853         if (fRec.fFrameWidth > 0) {
854             rec.setStrokeStyle(fRec.fFrameWidth,
855                                SkToBool(fRec.fFlags & kFrameAndFill_Flag));
856             // glyphs are always closed contours, so cap type is ignored,
857             // so we just pass something.
858             rec.setStrokeParams(SkPaint::kButt_Cap,
859                                 (SkPaint::Join)fRec.fStrokeJoin,
860                                 fRec.fMiterLimit);
861         }
862
863         if (fPathEffect) {
864             SkPath effectPath;
865             if (fPathEffect->filterPath(&effectPath, localPath, &rec, NULL)) {
866                 localPath.swap(effectPath);
867             }
868         }
869
870         if (rec.needToApply()) {
871             SkPath strokePath;
872             if (rec.applyToPath(&strokePath, localPath)) {
873                 localPath.swap(strokePath);
874             }
875         }
876
877         // now return stuff to the caller
878         if (fillToDevMatrix) {
879             *fillToDevMatrix = matrix;
880         }
881         if (devPath) {
882             localPath.transform(matrix, devPath);
883         }
884         if (fillPath) {
885             fillPath->swap(localPath);
886         }
887     } else {   // nothing tricky to do
888         if (fillToDevMatrix) {
889             fillToDevMatrix->reset();
890         }
891         if (devPath) {
892             if (fillPath == NULL) {
893                 devPath->swap(path);
894             } else {
895                 *devPath = path;
896             }
897         }
898
899         if (fillPath) {
900             fillPath->swap(path);
901         }
902     }
903
904     if (devPath) {
905         devPath->updateBoundsCache();
906     }
907     if (fillPath) {
908         fillPath->updateBoundsCache();
909     }
910 }
911
912
913 void SkScalerContextRec::getMatrixFrom2x2(SkMatrix* dst) const {
914     dst->setAll(fPost2x2[0][0], fPost2x2[0][1], 0,
915                 fPost2x2[1][0], fPost2x2[1][1], 0,
916                 0,              0,              SkScalarToPersp(SK_Scalar1));
917 }
918
919 void SkScalerContextRec::getLocalMatrix(SkMatrix* m) const {
920     SkPaint::SetTextMatrix(m, fTextSize, fPreScaleX, fPreSkewX);
921 }
922
923 void SkScalerContextRec::getSingleMatrix(SkMatrix* m) const {
924     this->getLocalMatrix(m);
925
926     //  now concat the device matrix
927     SkMatrix    deviceMatrix;
928     this->getMatrixFrom2x2(&deviceMatrix);
929     m->postConcat(deviceMatrix);
930 }
931
932 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix) {
933     SkASSERT(!matrix.hasPerspective());
934
935     if (0 == matrix[SkMatrix::kMSkewY]) {
936         return kX_SkAxisAlignment;
937     }
938     if (0 == matrix[SkMatrix::kMScaleX]) {
939         return kY_SkAxisAlignment;
940     }
941     return kNone_SkAxisAlignment;
942 }
943
944 ///////////////////////////////////////////////////////////////////////////////
945
946 #include "SkFontHost.h"
947
948 class SkScalerContext_Empty : public SkScalerContext {
949 public:
950     SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc)
951         : SkScalerContext(face, desc) {}
952
953 protected:
954     virtual unsigned generateGlyphCount() SK_OVERRIDE {
955         return 0;
956     }
957     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
958         return 0;
959     }
960     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
961         glyph->zeroMetrics();
962     }
963     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
964         glyph->zeroMetrics();
965     }
966     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {}
967     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {}
968     virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
969                                      SkPaint::FontMetrics* my) SK_OVERRIDE {
970         if (mx) {
971             sk_bzero(mx, sizeof(*mx));
972         }
973         if (my) {
974             sk_bzero(my, sizeof(*my));
975         }
976     }
977 };
978
979 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
980
981 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc,
982                                                  bool allowFailure) const {
983     SkScalerContext* c = this->onCreateScalerContext(desc);
984
985     if (!c && !allowFailure) {
986         c = SkNEW_ARGS(SkScalerContext_Empty,
987                        (const_cast<SkTypeface*>(this), desc));
988     }
989     return c;
990 }