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
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        SkOrderedReadBuffer   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("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
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    SkOrderedWriteBuffer androidBuffer(128);
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 */
175SkScalerContext* 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
192SkScalerContext* 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
211SkScalerContext* 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
231SkFontID 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 */
246unsigned 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 */
260uint16_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
276SkUnichar 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
291void 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
300void 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
400SK_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
413static 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
425template<bool APPLY_PREBLEND>
426static 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
501template<bool APPLY_PREBLEND>
502static 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
526static inline int convert_8_to_1(unsigned byte) {
527    SkASSERT(byte <= 0xFF);
528    return byte >> 7;
529}
530
531static 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
540static 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
571static 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
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