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
32void 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
41size_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
52void 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
69static 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
83SkScalerContext::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
128SkScalerContext::~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.
138SkScalerContext* 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 */
176SkScalerContext* 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
193SkScalerContext* 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
212SkScalerContext* 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
232SkFontID 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 */
247unsigned 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 */
261uint16_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
277SkUnichar 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
292void 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
301void 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
401SK_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
414static 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
426template<bool APPLY_PREBLEND>
427static 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
502template<bool APPLY_PREBLEND>
503static 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
527static inline int convert_8_to_1(unsigned byte) {
528    SkASSERT(byte <= 0xFF);
529    return byte >> 7;
530}
531
532static 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
541static 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
573static 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    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    const SkImageInfo info = SkImageInfo::MakeA8(dstW, dstH);
611    SkBitmap bm;
612
613    if (0 == dstRB) {
614        if (!bm.allocPixels(info)) {
615            // can't allocate offscreen, so empty the mask and return
616            sk_bzero(mask.fImage, mask.computeImageSize());
617            return;
618        }
619    } else {
620        bm.installPixels(info, mask.fImage, dstRB);
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
659static 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
679void 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
797void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
798    this->internalGetPath(glyph, NULL, path, NULL);
799}
800
801void 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
814SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
815    return 0;
816}
817
818///////////////////////////////////////////////////////////////////////////////
819
820void 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
912void 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
918void SkScalerContextRec::getLocalMatrix(SkMatrix* m) const {
919    SkPaint::SetTextMatrix(m, fTextSize, fPreScaleX, fPreSkewX);
920}
921
922void 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
931SkAxisAlignment 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
947class SkScalerContext_Empty : public SkScalerContext {
948public:
949    SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc)
950        : SkScalerContext(face, desc) {}
951
952protected:
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
978extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
979
980SkScalerContext* 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}
990