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