Esempio n. 1
0
static HB_Error getOutlinePoint(HB_Font hbFont, HB_Glyph glyph, int flags,
                                hb_uint32 index, HB_Fixed* xPos, HB_Fixed* yPos,
                                hb_uint32* resultingNumPoints) {
    SkHarfBuzzFont* font = reinterpret_cast<SkHarfBuzzFont*>(hbFont->userData);
    SkPaint paint;

    font->setupPaint(&paint);
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
    if (flags & HB_ShaperFlag_UseDesignMetrics) {
        paint.setHinting(SkPaint::kNo_Hinting);
    }

    SkPath path;
    uint16_t glyph16 = SkToU16(glyph);
    paint.getTextPath(&glyph16, sizeof(glyph16), 0, 0, &path);
    int numPoints = path.countPoints();
    if (index >= numPoints) {
        return HB_Err_Invalid_SubTable;
    }

    SkPoint pt = path.getPoint(index);
    *xPos = SkScalarToHarfbuzzFixed(pt.fX);
    *yPos = SkScalarToHarfbuzzFixed(pt.fY);
    *resultingNumPoints = numPoints;

    return HB_Err_Ok;
}
SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) {
    // TODO: we could potentially track invals which don't require rebuilding the blob.

    SkPaint font;
    font.setFlags(fFlags);
    font.setTypeface(fTypeface);
    font.setTextSize(fSize);
    font.setTextScaleX(fScaleX);
    font.setTextSkewX(fSkewX);
    font.setTextAlign(fAlign);
    font.setHinting(fHinting);

    // First, convert to glyphIDs.
    font.setTextEncoding(SkPaint::kUTF8_TextEncoding);
    SkSTArray<256, SkGlyphID, true> glyphs;
    glyphs.reset(font.textToGlyphs(fText.c_str(), fText.size(), nullptr));
    SkAssertResult(font.textToGlyphs(fText.c_str(), fText.size(), glyphs.begin()) == glyphs.count());
    font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

    // Next, build the cached blob.
    SkTextBlobBuilder builder;
    const auto& buf = builder.allocRun(font, glyphs.count(), 0, 0, nullptr);
    if (!buf.glyphs) {
        fBlob.reset();
        return SkRect::MakeEmpty();
    }

    memcpy(buf.glyphs, glyphs.begin(), glyphs.count() * sizeof(SkGlyphID));

    fBlob = builder.make();
    return fBlob
        ? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y())
        : SkRect::MakeEmpty();
}
Esempio n. 3
0
    virtual void onDraw(SkCanvas* originalCanvas) {
        SkISize size = this->getISize();
        SkBitmap bitmap;
        bitmap.allocN32Pixels(size.width(), size.height());
        SkDeviceProperties properties = SkDeviceProperties::Make(
            SkDeviceProperties::Geometry::Make(SkDeviceProperties::Geometry::kVertical_Orientation,
                                               SkDeviceProperties::Geometry::kBGR_Layout),
            SK_Scalar1);
        SkBitmapDevice device(bitmap, properties);
        SkCanvas canvas(&device);
        canvas.drawColor(SK_ColorWHITE);

        SkPaint paint;

        paint.setAntiAlias(true);
        paint.setLCDRenderText(true);
        //With freetype the default (normal hinting) can be really ugly.
        //Most distros now set slight (vertical hinting only) in any event.
        paint.setHinting(SkPaint::kSlight_Hinting);
        sk_tool_utils::set_portable_typeface(&paint, "Times Roman", SkTypeface::kNormal);

        const char* text = "Hamburgefons ooo mmm";
        const size_t textLen = strlen(text);

        for (int j = 0; j < 2; ++j) {
            for (int i = 0; i < 6; ++i) {
                SkScalar x = SkIntToScalar(10);
                SkScalar y = SkIntToScalar(20);

                SkAutoCanvasRestore acr(&canvas, true);
                canvas.translate(SkIntToScalar(50 + i * 230),
                                  SkIntToScalar(20));
                rotate_about(&canvas, SkIntToScalar(i * 5), x, y * 10);

                {
                    SkPaint p;
                    p.setAntiAlias(true);
                    SkRect r;
                    r.set(x - SkIntToScalar(3), SkIntToScalar(15),
                          x - SkIntToScalar(1), SkIntToScalar(280));
                    canvas.drawRect(r, p);
                }

                int index = 0;
                for (int ps = 6; ps <= 22; ps++) {
                    paint.setTextSize(SkIntToScalar(ps));
                    canvas.drawText(text, textLen, x, y, paint);
                    y += paint.getFontMetrics(NULL);
                    index += 1;
                }
            }
            canvas.translate(0, SkIntToScalar(360));
            paint.setSubpixelText(true);
        }
        originalCanvas->drawBitmap(bitmap, 0, 0);
    }
