aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-11-02 18:16:22 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-11-02 18:16:22 +0000
commitc8e51782f89ba79497578c1f683b7eb471c34bc0 (patch)
treeecdfbbd957509e31c8b1313fc6b73d301865630d
parent66e6cdb5ebbab9f3a695adc963f16b9c8b165afe (diff)
fix font id calculation
M src/ports/SkFontHost_mac_coretext.cpp git-svn-id: http://skia.googlecode.com/svn/trunk@2583 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/ports/SkFontHost_mac_coretext.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index f21ff57470..9fb46180e4 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -171,13 +171,40 @@ static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isMonospace) {
return (SkTypeface::Style)style;
}
+class AutoCFDataRelease {
+public:
+ AutoCFDataRelease(CFDataRef obj) : fObj(obj) {}
+ const uint16_t* getShortPtr() {
+ return fObj ? (const uint16_t*) CFDataGetBytePtr(fObj) : NULL;
+ }
+ ~AutoCFDataRelease() { CFRelease(fObj); }
+private:
+ CFDataRef fObj;
+};
+
static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) {
ATSFontRef ats = CTFontGetPlatformFont(fontRef, NULL);
+ SkFontID id = (SkFontID)ats;
+ if (id != 0) {
+ id &= 0x3FFFFFFF; // make top two bits 00
+ return id;
+ }
// CTFontGetPlatformFont returns NULL if the font is local
// (e.g., was created by a CSS3 @font-face rule).
- // FIXME: This may fail if fontRef is reused, or if the 64 bit pointer
- // duplicates the lowest 32 bits.
- return ats ? (SkFontID)ats : (SkFontID)fontRef;
+ CGFontRef cgFont = CTFontCopyGraphicsFont(fontRef, NULL);
+ AutoCFDataRelease headRef(CGFontCopyTableForTag(cgFont, 'head'));
+ const uint16_t* headData = headRef.getShortPtr();
+ if (headData) {
+ id = (SkFontID) (headData[4] | headData[5] << 16); // checksum
+ id = id & 0x3FFFFFFF | 0x40000000; // make top two bits 01
+ }
+ // well-formed fonts have checksums, but as a last resort, use the pointer.
+ if (id == 0) {
+ id = (SkFontID) (uintptr_t) fontRef;
+ id = id & 0x3FFFFFFF | 0x80000000; // make top two bits 10
+ }
+ CGFontRelease(cgFont);
+ return id;
}
class SkTypeface_Mac : public SkTypeface {
@@ -366,17 +393,6 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
///////////////////////////////////////////////////////////////////////////////
-class AutoCFDataRelease {
-public:
- AutoCFDataRelease(CFDataRef obj) : fObj(obj) {}
- const uint16_t* getShortPtr() {
- return fObj ? (const uint16_t*) CFDataGetBytePtr(fObj) : NULL;
- }
- ~AutoCFDataRelease() { CFRelease(fObj); }
-private:
- CFDataRef fObj;
-};
-
struct GlyphRect {
int16_t mMinX;
int16_t mMinY;