aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/colortype.cpp68
-rw-r--r--gyp/gmslides.gypi1
-rw-r--r--gyp/utils.gyp4
-rw-r--r--include/core/SkTypeface.h9
-rw-r--r--src/fonts/SkGScalerContext.cpp249
-rw-r--r--src/fonts/SkGScalerContext.h43
6 files changed, 374 insertions, 0 deletions
diff --git a/gm/colortype.cpp b/gm/colortype.cpp
new file mode 100644
index 0000000000..68576b853a
--- /dev/null
+++ b/gm/colortype.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "../src/fonts/SkGScalerContext.h"
+
+class ColorTypeGM : public skiagm::GM {
+public:
+ ColorTypeGM() {
+ const SkColor colors[] = {
+ SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
+ SK_ColorMAGENTA, SK_ColorCYAN, SK_ColorYELLOW
+ };
+ SkShader* s = SkGradientShader::CreateSweep(0,0, colors, NULL,
+ SK_ARRAY_COUNT(colors));
+ SkMatrix local;
+ local.setRotate(180);
+ s->setLocalMatrix(local);
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setShader(s)->unref();
+
+ SkAutoTUnref<SkTypeface> orig(SkTypeface::CreateFromName("Times",
+ SkTypeface::kBold));
+ fColorType = SkNEW_ARGS(SkGTypeface, (orig, paint));
+ }
+
+ virtual ~ColorTypeGM() {
+ fColorType->unref();
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("colortype");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setTypeface(fColorType);
+
+ for (int size = 10; size <= 100; size += 10) {
+ paint.setTextSize(size);
+ canvas->translate(0, paint.getFontMetrics(NULL));
+ canvas->drawText("Hamburgefons", 12, 10, 10, paint);
+ }
+ }
+
+ virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }
+
+private:
+ SkTypeface* fColorType;
+
+ typedef skiagm::GM INHERITED;
+};
+
+DEF_GM( return SkNEW(ColorTypeGM); )
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index e56d62bd79..641e9e0b04 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -19,6 +19,7 @@
'../gm/circles.cpp',
'../gm/colorfilterimagefilter.cpp',
'../gm/colormatrix.cpp',
+ '../gm/colortype.cpp',
'../gm/complexclip.cpp',
'../gm/complexclip2.cpp',
'../gm/composeshader.cpp',
diff --git a/gyp/utils.gyp b/gyp/utils.gyp
index a1820c0517..0791e19e62 100644
--- a/gyp/utils.gyp
+++ b/gyp/utils.gyp
@@ -111,6 +111,10 @@
'../src/utils/win/SkHRESULT.cpp',
'../src/utils/win/SkIStream.cpp',
'../src/utils/win/SkWGL_win.cpp',
+
+ #testing
+ '../src/fonts/SkGScalerContext.cpp',
+ '../src/fonts/SkGScalerContext.h',
],
'sources!': [
'../src/utils/SDL/SkOSWindow_SDL.cpp',
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index c91fa428fa..a314e0fffb 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -203,6 +203,15 @@ public:
SkStream* openStream(int* ttcIndex) const;
SkScalerContext* createScalerContext(const SkDescriptor*) const;
+ // PRIVATE / EXPERIMENTAL -- do not call
+ void filterRec(SkScalerContextRec* rec) const {
+ this->onFilterRec(rec);
+ }
+ // PRIVATE / EXPERIMENTAL -- do not call
+ void getFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+ this->onGetFontDescriptor(desc, isLocal);
+ }
+
protected:
/** uniqueID must be unique and non-zero
*/
diff --git a/src/fonts/SkGScalerContext.cpp b/src/fonts/SkGScalerContext.cpp
new file mode 100644
index 0000000000..4de261b394
--- /dev/null
+++ b/src/fonts/SkGScalerContext.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkGScalerContext.h"
+#include "SkGlyph.h"
+#include "SkPath.h"
+#include "SkCanvas.h"
+
+class SkGScalerContext : public SkScalerContext {
+public:
+ SkGScalerContext(SkGTypeface*, const SkDescriptor*);
+ virtual ~SkGScalerContext();
+
+protected:
+ virtual unsigned generateGlyphCount() SK_OVERRIDE;
+ virtual uint16_t generateCharToGlyph(SkUnichar) SK_OVERRIDE;
+ virtual void generateAdvance(SkGlyph*) SK_OVERRIDE;
+ virtual void generateMetrics(SkGlyph*) SK_OVERRIDE;
+ virtual void generateImage(const SkGlyph&) SK_OVERRIDE;
+ virtual void generatePath(const SkGlyph&, SkPath*) SK_OVERRIDE;
+ virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
+ SkPaint::FontMetrics* mY) SK_OVERRIDE;
+
+private:
+ SkGTypeface* fFace;
+ SkScalerContext* fProxy;
+ SkMatrix fMatrix;
+};
+
+#define STD_SIZE 1
+
+#include "SkDescriptor.h"
+
+SkGScalerContext::SkGScalerContext(SkGTypeface* face, const SkDescriptor* desc)
+ : SkScalerContext(face, desc)
+ , fFace(face)
+{
+
+ size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec);
+ SkAutoDescriptor ad(descSize);
+ SkDescriptor* newDesc = ad.getDesc();
+
+ newDesc->init();
+ void* entry = newDesc->addEntry(kRec_SkDescriptorTag,
+ sizeof(SkScalerContext::Rec), &fRec);
+ {
+ SkScalerContext::Rec* rec = (SkScalerContext::Rec*)entry;
+ rec->fTextSize = STD_SIZE;
+ rec->fPreScaleX = SK_Scalar1;
+ rec->fPreSkewX = 0;
+ rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
+ rec->fPost2x2[1][0] = rec->fPost2x2[0][1] = 0;
+ }
+ SkASSERT(descSize == newDesc->getLength());
+ newDesc->computeChecksum();
+
+ fProxy = face->proxy()->createScalerContext(newDesc);
+
+ fRec.getSingleMatrix(&fMatrix);
+ fMatrix.preScale(SK_Scalar1 / STD_SIZE, SK_Scalar1 / STD_SIZE);
+}
+
+SkGScalerContext::~SkGScalerContext() {
+ SkDELETE(fProxy);
+}
+
+unsigned SkGScalerContext::generateGlyphCount() {
+ return fProxy->getGlyphCount();
+}
+
+uint16_t SkGScalerContext::generateCharToGlyph(SkUnichar uni) {
+ return fProxy->charToGlyphID(uni);
+}
+
+void SkGScalerContext::generateAdvance(SkGlyph* glyph) {
+ fProxy->getAdvance(glyph);
+
+ SkVector advance;
+ fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
+ SkFixedToScalar(glyph->fAdvanceY), &advance);
+ glyph->fAdvanceX = SkScalarToFixed(advance.fX);
+ glyph->fAdvanceY = SkScalarToFixed(advance.fY);
+}
+
+void SkGScalerContext::generateMetrics(SkGlyph* glyph) {
+ fProxy->getMetrics(glyph);
+
+ SkVector advance;
+ fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX),
+ SkFixedToScalar(glyph->fAdvanceY), &advance);
+ glyph->fAdvanceX = SkScalarToFixed(advance.fX);
+ glyph->fAdvanceY = SkScalarToFixed(advance.fY);
+
+ SkPath path;
+ fProxy->getPath(*glyph, &path);
+ path.transform(fMatrix);
+
+ SkRect storage;
+ const SkPaint& paint = fFace->paint();
+ const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(),
+ &storage,
+ SkPaint::kFill_Style);
+ SkIRect ibounds;
+ newBounds.roundOut(&ibounds);
+ glyph->fLeft = ibounds.fLeft;
+ glyph->fTop = ibounds.fTop;
+ glyph->fWidth = ibounds.width();
+ glyph->fHeight = ibounds.height();
+ glyph->fMaskFormat = SkMask::kARGB32_Format;
+}
+
+void SkGScalerContext::generateImage(const SkGlyph& glyph) {
+ if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
+ SkPath path;
+ fProxy->getPath(glyph, &path);
+
+ SkBitmap bm;
+ bm.setConfig(SkBitmap::kARGB_8888_Config, glyph.fWidth, glyph.fHeight,
+ glyph.rowBytes());
+ bm.setPixels(glyph.fImage);
+ bm.eraseColor(0);
+
+ SkCanvas canvas(bm);
+ canvas.translate(-glyph.fLeft, -glyph.fTop);
+ canvas.concat(fMatrix);
+ canvas.drawPath(path, fFace->paint());
+ } else {
+ fProxy->getImage(glyph);
+ }
+}
+
+void SkGScalerContext::generatePath(const SkGlyph& glyph, SkPath* path) {
+ fProxy->getPath(glyph, path);
+ path->transform(fMatrix);
+}
+
+void SkGScalerContext::generateFontMetrics(SkPaint::FontMetrics*,
+ SkPaint::FontMetrics* metrics) {
+ fProxy->getFontMetrics(metrics);
+ if (metrics) {
+ SkScalar scale = fMatrix.getScaleY();
+ metrics->fTop = SkScalarMul(metrics->fTop, scale);
+ metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
+ metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
+ metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
+ metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
+ metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
+ metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
+ metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
+ metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTypefaceCache.h"
+
+SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
+ : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false)
+ , fProxy(SkRef(proxy))
+ , fPaint(paint) {}
+
+SkGTypeface::~SkGTypeface() {
+ fProxy->unref();
+}
+
+SkScalerContext* SkGTypeface::onCreateScalerContext(
+ const SkDescriptor* desc) const {
+ return SkNEW_ARGS(SkGScalerContext, (const_cast<SkGTypeface*>(this), desc));
+}
+
+void SkGTypeface::onFilterRec(SkScalerContextRec* rec) const {
+ fProxy->filterRec(rec);
+}
+
+SkAdvancedTypefaceMetrics* SkGTypeface::onGetAdvancedTypefaceMetrics(
+ SkAdvancedTypefaceMetrics::PerGlyphInfo info,
+ const uint32_t* glyphIDs,
+ uint32_t glyphIDsCount) const {
+ return fProxy->getAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
+}
+
+SkStream* SkGTypeface::onOpenStream(int* ttcIndex) const {
+ return fProxy->openStream(ttcIndex);
+}
+
+void SkGTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
+ bool* isLocal) const {
+ fProxy->getFontDescriptor(desc, isLocal);
+}
+
+int SkGTypeface::onGetUPEM() const {
+ return fProxy->getUnitsPerEm();
+}
+
+int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const {
+ return fProxy->getTableTags(tags);
+}
+
+size_t SkGTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
+ size_t length, void* data) const {
+ return fProxy->getTableData(tag, offset, length, data);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if 0
+// under construction -- defining a font purely in terms of skia primitives
+// ala an SVG-font.
+class SkGFont : public SkRefCnt {
+public:
+ virtual ~SkGFont();
+
+ int unicharToGlyph(SkUnichar) const;
+
+ int countGlyphs() const { return fCount; }
+
+ float getAdvance(int index) const {
+ SkASSERT((unsigned)index < (unsigned)fCount);
+ return fGlyphs[index].fAdvance;
+ }
+
+ const SkPath& getPath(int index) const {
+ SkASSERT((unsigned)index < (unsigned)fCount);
+ return fGlyphs[index].fPath;
+ }
+
+private:
+ struct Glyph {
+ SkUnichar fUni;
+ float fAdvance;
+ SkPath fPath;
+ };
+ int fCount;
+ Glyph* fGlyphs;
+
+ friend class SkGFontBuilder;
+ SkGFont(int count, Glyph* array);
+};
+
+class SkGFontBuilder {
+public:
+
+};
+#endif
diff --git a/src/fonts/SkGScalerContext.h b/src/fonts/SkGScalerContext.h
new file mode 100644
index 0000000000..504bc7b647
--- /dev/null
+++ b/src/fonts/SkGScalerContext.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkGScalerContext_DEFINED
+#define SkGScalerContext_DEFINED
+
+#include "SkScalerContext.h"
+#include "SkTypeface.h"
+
+class SkGTypeface : public SkTypeface {
+public:
+ SkGTypeface(SkTypeface* proxy, const SkPaint&);
+ virtual ~SkGTypeface();
+
+ SkTypeface* proxy() const { return fProxy; }
+ const SkPaint& paint() const { return fPaint; }
+
+protected:
+ virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
+ virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
+ virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+ SkAdvancedTypefaceMetrics::PerGlyphInfo,
+ const uint32_t* glyphIDs,
+ uint32_t glyphIDsCount) const SK_OVERRIDE;
+ virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
+ virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const SK_OVERRIDE;
+
+ virtual int onGetUPEM() const SK_OVERRIDE;
+
+ virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
+ virtual size_t onGetTableData(SkFontTableTag, size_t offset,
+ size_t length, void* data) const SK_OVERRIDE;
+
+private:
+ SkTypeface* fProxy;
+ SkPaint fPaint;
+};
+
+#endif