Esempio n. 4
0
static SkPaint make_paint() {
    SkPaint paint;
    if (fuzz->exhausted()) {
        return paint;
    }
    paint.setHinting(make_paint_hinting());
    paint.setAntiAlias(make_bool());
    paint.setDither(make_bool());
    paint.setLinearText(make_bool());
    paint.setSubpixelText(make_bool());
    paint.setLCDRenderText(make_bool());
    paint.setEmbeddedBitmapText(make_bool());
    paint.setAutohinted(make_bool());
    paint.setVerticalText(make_bool());
    paint.setFakeBoldText(make_bool());
    paint.setDevKernText(make_bool());
    paint.setFilterQuality(make_filter_quality());
    paint.setStyle(make_paint_style());
    paint.setColor(make_color());
    paint.setStrokeWidth(make_number(false));
    paint.setStrokeMiter(make_number(false));
    paint.setStrokeCap(make_paint_cap());
    paint.setStrokeJoin(make_paint_join());
    paint.setColorFilter(make_color_filter());
    paint.setBlendMode(make_blendmode());
    paint.setPathEffect(make_path_effect());
    paint.setMaskFilter(make_mask_filter());

    if (false) {
        // our validating buffer does not support typefaces yet, so skip this for now
        paint.setTypeface(SkTypeface::MakeFromName(make_font_name().c_str(),make_typeface_style()));
    }

    SkLayerRasterizer::Builder rasterizerBuilder;
    SkPaint paintForRasterizer;
    if (make_bool()) {
        paintForRasterizer = make_paint();
    }
    rasterizerBuilder.addLayer(paintForRasterizer);
    paint.setRasterizer(rasterizerBuilder.detach());
    paint.setImageFilter(make_image_filter());
    bool a, b, c;
    fuzz->next(&a, &b, &c);
    sk_sp<SkData> data(make_3Dlut(nullptr, a, b, c));
    paint.setTextAlign(make_paint_align());
    SkScalar d, e, f;
    fuzz->next(&d, &e, &f);
    paint.setTextSize(d);
    paint.setTextScaleX(e);
    paint.setTextSkewX(f);
    paint.setTextEncoding(make_paint_text_encoding());
    return paint;
}
Esempio n. 5
0
static SkPaint make_paint() {
    SkPaint paint;
    paint.setHinting(make_paint_hinting());
    paint.setAntiAlias(make_bool());
    paint.setDither(make_bool());
    paint.setLinearText(make_bool());
    paint.setSubpixelText(make_bool());
    paint.setLCDRenderText(make_bool());
    paint.setEmbeddedBitmapText(make_bool());
    paint.setAutohinted(make_bool());
    paint.setVerticalText(make_bool());
    paint.setUnderlineText(make_bool());
    paint.setStrikeThruText(make_bool());
    paint.setFakeBoldText(make_bool());
    paint.setDevKernText(make_bool());
    paint.setFilterQuality(make_filter_quality());
    paint.setStyle(make_paint_style());
    paint.setColor(make_color());
    paint.setStrokeWidth(make_scalar());
    paint.setStrokeMiter(make_scalar());
    paint.setStrokeCap(make_paint_cap());
    paint.setStrokeJoin(make_paint_join());
    paint.setColorFilter(make_color_filter());
    paint.setXfermodeMode(make_xfermode());
    paint.setPathEffect(make_path_effect());
    paint.setMaskFilter(make_mask_filter());

    if (false) {
        // our validating buffer does not support typefaces yet, so skip this for now
        SkAutoTUnref<SkTypeface> typeface(
                      SkTypeface::CreateFromName(make_font_name().c_str(), make_typeface_style()));
        paint.setTypeface(typeface);
    }

    SkLayerRasterizer::Builder rasterizerBuilder;
    SkPaint paintForRasterizer;
    if (R(2) == 1) {
        paintForRasterizer = make_paint();
    }
    rasterizerBuilder.addLayer(paintForRasterizer);
    paint.setRasterizer(rasterizerBuilder.detach());
    paint.setImageFilter(make_image_filter());
    sk_sp<SkData> data(make_3Dlut(nullptr, make_bool(), make_bool(), make_bool()));
    paint.setTextAlign(make_paint_align());
    paint.setTextSize(make_scalar());
    paint.setTextScaleX(make_scalar());
    paint.setTextSkewX(make_scalar());
    paint.setTextEncoding(make_paint_text_encoding());
    return paint;
}
Esempio n. 6
0
static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
                       SkGPipeState* state) {
    size_t offset = reader->offset();
    size_t stop = offset + PaintOp_unpackData(op32);
    SkPaint* p = state->editPaint();

    do {
        uint32_t p32 = reader->readU32();
        unsigned op = PaintOp_unpackOp(p32);
        unsigned data = PaintOp_unpackData(p32);

//        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);

        switch (op) {
            case kReset_PaintOp: p->reset(); break;
            case kFlags_PaintOp: p->setFlags(data); break;
            case kColor_PaintOp: p->setColor(reader->readU32()); break;
            case kFilterLevel_PaintOp: p->setFilterQuality((SkFilterQuality)data); break;
            case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
            case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
            case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
            case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
            case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
            case kEncoding_PaintOp:
                p->setTextEncoding((SkPaint::TextEncoding)data);
                break;
            case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
            case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
            case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
            case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
            case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;

            case kFlatIndex_PaintOp: {
                PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
                unsigned index = data;
                set_paintflat(p, state->getFlat(index), pf);
                break;
            }

            case kTypeface_PaintOp:
                SkASSERT(SkToBool(state->getFlags() &
                                  SkGPipeWriter::kCrossProcess_Flag));
                p->setTypeface(state->getTypeface(data));
                break;
            default: SkDEBUGFAIL("bad paintop"); return;
        }
        SkASSERT(reader->offset() <= stop);
    } while (reader->offset() < stop);
}
Esempio n. 7
0
SkExclusiveStrikePtr SkPDFFont::MakeVectorCache(SkTypeface* face, int* size) {
    SkPaint tmpPaint;
    tmpPaint.setHinting(SkPaint::kNo_Hinting);
    tmpPaint.setTypeface(sk_ref_sp(face));
    int unitsPerEm = face->getUnitsPerEm();
    if (unitsPerEm <= 0) {
        unitsPerEm = 1024;
    }
    if (size) {
        *size = unitsPerEm;
    }
    tmpPaint.setTextSize((SkScalar)unitsPerEm);
    const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
    return SkStrikeCache::FindOrCreateStrikeExclusive(
            tmpPaint, &props, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr);
}
Esempio n. 8
0
const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface,
                                                       SkPDFCanon* canon) {
    SkASSERT(typeface);
    SkFontID id = typeface->uniqueID();
    if (std::unique_ptr<SkAdvancedTypefaceMetrics>* ptr = canon->fTypefaceMetrics.find(id)) {
        return ptr->get();  // canon retains ownership.
    }
    int count = typeface->countGlyphs();
    if (count <= 0 || count > 1 + SK_MaxU16) {
        // Cache nullptr to skip this check.  Use SkSafeUnref().
        canon->fTypefaceMetrics.set(id, nullptr);
        return nullptr;
    }
    std::unique_ptr<SkAdvancedTypefaceMetrics> metrics = typeface->getAdvancedMetrics();
    if (!metrics) {
        metrics = skstd::make_unique<SkAdvancedTypefaceMetrics>();
    }

    if (0 == metrics->fStemV || 0 == metrics->fCapHeight) {
        SkPaint tmpPaint;
        tmpPaint.setHinting(SkPaint::kNo_Hinting);
        tmpPaint.setTypeface(sk_ref_sp(typeface));
        tmpPaint.setTextSize(1000);  // glyph coordinate system
        if (0 == metrics->fStemV) {
            // Figure out a good guess for StemV - Min width of i, I, !, 1.
            // This probably isn't very good with an italic font.
            int16_t stemV = SHRT_MAX;
            for (char c : {'i', 'I', '!', '1'}) {
                SkRect bounds;
                tmpPaint.measureText(&c, 1, &bounds);
                stemV = SkTMin(stemV, SkToS16(SkScalarRoundToInt(bounds.width())));
            }
            metrics->fStemV = stemV;
        }
        if (0 == metrics->fCapHeight) {
            // Figure out a good guess for CapHeight: average the height of M and X.
            SkScalar capHeight = 0;
            for (char c : {'M', 'X'}) {
                SkRect bounds;
                tmpPaint.measureText(&c, 1, &bounds);
                capHeight += bounds.height();
            }
            metrics->fCapHeight = SkToS16(SkScalarRoundToInt(capHeight / 2));
        }
    }
    return canon->fTypefaceMetrics.set(id, std::move(metrics))->get();
}
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;

        paint.setAntiAlias(true);
        paint.setLCDRenderText(true);
        //With freetype the default (normal hinting) can be really ugly.
        //Most distros now set slight (vertical hinting only) in any event.
        paint.setHinting(SkPaint::kSlight_Hinting);
        SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal)));

        const char* text = "Hamburgefons ooo mmm";
        const size_t textLen = strlen(text);

        for (int j = 0; j < 2; ++j) {
            // This used to do 6 iterations but it causes the N4 to crash in the MSAA4 config.
            for (int i = 0; i < 5; ++i) {
                SkScalar x = SkIntToScalar(10);
                SkScalar y = SkIntToScalar(20);

                SkAutoCanvasRestore acr(canvas, true);
                canvas->translate(SkIntToScalar(50 + i * 230),
                                  SkIntToScalar(20));
                rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10);

                {
                    SkPaint p;
                    p.setAntiAlias(true);
                    SkRect r;
                    r.set(x - SkIntToScalar(3), SkIntToScalar(15),
                          x - SkIntToScalar(1), SkIntToScalar(280));
                    canvas->drawRect(r, p);
                }

                int index = 0;
                for (int ps = 6; ps <= 22; ps++) {
                    paint.setTextSize(SkIntToScalar(ps));
                    canvas->drawText(text, textLen, x, y, paint);
                    y += paint.getFontMetrics(NULL);
                    index += 1;
                }
            }
            canvas->translate(0, SkIntToScalar(360));
            paint.setSubpixelText(true);
        }
    }
