* found in the LICENSE file.
*/
#include "gm.h"
+#include "Resources.h"
+#include "SkCanvas.h"
+#include "SkStream.h"
#include "SkSurface.h"
#include "SkTypeface.h"
-namespace skiagm {
-
-class DFTextGM : public GM {
+class DFTextGM : public skiagm::GM {
public:
DFTextGM() {
this->setBGColor(0xFFFFFFFF);
+ fTypeface = NULL;
}
virtual ~DFTextGM() {
+ SkSafeUnref(fTypeface);
}
protected:
+ virtual void onOnceBeforeDraw() SK_OVERRIDE {
+ SkString filename = GetResourcePath("/Funkster.ttf");
+ SkAutoTUnref<SkFILEStream> stream(new SkFILEStream(filename.c_str()));
+ if (!stream->isValid()) {
+ SkDebugf("Could not find Funkster.ttf, please set --resourcePath correctly.\n");
+ return;
+ }
+
+ fTypeface = SkTypeface::CreateFromStream(stream);
+ }
+
virtual uint32_t onGetFlags() const SK_OVERRIDE {
return kGPUOnly_Flag;
}
- virtual SkString onShortName() {
+ virtual SkString onShortName() SK_OVERRIDE {
return SkString("dftext");
}
- virtual SkISize onISize() {
+ virtual SkISize onISize() SK_OVERRIDE {
return SkISize::Make(1024, 768);
}
y += paint.getFontMetrics(NULL);
}
+ // check color emoji
+ paint.setTypeface(fTypeface);
+ canvas->drawText(text, textLen, 670, 100, paint);
+
#if SK_SUPPORT_GPU
// render offscreen buffer
if (surface) {
}
private:
- typedef GM INHERITED;
-};
+ SkTypeface* fTypeface;
-//////////////////////////////////////////////////////////////////////////////
-
-static GM* MyFactory(void*) { return new DFTextGM; }
-static GMRegistry reg(MyFactory);
+ typedef skiagm::GM INHERITED;
+};
-}
+DEF_GM( return SkNEW(DFTextGM); )
setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
const char* stop = text + byteLength;
+ SkTArray<char> fallbackTxt;
+ SkTArray<SkScalar> fallbackPos;
if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
while (text < stop) {
+ const char* lastText = text;
// the last 2 parameters are ignored
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
SkScalar x = offset.x() + pos[0];
SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0);
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkScalarToFixed(x),
- SkScalarToFixed(y),
- fontScaler);
+ if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkScalarToFixed(x),
+ SkScalarToFixed(y),
+ fontScaler)) {
+ // couldn't append, send to fallback
+ fallbackTxt.push_back_n(text-lastText, lastText);
+ fallbackPos.push_back(pos[0]);
+ if (2 == scalarsPerPosition) {
+ fallbackPos.push_back(pos[1]);
+ }
+ }
}
pos += scalarsPerPosition;
}
SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf
: SK_Scalar1;
while (text < stop) {
+ const char* lastText = text;
// the last 2 parameters are ignored
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fTextRatio;
SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fTextRatio;
- this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
- glyph.getSubXFixed(),
- glyph.getSubYFixed()),
- SkScalarToFixed(x - advanceX),
- SkScalarToFixed(y - advanceY),
- fontScaler);
+ if (!this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(),
+ glyph.getSubXFixed(),
+ glyph.getSubYFixed()),
+ SkScalarToFixed(x - advanceX),
+ SkScalarToFixed(y - advanceY),
+ fontScaler)) {
+ // couldn't append, send to fallback
+ fallbackTxt.push_back_n(text-lastText, lastText);
+ fallbackPos.push_back(pos[0]);
+ if (2 == scalarsPerPosition) {
+ fallbackPos.push_back(pos[1]);
+ }
+ }
}
pos += scalarsPerPosition;
}
}
this->finish();
+
+ if (fallbackTxt.count() > 0) {
+ fFallbackTextContext->drawPosText(paint, skPaint, fallbackTxt.begin(), fallbackTxt.count(),
+ fallbackPos.begin(), scalarsPerPosition, offset);
+ }
}
static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
}
-void GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
+// Returns true if this method handled the glyph, false if needs to be passed to fallback
+//
+bool GrDistanceFieldTextContext::appendGlyph(GrGlyph::PackedID packed,
SkFixed vx, SkFixed vy,
GrFontScaler* scaler) {
if (NULL == fDrawTarget) {
- return;
+ return true;
}
if (NULL == fStrike) {
GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
if (NULL == glyph || glyph->fBounds.isEmpty()) {
- return;
+ return true;
}
- // TODO: support color glyphs
+ // fallback to color glyph support
if (kA8_GrMaskFormat != glyph->fMaskFormat) {
- return;
+ return false;
}
SkScalar sx = SkFixedToScalar(vx);
if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
// flag the glyph as being dead?
delete path;
- return;
+ return true;
}
glyph->fPath = path;
}
am.setPreConcat(fContext, ctm, &tmpPaint);
GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo);
- return;
+ return true;
}
HAS_ATLAS:
}
fCurrVertex += 4;
+
+ return true;
}
void GrDistanceFieldTextContext::flush() {