Upstream version 7.36.149.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     SkASSERT(width >= 0);
552     SkASSERT(srcRB >= (size_t)width);
553     const size_t srcPad = srcRB - width;
554
555     for (int y = 0; y < height; ++y) {
556         for (int i = 0; i < octs; ++i) {
557             *dst++ = pack_8_to_1(src);
558             src += 8;
559         }
560         if (leftOverBits > 0) {
561             unsigned bits = 0;
562             int shift = 7;
563             for (int i = 0; i < leftOverBits; ++i, --shift) {
564                 bits |= convert_8_to_1(*src++) << shift;
565             }
566             *dst++ = bits;
567         }
568         src += srcPad;
569         dst += dstPad;
570     }
571 }
572
573 static void generateMask(const SkMask& mask, const SkPath& path,
574                          const SkMaskGamma::PreBlend& maskPreBlend) {
575     SkPaint paint;
576
577     int srcW = mask.fBounds.width();
578     int srcH = mask.fBounds.height();
579     int dstW = srcW;
580     int dstH = srcH;
581     int dstRB = mask.fRowBytes;
582
583     SkMatrix matrix;
584     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
585                         -SkIntToScalar(mask.fBounds.fTop));
586
587     SkBitmap::Config config = SkBitmap::kA8_Config;
588     paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
589     switch (mask.fFormat) {
590         case SkMask::kBW_Format:
591             dstRB = 0;  // signals we need a copy
592             break;
593         case SkMask::kA8_Format:
594             break;
595         case SkMask::kLCD16_Format:
596         case SkMask::kLCD32_Format:
597             // TODO: trigger off LCD orientation
598             dstW = 4*dstW - 8;
599             matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
600                                 -SkIntToScalar(mask.fBounds.fTop));
601             matrix.postScale(SkIntToScalar(4), SK_Scalar1);
602             dstRB = 0;  // signals we need a copy
603             break;
604         default:
605             SkDEBUGFAIL("unexpected mask format");
606     }
607
608     SkRasterClip clip;
609     clip.setRect(SkIRect::MakeWH(dstW, dstH));
610
611     SkBitmap bm;
612     bm.setConfig(config, dstW, dstH, dstRB);
613
614     if (0 == dstRB) {
615         if (!bm.allocPixels()) {
616             // can't allocate offscreen, so empty the mask and return
617             sk_bzero(mask.fImage, mask.computeImageSize());
618             return;
619         }
620         bm.lockPixels();
621     } else {
622         bm.setPixels(mask.fImage);
623     }
624     sk_bzero(bm.getPixels(), bm.getSafeSize());
625
626     SkDraw  draw;
627     draw.fRC    = &clip;
628     draw.fClip  = &clip.bwRgn();
629     draw.fMatrix = &matrix;
630     draw.fBitmap = &bm;
631     draw.drawPath(path, paint);
632
633     switch (mask.fFormat) {
634         case SkMask::kBW_Format:
635             packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
636             break;
637         case SkMask::kA8_Format:
638             if (maskPreBlend.isApplicable()) {
639                 applyLUTToA8Mask(mask, maskPreBlend.fG);
640             }
641             break;
642         case SkMask::kLCD16_Format:
643             if (maskPreBlend.isApplicable()) {
644                 pack4xHToLCD16<true>(bm, mask, maskPreBlend);
645             } else {
646                 pack4xHToLCD16<false>(bm, mask, maskPreBlend);
647             }
648             break;
649         case SkMask::kLCD32_Format:
650             if (maskPreBlend.isApplicable()) {
651                 pack4xHToLCD32<true>(bm, mask, maskPreBlend);
652             } else {
653                 pack4xHToLCD32<false>(bm, mask, maskPreBlend);
654             }
655             break;
656         default:
657             break;
658     }
659 }
660
661 static void extract_alpha(const SkMask& dst,
662                           const SkPMColor* srcRow, size_t srcRB) {
663     int width = dst.fBounds.width();
664     int height = dst.fBounds.height();
665     int dstRB = dst.fRowBytes;
666     uint8_t* dstRow = dst.fImage;
667
668     for (int y = 0; y < height; ++y) {
669         for (int x = 0; x < width; ++x) {
670             dstRow[x] = SkGetPackedA32(srcRow[x]);
671         }
672         // zero any padding on each row
673         for (int x = width; x < dstRB; ++x) {
674             dstRow[x] = 0;
675         }
676         dstRow += dstRB;
677         srcRow = (const SkPMColor*)((const char*)srcRow + srcRB);
678     }
679 }
680
681 void SkScalerContext::getImage(const SkGlyph& origGlyph) {
682     const SkGlyph*  glyph = &origGlyph;
683     SkGlyph         tmpGlyph;
684
685     // in case we need to call generateImage on a mask-format that is different
686     // (i.e. larger) than what our caller allocated by looking at origGlyph.
687     SkAutoMalloc tmpGlyphImageStorage;
688
689     // If we are going to draw-from-path, then we cannot generate color, since
690     // the path only makes a mask. This case should have been caught up in
691     // generateMetrics().
692     SkASSERT(!fGenerateImageFromPath ||
693              SkMask::kARGB32_Format != origGlyph.fMaskFormat);
694
695     if (fMaskFilter) {   // restore the prefilter bounds
696         tmpGlyph.init(origGlyph.fID);
697
698         // need the original bounds, sans our maskfilter
699         SkMaskFilter* mf = fMaskFilter;
700         fMaskFilter = NULL;             // temp disable
701         this->getMetrics(&tmpGlyph);
702         fMaskFilter = mf;               // restore
703
704         // we need the prefilter bounds to be <= filter bounds
705         SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
706         SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
707
708         if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
709             tmpGlyph.fImage = origGlyph.fImage;
710         } else {
711             tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize());
712             tmpGlyph.fImage = tmpGlyphImageStorage.get();
713         }
714         glyph = &tmpGlyph;
715     }
716
717     if (fGenerateImageFromPath) {
718         SkPath      devPath, fillPath;
719         SkMatrix    fillToDevMatrix;
720         SkMask      mask;
721
722         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
723         glyph->toMask(&mask);
724
725         if (fRasterizer) {
726             mask.fFormat = SkMask::kA8_Format;
727             sk_bzero(glyph->fImage, mask.computeImageSize());
728
729             if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
730                                         fMaskFilter, &mask,
731                                         SkMask::kJustRenderImage_CreateMode)) {
732                 return;
733             }
734             if (fPreBlend.isApplicable()) {
735                 applyLUTToA8Mask(mask, fPreBlend.fG);
736             }
737         } else {
738             SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
739             generateMask(mask, devPath, fPreBlend);
740         }
741     } else {
742         this->getGlyphContext(*glyph)->generateImage(*glyph);
743     }
744
745     if (fMaskFilter) {
746         SkMask      srcM, dstM;
747         SkMatrix    matrix;
748
749         // the src glyph image shouldn't be 3D
750         SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
751
752         SkAutoSMalloc<32*32> a8storage;
753         glyph->toMask(&srcM);
754         if (SkMask::kARGB32_Format == srcM.fFormat) {
755             // now we need to extract the alpha-channel from the glyph's image
756             // and copy it into a temp buffer, and then point srcM at that temp.
757             srcM.fFormat = SkMask::kA8_Format;
758             srcM.fRowBytes = SkAlign4(srcM.fBounds.width());
759             size_t size = srcM.computeImageSize();
760             a8storage.reset(size);
761             srcM.fImage = (uint8_t*)a8storage.get();
762             extract_alpha(srcM,
763                           (const SkPMColor*)glyph->fImage, glyph->rowBytes());
764         }
765
766         fRec.getMatrixFrom2x2(&matrix);
767
768         if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) {
769             int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width());
770             int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height());
771             int dstRB = origGlyph.rowBytes();
772             int srcRB = dstM.fRowBytes;
773
774             const uint8_t* src = (const uint8_t*)dstM.fImage;
775             uint8_t* dst = (uint8_t*)origGlyph.fImage;
776
777             if (SkMask::k3D_Format == dstM.fFormat) {
778                 // we have to copy 3 times as much
779                 height *= 3;
780             }
781
782             // clean out our glyph, since it may be larger than dstM
783             //sk_bzero(dst, height * dstRB);
784
785             while (--height >= 0) {
786                 memcpy(dst, src, width);
787                 src += srcRB;
788                 dst += dstRB;
789             }
790             SkMask::FreeImage(dstM.fImage);
791
792             if (fPreBlendForFilter.isApplicable()) {
793                 applyLUTToA8Mask(srcM, fPreBlendForFilter.fG);
794             }
795         }
796     }
797 }
798
799 void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
800     this->internalGetPath(glyph, NULL, path, NULL);
801 }
802
803 void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) {
804     // All of this complexity should go away when we change generateFontMetrics
805     // to just take one parameter (since it knows if it is vertical or not)
806     SkPaint::FontMetrics* mx = NULL;
807     SkPaint::FontMetrics* my = NULL;
808     if (fRec.fFlags & kVertical_Flag) {
809         mx = fm;
810     } else {
811         my = fm;
812     }
813     this->generateFontMetrics(mx, my);
814 }
815
816 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
817     return 0;
818 }
819
820 ///////////////////////////////////////////////////////////////////////////////
821
822 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
823                                   SkPath* devPath, SkMatrix* fillToDevMatrix) {
824     SkPath  path;
825
826     this->getGlyphContext(glyph)->generatePath(glyph, &path);
827
828     if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
829         SkFixed dx = glyph.getSubXFixed();
830         SkFixed dy = glyph.getSubYFixed();
831         if (dx | dy) {
832             path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy));
833         }
834     }
835
836     if (fRec.fFrameWidth > 0 || fPathEffect != NULL) {
837         // need the path in user-space, with only the point-size applied
838         // so that our stroking and effects will operate the same way they
839         // would if the user had extracted the path themself, and then
840         // called drawPath
841         SkPath      localPath;
842         SkMatrix    matrix, inverse;
843
844         fRec.getMatrixFrom2x2(&matrix);
845         if (!matrix.invert(&inverse)) {
846             // assume fillPath and devPath are already empty.
847             return;
848         }
849         path.transform(inverse, &localPath);
850         // now localPath is only affected by the paint settings, and not the canvas matrix
851
852         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
853
854         if (fRec.fFrameWidth > 0) {
855             rec.setStrokeStyle(fRec.fFrameWidth,
856                                SkToBool(fRec.fFlags & kFrameAndFill_Flag));
857             // glyphs are always closed contours, so cap type is ignored,
858             // so we just pass something.
859             rec.setStrokeParams(SkPaint::kButt_Cap,
860                                 (SkPaint::Join)fRec.fStrokeJoin,
861                                 fRec.fMiterLimit);
862         }
863
864         if (fPathEffect) {
865             SkPath effectPath;
866             if (fPathEffect->filterPath(&effectPath, localPath, &rec, NULL)) {
867                 localPath.swap(effectPath);
868             }
869         }
870
871         if (rec.needToApply()) {
872             SkPath strokePath;
873             if (rec.applyToPath(&strokePath, localPath)) {
874                 localPath.swap(strokePath);
875             }
876         }
877
878         // now return stuff to the caller
879         if (fillToDevMatrix) {
880             *fillToDevMatrix = matrix;
881         }
882         if (devPath) {
883             localPath.transform(matrix, devPath);
884         }
885         if (fillPath) {
886             fillPath->swap(localPath);
887         }
888     } else {   // nothing tricky to do
889         if (fillToDevMatrix) {
890             fillToDevMatrix->reset();
891         }
892         if (devPath) {
893             if (fillPath == NULL) {
894                 devPath->swap(path);
895             } else {
896                 *devPath = path;
897             }
898         }
899
900         if (fillPath) {
901             fillPath->swap(path);
902         }
903     }
904
905     if (devPath) {
906         devPath->updateBoundsCache();
907     }
908     if (fillPath) {
909         fillPath->updateBoundsCache();
910     }
911 }
912
913
914 void SkScalerContextRec::getMatrixFrom2x2(SkMatrix* dst) const {
915     dst->setAll(fPost2x2[0][0], fPost2x2[0][1], 0,
916                 fPost2x2[1][0], fPost2x2[1][1], 0,
917                 0,              0,              SkScalarToPersp(SK_Scalar1));
918 }
919
920 void SkScalerContextRec::getLocalMatrix(SkMatrix* m) const {
921     SkPaint::SetTextMatrix(m, fTextSize, fPreScaleX, fPreSkewX);
922 }
923
924 void SkScalerContextRec::getSingleMatrix(SkMatrix* m) const {
925     this->getLocalMatrix(m);
926
927     //  now concat the device matrix
928     SkMatrix    deviceMatrix;
929     this->getMatrixFrom2x2(&deviceMatrix);
930     m->postConcat(deviceMatrix);
931 }
932
933 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix) {
934     SkASSERT(!matrix.hasPerspective());
935
936     if (0 == matrix[SkMatrix::kMSkewY]) {
937         return kX_SkAxisAlignment;
938     }
939     if (0 == matrix[SkMatrix::kMScaleX]) {
940         return kY_SkAxisAlignment;
941     }
942     return kNone_SkAxisAlignment;
943 }
944
945 ///////////////////////////////////////////////////////////////////////////////
946
947 #include "SkFontHost.h"
948
949 class SkScalerContext_Empty : public SkScalerContext {
950 public:
951     SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc)
952         : SkScalerContext(face, desc) {}
953
954 protected:
955     virtual unsigned generateGlyphCount() SK_OVERRIDE {
956         return 0;
957     }
958     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
959         return 0;
960     }
961     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
962         glyph->zeroMetrics();
963     }
964     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
965         glyph->zeroMetrics();
966     }
967     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {}
968     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {}
969     virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
970                                      SkPaint::FontMetrics* my) SK_OVERRIDE {
971         if (mx) {
972             sk_bzero(mx, sizeof(*mx));
973         }
974         if (my) {
975             sk_bzero(my, sizeof(*my));
976         }
977     }
978 };
979
980 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
981
982 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc,
983                                                  bool allowFailure) const {
984     SkScalerContext* c = this->onCreateScalerContext(desc);
985
986     if (!c && !allowFailure) {
987         c = SkNEW_ARGS(SkScalerContext_Empty,
988                        (const_cast<SkTypeface*>(this), desc));
989     }
990     return c;
991 }