static SkPaint make_paint() {
    SkPaint paint;
    paint.setHinting(make_paint_hinting());
    paint.setAntiAlias(make_bool());
    paint.setDither(make_bool());
    paint.setLinearText(make_bool());
    paint.setSubpixelText(make_bool());
    paint.setLCDRenderText(make_bool());
    paint.setEmbeddedBitmapText(make_bool());
    paint.setAutohinted(make_bool());
    paint.setVerticalText(make_bool());
    paint.setFakeBoldText(make_bool());
    paint.setDevKernText(make_bool());
    paint.setFilterQuality(make_filter_quality());
    paint.setStyle(make_paint_style());
    paint.setColor(make_color());
    paint.setStrokeWidth(make_scalar());
    paint.setStrokeMiter(make_scalar());
    paint.setStrokeCap(make_paint_cap());
    paint.setStrokeJoin(make_paint_join());
    paint.setColorFilter(make_color_filter());
    paint.setBlendMode(make_xfermode());
    paint.setPathEffect(make_path_effect());
    paint.setMaskFilter(make_mask_filter());

    if (false) {
        // our validating buffer does not support typefaces yet, so skip this for now
        paint.setTypeface(SkTypeface::MakeFromName(make_font_name().c_str(),
                                                   make_typeface_style()));
    }

    paint.setImageFilter(make_image_filter());
    sk_sp<SkData> data(make_3Dlut(nullptr, make_bool(), make_bool(), make_bool()));
    paint.setTextAlign(make_paint_align());
    paint.setTextSize(make_scalar());
    paint.setTextScaleX(make_scalar());
    paint.setTextSkewX(make_scalar());
    paint.setTextEncoding(make_paint_text_encoding());
    return paint;
}
Esempio n. 11
0
static void test_cachedfont(skiatest::Reporter* reporter) {
    static const char* const faces[] = {
        nullptr,   // default font
        "Arial", "Times", "Times New Roman", "Helvetica", "Courier",
        "Courier New", "Verdana", "monospace",
    };

    static const struct {
        SkPaint::Hinting    hinting;
        unsigned            flags;
    } settings[] = {
        { SkPaint::kNo_Hinting,     0                               },
        { SkPaint::kNo_Hinting,     SkPaint::kLinearText_Flag       },
        { SkPaint::kNo_Hinting,     SkPaint::kSubpixelText_Flag     },
        { SkPaint::kSlight_Hinting, 0                               },
        { SkPaint::kSlight_Hinting, SkPaint::kLinearText_Flag       },
        { SkPaint::kSlight_Hinting, SkPaint::kSubpixelText_Flag     },
        { SkPaint::kNormal_Hinting, 0                               },
        { SkPaint::kNormal_Hinting, SkPaint::kLinearText_Flag       },
        { SkPaint::kNormal_Hinting, SkPaint::kSubpixelText_Flag     },
    };

    static const struct {
        SkScalar    fScaleX;
        SkScalar    fSkewX;
    } gScaleRec[] = {
        { SK_Scalar1, 0 },
        { SK_Scalar1/2, 0 },
        // these two exercise obliquing (skew)
        { SK_Scalar1, -SK_Scalar1/4 },
        { SK_Scalar1/2, -SK_Scalar1/4 },
    };

    SkPaint paint;
    char txt[] = "long.text.with.lots.of.dots.";

    for (size_t i = 0; i < SK_ARRAY_COUNT(faces); i++) {
        SkAutoTUnref<SkTypeface> face(SkTypeface::CreateFromName(faces[i], SkTypeface::kNormal));
        paint.setTypeface(face);

        for (size_t j = 0; j  < SK_ARRAY_COUNT(settings); j++) {
            paint.setHinting(settings[j].hinting);
            paint.setLinearText((settings[j].flags & SkPaint::kLinearText_Flag) != 0);
            paint.setSubpixelText((settings[j].flags & SkPaint::kSubpixelText_Flag) != 0);

            for (size_t k = 0; k < SK_ARRAY_COUNT(gScaleRec); ++k) {
                paint.setTextScaleX(gScaleRec[k].fScaleX);
                paint.setTextSkewX(gScaleRec[k].fSkewX);

                test_cachedfont(reporter, paint);

                SkRect bounds;

                // For no hinting and light hinting this should take the
                // optimized generateAdvance path.
                SkScalar width1 = paint.measureText(txt, strlen(txt));

                // Requesting the bounds forces a generateMetrics call.
                SkScalar width2 = paint.measureText(txt, strlen(txt), &bounds);

                REPORTER_ASSERT(reporter, width1 == width2);

                SkAutoTUnref<SkFont> font(SkFont::Testing_CreateFromPaint(paint));
                SkScalar font_width1 = font->measureText(txt, strlen(txt), kUTF8_SkTextEncoding);
                // measureText not yet implemented...
                REPORTER_ASSERT(reporter, font_width1 == -1);
//                REPORTER_ASSERT(reporter, width1 == font_width1);
            }
        }
    }
}