のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

complextext

    323 void Font::drawComplexText(GraphicsContext* gc, TextRun const& run,
    324                            FloatPoint const& point, int, int) const
    325 {
    326     SkCanvas*   canvas = gc->platformContext()->mCanvas;
    327     SkPaint     paint;
    328 
    329     if (!setupForText(&paint, gc, primaryFont())) {
    330         return;
    331     }
    332 
    333     // go to chars, instead of glyphs, which was set by setupForText()
    334     paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    335 
    336     canvas->drawText(run.characters(), run.length() << 1,
    337                      SkFloatToScalar(point.x()), SkFloatToScalar(point.y()),
    338                      paint);
    339 }
   1703 void SkCanvas::drawText(const void* text, size_t byteLength,
   1704                         SkScalar x, SkScalar y, const SkPaint& paint) {
   1705     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type)
   1706 
   1707     while (iter.next()) {
   1708         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
   1709         iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
   1710         DrawTextDecorations(iter, dfp.paint(),
   1711                             static_cast<const char*>(text), byteLength, x, y);
   1712     }
   1713 
   1714     LOOPER_END
   1715 }
    321 void SkDevice::drawText(const SkDraw& draw, const void* text, size_t len,
    322                             SkScalar x, SkScalar y, const SkPaint& paint) {
    323     draw.drawText((const char*)text, len, x, y, paint);
    324 }
   1524 void SkDraw::drawText(const char text[], size_t byteLength,
   1525                       SkScalar x, SkScalar y, const SkPaint& paint) const {
   1526     SkASSERT(byteLength == 0 || text != NULL);
   1527 
   1528     SkDEBUGCODE(this->validate();)
   1529 
   1530     // nothing to draw
   1531     if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
   1532         return;
   1533     }
   1534 
   1535     if (/*paint.isLinearText() ||*/
   1536         (fMatrix->hasPerspective())) {
   1537         this->drawText_asPaths(text, byteLength, x, y, paint);
   1538         return;
   1539     }
   1540 
   1541     SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
   1542 
   1543     const SkMatrix* matrix = fMatrix;
   1544     if (hasCustomD1GProc(*this)) {
   1545         // only support the fMVMatrix (for now) for the GPU case, which also
   1546         // sets the fD1GProc
   1547         if (fMVMatrix) {
   1548             matrix = fMVMatrix;
   1549         }
   1550     }
   1551 
   1552     SkAutoGlyphCache    autoCache(paint, matrix);
   1553     SkGlyphCache*       cache = autoCache.getCache();
   1554 
   1555     // transform our starting point
   1556     {
   1557         SkPoint loc;
   1558         matrix->mapXY(x, y, &loc);
   1559         x = loc.fX;
   1560         y = loc.fY;
   1561     }
   1562 
   1563     // need to measure first
   1564     if (paint.getTextAlign() != SkPaint::kLeft_Align) {
   1565         SkVector    stop;
   1566 
   1567         measure_text(cache, glyphCacheProc, text, byteLength, &stop);
   1568 
   1569         SkScalar    stopX = stop.fX;
   1570         SkScalar    stopY = stop.fY;
   1571 
   1572         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
   1573             stopX = SkScalarHalf(stopX);
   1574             stopY = SkScalarHalf(stopY);
   1575         }
   1576         x -= stopX;
   1577         y -= stopY;
   1578     }
   1579 
   1580     SkFixed fx = SkScalarToFixed(x);
   1581     SkFixed fy = SkScalarToFixed(y);
   1582     const char* stop = text + byteLength;
   1583 
   1584     SkFixed fxMask = ~0;
   1585     SkFixed fyMask = ~0;
   1586     if (cache->isSubpixel()) {
   1587         SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(*matrix);
   1588         if (kX_SkAxisAlignment == baseline) {
   1589             fyMask = 0;
   1590         } else if (kY_SkAxisAlignment == baseline) {
   1591             fxMask = 0;
   1592         }
   1593 
   1594     // apply bias here to avoid adding 1/2 the sampling frequency in the loop
   1595         fx += SK_FixedHalf >> SkGlyph::kSubBits;
   1596         fy += SK_FixedHalf >> SkGlyph::kSubBits;
   1597     } else {
   1598         fx += SK_FixedHalf;
   1599         fy += SK_FixedHalf;
   1600     }
   1601 
   1602     SkAAClipBlitter     aaBlitter;
   1603     SkAutoBlitterChoose blitterChooser;
   1604     SkBlitter*          blitter = NULL;
   1605     if (needsRasterTextBlit(*this)) {
   1606         blitterChooser.choose(*fBitmap, *matrix, paint);
   1607         blitter = blitterChooser.get();
   1608         if (fRC->isAA()) {
   1609             aaBlitter.init(blitter, &fRC->aaRgn());
   1610             blitter = &aaBlitter;
   1611         }
   1612     }
   1613 
   1614     SkAutoKern          autokern;
   1615     SkDraw1Glyph        d1g;
   1616     SkDraw1Glyph::Proc  proc = d1g.init(this, blitter, cache);
   1617 
   1618     while (text < stop) {
   1619         const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask);
   1620 
   1621         fx += autokern.adjust(glyph);
   1622 
   1623         if (glyph.fWidth) {
   1624             proc(d1g, fx, fy, glyph);
   1625         }
   1626         fx += glyph.fAdvanceX;
   1627         fy += glyph.fAdvanceY;
   1628     }
   1629 }
    254 inline const SimpleFontData* Font::primaryFont() const
    255 {
    256     ASSERT(m_fontList);
    257     return m_fontList->primarySimpleFontData(this);
    258 }
     58     const SimpleFontData* primarySimpleFontData(const Font* f)
     59     {
     60         ASSERT(isMainThread());
     61         if (!m_cachedPrimarySimpleFontData)
     62             m_cachedPrimarySimpleFontData = primaryFontData(f)->fontDataForCharacter(' ');
     63         return m_cachedPrimarySimpleFontData;
     64     }
     91 static bool setupForText(SkPaint* paint, GraphicsContext* gc,
     92                          const SimpleFontData* font) {
     93     int mode = gc->textDrawingMode() & (TextModeFill | TextModeStroke);
     94     if (!mode)
     95         return false;
     96 
     97     paint->setVerticalText(font->platformData().orientation() == Vertical);
     98 
     99     FloatSize shadowOffset;
    100     float shadowBlur;
    101     Color shadowColor;
    102     ColorSpace shadowColorSpace;
    103 
    104     if (RenderSkinAndroid::DrawableResolution() >= RenderSkinAndroid::HighRes)
    105         paint->setAutohinted(false);
    106 
    107     bool hasShadow = gc->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
    108     bool hasBothStrokeAndFill =
    109         (mode & (TextModeStroke | TextModeFill)) == (TextModeStroke | TextModeFill);
    110     if (hasShadow || hasBothStrokeAndFill) {
    111         SkLayerDrawLooper* looper = new SkLayerDrawLooper;
    112         paint->setLooper(looper)->unref();
    113 
    114         // The layerDrawLooper uses at the root paint to determine the text
    115         // encoding so we need to make sure it is properly configured.
    116         updateForFont(paint, font);
    117 
    118         // Specify the behavior of the looper
    119         SkLayerDrawLooper::LayerInfo info;
    120         info.fPaintBits = SkLayerDrawLooper::kEntirePaint_Bits;
    121         info.fColorMode = SkXfermode::kSrc_Mode;
    122         info.fFlagsMask = SkPaint::kAllFlags;
    123 
    124         // The paint is only valid until the looper receives another call to
    125         // addLayer(). Therefore, we must cache certain state for later use.
    126         bool hasFillPaint = false;
    127         bool hasStrokePaint = false;
    128         SkScalar strokeWidth;
    129 
    130         if ((mode & TextModeStroke) && gc->willStroke()) {
    131             strokeWidth = setupStroke(looper->addLayer(info), gc, font)->getStrokeWidth();
    132             hasStrokePaint = true;
    133         }
    134         if ((mode & TextModeFill) && gc->willFill()) {
    135             setupFill(looper->addLayer(info), gc, font);
    136             hasFillPaint = true;
    137         }
    138 
    139         if (hasShadow) {
    140             SkPaint shadowPaint;
    141             SkPoint offset;
    142             if (gc->setupShadowPaint(&shadowPaint, &offset)) {
    143 
    144                 // add an offset to the looper when creating a shadow layer
    145                 info.fOffset.set(offset.fX, offset.fY);
    146 
    147                 SkPaint* p = looper->addLayer(info);
    148                 *p = shadowPaint;
    149 
    150                 // Currently, only GraphicsContexts associated with the
    151                 // HTMLCanvasElement have shadows ignore transforms set.  This
    152                 // allows us to distinguish between CSS and Canvas shadows which
    153                 // have different rendering specifications.
    154                 if (gc->shadowsIgnoreTransforms()) {
    155                     SkColorFilter* cf = SkColorFilter::CreateModeFilter(p->getColor(),
    156                             SkXfermode::kSrcIn_Mode);
    157                     p->setColorFilter(cf)->unref();
    158                 } else { // in CSS
    159                     p->setShader(NULL);
    160                 }
    161 
    162                 if (hasStrokePaint && !hasFillPaint) {
    163                     // stroke the shadow if we have stroke but no fill
    164                     p->setStyle(SkPaint::kStroke_Style);
    165                     p->setStrokeWidth(strokeWidth);
    166                 }
    167                 updateForFont(p, font);
    168             }
    169         }
    170     } else if (mode & TextModeFill) {
    171         (void)setupFill(paint, gc, font);
    172     } else if (mode & TextModeStroke) {
    173         (void)setupStroke(paint, gc, font);
    174     } else {
    175         return false;
    176     }
    177     return true;
    178 }

>