aboutsummaryrefslogtreecommitdiffstats
path: root/src/ports
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2011-03-14 11:20:24 -0400
committerDerek Sollenberger <djsollen@google.com>2011-03-14 16:33:36 -0400
commit05b6b4d746867a9fb02e14edfe1bf3685abeb813 (patch)
tree34b121f598d1693c014df48ee70bffa382b0cc23 /src/ports
parent6210a7c68844602ee390bcce61dbb637910a3c6b (diff)
downloadexternal_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.zip
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.gz
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.bz2
Skia Merge (revision 922)
Change-Id: I7ed57d10905d8bad6486a4d7410165eec1cc2b4f
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp8
-rw-r--r--src/ports/SkFontHost_ascender.cpp4
-rw-r--r--src/ports/SkFontHost_mac_atsui.cpp4
-rw-r--r--src/ports/SkFontHost_mac_coretext.cpp123
-rw-r--r--src/ports/SkFontHost_win.cpp236
5 files changed, 235 insertions, 140 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 043f0df..5dc38b8 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -121,7 +121,7 @@ public:
}
protected:
- virtual unsigned generateGlyphCount() const;
+ virtual unsigned generateGlyphCount();
virtual uint16_t generateCharToGlyph(SkUnichar uni);
virtual void generateAdvance(SkGlyph* glyph);
virtual void generateMetrics(SkGlyph* glyph);
@@ -346,7 +346,7 @@ static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) {
-#ifdef ANDROID
+#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
return NULL;
#else
SkAutoMutexAcquire ac(gFTMutex);
@@ -541,6 +541,7 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
rec->setHinting(h);
}
+#ifdef ANDROID
uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
SkAutoMutexAcquire ac(gFTMutex);
SkFaceRec *rec = ref_ft_face(fontID);
@@ -553,6 +554,7 @@ uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
return (uint32_t)unitsPerEm;
}
+#endif
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
: SkScalerContext(desc) {
@@ -748,7 +750,7 @@ void SkScalerContext_FreeType::emboldenOutline(FT_Outline* outline) {
FT_Outline_Embolden(outline, strength);
}
-unsigned SkScalerContext_FreeType::generateGlyphCount() const {
+unsigned SkScalerContext_FreeType::generateGlyphCount() {
return fFace->num_glyphs;
}
diff --git a/src/ports/SkFontHost_ascender.cpp b/src/ports/SkFontHost_ascender.cpp
index 88cde38..6f5cf0b 100644
--- a/src/ports/SkFontHost_ascender.cpp
+++ b/src/ports/SkFontHost_ascender.cpp
@@ -22,7 +22,7 @@ public:
virtual ~SkScalerContext_Ascender();
protected:
- virtual unsigned generateGlyphCount() const;
+ virtual unsigned generateGlyphCount();
virtual uint16_t generateCharToGlyph(SkUnichar uni);
virtual void generateMetrics(SkGlyph* glyph);
virtual void generateImage(const SkGlyph& glyph);
@@ -102,7 +102,7 @@ SkScalerContext_Ascender::~SkScalerContext_Ascender()
sk_free(fHandle);
}
-unsigned SkScalerContext_Ascender::generateGlyphCount() const
+unsigned SkScalerContext_Ascender::generateGlyphCount()
{
return 1000;
}
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index 5183730..1d40a42 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -87,7 +87,7 @@ public:
virtual ~SkScalerContext_Mac();
protected:
- virtual unsigned generateGlyphCount() const;
+ virtual unsigned generateGlyphCount();
virtual uint16_t generateCharToGlyph(SkUnichar uni);
virtual void generateAdvance(SkGlyph* glyph);
virtual void generateMetrics(SkGlyph* glyph);
@@ -184,7 +184,7 @@ SkScalerContext_Mac::~SkScalerContext_Mac() {
// man, we need to consider caching this, since it is just dependent on
// fFontID, and not on any of the other settings like matrix or flags
-unsigned SkScalerContext_Mac::generateGlyphCount() const {
+unsigned SkScalerContext_Mac::generateGlyphCount() {
// The 'maxp' table stores the number of glyphs a offset 4, in 2 bytes
uint16_t numGlyphs;
if (SkFontHost::GetTableData(fRec.fFontID,
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index 4b5c36d..ae39361 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -1,16 +1,16 @@
/*
** Copyright 2006, The Android Open Source Project
**
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
**
- ** http://www.apache.org/licenses/LICENSE-2.0
+ ** http://www.apache.org/licenses/LICENSE-2.0
**
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <vector>
@@ -21,7 +21,7 @@
#include "SkString.h"
#include "SkPaint.h"
#include "SkFloatingPoint.h"
-
+#include "SkUtils.h"
@@ -88,13 +88,13 @@ public:
// Is a font ID valid?
bool IsValid(SkFontID fontID);
-
-
+
+
// Get a font
CTFontRef GetFont(SkFontID fontID);
SkNativeFontInfo GetFontInfo(const SkString &theName, SkTypeface::Style theStyle);
-
-
+
+
// Create a font
SkNativeFontInfo CreateFont(const SkString &theName, SkTypeface::Style theStyle);
@@ -132,7 +132,7 @@ SkNativeFontCache::SkNativeFontCache(void)
fontInfo.style = SkTypeface::kNormal;
fontInfo.fontID = kSkInvalidFontID;
fontInfo.fontRef = NULL;
-
+
mFonts.push_back(fontInfo);
}
@@ -190,7 +190,7 @@ SkNativeFontInfo SkNativeFontCache::GetFontInfo(const SkString &theName, SkTypef
if (theIter->name == theName && theIter->style == theStyle)
return(*theIter);
}
-
+
return(fontInfo);
}
@@ -314,7 +314,7 @@ public:
protected:
- unsigned generateGlyphCount(void) const;
+ unsigned generateGlyphCount(void);
uint16_t generateCharToGlyph(SkUnichar uni);
void generateAdvance(SkGlyph* glyph);
void generateMetrics(SkGlyph* glyph);
@@ -328,7 +328,8 @@ private:
private:
- CGColorSpaceRef mColorSpace;
+ CGColorSpaceRef mColorSpaceGray;
+ CGColorSpaceRef mColorSpaceRGB;
CGAffineTransform mTransform;
CTFontRef mFont;
@@ -352,7 +353,11 @@ SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc)
// Initialise ourselves
- mColorSpace = CGColorSpaceCreateDeviceGray();
+// mColorSpaceRGB = CGColorSpaceCreateDeviceRGB();
+// mColorSpaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ mColorSpaceRGB = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
+ mColorSpaceGray = CGColorSpaceCreateDeviceGray();
+
const float inv = 1.0f / FONT_CANONICAL_POINTSIZE;
mTransform = CGAffineTransformMake(SkScalarToFloat(skMatrix[SkMatrix::kMScaleX]) * inv,
-SkScalarToFloat(skMatrix[SkMatrix::kMSkewY]) * inv,
@@ -369,11 +374,12 @@ SkScalerContext_Mac::~SkScalerContext_Mac(void)
{
// Clean up
- CFSafeRelease(mColorSpace);
+ CFSafeRelease(mColorSpaceGray);
+ CFSafeRelease(mColorSpaceRGB);
CFSafeRelease(mFont);
}
-unsigned SkScalerContext_Mac::generateGlyphCount(void) const
+unsigned SkScalerContext_Mac::generateGlyphCount(void)
{
return(mGlyphCount);
}
@@ -437,8 +443,27 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph)
glyph->fLeft = sk_float_round2int(CGRectGetMinX(theBounds));
}
-void SkScalerContext_Mac::generateImage(const SkGlyph& glyph)
-{ CGContextRef cgContext;
+#include "SkColorPriv.h"
+
+static inline uint16_t rgb_to_lcd16(uint32_t rgb) {
+ int r = (rgb >> 16) & 0xFF;
+ int g = (rgb >> 8) & 0xFF;
+ int b = (rgb >> 0) & 0xFF;
+
+ // invert, since we draw black-on-white, but we want the original
+ // src mask values.
+ r = 255 - r;
+ g = 255 - g;
+ b = 255 - b;
+
+ return SkPackRGB16(SkR32ToR16(r), SkG32ToG16(g), SkB32ToB16(b));
+}
+
+#define BITMAP_INFO_RGB (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
+#define BITMAP_INFO_GRAY (kCGImageAlphaNone)
+
+void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) {
+ CGContextRef cgContext;
CGGlyph cgGlyph;
CGFontRef cgFont;
@@ -447,17 +472,61 @@ void SkScalerContext_Mac::generateImage(const SkGlyph& glyph)
cgGlyph = (CGGlyph) glyph.getGlyphID(fBaseGlyphCount);
cgFont = CTFontCopyGraphicsFont(mFont, NULL);
- cgContext = CGBitmapContextCreate( glyph.fImage, glyph.fWidth, glyph.fHeight, 8,
- glyph.rowBytes(), mColorSpace, kCGImageAlphaNone);
+
+ SkAutoSMalloc<1024> storage;
+
+ CGColorSpaceRef colorspace = mColorSpaceGray;
+ uint32_t info = BITMAP_INFO_GRAY;
+ void* image = glyph.fImage;
+ size_t rowBytes = glyph.rowBytes();
+ float grayColor = 1; // white
+
+ /* For LCD16, we first create a temp offscreen cg-context in 32bit,
+ * erase to white, and then draw a black glyph into it. Then we can
+ * extract the r,g,b values, invert-them, and now we have the original
+ * src mask components, which we pack into our 16bit mask.
+ */
+ if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
+ colorspace = mColorSpaceRGB;
+ info = BITMAP_INFO_RGB;
+ // need tmp storage for 32bit RGB offscreen
+ rowBytes = glyph.fWidth << 2;
+ size_t size = glyph.fHeight * rowBytes;
+ image = storage.realloc(size);
+ // we draw black-on-white (and invert in rgb_to_lcd16)
+ sk_memset32((uint32_t*)image, 0xFFFFFFFF, size >> 2);
+ grayColor = 0; // black
+ }
+
+ cgContext = CGBitmapContextCreate(image, glyph.fWidth, glyph.fHeight, 8,
+ rowBytes, colorspace, info);
// Draw the glyph
if (cgFont != NULL && cgContext != NULL) {
- CGContextSetGrayFillColor( cgContext, 1.0, 1.0);
+ CGContextSetAllowsFontSubpixelQuantization(cgContext, true);
+ CGContextSetShouldSubpixelQuantizeFonts(cgContext, true);
+
+ CGContextSetGrayFillColor( cgContext, grayColor, 1.0);
CGContextSetTextDrawingMode(cgContext, kCGTextFill);
CGContextSetFont( cgContext, cgFont);
CGContextSetFontSize( cgContext, FONT_CANONICAL_POINTSIZE);
CGContextSetTextMatrix( cgContext, mTransform);
CGContextShowGlyphsAtPoint( cgContext, -glyph.fLeft, glyph.fTop + glyph.fHeight, &cgGlyph, 1);
+
+ if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
+ // downsample from rgba to rgb565
+ int width = glyph.fWidth;
+ const uint32_t* src = (const uint32_t*)image;
+ uint16_t* dst = (uint16_t*)glyph.fImage;
+ size_t dstRB = glyph.rowBytes();
+ for (int y = 0; y < glyph.fHeight; y++) {
+ for (int i = 0; i < width; i++) {
+ dst[i] = rgb_to_lcd16(src[i]);
+ }
+ src = (const uint32_t*)((const char*)src + rowBytes);
+ dst = (uint16_t*)((char*)dst + dstRB);
+ }
+ }
}
// Clean up
@@ -539,7 +608,7 @@ void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element
case kCGPathElementCloseSubpath:
skPath->close();
break;
-
+
default:
SkASSERT("Unknown path element!");
break;
@@ -783,7 +852,7 @@ size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag)
theSize = CFDataGetLength(cfData);
CFSafeRelease(cfData);
}
-
+
return(theSize);
}
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index c2055aa..a20f001 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -17,11 +17,13 @@
#include "SkString.h"
//#include "SkStream.h"
+#include "SkEndian.h"
#include "SkFontHost.h"
#include "SkDescriptor.h"
#include "SkAdvancedTypefaceMetrics.h"
#include "SkStream.h"
#include "SkThread.h"
+#include "SkTypeface_win.h"
#include "SkUtils.h"
#ifdef WIN32
@@ -42,6 +44,18 @@ static uint8_t glyphbuf[BUFFERSIZE];
// Give 1MB font cache budget
#define FONT_CACHE_MEMORY_BUDGET (1024 * 1024)
+/**
+ * Since LOGFONT wants its textsize as an int, and we support fractional sizes,
+ * and since we have a cache of LOGFONTs for our tyepfaces, we always set the
+ * lfHeight to a canonical size, and then we use the 2x2 matrix to achieve the
+ * actual requested size.
+ */
+static const int gCanonicalTextSize = 64;
+
+static void make_canonical(LOGFONT* lf) {
+ lf->lfHeight = -gCanonicalTextSize;
+}
+
static inline FIXED SkFixedToFIXED(SkFixed x) {
return *(FIXED*)(&x);
}
@@ -50,6 +64,32 @@ static inline FIXED SkScalarToFIXED(SkScalar x) {
return SkFixedToFIXED(SkScalarToFixed(x));
}
+static unsigned calculateGlyphCount(HDC hdc) {
+ // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
+ const DWORD maxpTag = *(DWORD*) "maxp";
+ uint16_t glyphs;
+ if (GetFontData(hdc, maxpTag, 4, &glyphs, sizeof(glyphs)) != GDI_ERROR) {
+ return SkEndian_SwapBE16(glyphs);
+ }
+
+ // Binary search for glyph count.
+ static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
+ int32_t max = SK_MaxU16 + 1;
+ int32_t min = 0;
+ GLYPHMETRICS gm;
+ while (min < max) {
+ int32_t mid = min + ((max - min) / 2);
+ if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
+ NULL, &mat2) == GDI_ERROR) {
+ max = mid;
+ } else {
+ min = mid + 1;
+ }
+ }
+ SkASSERT(min == max);
+ return min;
+}
+
static SkTypeface::Style GetFontStyle(const LOGFONT& lf) {
int style = SkTypeface::kNormal;
if (lf.lfWeight == FW_SEMIBOLD || lf.lfWeight == FW_DEMIBOLD || lf.lfWeight == FW_BOLD)
@@ -72,15 +112,17 @@ private:
public:
- LogFontTypeface(Style style, const LOGFONT& logFont) :
+ LogFontTypeface(Style style, const LOGFONT& logFont) :
SkTypeface(style, sk_atomic_inc(&gCurrId)+1), // 0 id is reserved so add 1
fLogFont(logFont)
{
+ make_canonical(&fLogFont);
+
SkAutoMutexAcquire am(gMutex);
fNext = gHead;
gHead = this;
}
-
+
const LOGFONT& logFont() const { return fLogFont; }
virtual ~LogFontTypeface() {
@@ -108,11 +150,14 @@ public:
}
return curr;
}
-
+
static LogFontTypeface* FindByLogFont(const LOGFONT& lf)
{
+ LOGFONT canonical = lf;
+ make_canonical(&canonical);
+
LogFontTypeface* curr = gHead;
- while (curr && memcmp(&curr->fLogFont, &lf, sizeof(LOGFONT))) {
+ while (curr && memcmp(&curr->fLogFont, &canonical, sizeof(LOGFONT))) {
curr = curr->fNext;
}
return curr;
@@ -145,16 +190,15 @@ static const LOGFONT& get_default_font() {
return gDefaultFont;
}
-static SkTypeface* CreateTypeface_(const LOGFONT& lf) {
-
+SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& lf) {
LogFontTypeface* ptypeface = LogFontTypeface::FindByLogFont(lf);
-
+
if (NULL == ptypeface) {
SkTypeface::Style style = GetFontStyle(lf);
ptypeface = new LogFontTypeface(style, lf);
} else {
- ptypeface->ref();
- }
+ ptypeface->ref();
+ }
return ptypeface;
}
@@ -171,63 +215,64 @@ public:
virtual ~SkScalerContext_Windows();
protected:
- virtual unsigned generateGlyphCount() const;
+ virtual unsigned generateGlyphCount();
virtual uint16_t generateCharToGlyph(SkUnichar uni);
virtual void generateAdvance(SkGlyph* glyph);
virtual void generateMetrics(SkGlyph* glyph);
virtual void generateImage(const SkGlyph& glyph);
virtual void generatePath(const SkGlyph& glyph, SkPath* path);
- virtual void generateLineHeight(SkPoint* ascent, SkPoint* descent);
virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY);
//virtual SkDeviceContext getDC() {return ddc;}
private:
- LOGFONT lf;
- MAT2 mat22;
- HDC ddc;
- HFONT savefont;
- HFONT font;
- SCRIPT_CACHE sc;
+ SkScalar fScale; // to get from canonical size to real size
+ MAT2 fMat22;
+ HDC fDDC;
+ HFONT fSavefont;
+ HFONT fFont;
+ SCRIPT_CACHE fSC;
+ int fGlyphCount;
};
SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)
- : SkScalerContext(desc), ddc(0), font(0), savefont(0), sc(0) {
+ : SkScalerContext(desc), fDDC(0), fFont(0), fSavefont(0), fSC(0)
+ , fGlyphCount(-1) {
SkAutoMutexAcquire ac(gFTMutex);
- lf = LogFontTypeface::FindById(fRec.fFontID)->logFont();
+ fScale = fRec.fTextSize / gCanonicalTextSize;
+ fMat22.eM11 = SkScalarToFIXED(SkScalarMul(fScale, fRec.fPost2x2[0][0]));
+ fMat22.eM12 = SkScalarToFIXED(SkScalarMul(fScale, -fRec.fPost2x2[0][1]));
+ fMat22.eM21 = SkScalarToFIXED(SkScalarMul(fScale, fRec.fPost2x2[1][0]));
+ fMat22.eM22 = SkScalarToFIXED(SkScalarMul(fScale, -fRec.fPost2x2[1][1]));
- mat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]);
- mat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[0][1]);
- mat22.eM21 = SkScalarToFIXED(fRec.fPost2x2[1][0]);
- mat22.eM22 = SkScalarToFIXED(-fRec.fPost2x2[1][1]);
-
- ddc = ::CreateCompatibleDC(NULL);
- SetBkMode(ddc, TRANSPARENT);
+ fDDC = ::CreateCompatibleDC(NULL);
+ SetBkMode(fDDC, TRANSPARENT);
// Scaling by the DPI is inconsistent with how Skia draws elsewhere
//SkScalar height = -(fRec.fTextSize * GetDeviceCaps(ddc, LOGPIXELSY) / 72);
- SkScalar height = -fRec.fTextSize;
- lf.lfHeight = SkScalarRound(height);
- font = CreateFontIndirect(&lf);
- savefont = (HFONT)SelectObject(ddc, font);
+ LOGFONT lf = LogFontTypeface::FindById(fRec.fFontID)->logFont();
+ lf.lfHeight = -gCanonicalTextSize;
+ fFont = CreateFontIndirect(&lf);
+ fSavefont = (HFONT)SelectObject(fDDC, fFont);
}
SkScalerContext_Windows::~SkScalerContext_Windows() {
- if (ddc) {
- ::SelectObject(ddc, savefont);
- ::DeleteDC(ddc);
- ddc = NULL;
+ if (fDDC) {
+ ::SelectObject(fDDC, fSavefont);
+ ::DeleteDC(fDDC);
}
- if (font) {
- ::DeleteObject(font);
+ if (fFont) {
+ ::DeleteObject(fFont);
}
- if (sc) {
- ::ScriptFreeCache(&sc);
+ if (fSC) {
+ ::ScriptFreeCache(&fSC);
}
}
-unsigned SkScalerContext_Windows::generateGlyphCount() const {
- return 0xFFFF;
- // return fFace->num_glyphs;
+unsigned SkScalerContext_Windows::generateGlyphCount() {
+ if (fGlyphCount < 0) {
+ fGlyphCount = calculateGlyphCount(fDDC);
+ }
+ return fGlyphCount;
}
uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
@@ -236,7 +281,7 @@ uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
// TODO(ctguil): Support characters that generate more than one glyph.
if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) {
// Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.
- SkAssertResult(GetGlyphIndicesW(ddc, c, 1, &index, 0));
+ SkAssertResult(GetGlyphIndicesW(fDDC, c, 1, &index, 0));
} else {
// Use uniscribe to detemine glyph index for non-BMP characters.
// Need to add extra item to SCRIPT_ITEM to work around a bug in older
@@ -250,7 +295,7 @@ uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
SCRIPT_VISATTR vsa;
int glyphs;
SkAssertResult(SUCCEEDED(ScriptShape(
- ddc, &sc, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs)));
+ fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs)));
}
return index;
}
@@ -261,7 +306,7 @@ void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
- SkASSERT(ddc);
+ SkASSERT(fDDC);
GLYPHMETRICS gm;
memset(&gm, 0, sizeof(gm));
@@ -271,7 +316,7 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
// Note: need to use GGO_GRAY8_BITMAP instead of GGO_METRICS because GGO_METRICS returns a smaller
// BlackBlox; we need the bigger one in case we need the image. fAdvance is the same.
- uint32_t ret = GetGlyphOutlineW(ddc, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &mat22);
+ uint32_t ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
if (GDI_ERROR != ret) {
if (ret == 0) {
@@ -301,31 +346,31 @@ void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
if (!(mx || my))
return;
- SkASSERT(ddc);
+ SkASSERT(fDDC);
OUTLINETEXTMETRIC otm;
- uint32_t ret = GetOutlineTextMetrics(ddc, sizeof(otm), &otm);
+ uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
if (sizeof(otm) != ret) {
return;
}
if (mx) {
- mx->fTop = -SkIntToScalar(otm.otmTextMetrics.tmAscent); // Actually a long.
- mx->fAscent = -SkIntToScalar(otm.otmAscent);
- mx->fDescent = -SkIntToScalar(otm.otmDescent);
- mx->fBottom = SkIntToScalar(otm.otmTextMetrics.tmDescent); // Long
- mx->fLeading = SkIntToScalar(otm.otmTextMetrics.tmInternalLeading
- + otm.otmTextMetrics.tmExternalLeading); // Long
+ mx->fTop = -fScale * otm.otmTextMetrics.tmAscent;
+ mx->fAscent = -fScale * otm.otmAscent;
+ mx->fDescent = -fScale * otm.otmDescent;
+ mx->fBottom = fScale * otm.otmTextMetrics.tmDescent;
+ mx->fLeading = fScale * (otm.otmTextMetrics.tmInternalLeading
+ + otm.otmTextMetrics.tmExternalLeading);
}
if (my) {
- my->fTop = -SkIntToScalar(otm.otmTextMetrics.tmAscent); // Actually a long.
- my->fAscent = -SkIntToScalar(otm.otmAscent);
- my->fDescent = -SkIntToScalar(otm.otmDescent);
- my->fBottom = SkIntToScalar(otm.otmTextMetrics.tmDescent); // Long
- my->fLeading = SkIntToScalar(otm.otmTextMetrics.tmInternalLeading
- + otm.otmTextMetrics.tmExternalLeading); // Long
+ my->fTop = -fScale * otm.otmTextMetrics.tmAscent;
+ my->fAscent = -fScale * otm.otmAscent;
+ my->fDescent = -fScale * otm.otmDescent;
+ my->fBottom = fScale * otm.otmTextMetrics.tmDescent;
+ my->fLeading = fScale * (otm.otmTextMetrics.tmInternalLeading
+ + otm.otmTextMetrics.tmExternalLeading);
}
}
@@ -333,7 +378,7 @@ void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
SkAutoMutexAcquire ac(gFTMutex);
- SkASSERT(ddc);
+ SkASSERT(fDDC);
GLYPHMETRICS gm;
memset(&gm, 0, sizeof(gm));
@@ -345,11 +390,11 @@ void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
#endif
uint32_t bytecount = 0;
- uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &mat22);
+ uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
if (GDI_ERROR != total_size && total_size > 0) {
uint8_t *pBuff = new uint8_t[total_size];
if (NULL != pBuff) {
- total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, total_size, pBuff, &mat22);
+ total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, total_size, pBuff, &fMat22);
SkASSERT(total_size != GDI_ERROR);
@@ -393,7 +438,7 @@ void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
SkAutoMutexAcquire ac(gFTMutex);
SkASSERT(&glyph && path);
- SkASSERT(ddc);
+ SkASSERT(fDDC);
path->reset();
@@ -404,7 +449,7 @@ void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
#endif
GLYPHMETRICS gm;
- uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &mat22);
+ uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &fMat22);
if (GDI_ERROR != total_size) {
@@ -455,26 +500,6 @@ void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
//OutputDebugString(buf);
}
-
-// Note: not sure this is the correct implementation
-void SkScalerContext_Windows::generateLineHeight(SkPoint* ascent, SkPoint* descent) {
-
- SkASSERT(ddc);
-
- OUTLINETEXTMETRIC otm;
-
- uint32_t ret = GetOutlineTextMetrics(ddc, sizeof(otm), &otm);
-
- if (sizeof(otm) == ret) {
- if (ascent)
- ascent->iset(0, otm.otmAscent);
- if (descent)
- descent->iset(0, otm.otmDescent);
- }
-
- return;
-}
-
void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
SkASSERT(!"SkFontHost::Serialize unimplemented");
}
@@ -524,8 +549,13 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
goto Error;
}
+ const unsigned glyphCount = calculateGlyphCount(hdc);
info = new SkAdvancedTypefaceMetrics;
+ info->fEmSize = otm.otmEMSquare;
+ info->fMultiMaster = false;
+ info->fLastGlyphID = SkToU16(glyphCount - 1);
+ info->fStyle = 0;
#ifdef UNICODE
// Get the buffer size needed first.
size_t str_len = WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, NULL,
@@ -545,12 +575,15 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
} else {
info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
+ info->fItalicAngle = 0;
+ info->fAscent = 0;
+ info->fDescent = 0;
+ info->fStemV = 0;
+ info->fCapHeight = 0;
+ info->fBBox = SkIRect::MakeEmpty();
+ return info;
}
- info->fEmSize = otm.otmEMSquare;
- info->fMultiMaster = false;
- info->fLastGlyphID = 0;
-
- info->fStyle = 0;
+
// If this bit is clear the font is a fixed pitch font.
if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
@@ -602,16 +635,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
} else if (perGlyphInfo) {
info->fGlyphWidths.reset(
- getAdvanceData(hdc, SHRT_MAX, &getWidthAdvance));
-
- // Obtain the last glyph index.
- SkAdvancedTypefaceMetrics::WidthRange* last = info->fGlyphWidths.get();
- if (last) {
- while (last->fNext.get()) {
- last = last->fNext.get();
- }
- info->fLastGlyphID = last->fEndId;
- }
+ getAdvanceData(hdc, glyphCount, &getWidthAdvance));
}
Error:
@@ -626,8 +650,8 @@ Error:
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
//Should not be used on Windows, keep linker happy
- SkASSERT(false);
- return CreateTypeface_(get_default_font());
+ SkASSERT(false);
+ return SkCreateTypefaceFromLOGFONT(get_default_font());
}
SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {
@@ -689,12 +713,12 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
// hack until we figure out if SkTypeface should cache this itself
if (style == SkTypeface::kNormal) {
if (NULL == gDefaultTypeface) {
- gDefaultTypeface = CreateTypeface_(lf);
+ gDefaultTypeface = SkCreateTypefaceFromLOGFONT(lf);
}
tf = gDefaultTypeface;
tf->ref();
} else {
- tf = CreateTypeface_(lf);
+ tf = SkCreateTypefaceFromLOGFONT(lf);
}
} else {
#ifdef CAN_USE_LOGFONT_NAME
@@ -738,12 +762,12 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
// use the style desired
lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
- tf = CreateTypeface_(lf);
+ tf = SkCreateTypefaceFromLOGFONT(lf);
#endif
}
- if (NULL == tf) {
- tf = CreateTypeface_(get_default_font());
+ if (NULL == tf) {
+ tf = SkCreateTypefaceFromLOGFONT(get_default_font());
}
return tf;
}