void SkGraphics::Init() { SkGlobals::Init(); #ifdef BUILD_EMBOSS_TABLE SkEmbossMask_BuildTable(); #endif #ifdef BUILD_RADIALGRADIENT_TABLE SkRadialGradient_BuildTable(); #endif #ifdef SK_DEBUGx int i; static const struct { const char* fTypeName; size_t fSizeOf; } gTypeSize[] = { typesizeline(char), typesizeline(short), typesizeline(int), typesizeline(long), typesizeline(size_t), typesizeline(void*), typesizeline(S8CPU), typesizeline(U8CPU), typesizeline(S16CPU), typesizeline(U16CPU), typesizeline(SkPoint), typesizeline(SkRect), typesizeline(SkMatrix), typesizeline(SkPath), typesizeline(SkGlyph), typesizeline(SkRefCnt), typesizeline(SkPaint), typesizeline(SkCanvas), typesizeline(SkBlitter), typesizeline(SkShader), typesizeline(SkXfermode), typesizeline(SkPathEffect) }; #ifdef SK_CPU_BENDIAN SkDebugf("SkGraphics: big-endian\n"); #else SkDebugf("SkGraphics: little-endian\n"); #endif { char test = 0xFF; int itest = test; // promote to int, see if it sign-extended if (itest < 0) SkDebugf("SkGraphics: char is signed\n"); else SkDebugf("SkGraphics: char is unsigned\n"); } for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) { SkDebugf("SkGraphics: sizeof(%s) = %d\n", gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf); } #endif if (false) // test asm fixmul { int j; SkMSec now = SkTime::GetMSecs(); for (j = 0; j < BIG_LOOP_COUNT; j++) { (void)SkFixedMul_portable(0x8000, 0x150000); } SkMSec now2 = SkTime::GetMSecs(); printf("-------- SkFixedMul_portable = %d\n", now2 - now); for (j = 0; j < BIG_LOOP_COUNT; j++) { (void)SkFixedMul(0x8000, 0x150000); } printf("-------- SkFixedMul = %d\n", SkTime::GetMSecs() - now2); SkRandom rand; for (j = 0; j < 10000; j++) { SkFixed a = rand.nextS() >> 8; SkFixed b = rand.nextS() >> 8; SkFixed c1 = SkFixedMul_portable(a, b); SkFixed c2 = SkFixedMul(a, b); if (SkAbs32(c1 - c2) > 1) printf("------ FixMul disagreement: (%x %x) slow=%x fast=%x\n", a, b, c1, c2); } }
void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y) { SkASSERT(byteLength == 0 || text != NULL); // nothing to draw if (text == NULL || byteLength == 0) { return; } fViewMatrix = viewMatrix; SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); SkAutoGlyphCache autoCache(skPaint, &fDeviceProperties, NULL); SkGlyphCache* cache = autoCache.getCache(); SkTArray<SkScalar> positions; const char* textPtr = text; SkFixed stopX = 0; SkFixed stopY = 0; SkFixed origin; switch (skPaint.getTextAlign()) { case SkPaint::kRight_Align: origin = SK_Fixed1; break; case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; case SkPaint::kLeft_Align: origin = 0; break; default: SkFAIL("Invalid paint origin"); return; } SkAutoKern autokern; const char* stop = text + byteLength; while (textPtr < stop) { // don't need x, y here, since all subpixel variants will have the // same advance const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); positions.push_back(SkFixedToScalar(stopX + SkFixedMul_portable(origin, width))); SkFixed height = glyph.fAdvanceY; positions.push_back(SkFixedToScalar(stopY + SkFixedMul_portable(origin, height))); stopX += width; stopY += height; } SkASSERT(textPtr == stop); // now adjust starting point depending on alignment SkScalar alignX = SkFixedToScalar(stopX); SkScalar alignY = SkFixedToScalar(stopY); if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { alignX = SkScalarHalf(alignX); alignY = SkScalarHalf(alignY); } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { alignX = 0; alignY = 0; } x -= alignX; y -= alignY; SkPoint offset = SkPoint::Make(x, y); this->drawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2, offset); }
void GrStencilAndCoverTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, SkScalar x, SkScalar y) { SkASSERT(byteLength == 0 || text != NULL); if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { return; } // This is the slow path, mainly used by Skia unit tests. The other // backends (8888, gpu, ...) use device-space dependent glyph caches. In // order to match the glyph positions that the other code paths produce, we // must also use device-space dependent glyph cache. This has the // side-effect that the glyph shape outline will be in device-space, // too. This in turn has the side-effect that NVPR can not stroke the paths, // as the stroke in NVPR is defined in object-space. // NOTE: here we have following coincidence that works at the moment: // - When using the device-space glyphs, the transforms we pass to NVPR // instanced drawing are the global transforms, and the view transform is // identity. NVPR can not use non-affine transforms in the instanced // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it // will turn off the use of device-space glyphs when perspective transforms // are in use. this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode); // Transform our starting point. if (fNeedsDeviceSpaceGlyphs) { SkPoint loc; fContextInitialMatrix.mapXY(x, y, &loc); x = loc.fX; y = loc.fY; } SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); fTransformType = GrPathRendering::kTranslate_PathTransformType; const char* stop = text + byteLength; // Measure first if needed. if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { SkFixed stopX = 0; SkFixed stopY = 0; const char* textPtr = text; while (textPtr < stop) { // We don't need x, y here, since all subpixel variants will have the // same advance. const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &textPtr, 0, 0); stopX += glyph.fAdvanceX; stopY += glyph.fAdvanceY; } SkASSERT(textPtr == stop); SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio; SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio; if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { alignX = SkScalarHalf(alignX); alignY = SkScalarHalf(alignY); } x -= alignX; y -= alignY; } SkAutoKern autokern; SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio); SkFixed fx = SkScalarToFixed(x); SkFixed fy = SkScalarToFixed(y); while (text < stop) { const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); fx += SkFixedMul_portable(autokern.adjust(glyph), fixedSizeRatio); if (glyph.fWidth) { this->appendGlyph(glyph.getGlyphID(), SkFixedToScalar(fx), SkFixedToScalar(fy)); } fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio); fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio); } this->finish(); }