start a wrapper for color fonts
BUG= R=bungeman@google.com Review URL: https://codereview.chromium.org/14890016 git-svn-id: http://skia.googlecode.com/svn/trunk@9381 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a96627fd24
commit
7edec14039
68
gm/colortype.cpp
Normal file
68
gm/colortype.cpp
Normal file
@ -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); )
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
*/
|
||||
|
249
src/fonts/SkGScalerContext.cpp
Normal file
249
src/fonts/SkGScalerContext.cpp
Normal file
@ -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
|
43
src/fonts/SkGScalerContext.h
Normal file
43
src/fonts/SkGScalerContext.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user