aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-11 12:11:56 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-11 12:11:56 -0700
commit5956d1c224aadf1d2712b46b32d3fc69a19915bd (patch)
tree5ab68a461e0f60a8c80b2f9f4cc1798271849283
parent4b86a58dcecc030f2220cb91f4744f8099e7dfe6 (diff)
downloadexternal_skia-5956d1c224aadf1d2712b46b32d3fc69a19915bd.zip
external_skia-5956d1c224aadf1d2712b46b32d3fc69a19915bd.tar.gz
external_skia-5956d1c224aadf1d2712b46b32d3fc69a19915bd.tar.bz2
auto import from //branches/cupcake/...@137873
-rw-r--r--include/core/SkGraphics.h2
-rw-r--r--include/core/SkPathMeasure.h1
-rw-r--r--include/core/SkStream.h4
-rw-r--r--include/core/SkTSearch.h2
-rw-r--r--include/core/SkTypeface.h6
-rw-r--r--samplecode/SampleApp.cpp2
-rw-r--r--src/core/SkGraphics.cpp29
-rw-r--r--src/core/SkPathMeasure.cpp37
-rw-r--r--src/core/SkStream.cpp118
-rw-r--r--src/core/SkTSearch.cpp32
-rw-r--r--src/core/SkTypeface.cpp24
-rw-r--r--src/ports/SkFontHost_FONTPATH.cpp324
-rw-r--r--src/ports/SkFontHost_ascender.cpp211
-rw-r--r--src/ports/SkFontHost_linux.cpp594
-rwxr-xr-xsrc/ports/SkFontHost_mac.cpp572
-rw-r--r--src/ports/SkFontHost_none.cpp86
-rw-r--r--src/ports/SkFontHost_win.cpp602
-rw-r--r--src/ports/SkImageDecoder_CG.cpp192
18 files changed, 10 insertions, 2828 deletions
diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h
index cb06128..1862a2b 100644
--- a/include/core/SkGraphics.h
+++ b/include/core/SkGraphics.h
@@ -21,7 +21,7 @@
class SkGraphics {
public:
- static void Init(bool runUnitTests);
+ static void Init();
static void Term();
/** Return the (approximate) number of bytes used by the font cache.
diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h
index 5ab97ca..2d94ae2 100644
--- a/include/core/SkPathMeasure.h
+++ b/include/core/SkPathMeasure.h
@@ -80,7 +80,6 @@ public:
#ifdef SK_DEBUG
void dump();
- static void UnitTest();
#endif
private:
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index 26ef43f..3a82991 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -68,8 +68,6 @@ public:
bool readBool() { return this->readU8() != 0; }
SkScalar readScalar();
size_t readPackedUInt();
-
- static void UnitTest();
};
class SkWStream : SkNoncopyable {
@@ -101,8 +99,6 @@ public:
bool writePackedUInt(size_t);
bool writeStream(SkStream* input, size_t length);
-
- static void UnitTest();
};
////////////////////////////////////////////////////////////////////////////////////////
diff --git a/include/core/SkTSearch.h b/include/core/SkTSearch.h
index f29e6f5..e208071 100644
--- a/include/core/SkTSearch.h
+++ b/include/core/SkTSearch.h
@@ -161,7 +161,5 @@ extern "C" {
void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
}
-SkDEBUGCODE(void SkQSort_UnitTest();)
-
#endif
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index ed45c03..bf783a3 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -110,7 +110,7 @@ public:
typeface referencing the same font when Deserialize is called.
*/
void serialize(SkWStream*) const;
-
+
/** Given the data previously written by serialize(), return a new instance
to a typeface referring to the same font. If that font is not available,
return null. If an instance is returned, the caller is responsible for
@@ -121,8 +121,8 @@ public:
protected:
/** uniqueID must be unique (please!) and non-zero
*/
- SkTypeface(Style style, uint32_t uniqueID);
- virtual ~SkTypeface();
+ SkTypeface(Style style, uint32_t uniqueID)
+ : fUniqueID(uniqueID), fStyle(style) {}
private:
uint32_t fUniqueID;
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 0d2bbbc..3a81902 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -597,7 +597,7 @@ void get_preferred_size(int* x, int* y, int* width, int* height) {
void application_init() {
// setenv("ANDROID_ROOT", "../../../data", 0);
setenv("ANDROID_ROOT", "/android/device/data", 0);
- SkGraphics::Init(true);
+ SkGraphics::Init();
SkEvent::Init();
}
diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp
index ff41f0c..7e72c3f 100644
--- a/src/core/SkGraphics.cpp
+++ b/src/core/SkGraphics.cpp
@@ -27,7 +27,6 @@
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkPathEffect.h"
-#include "SkPathMeasure.h"
#include "SkRandom.h"
#include "SkRefCnt.h"
#include "SkScalerContext.h"
@@ -78,7 +77,6 @@ static void test_sort()
#define SPEED_TESTx
#define typesizeline(type) { #type , sizeof(type) }
-#define unittestline(type) { #type , type::UnitTest }
#ifdef BUILD_EMBOSS_TABLE
@@ -271,7 +269,7 @@ static float time_intToFloat() {
#endif
#endif
-void SkGraphics::Init(bool runUnitTests)
+void SkGraphics::Init()
{
SkGlobals::Init();
@@ -287,9 +285,7 @@ void SkGraphics::Init(bool runUnitTests)
SkRadialGradient_BuildTable();
#endif
-#ifdef SK_SUPPORT_UNITTEST
- if (runUnitTests == false)
- return;
+#ifdef SK_DEBUGx
int i;
static const struct {
@@ -337,25 +333,10 @@ void SkGraphics::Init(bool runUnitTests)
else
SkDebugf("SkGraphics: char is unsigned\n");
}
- for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++)
- SkDebugf("SkGraphics: sizeof(%s) = %d\n", gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf);
-
- static const struct {
- const char* fTypeName;
- void (*fUnitTest)();
- } gUnitTests[] = {
- unittestline(SkPathMeasure),
- unittestline(SkStream),
- unittestline(SkWStream),
- };
-
- for (i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++)
- {
- SkDebugf("SkGraphics: Running UnitTest for %s\n", gUnitTests[i].fTypeName);
- gUnitTests[i].fUnitTest();
- SkDebugf("SkGraphics: End UnitTest for %s\n", gUnitTests[i].fTypeName);
+ for (i = 0; i < (int)SK_ARRAY_COUNT(gTypeSize); i++) {
+ SkDebugf("SkGraphics: sizeof(%s) = %d\n",
+ gTypeSize[i].fTypeName, gTypeSize[i].fSizeOf);
}
- SkQSort_UnitTest();
#endif
diff --git a/src/core/SkPathMeasure.cpp b/src/core/SkPathMeasure.cpp
index ec1510d..99bdece 100644
--- a/src/core/SkPathMeasure.cpp
+++ b/src/core/SkPathMeasure.cpp
@@ -558,41 +558,4 @@ void SkPathMeasure::dump() {
}
}
-void SkPathMeasure::UnitTest() {
-#ifdef SK_SUPPORT_UNITTEST
- SkPath path;
-
- path.moveTo(0, 0);
- path.lineTo(SK_Scalar1, 0);
- path.lineTo(SK_Scalar1, SK_Scalar1);
- path.lineTo(0, SK_Scalar1);
-
- SkPathMeasure meas(path, true);
- SkScalar length = meas.getLength();
- SkASSERT(length == SK_Scalar1*4);
-
- path.reset();
- path.moveTo(0, 0);
- path.lineTo(SK_Scalar1*3, SK_Scalar1*4);
- meas.setPath(&path, false);
- length = meas.getLength();
- SkASSERT(length == SK_Scalar1*5);
-
- path.reset();
- path.addCircle(0, 0, SK_Scalar1);
- meas.setPath(&path, true);
- length = meas.getLength();
- SkDebugf("circle arc-length = %g\n", length);
-
- for (int i = 0; i < 8; i++) {
- SkScalar d = length * i / 8;
- SkPoint p;
- SkVector v;
- meas.getPosTan(d, &p, &v);
- SkDebugf("circle arc-length=%g, pos[%g %g] tan[%g %g]\n",
- d, p.fX, p.fY, v.fX, v.fY);
- }
-#endif
-}
-
#endif
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index b199a1b..6571328 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -736,121 +736,3 @@ bool SkDebugWStream::write(const void* buffer, size_t size)
return true;
}
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-
-#include "SkRandom.h"
-
-#ifdef SK_SUPPORT_UNITTEST
-#define MAX_SIZE (256 * 1024)
-
-static void random_fill(SkRandom& rand, void* buffer, size_t size) {
- char* p = (char*)buffer;
- char* stop = p + size;
- while (p < stop) {
- *p++ = (char)(rand.nextU() >> 8);
- }
-}
-
-static void test_buffer() {
- SkRandom rand;
- SkAutoMalloc am(MAX_SIZE * 2);
- char* storage = (char*)am.get();
- char* storage2 = storage + MAX_SIZE;
-
- random_fill(rand, storage, MAX_SIZE);
-
- for (int sizeTimes = 0; sizeTimes < 100; sizeTimes++) {
- int size = rand.nextU() % MAX_SIZE;
- if (size == 0) {
- size = MAX_SIZE;
- }
- for (int times = 0; times < 100; times++) {
- int bufferSize = 1 + (rand.nextU() & 0xFFFF);
- SkMemoryStream mstream(storage, size);
- SkBufferStream bstream(&mstream, bufferSize);
-
- int bytesRead = 0;
- while (bytesRead < size) {
- int s = 17 + (rand.nextU() & 0xFFFF);
- int ss = bstream.read(storage2, s);
- SkASSERT(ss > 0 && ss <= s);
- SkASSERT(bytesRead + ss <= size);
- SkASSERT(memcmp(storage + bytesRead, storage2, ss) == 0);
- bytesRead += ss;
- }
- SkASSERT(bytesRead == size);
- }
- }
-}
-#endif
-
-void SkStream::UnitTest() {
-#ifdef SK_SUPPORT_UNITTEST
- {
- static const char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- char copy[sizeof(s)];
- SkRandom rand;
-
- for (int i = 0; i < 65; i++)
- {
- char* copyPtr = copy;
- SkMemoryStream mem(s, sizeof(s));
- SkBufferStream buff(&mem, i);
-
- do {
- copyPtr += buff.read(copyPtr, rand.nextU() & 15);
- } while (copyPtr < copy + sizeof(s));
- SkASSERT(copyPtr == copy + sizeof(s));
- SkASSERT(memcmp(s, copy, sizeof(s)) == 0);
- }
- }
- test_buffer();
-#endif
-}
-
-void SkWStream::UnitTest()
-{
-#ifdef SK_SUPPORT_UNITTEST
- {
- SkDebugWStream s;
-
- s.writeText("testing wstream helpers\n");
- s.writeText("compare: 0 "); s.writeDecAsText(0); s.newline();
- s.writeText("compare: 591 "); s.writeDecAsText(591); s.newline();
- s.writeText("compare: -9125 "); s.writeDecAsText(-9125); s.newline();
- s.writeText("compare: 0 "); s.writeHexAsText(0, 0); s.newline();
- s.writeText("compare: 03FA "); s.writeHexAsText(0x3FA, 4); s.newline();
- s.writeText("compare: DEADBEEF "); s.writeHexAsText(0xDEADBEEF, 4); s.newline();
- s.writeText("compare: 0 "); s.writeScalarAsText(SkIntToScalar(0)); s.newline();
- s.writeText("compare: 27 "); s.writeScalarAsText(SkIntToScalar(27)); s.newline();
- s.writeText("compare: -119 "); s.writeScalarAsText(SkIntToScalar(-119)); s.newline();
- s.writeText("compare: 851.3333 "); s.writeScalarAsText(SkIntToScalar(851) + SK_Scalar1/3); s.newline();
- s.writeText("compare: -0.08 "); s.writeScalarAsText(-SK_Scalar1*8/100); s.newline();
- }
-
- {
- SkDynamicMemoryWStream ds;
- const char s[] = "abcdefghijklmnopqrstuvwxyz";
- int i;
- for (i = 0; i < 100; i++) {
- bool result = ds.write(s, 26);
- SkASSERT(result);
- }
- SkASSERT(ds.getOffset() == 100 * 26);
- char* dst = new char[100 * 26 + 1];
- dst[100*26] = '*';
- ds.copyTo(dst);
- SkASSERT(dst[100*26] == '*');
- // char* p = dst;
- for (i = 0; i < 100; i++)
- SkASSERT(memcmp(&dst[i * 26], s, 26) == 0);
- SkASSERT(memcmp(dst, ds.getStream(), 100*26) == 0);
- delete[] dst;
- }
-#endif
-}
-
-#endif
diff --git a/src/core/SkTSearch.cpp b/src/core/SkTSearch.cpp
index bab348f..6d9ff81 100644
--- a/src/core/SkTSearch.cpp
+++ b/src/core/SkTSearch.cpp
@@ -185,35 +185,3 @@ void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc compa
SkQSort_Partition((char*)base, (char*)base + (count - 1) * elemSize, elemSize, compare);
}
-#ifdef SK_DEBUG
-
-#include "SkRandom.h"
-
-#ifdef SK_SUPPORT_UNITTEST
-extern "C" {
- int compare_int(const void* a, const void* b)
- {
- return *(const int*)a - *(const int*)b;
- }
-}
-#endif
-
-void SkQSort_UnitTest()
-{
-#ifdef SK_SUPPORT_UNITTEST
- int array[100];
- SkRandom rand;
-
- for (int i = 0; i < 1000; i++)
- {
- int j, count = rand.nextRangeU(1, SK_ARRAY_COUNT(array));
- for (j = 0; j < count; j++)
- array[j] = rand.nextS() & 0xFF;
- SkQSort(array, count, sizeof(int), compare_int);
- for (j = 1; j < count; j++)
- SkASSERT(array[j-1] <= array[j]);
- }
-#endif
-}
-
-#endif
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index b87db6b..65052c1 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -1,30 +1,6 @@
#include "SkTypeface.h"
#include "SkFontHost.h"
-//#define TRACK_TYPEFACE_ALLOCS
-
-#ifdef TRACK_TYPEFACE_ALLOCS
- static int32_t gTypefaceAllocCount;
-#endif
-
-SkTypeface::SkTypeface(Style style, uint32_t uniqueID)
- : fUniqueID(uniqueID), fStyle(style) {
-#ifdef TRACK_TYPEFACE_ALLOCS
- sk_atomic_inc(&gTypefaceAllocCount);
- SkDebugf("+++ [%d] typeface %p [style=%d uniqueID=%d]\n",
- gTypefaceAllocCount, this, style, uniqueID);
-#endif
-}
-
-SkTypeface::~SkTypeface() {
-#ifdef TRACK_TYPEFACE_ALLOCS
- SkDebugf("--- [%d] typeface %p\n", gTypefaceAllocCount, this);
- sk_atomic_inc(&gTypefaceAllocCount);
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
if (face) {
return face->uniqueID();
diff --git a/src/ports/SkFontHost_FONTPATH.cpp b/src/ports/SkFontHost_FONTPATH.cpp
deleted file mode 100644
index ceab395..0000000
--- a/src/ports/SkFontHost_FONTPATH.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-/* libs/graphics/ports/SkFontHost_android.cpp
-**
-** 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
-**
-** 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
-** limitations under the License.
-*/
-
-#include "SkFontHost.h"
-#include "SkDescriptor.h"
-#include "SkString.h"
-#include "SkStream.h"
-#include <stdio.h>
-
-/* define this if we can use mmap() to access fonts from the filesystem */
-#define SK_CAN_USE_MMAP
-
-#ifndef SK_FONTPATH
- #define SK_FONTPATH "the complete path for a font file"
-#endif
-
-struct FontFaceRec {
- const char* fFileName;
- uint8_t fFamilyIndex;
- SkBool8 fBold;
- SkBool8 fItalic;
-
- static const FontFaceRec& FindFace(const FontFaceRec rec[], int count,
- int isBold, int isItalic);
-};
-
-struct FontFamilyRec {
- const FontFaceRec* fFaces;
- int fFaceCount;
-};
-
-const FontFaceRec& FontFaceRec::FindFace(const FontFaceRec rec[], int count,
- int isBold, int isItalic)
-{
- SkASSERT(count > 0);
-
- int i;
-
- // look for an exact match
- for (i = 0; i < count; i++) {
- if (rec[i].fBold == isBold && rec[i].fItalic == isItalic)
- return rec[i];
- }
- // look for a match in the bold field
- for (i = 0; i < count; i++) {
- if (rec[i].fBold == isBold)
- return rec[i];
- }
- // look for a normal/regular face
- for (i = 0; i < count; i++) {
- if (!rec[i].fBold && !rec[i].fItalic)
- return rec[i];
- }
- // give up
- return rec[0];
-}
-
-enum {
- DEFAULT_FAMILY_INDEX,
-
- FAMILY_INDEX_COUNT
-};
-
-static const FontFaceRec gDefaultFaces[] = {
- { SK_FONTPATH, DEFAULT_FAMILY_INDEX, 0, 0 }
-};
-
-// This table must be in the same order as the ..._FAMILY_INDEX enum specifies
-static const FontFamilyRec gFamilies[] = {
- { gDefaultFaces, SK_ARRAY_COUNT(gDefaultFaces) }
-};
-
-#define DEFAULT_FAMILY_INDEX DEFAULT_FAMILY_INDEX
-#define DEFAULT_FAMILY_FACE_INDEX 0
-
-///////////////////////////////////////////////////////////////////////////////
-
-/* map common "web" font names to our font list */
-
-struct FontFamilyMatchRec {
- const char* fLCName;
- int fFamilyIndex;
-};
-
-/* This is a table of synonyms for collapsing font names
- down to their pseudo-equivalents (i.e. in terms of fonts
- we actually have.)
- Keep this sorted by the first field so we can do a binary search.
- If this gets big, we could switch to a hash...
-*/
-static const FontFamilyMatchRec gMatches[] = {
-#if 0
- { "Ahem", Ahem_FAMILY_INDEX },
- { "arial", SANS_FAMILY_INDEX },
- { "courier", MONO_FAMILY_INDEX },
- { "courier new", MONO_FAMILY_INDEX },
- { "cursive", SERIF_FAMILY_INDEX },
- { "fantasy", SERIF_FAMILY_INDEX },
- { "georgia", SERIF_FAMILY_INDEX },
- { "goudy", SERIF_FAMILY_INDEX },
- { "helvetica", SANS_FAMILY_INDEX },
- { "palatino", SERIF_FAMILY_INDEX },
- { "tahoma", SANS_FAMILY_INDEX },
- { "sans-serif", SANS_FAMILY_INDEX },
- { "serif", SERIF_FAMILY_INDEX },
- { "times", SERIF_FAMILY_INDEX },
- { "times new roman", SERIF_FAMILY_INDEX },
- { "verdana", SANS_FAMILY_INDEX }
-#endif
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkTSearch.h"
-
-static bool contains_only_ascii(const char s[])
-{
- for (;;)
- {
- int c = *s++;
- if (c == 0)
- break;
- if ((c >> 7) != 0)
- return false;
- }
- return true;
-}
-
-#define TRACE_FONT_NAME(code)
-//#define TRACE_FONT_NAME(code) code
-
-const FontFamilyRec* find_family_rec(const char target[])
-{
- int index;
-
- // If we're asked for a font name that contains non-ascii,
- // 1) SkStrLCSearch can't handle it
- // 2) All of our fonts are have ascii names, so...
-
-TRACE_FONT_NAME(printf("----------------- font request <%s>", target);)
-
- if (contains_only_ascii(target))
- {
- // Search for the font by matching the entire name
- index = SkStrLCSearch(&gMatches[0].fLCName, SK_ARRAY_COUNT(gMatches),
- target, sizeof(gMatches[0]));
- if (index >= 0)
- {
- TRACE_FONT_NAME(printf(" found %d\n", index);)
- return &gFamilies[gMatches[index].fFamilyIndex];
- }
- }
-
- // Sniff for key words...
-
-#if 0
- if (strstr(target, "sans") || strstr(target, "Sans"))
- {
- TRACE_FONT_NAME(printf(" found sans\n");)
- return &gFamilies[SANS_FAMILY_INDEX];
- }
- if (strstr(target, "serif") || strstr(target, "Serif"))
- {
- TRACE_FONT_NAME(printf(" found serif\n");)
- return &gFamilies[SERIF_FAMILY_INDEX];
- }
- if (strstr(target, "mono") || strstr(target, "Mono"))
- {
- TRACE_FONT_NAME(printf(" found mono\n");)
- return &gFamilies[MONO_FAMILY_INDEX];
- }
-#endif
-
- TRACE_FONT_NAME(printf(" use default\n");)
- // we give up, just give them the default font
- return &gFamilies[DEFAULT_FAMILY_INDEX];
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static const FontFaceRec* get_default_face()
-{
- return &gFamilies[DEFAULT_FAMILY_INDEX].fFaces[DEFAULT_FAMILY_FACE_INDEX];
-}
-
-static SkTypeface::Style get_style(const FontFaceRec& face) {
- int style = 0;
- if (face.fBold) {
- style |= SkTypeface::kBold;
- }
- if (face.fItalic) {
- style |= SkTypeface::kItalic;
- }
- return static_cast<SkTypeface::Style>(style);
-}
-
-// This global const reference completely identifies the face
-static uint32_t get_id(const FontFaceRec& face) {
- uintptr_t id = reinterpret_cast<uintptr_t>(&face);
- return static_cast<uint32_t>(id);
-}
-
-class FontFaceRec_Typeface : public SkTypeface {
-public:
- FontFaceRec_Typeface(const FontFaceRec& face) :
- SkTypeface(get_style(face), get_id(face)),
- fFace(face)
- {
- }
-
- // This global const reference completely identifies the face
- const FontFaceRec& fFace;
-};
-
-static const FontFaceRec* get_typeface_rec(const SkTypeface* face)
-{
- const FontFaceRec_Typeface* f = (FontFaceRec_Typeface*)face;
- return f ? &f->fFace : get_default_face();
-}
-
-static uint32_t ptr2uint32(const void* p)
-{
- // cast so we avoid warnings on 64bit machines that a ptr difference
- // which might be 64bits is being trucated from 64 to 32
- return (uint32_t)((char*)p - (char*)0);
-}
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[],
- SkTypeface::Style style)
-{
- const FontFamilyRec* family;
-
- if (familyFace)
- family = &gFamilies[
- ((FontFaceRec_Typeface*)familyFace)->fFace.fFamilyIndex];
- else if (familyName)
- family = find_family_rec(familyName);
- else
- family = &gFamilies[DEFAULT_FAMILY_INDEX];
-
- const FontFaceRec& face = FontFaceRec::FindFace(family->fFaces,
- family->fFaceCount,
- (style & SkTypeface::kBold) != 0,
- (style & SkTypeface::kItalic) != 0);
-
- // if we're returning our input parameter, no need to create a new instance
- if (familyFace != NULL &&
- &((FontFaceRec_Typeface*)familyFace)->fFace == &face)
- {
- familyFace->ref();
- return (SkTypeface*)familyFace;
- }
- return SkNEW_ARGS(FontFaceRec_Typeface, (face));
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
- sk_throw(); // not implemented
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
- sk_throw(); // not implemented
- return NULL;
-}
-
-bool SkFontHost::ValidFontID(uint32_t fontID) {
- return get_id(*get_default_face()) == fontID;
-}
-
-SkStream* SkFontHost::OpenStream(uint32_t fontID) {
- sk_throw(); // not implemented
- return NULL;
-}
-
-void SkFontHost::Serialize(const SkTypeface* tface, SkWStream* stream) {
- const FontFaceRec* face = &((const FontFaceRec_Typeface*)tface)->fFace;
- stream->write(face, sizeof(face));
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
- const FontFaceRec* face;
- stream->read(&face, sizeof(face));
- return new FontFaceRec_Typeface(*face);
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(
- const SkScalerContext::Rec& rec)
-{
- const FontFaceRec* face = get_default_face();
-
- SkAutoDescriptor ad(sizeof(rec) + sizeof(face) +
- SkDescriptor::ComputeOverhead(2));
- SkDescriptor* desc = ad.getDesc();
- SkScalerContext::Rec* newRec;
-
- desc->init();
- newRec = reinterpret_cast<SkScalerContext::Rec*>(
- desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec));
- newRec->fFontID = get_id(*face);
- desc->computeChecksum();
-
- return SkFontHost::CreateScalerContext(desc);
-}
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar)
-{
- return 0; // nothing to do (change me if you want to limit the font cache)
-}
-
diff --git a/src/ports/SkFontHost_ascender.cpp b/src/ports/SkFontHost_ascender.cpp
deleted file mode 100644
index 2148850..0000000
--- a/src/ports/SkFontHost_ascender.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-#include "SkScalerContext.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkDescriptor.h"
-#include "SkFDot6.h"
-#include "SkFontHost.h"
-#include "SkMask.h"
-#include "SkStream.h"
-#include "SkString.h"
-#include "SkThread.h"
-#include "SkTemplates.h"
-
-#include <acaapi.h>
-
-//////////////////////////////////////////////////////////////////////////
-
-#include "SkMMapStream.h"
-
-class SkScalerContext_Ascender : public SkScalerContext {
-public:
- SkScalerContext_Ascender(const SkDescriptor* desc);
- virtual ~SkScalerContext_Ascender();
-
-protected:
- virtual unsigned generateGlyphCount() const;
- virtual uint16_t generateCharToGlyph(SkUnichar uni);
- virtual void generateMetrics(SkGlyph* glyph);
- virtual void generateImage(const SkGlyph& glyph);
- virtual void generatePath(const SkGlyph& glyph, SkPath* path);
- virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my);
-
-private:
- aca_FontHandle fHandle;
- void* fWorkspace;
- void* fGlyphWorkspace;
- SkStream* fFontStream;
- SkStream* fHintStream;
-};
-
-///////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////
-
-SkScalerContext_Ascender::SkScalerContext_Ascender(const SkDescriptor* desc)
- : SkScalerContext(desc)
-{
- int size = aca_Get_FontHandleRec_Size();
- fHandle = (aca_FontHandle)sk_malloc_throw(size);
-
- // get the pointer to the font
-
- fFontStream = new SkMMAPStream("/UcsGB2312-Hei-H.FDL");
- fHintStream = new SkMMAPStream("/genv6-23.bin");
-
- void* hints = sk_malloc_throw(fHintStream->getLength());
- memcpy(hints, fHintStream->getMemoryBase(), fHintStream->getLength());
-
- aca_Create_Font_Handle(fHandle,
- (void*)fFontStream->getMemoryBase(), fFontStream->getLength(),
- "fred",
- hints, fHintStream->getLength());
-
- // compute our factors from the record
-
- SkMatrix m;
-
- fRec.getSingleMatrix(&m);
-
- // now compute our scale factors
- SkScalar sx = m.getScaleX();
- SkScalar sy = m.getScaleY();
-
- int ppemX = SkScalarRound(sx);
- int ppemY = SkScalarRound(sy);
-
- size = aca_Find_Font_Memory_Required(fHandle, ppemX, ppemY);
- size *= 8; // Jeff suggests this :)
- fWorkspace = sk_malloc_throw(size);
- aca_Set_Font_Memory(fHandle, (uint8_t*)fWorkspace, size);
-
- aca_GlyphAttribsRec rec;
-
- memset(&rec, 0, sizeof(rec));
- rec.xSize = ppemX;
- rec.ySize = ppemY;
- rec.doAdjust = true;
- rec.doExceptions = true;
- rec.doGlyphHints = true;
- rec.doInterpolate = true;
- rec.grayMode = 2;
- aca_Set_Font_Attributes(fHandle, &rec, &size);
-
- fGlyphWorkspace = sk_malloc_throw(size);
- aca_Set_Glyph_Memory(fHandle, fGlyphWorkspace);
-}
-
-SkScalerContext_Ascender::~SkScalerContext_Ascender()
-{
- delete fHintStream;
- delete fFontStream;
- sk_free(fGlyphWorkspace);
- sk_free(fWorkspace);
- sk_free(fHandle);
-}
-
-unsigned SkScalerContext_Ascender::generateGlyphCount() const
-{
- return 1000;
-}
-
-uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni)
-{
- return (uint16_t)(uni & 0xFFFF);
-}
-
-void SkScalerContext_Ascender::generateMetrics(SkGlyph* glyph)
-{
- glyph->fRsbDelta = 0;
- glyph->fLsbDelta = 0;
-
- aca_GlyphImageRec rec;
- aca_Vector topLeft;
-
- int adv = aca_Get_Adv_Width(fHandle, glyph->getGlyphID());
- if (aca_GLYPH_NOT_PRESENT == adv)
- goto ERROR;
-
- aca_Rasterize(glyph->getGlyphID(), fHandle, &rec, &topLeft);
-
- if (false) // error
- {
-ERROR:
- glyph->fWidth = 0;
- glyph->fHeight = 0;
- glyph->fTop = 0;
- glyph->fLeft = 0;
- glyph->fAdvanceX = 0;
- glyph->fAdvanceY = 0;
- return;
- }
-
- glyph->fWidth = rec.width;
- glyph->fHeight = rec.rows;
- glyph->fRowBytes = rec.width;
- glyph->fTop = -topLeft.y;
- glyph->fLeft = topLeft.x;
- glyph->fAdvanceX = SkIntToFixed(adv);
- glyph->fAdvanceY = SkIntToFixed(0);
-}
-
-void SkScalerContext_Ascender::generateImage(const SkGlyph& glyph)
-{
- aca_GlyphImageRec rec;
- aca_Vector topLeft;
-
- aca_Rasterize(glyph.getGlyphID(), fHandle, &rec, &topLeft);
-
- const uint8_t* src = (const uint8_t*)rec.buffer;
- uint8_t* dst = (uint8_t*)glyph.fImage;
- int height = glyph.fHeight;
-
- src += rec.y0 * rec.pitch + rec.x0;
- while (--height >= 0)
- {
- memcpy(dst, src, glyph.fWidth);
- src += rec.pitch;
- dst += glyph.fRowBytes;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-void SkScalerContext_Ascender::generatePath(const SkGlyph& glyph, SkPath* path)
-{
- SkRect r;
-
- r.set(0, 0, SkIntToScalar(4), SkIntToScalar(4));
- path->reset();
- path->addRect(r);
-}
-
-void SkScalerContext_Ascender::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my)
-{
- if (NULL == mx && NULL == my)
- return;
-
- if (mx)
- {
- mx->fTop = SkIntToScalar(-16);
- mx->fAscent = SkIntToScalar(-16);
- mx->fDescent = SkIntToScalar(4);
- mx->fBottom = SkIntToScalar(4);
- mx->fLeading = 0;
- }
- if (my)
- {
- my->fTop = SkIntToScalar(-16);
- my->fAscent = SkIntToScalar(-16);
- my->fDescent = SkIntToScalar(4);
- my->fBottom = SkIntToScalar(4);
- my->fLeading = 0;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
-{
- return SkNEW_ARGS(SkScalerContext_Ascender, (desc));
-}
-
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
deleted file mode 100644
index 0c69126..0000000
--- a/src/ports/SkFontHost_linux.cpp
+++ /dev/null
@@ -1,594 +0,0 @@
-/* libs/graphics/ports/SkFontHost_android.cpp
- **
- ** 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
- **
- ** 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
- ** limitations under the License.
- */
-
-#include "SkFontHost.h"
-#include "SkDescriptor.h"
-#include "SkMMapStream.h"
-#include "SkOSFile.h"
-#include "SkPaint.h"
-#include "SkString.h"
-#include "SkStream.h"
-#include "SkThread.h"
-#include "SkTSearch.h"
-#include <stdio.h>
-
-#define FONT_CACHE_MEMORY_BUDGET (1 * 1024 * 1024)
-
-#ifndef SK_FONT_FILE_PREFIX
- #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/msttcorefonts/"
-#endif
-
-SkTypeface::Style find_name_and_style(SkStream* stream, SkString* name);
-
-static void GetFullPathForSysFonts(SkString* full, const char name[])
-{
- full->append(SK_FONT_FILE_PREFIX);
- full->append(name);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-struct FamilyRec;
-
-/* This guy holds a mapping of a name -> family, used for looking up fonts.
- Since it is stored in a stretchy array that doesn't preserve object
- semantics, we don't use constructor/destructors, but just have explicit
- helpers to manage our internal bookkeeping.
- */
-struct NameFamilyPair {
- const char* fName; // we own this
- FamilyRec* fFamily; // we don't own this, we just reference it
-
- void construct(const char name[], FamilyRec* family)
- {
- fName = strdup(name);
- fFamily = family; // we don't own this, so just record the referene
- }
- void destruct()
- {
- free((char*)fName);
- // we don't own family, so just ignore our reference
- }
-};
-
-// we use atomic_inc to grow this for each typeface we create
-static int32_t gUniqueFontID;
-
-// this is the mutex that protects these globals
-static SkMutex gFamilyMutex;
-static FamilyRec* gFamilyHead;
-static SkTDArray<NameFamilyPair> gNameList;
-
-struct FamilyRec {
- FamilyRec* fNext;
- SkTypeface* fFaces[4];
-
- FamilyRec()
- {
- fNext = gFamilyHead;
- memset(fFaces, 0, sizeof(fFaces));
- gFamilyHead = this;
- }
-};
-
-static SkTypeface* find_best_face(const FamilyRec* family,
- SkTypeface::Style style) {
- SkTypeface* const* faces = family->fFaces;
-
- if (faces[style] != NULL) { // exact match
- return faces[style];
- }
- // look for a matching bold
- style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
- if (faces[style] != NULL) {
- return faces[style];
- }
- // look for the plain
- if (faces[SkTypeface::kNormal] != NULL) {
- return faces[SkTypeface::kNormal];
- }
- // look for anything
- for (int i = 0; i < 4; i++) {
- if (faces[i] != NULL) {
- return faces[i];
- }
- }
- // should never get here, since the faces list should not be empty
- SkASSERT(!"faces list is empty");
- return NULL;
-}
-
-static FamilyRec* find_family(const SkTypeface* member) {
- FamilyRec* curr = gFamilyHead;
- while (curr != NULL) {
- for (int i = 0; i < 4; i++) {
- if (curr->fFaces[i] == member) {
- return curr;
- }
- }
- curr = curr->fNext;
- }
- return NULL;
-}
-
-static bool valid_uniqueID(uint32_t uniqueID) {
- FamilyRec* curr = gFamilyHead;
- while (curr != NULL) {
- for (int i = 0; i < 4; i++) {
- SkTypeface* face = curr->fFaces[i];
- if (face != NULL && face->uniqueID() == uniqueID) {
- return true;
- }
- }
- curr = curr->fNext;
- }
- return false;
-}
-
-/* Remove reference to this face from its family. If the resulting family
- is empty (has no faces), return that family, otherwise return NULL
- */
-static FamilyRec* remove_from_family(const SkTypeface* face) {
- FamilyRec* family = find_family(face);
- SkASSERT(family->fFaces[face->style()] == face);
- family->fFaces[face->style()] = NULL;
-
- for (int i = 0; i < 4; i++) {
- if (family->fFaces[i] != NULL) { // family is non-empty
- return NULL;
- }
- }
- return family; // return the empty family
-}
-
-// maybe we should make FamilyRec be doubly-linked
-static void detach_and_delete_family(FamilyRec* family) {
- FamilyRec* curr = gFamilyHead;
- FamilyRec* prev = NULL;
-
- while (curr != NULL) {
- FamilyRec* next = curr->fNext;
- if (curr == family) {
- if (prev == NULL) {
- gFamilyHead = next;
- } else {
- prev->fNext = next;
- }
- SkDELETE(family);
- return;
- }
- prev = curr;
- curr = next;
- }
- SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
-}
-
-static FamilyRec* find_familyrec(const char name[]) {
- const NameFamilyPair* list = gNameList.begin();
- int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name,
- sizeof(list[0]));
- return index >= 0 ? list[index].fFamily : NULL;
-}
-
-static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
- FamilyRec* rec = find_familyrec(name);
- return rec ? find_best_face(rec, style) : NULL;
-}
-
-static SkTypeface* find_typeface(const SkTypeface* familyMember,
- SkTypeface::Style style) {
- const FamilyRec* family = find_family(familyMember);
- return family ? find_best_face(family, style) : NULL;
-}
-
-static void add_name(const char name[], FamilyRec* family) {
- SkAutoAsciiToLC tolc(name);
- name = tolc.lc();
-
- NameFamilyPair* list = gNameList.begin();
- int count = gNameList.count();
-
- int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
-
- if (index < 0) {
- list = gNameList.insert(~index);
- list->construct(name, family);
- }
-}
-
-static void remove_from_names(FamilyRec* emptyFamily) {
-#ifdef SK_DEBUG
- for (int i = 0; i < 4; i++) {
- SkASSERT(emptyFamily->fFaces[i] == NULL);
- }
-#endif
-
- SkTDArray<NameFamilyPair>& list = gNameList;
-
- // must go backwards when removing
- for (int i = list.count() - 1; i >= 0; --i) {
- NameFamilyPair* pair = &list[i];
- if (pair->fFamily == emptyFamily) {
- pair->destruct();
- list.remove(i);
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-class FamilyTypeface : public SkTypeface {
-public:
- FamilyTypeface(Style style, bool sysFont, FamilyRec* family)
- : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
- fIsSysFont = sysFont;
-
- SkAutoMutexAcquire ac(gFamilyMutex);
-
- if (NULL == family) {
- family = SkNEW(FamilyRec);
- }
- family->fFaces[style] = this;
- fFamilyRec = family; // just record it so we can return it if asked
- }
-
- virtual ~FamilyTypeface() {
- SkAutoMutexAcquire ac(gFamilyMutex);
-
- // remove us from our family. If the family is now empty, we return
- // that and then remove that family from the name list
- FamilyRec* family = remove_from_family(this);
- if (NULL != family) {
- remove_from_names(family);
- detach_and_delete_family(family);
- }
- }
-
- bool isSysFont() const { return fIsSysFont; }
- FamilyRec* getFamily() const { return fFamilyRec; }
-
- virtual SkStream* openStream() = 0;
- virtual void closeStream(SkStream*) = 0;
- virtual const char* getUniqueString() const = 0;
-
-private:
- FamilyRec* fFamilyRec; // we don't own this, just point to it
- bool fIsSysFont;
-
- typedef SkTypeface INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class StreamTypeface : public FamilyTypeface {
-public:
- StreamTypeface(Style style, bool sysFont, FamilyRec* family,
- SkStream* stream)
- : INHERITED(style, sysFont, family) {
- fStream = stream;
- }
- virtual ~StreamTypeface() {
- SkDELETE(fStream);
- }
-
- // overrides
- virtual SkStream* openStream() { return fStream; }
- virtual void closeStream(SkStream*) {}
- virtual const char* getUniqueString() const { return NULL; }
-
-private:
- SkStream* fStream;
-
- typedef FamilyTypeface INHERITED;
-};
-
-class FileTypeface : public FamilyTypeface {
-public:
- FileTypeface(Style style, bool sysFont, FamilyRec* family,
- const char path[])
- : INHERITED(style, sysFont, family) {
- fPath.set(path);
- }
-
- // overrides
- virtual SkStream* openStream()
- {
- SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
-
- // check for failure
- if (stream->getLength() <= 0) {
- SkDELETE(stream);
- // maybe MMAP isn't supported. try FILE
- stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
- if (stream->getLength() <= 0) {
- SkDELETE(stream);
- stream = NULL;
- }
- }
- return stream;
- }
- virtual void closeStream(SkStream* stream)
- {
- SkDELETE(stream);
- }
- virtual const char* getUniqueString() const {
- const char* str = strrchr(fPath.c_str(), '/');
- if (str) {
- str += 1; // skip the '/'
- }
- return str;
- }
-
-private:
- SkString fPath;
-
- typedef FamilyTypeface INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-static bool get_name_and_style(const char path[], SkString* name,
- SkTypeface::Style* style) {
- SkMMAPStream stream(path);
- if (stream.getLength() > 0) {
- *style = find_name_and_style(&stream, name);
- return true;
- }
- else {
- SkFILEStream stream(path);
- if (stream.getLength() > 0) {
- *style = find_name_and_style(&stream, name);
- return true;
- }
- }
-
- SkDebugf("---- failed to open <%s> as a font\n", path);
- return false;
-}
-
-// these globals are assigned (once) by load_system_fonts()
-static SkTypeface* gFallBackTypeface;
-static FamilyRec* gDefaultFamily;
-static SkTypeface* gDefaultNormal;
-
-static void load_system_fonts() {
- // check if we've already be called
- if (NULL != gDefaultNormal) {
- return;
- }
-
- SkOSFile::Iter iter(SK_FONT_FILE_PREFIX, ".ttf");
- SkString name;
-
- while (iter.next(&name, false)) {
- SkString filename;
- GetFullPathForSysFonts(&filename, name.c_str());
-// while (filename.size() == 0) { filename.set("/usr/share/fonts/truetype/msttcorefonts/Arial.ttf");
-
- SkString realname;
- SkTypeface::Style style;
-
- if (!get_name_and_style(filename.c_str(), &realname, &style)) {
- SkDebugf("------ can't load <%s> as a font\n", filename.c_str());
- continue;
- }
-
-// SkDebugf("font: <%s> %d <%s>\n", realname.c_str(), style, filename.c_str());
-
- FamilyRec* family = find_familyrec(realname.c_str());
- // this constructor puts us into the global gFamilyHead llist
- FamilyTypeface* tf = SkNEW_ARGS(FileTypeface,
- (style,
- true, // system-font (cannot delete)
- family, // what family to join
- filename.c_str()) // filename
- );
-
- if (NULL == family) {
- add_name(realname.c_str(), tf->getFamily());
- }
- }
-
- // do this after all fonts are loaded. This is our default font, and it
- // acts as a sentinel so we only execute load_system_fonts() once
- static const char* gDefaultNames[] = {
- "Arial", "Verdana", "Times New Roman", NULL
- };
- const char** names = gDefaultNames;
- while (*names) {
- SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal);
- if (tf) {
- gDefaultNormal = tf;
- break;
- }
- }
- // check if we found *something*
- if (NULL == gDefaultNormal) {
- if (NULL == gFamilyHead) {
- sk_throw();
- }
- for (int i = 0; i < 4; i++) {
- if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) {
- break;
- }
- }
- }
- if (NULL == gDefaultNormal) {
- sk_throw();
- }
- gFallBackTypeface = gDefaultNormal;
- gDefaultFamily = find_family(gDefaultNormal);
-
-// SkDebugf("---- default %p head %p family %p\n", gDefaultNormal, gFamilyHead, gDefaultFamily);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
-#if 0
- const char* name = ((FamilyTypeface*)face)->getUniqueString();
-
- stream->write8((uint8_t)face->getStyle());
-
- if (NULL == name || 0 == *name) {
- stream->writePackedUInt(0);
- // SkDebugf("--- fonthost serialize null\n");
- } else {
- uint32_t len = strlen(name);
- stream->writePackedUInt(len);
- stream->write(name, len);
- // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->getStyle());
- }
-#endif
- sk_throw();
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
-#if 0
- load_system_fonts();
-
- int style = stream->readU8();
-
- int len = stream->readPackedUInt();
- if (len > 0) {
- SkString str;
- str.resize(len);
- stream->read(str.writable_str(), len);
-
- const FontInitRec* rec = gSystemFonts;
- for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
- if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
- // backup until we hit the fNames
- for (int j = i; j >= 0; --j) {
- if (rec[j].fNames != NULL) {
- return SkFontHost::CreateTypeface(NULL, rec[j].fNames[0],
- (SkTypeface::Style)style);
- }
- }
- }
- }
- }
- return SkFontHost::CreateTypeface(NULL, NULL, (SkTypeface::Style)style);
-#endif
- sk_throw();
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[],
- SkTypeface::Style style) {
- load_system_fonts();
-
- SkAutoMutexAcquire ac(gFamilyMutex);
-
- // clip to legal style bits
- style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
- SkTypeface* tf = NULL;
-
- if (NULL != familyFace) {
- tf = find_typeface(familyFace, style);
- } else if (NULL != familyName) {
- // SkDebugf("======= familyName <%s>\n", familyName);
- tf = find_typeface(familyName, style);
- }
-
- if (NULL == tf) {
- tf = find_best_face(gDefaultFamily, style);
- }
-
- return tf;
-}
-
-SkTypeface* SkFontHost::ValidFontID(uint32_t fontID) {
- SkAutoMutexAcquire ac(gFamilyMutex);
-
- return valid_uniqueID(fontID);
-}
-
-SkStream* SkFontHost::OpenStream(uint32_t fontID) {
- FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID);
- SkStream* stream = tf ? tf->openStream() : NULL;
-
- if (NULL == stream || stream->getLength() == 0) {
- delete stream;
- stream = NULL;
- }
- return stream;
-}
-
-void SkFontHost::CloseStream(uint32_t fontID, SkStream* stream) {
- FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID);
- if (NULL != tf) {
- tf->closeStream(stream);
- }
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(
- const SkScalerContext::Rec& rec) {
- load_system_fonts();
-
- SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
- SkDescriptor* desc = ad.getDesc();
-
- desc->init();
- SkScalerContext::Rec* newRec =
- (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
- sizeof(rec), &rec);
- newRec->fFontID = gFallBackTypeface->uniqueID();
- desc->computeChecksum();
-
- return SkFontHost::CreateScalerContext(desc);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
- if (NULL == stream || stream->getLength() <= 0) {
- SkDELETE(stream);
- return NULL;
- }
-
- SkString name;
- SkTypeface::Style style = find_name_and_style(stream, &name);
-
- return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream));
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
- SkTypeface* face = NULL;
- SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
-
- if (stream->isValid()) {
- return CreateTypeface(stream);
- }
- stream->unref();
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
- if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
- return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
- else
- return 0; // nothing to do
-}
-
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
deleted file mode 100755
index f0e3a93..0000000
--- a/src/ports/SkFontHost_mac.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- ** 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
- **
- ** 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
- ** limitations under the License.
-*/
-
-#include <carbon/carbon.h>
-#include "SkFontHost.h"
-#include "SkDescriptor.h"
-#include "SkPoint.h"
-
-// Give 1MB font cache budget
-#define FONT_CACHE_MEMORY_BUDGET (1024 * 1024)
-
-const char* gDefaultfont = "Arial"; // hard code for now
-static SkMutex gFTMutex;
-
-static inline SkPoint F32PtToSkPoint(const Float32Point p) {
- SkPoint sp = { SkFloatToScalar(p.x), SkFloatToScalar(p.y) };
- return sp;
-}
-
-static inline uint32_t _rotl(uint32_t v, uint32_t r) {
- return (v << r | v >> (32 - r));
-}
-
-// This will generate a unique ID based on the fontname + fontstyle
-// and also used by upper layer
-uint32_t FontFaceChecksum(const char *name,SkTypeface::Style style)
-{
- if (!name) return style;
-
- char* q = (char*)name;
-
- // From "Performance in Practice of String Hashing Functions"
- // Ramakrishna & Zobel
- const uint32_t L = 5;
- const uint32_t R = 2;
-
- uint32_t h = 0x12345678;
- while (*q) {
- uint32_t ql = tolower(*q);
- h ^= ((h << L) + (h >> R) + ql);
- q ++;
- }
-
- // add style
- h = _rotl(h, 3) ^ style;
-
- return h;
-}
-
-#pragma mark -
-struct SkFaceRec {
- SkFaceRec* fNext;
- uint32_t fRefCnt;
- ATSUFontID fFontID;
- ATSUStyle fStyle;
-
- SkFaceRec() : fFontID(0), fRefCnt(0), fStyle(NULL) {};
-
- ~SkFaceRec() {
- if (fStyle) {
- ::ATSUDisposeStyle(fStyle);
- fStyle = NULL;
- }
- }
-
- uint32_t ref() {
- return ++fRefCnt;
- }
-};
-
-// Font Face list
-static SkFaceRec* gFaceRecHead = NULL;
-
-static SkFaceRec* find_ft_face(const ATSUFontID fontID) {
- SkFaceRec* rec = gFaceRecHead;
- while (rec) {
- if (rec->fFontID == fontID) {
- return rec;
- }
- rec = rec->fNext;
- }
-
- return NULL;
-}
-
-static SkFaceRec* insert_ft_face(const ATSUFontID afontID, const ATSUStyle atsuStyle) {
- SkFaceRec* rec = find_ft_face(afontID);
- if (rec) {
- return rec; // found?
- }
-
- rec = SkNEW(SkFaceRec);
- rec->fFontID = afontID;
- rec->fStyle = atsuStyle;
- rec->fNext = gFaceRecHead;
- gFaceRecHead = rec;
-
- return rec;
-}
-
-static void unref_ft_face(const ATSUFontID fontID) {
-
- SkFaceRec* rec = gFaceRecHead;
- SkFaceRec* prev = NULL;
- while (rec) {
- SkFaceRec* next = rec->fNext;
- if (rec->fFontID == fontID) {
- if (--rec->fRefCnt == 0) {
- if (prev)
- prev->fNext = next;
- else
- gFaceRecHead = next;
-
- SkDELETE(rec);
- }
- return;
- }
- prev = rec;
- rec = next;
- }
- SkASSERT("shouldn't get here, face not in list");
-}
-
-#pragma mark -
-
-// have to do this because SkTypeface::SkTypeface() is protected
-class SkTypeface_Mac : public SkTypeface {
-public:
- SkTypeface_Mac(SkTypeface::Style style, uint32_t id) : SkTypeface(style, id) {}
-
- ~SkTypeface_Mac() {}
-};
-
-#pragma mark -
-
-static SkTypeface* CreateTypeface_(const char *name, const SkTypeface::Style style) {
-
- OSStatus err;
- ATSUStyle atsuStyle;
- ::ATSUCreateStyle(&atsuStyle);
- if (name != NULL) {
- static const ATSUAttributeTag fontTag = kATSUFontTag;
- static const ByteCount fontTagSize = sizeof(ATSUFontID);
-
- ATSUFontID fontID = 0;
-#if 1
- err = ::ATSUFindFontFromName(
- name,strlen(name),kFontNoNameCode, /* instead of regular, kFontFamilyName returns bold and/or italic sometimes, but why this works?? */
- kFontMacintoshPlatform,kFontNoScriptCode,kFontNoLanguageCode,&fontID);
-#else
- CFStringRef cfontName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
- ATSFontRef fontRef = ::ATSFontFindFromName(cfontName,kATSOptionFlagsDefault);
- fontID = ::FMGetFontFromATSFontRef(fontRef);
- CFRelease(cfontName);
-#endif
- if (0 != fontID) {
- const ATSUAttributeValuePtr values[] = { &fontID };
- err = ::ATSUSetAttributes(atsuStyle,1,&fontTag,&fontTagSize,values);
- }
- else {
- }
- }
- if (style != SkTypeface::kNormal) {
- Boolean fontItalic = ((style & SkTypeface::kItalic) != 0);
- Boolean fontBold = ((style & SkTypeface::kBold) != 0);
- const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag };
- const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic };
- const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) };
- err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values);
- }
-
- uint32_t cs = FontFaceChecksum(name,style);
- SkTypeface_Mac* ptypeface = new SkTypeface_Mac(style,cs);
-
- if (NULL == ptypeface) {
- SkASSERT(false);
- return NULL;
- }
-
- SkFaceRec* rec = insert_ft_face(cs, atsuStyle);
- SkASSERT(rec);
-
- return ptypeface;
-}
-
-static SkTypeface* CreateTypeface_(const SkFaceRec* rec, const SkTypeface::Style style) {
-
- OSStatus err;
- ATSUStyle atsuStyle;
- err = ::ATSUCreateAndCopyStyle(rec->fStyle, &atsuStyle);
-
- Boolean fontItalic = ((style & SkTypeface::kItalic) != 0);
- Boolean fontBold = ((style & SkTypeface::kBold) != 0);
- const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag };
- const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic };
- const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) };
- err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values);
-
- // get old font id and name
- ATSUFontID fontID = 0;
- ByteCount actual = 0;
- err = ::ATSUGetAttribute(rec->fStyle,kATSUFontTag,sizeof(ATSUFontID),&fontID,&actual);
-
- ByteCount actualLength = 0;
- char *fontname = NULL;
- err = ::ATSUFindFontName(fontID , kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
- kFontNoLanguageCode , 0 , NULL , &actualLength , NULL );
- if ( err == noErr)
- {
- actualLength += 1 ;
- fontname = (char*)malloc( actualLength );
- err = ::ATSUFindFontName(fontID, kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
- kFontNoLanguageCode, actualLength, fontname , NULL, NULL);
- }
-
- SkTypeface_Mac* ptypeface = NULL;
- if (fontname == NULL) {
- ptypeface = new SkTypeface_Mac(style,rec->fFontID);
- return ptypeface;
- }
- else {
- uint32_t cs = FontFaceChecksum(fontname,style);
- ptypeface = new SkTypeface_Mac(style, cs);
-
- if (NULL == ptypeface) {
- SkASSERT(false);
- return NULL;
- }
-
- free(fontname);
-
- insert_ft_face(cs,atsuStyle);
- }
- return ptypeface;
-}
-
-#pragma mark -
-
-class SkScalerContext_Mac : public SkScalerContext {
-public:
- SkScalerContext_Mac(const SkDescriptor* desc);
- virtual ~SkScalerContext_Mac();
-
-protected:
- virtual unsigned generateGlyphCount() const;
- 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 NULL; } // not implemented on Mac
-
-private:
- ATSUTextLayout fLayout;
- ATSUStyle fStyle;
- CGColorSpaceRef fGrayColorSpace;
-
- static OSStatus MoveTo(const Float32Point *pt, void *cb);
- static OSStatus Line(const Float32Point *pt, void *cb);
- static OSStatus Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb);
- static OSStatus Close(void *cb);
-};
-
-SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc)
- : SkScalerContext(desc), fLayout(0), fStyle(0)
-{
- SkAutoMutexAcquire ac(gFTMutex);
- OSStatus err;
-
- SkFaceRec* rec = find_ft_face(fRec.fFontID);
- if (rec) {
- rec->ref();
- err = ::ATSUCreateAndCopyStyle(rec->fStyle, &fStyle);
- }
- else {
- SkASSERT(false);
- // create a default
- err = ::ATSUCreateStyle(&fStyle);
- }
-
- uint32_t size = SkScalarFloor(fRec.fTextSize);
- Fixed fixedSize = IntToFixed(size);
- static const ATSUAttributeTag sizeTag = kATSUSizeTag;
- static const ByteCount sizeTagSize = sizeof(Fixed);
- const ATSUAttributeValuePtr values[] = { &fixedSize };
- err = ::ATSUSetAttributes(fStyle,1,&sizeTag,&sizeTagSize,values);
-
- err = ::ATSUCreateTextLayout(&fLayout);
-
- fGrayColorSpace = ::CGColorSpaceCreateDeviceGray();
-}
-
-SkScalerContext_Mac::~SkScalerContext_Mac()
-{
- ::CGColorSpaceRelease(fGrayColorSpace);
-
- unref_ft_face(fRec.fFontID);
-
- ::ATSUDisposeTextLayout(fLayout);
- ::ATSUDisposeStyle(fStyle);
-}
-
-unsigned SkScalerContext_Mac::generateGlyphCount() const
-{
- return 0xFFFF;
-}
-
-uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni)
-{
- SkAutoMutexAcquire ac(gFTMutex);
-
- OSStatus err;
- UniChar achar = uni;
- err = ::ATSUSetTextPointerLocation(fLayout,&achar,0,1,1);
- err = ::ATSUSetRunStyle(fLayout,fStyle,kATSUFromTextBeginning,kATSUToTextEnd);
-
- ATSLayoutRecord *layoutPtr;
- ItemCount count;
- ATSGlyphRef glyph;
-
- err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(fLayout,0,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr,&count);
- glyph = layoutPtr->glyphID;
- ::ATSUDirectReleaseLayoutDataArrayPtr(NULL,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr);
- return glyph;
-}
-
-static void set_glyph_metrics_on_error(SkGlyph* glyph) {
- glyph->fRsbDelta = 0;
- glyph->fLsbDelta = 0;
- glyph->fWidth = 0;
- glyph->fHeight = 0;
- glyph->fTop = 0;
- glyph->fLeft = 0;
- glyph->fAdvanceX = 0;
- glyph->fAdvanceY = 0;
-}
-
-void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) {
- this->generateMetrics(glyph);
-}
-
-void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) {
- GlyphID glyphID = glyph->getGlyphID(fBaseGlyphCount);
- ATSGlyphScreenMetrics metrics;
-
- OSStatus err = ATSUGlyphGetScreenMetrics(fStyle, 1, &glyphID, 0, true, true,
- &metrics);
- if (noErr != err) {
- set_glyph_metrics_on_error(glyph);
- } else {
- glyph->fAdvanceX = SkFloatToFixed(metrics.deviceAdvance.x);
- glyph->fAdvanceY = -SkFloatToFixed(metrics.deviceAdvance.y);
- glyph->fWidth = metrics.width;
- glyph->fHeight = metrics.height;
- glyph->fLeft = sk_float_round2int(metrics.topLeft.x);
- glyph->fTop = -sk_float_round2int(metrics.topLeft.y);
- }
-}
-
-void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx,
- SkPaint::FontMetrics* my) {
-#if 0
- OSStatus ATSFontGetVerticalMetrics (
- ATSFontRef iFont,
- ATSOptionFlags iOptions,
- ATSFontMetrics *oMetrics
- );
-#endif
- //SkASSERT(false);
- if (mx)
- memset(mx, 0, sizeof(SkPaint::FontMetrics));
- if (my)
- memset(my, 0, sizeof(SkPaint::FontMetrics));
- return;
-}
-
-void SkScalerContext_Mac::generateImage(const SkGlyph& glyph)
-{
- SkAutoMutexAcquire ac(gFTMutex);
- SkASSERT(fLayout);
- OSStatus err;
-
- bzero(glyph.fImage, glyph.fHeight * glyph.rowBytes());
- CGContextRef contextRef = ::CGBitmapContextCreate(glyph.fImage,
- glyph.fWidth, glyph.fHeight, 8,
- glyph.rowBytes(), fGrayColorSpace,
- kCGImageAlphaNone);
- if (!contextRef) {
- SkASSERT(false);
- return;
- }
-
- ::CGContextSetGrayFillColor(contextRef, 1.0, 1.0);
- ::CGContextSetTextDrawingMode(contextRef, kCGTextFill);
-
- ATSUAttributeTag tag = kATSUCGContextTag;
- ByteCount size = sizeof(CGContextRef);
- ATSUAttributeValuePtr value = &contextRef;
- err = ::ATSUSetLayoutControls(fLayout, 1, &tag, &size, &value);
- SkASSERT(!err);
- err = ::ATSUDrawText(fLayout, kATSUFromTextBeginning, kATSUToTextEnd,
- SkIntToFixed(-glyph.fLeft),
- SkIntToFixed(glyph.fTop + glyph.fHeight));
- SkASSERT(!err);
- ::CGContextRelease(contextRef);
-}
-
-void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path)
-{
- SkAutoMutexAcquire ac(gFTMutex);
- OSStatus err,result;
-
- err = ::ATSUGlyphGetCubicPaths(
- fStyle,glyph.fID,
- &SkScalerContext_Mac::MoveTo,
- &SkScalerContext_Mac::Line,
- &SkScalerContext_Mac::Curve,
- &SkScalerContext_Mac::Close,
- path,&result);
- SkASSERT(err == noErr);
-}
-
-void SkScalerContext_Mac::generateLineHeight(SkPoint* ascent, SkPoint* descent)
-{
- ATSUTextMeasurement textAscent, textDescent;
- ByteCount actual = 0;
- OSStatus err = ::ATSUGetAttribute(fStyle,kATSULineAscentTag,sizeof(ATSUTextMeasurement),&textAscent,&actual);
- ascent->set(0,textAscent);
- err = ::ATSUGetAttribute(fStyle,kATSULineDescentTag,sizeof(ATSUTextMeasurement),&textDescent,&actual);
- descent->set(0,textDescent);
-}
-
-OSStatus SkScalerContext_Mac::MoveTo(const Float32Point *pt, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->moveTo(F32PtToSkPoint(*pt));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Line(const Float32Point *pt, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->lineTo(F32PtToSkPoint(*pt));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Curve(const Float32Point *pt1,
- const Float32Point *pt2,
- const Float32Point *pt3, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->cubicTo(F32PtToSkPoint(*pt1),
- F32PtToSkPoint(*pt2),
- F32PtToSkPoint(*pt3));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Close(void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->close();
- return noErr;
-}
-
-#pragma mark -
-
-void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
- SkASSERT(!"SkFontHost::Serialize unimplemented");
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
- SkASSERT(!"SkFontHost::Deserialize unimplemented");
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
-
- //Should not be used on Mac, keep linker happy
- SkASSERT(false);
- return CreateTypeface_(gDefaultfont,SkTypeface::kNormal);
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
- // TODO
- return CreateTypeface_(gDefaultfont,SkTypeface::kNormal);
-}
-
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
-{
- return new SkScalerContext_Mac(desc);
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(const SkScalerContext::Rec& rec)
-{
- SkAutoDescriptor ad(sizeof(rec) + sizeof(gDefaultfont) + SkDescriptor::ComputeOverhead(2));
- SkDescriptor* desc = ad.getDesc();
-
- desc->init();
- SkScalerContext::Rec* newRec =
- (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
- CreateTypeface_(gDefaultfont,SkTypeface::kNormal);
- newRec->fFontID = FontFaceChecksum(gDefaultfont,SkTypeface::kNormal);
- desc->computeChecksum();
-
- return SkFontHost::CreateScalerContext(desc);
-}
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[], SkTypeface::Style style) {
-
- SkAutoMutexAcquire ac(gFTMutex);
-
- // clip to legal style bits
- style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
- SkTypeface* tf = NULL;
-
- if (NULL == familyFace && NULL == familyName) {
- tf = CreateTypeface_(gDefaultfont,style);
- }
- else {
- if (NULL != familyFace) {
- uint32_t id = familyFace->uniqueID();
- SkFaceRec* rec = find_ft_face(id);
- if (!rec) {
- SkASSERT(false);
- tf = CreateTypeface_(gDefaultfont,style);
- }
- else {
- tf = CreateTypeface_(rec,style);
- }
- }
- else {
- tf = CreateTypeface_(familyName,style);
- }
- }
-
- if (NULL == tf) {
- tf = CreateTypeface_(gDefaultfont,style);
- }
- return tf;
-
-}
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
- if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
- return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
- else
- return 0; // nothing to do
-}
-
-int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
- return 0;
-}
-
-void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
- tables[0] = NULL; // black gamma (e.g. exp=1.4)
- tables[1] = NULL; // white gamma (e.g. exp= 1/1.4)
-}
-
diff --git a/src/ports/SkFontHost_none.cpp b/src/ports/SkFontHost_none.cpp
deleted file mode 100644
index 608ee29..0000000
--- a/src/ports/SkFontHost_none.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright 2006-2008, 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
-**
-** 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
-** limitations under the License.
-*/
-
-#include "SkFontHost.h"
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char famillyName[],
- SkTypeface::Style style) {
- SkASSERT(!"SkFontHost::FindTypeface unimplemented");
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*) {
- SkASSERT(!"SkFontHost::CreateTypeface unimplemented");
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
- SkASSERT(!"SkFontHost::CreateTypefaceFromFile unimplemented");
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-bool SkFontHost::ValidFontID(uint32_t uniqueID) {
- SkASSERT(!"SkFontHost::ResolveTypeface unimplemented");
- return false;
-}
-
-SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
- SkASSERT(!"SkFontHost::OpenStream unimplemented");
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
- SkASSERT(!"SkFontHost::Serialize unimplemented");
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
- SkASSERT(!"SkFontHost::Deserialize unimplemented");
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
- SkASSERT(!"SkFontHost::CreateScalarContext unimplemented");
- return NULL;
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(
- const SkScalerContext::Rec&) {
- SkASSERT(!"SkFontHost::CreateFallbackScalerContext unimplemented");
- return NULL;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
- return 0; // nothing to do (change me if you want to limit the font cache)
-}
-
-int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
- return 0;
-}
-
-void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
- tables[0] = NULL; // black gamma (e.g. exp=1.4)
- tables[1] = NULL; // white gamma (e.g. exp= 1/1.4)
-}
-
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
deleted file mode 100644
index 4cc04b5..0000000
--- a/src/ports/SkFontHost_win.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- ** 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
- **
- ** 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
- ** limitations under the License.
- */
-
-#include "SkString.h"
-//#include "SkStream.h"
-
-#include "SkFontHost.h"
-#include "SkDescriptor.h"
-#include "SkThread.h"
-
-#ifdef WIN32
-#include "windows.h"
-#include "tchar.h"
-
-// client3d has to undefine this for now
-#define CAN_USE_LOGFONT_NAME
-
-static SkMutex gFTMutex;
-
-// these globals are loaded (once) by get_default_font()
-static LOGFONT gDefaultFont = {0};
-
-static const uint16_t BUFFERSIZE = (16384 - 32);
-static uint8_t glyphbuf[BUFFERSIZE];
-
-// Give 1MB font cache budget
-#define FONT_CACHE_MEMORY_BUDGET (1024 * 1024)
-
-static inline FIXED SkFixedToFIXED(SkFixed x) {
- return *(FIXED*)(&x);
-}
-
-static inline FIXED SkScalarToFIXED(SkScalar x) {
- return SkFixedToFIXED(SkScalarToFixed(x));
-}
-
-// This will generate a unique ID based on the fontname + fontstyle
-// and also used by upper layer
-uint32_t FontFaceChecksum(const TCHAR *q, SkTypeface::Style style)
-{
- if (!q) return style;
-
- // From "Performance in Practice of String Hashing Functions"
- // Ramakrishna & Zobel
- const uint32_t L = 5;
- const uint32_t R = 2;
-
- uint32_t h = 0x12345678;
- while (*q) {
- //uint32_t ql = tolower(*q);
- h ^= ((h << L) + (h >> R) + *q);
- q ++;
- }
-
- // add style
- h = _rotl(h, 3) ^ style;
-
- return h;
-}
-
-static SkTypeface::Style GetFontStyle(const LOGFONT& lf) {
- int style = SkTypeface::kNormal;
- if (lf.lfWeight == FW_SEMIBOLD || lf.lfWeight == FW_DEMIBOLD || lf.lfWeight == FW_BOLD)
- style |= SkTypeface::kBold;
- if (lf.lfItalic)
- style |= SkTypeface::kItalic;
-
- return (SkTypeface::Style)style;
-}
-
-struct SkFaceRec {
- SkFaceRec* fNext;
- uint32_t fRefCnt;
- uint32_t fFontID; // checksum of fFace
- LOGFONT fFace;
-
- SkFaceRec() : fFontID(-1), fRefCnt(0) {
- memset(&fFace, 0, sizeof(LOGFONT));
- }
- ~SkFaceRec() {}
-
- uint32_t ref() {
- return ++fRefCnt;
- }
-};
-
-// Font Face list
-static SkFaceRec* gFaceRecHead = NULL;
-
-static SkFaceRec* find_ft_face(uint32_t fontID) {
- SkFaceRec* rec = gFaceRecHead;
- while (rec) {
- if (rec->fFontID == fontID) {
- return rec;
- }
- rec = rec->fNext;
- }
-
- return NULL;
-}
-
-static SkFaceRec* insert_ft_face(const LOGFONT& lf) {
- // need a const char*
- uint32_t id = FontFaceChecksum(&(lf.lfFaceName[0]), GetFontStyle(lf));
- SkFaceRec* rec = find_ft_face(id);
- if (rec) {
- return rec; // found?
- }
-
- rec = SkNEW(SkFaceRec);
- rec->fFontID = id;
- memcpy(&(rec->fFace), &lf, sizeof(LOGFONT));
- rec->fNext = gFaceRecHead;
- gFaceRecHead = rec;
-
- return rec;
-}
-
-static void unref_ft_face(uint32_t fontID) {
-
- SkFaceRec* rec = gFaceRecHead;
- SkFaceRec* prev = NULL;
- while (rec) {
- SkFaceRec* next = rec->fNext;
- if (rec->fFontID == fontID) {
- if (--rec->fRefCnt == 0) {
- if (prev)
- prev->fNext = next;
- else
- gFaceRecHead = next;
-
- SkDELETE(rec);
- }
- return;
- }
- prev = rec;
- rec = next;
- }
- SkASSERT("shouldn't get here, face not in list");
-}
-
-// have to do this because SkTypeface::SkTypeface() is protected
-class FontFaceRec_Typeface : public SkTypeface {
-public:
-
- FontFaceRec_Typeface(Style style, uint32_t id) : SkTypeface(style, id) {};
-
- virtual ~FontFaceRec_Typeface() {};
-};
-
-static const LOGFONT* get_default_font() {
- // don't hardcode on Windows, Win2000, XP, Vista, and international all have different default
- // and the user could change too
-
- if (gDefaultFont.lfFaceName[0] != 0) {
- return &gDefaultFont;
- }
-
- NONCLIENTMETRICS ncm;
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
-
- memcpy(&gDefaultFont, &(ncm.lfMessageFont), sizeof(LOGFONT));
-
- return &gDefaultFont;
-}
-
-static SkTypeface* CreateTypeface_(const LOGFONT& lf) {
-
- SkTypeface::Style style = GetFontStyle(lf);
- FontFaceRec_Typeface* ptypeface = new FontFaceRec_Typeface(style, FontFaceChecksum(lf.lfFaceName, style));
-
- if (NULL == ptypeface) {
- SkASSERT(false);
- return NULL;
- }
-
- SkFaceRec* rec = insert_ft_face(lf);
- SkASSERT(rec);
-
- return ptypeface;
-}
-
-class SkScalerContext_Windows : public SkScalerContext {
-public:
- SkScalerContext_Windows(const SkDescriptor* desc);
- virtual ~SkScalerContext_Windows();
-
-protected:
- virtual unsigned generateGlyphCount() const;
- 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:
- uint32_t fFontID;
- LOGFONT lf;
- MAT2 mat22;
- HDC ddc;
- HFONT savefont;
- HFONT font;
-};
-
-SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc) : SkScalerContext(desc), ddc(0), font(0), savefont(0) {
- SkAutoMutexAcquire ac(gFTMutex);
-
- fFontID = fRec.fFontID;
- SkFaceRec* rec = find_ft_face(fRec.fFontID);
- if (rec) {
- rec->ref();
- memcpy(&lf, &(rec->fFace), sizeof(LOGFONT));
- }
- else {
- SkASSERT(false);
- memcpy(&lf, &gDefaultFont, sizeof(LOGFONT));
- }
-
- 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);
-
- lf.lfHeight = SkScalarFloor(fRec.fTextSize);
- font = CreateFontIndirect(&lf);
- savefont = (HFONT)SelectObject(ddc, font);
-}
-
-SkScalerContext_Windows::~SkScalerContext_Windows() {
- unref_ft_face(fFontID);
-
- if (ddc) {
- ::SelectObject(ddc, savefont);
- ::DeleteDC(ddc);
- ddc = NULL;
- }
- if (font) {
- ::DeleteObject(font);
- }
-}
-
-unsigned SkScalerContext_Windows::generateGlyphCount() const {
- return 0xFFFF;
- // return fFace->num_glyphs;
-}
-
-uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
-
- //uint16_t index = 0;
- //GetGlyphIndicesW(ddc, &(uint16_t&)uni, 1, &index, 0);
- //return index;
-
- // let's just use the uni as index on Windows
- return SkToU16(uni);
-}
-
-void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
- this->generateMetrics(glyph);
-}
-
-void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
-
- SkASSERT(ddc);
-
- GLYPHMETRICS gm;
- memset(&gm, 0, sizeof(gm));
-
- glyph->fRsbDelta = 0;
- glyph->fLsbDelta = 0;
-
- UINT glyphIndexFlag = 0; //glyph->fIsCodePoint ? 0 : GGO_GLYPH_INDEX;
- // UINT glyphIndexFlag = GGO_GLYPH_INDEX;
- // 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 | glyphIndexFlag, &gm, 0, NULL, &mat22);
-
- if (GDI_ERROR != ret) {
- if (ret == 0) {
- // for white space, ret is zero and gmBlackBoxX, gmBlackBoxY are 1 incorrectly!
- gm.gmBlackBoxX = gm.gmBlackBoxY = 0;
- }
- glyph->fWidth = gm.gmBlackBoxX;
- glyph->fHeight = gm.gmBlackBoxY;
- glyph->fTop = SkToS16(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY);
- glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x);
- glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX);
- glyph->fAdvanceY = -SkIntToFixed(gm.gmCellIncY);
- } else {
- glyph->fWidth = 0;
- }
-
-#if 0
- char buf[1024];
- sprintf(buf, "generateMetrics: id:%d, w=%d, h=%d, font:%s, fh:%d\n", glyph->fID, glyph->fWidth, glyph->fHeight, lf.lfFaceName, lf.lfHeight);
- OutputDebugString(buf);
-#endif
-}
-
-void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
- //SkASSERT(false);
- if (mx)
- memset(mx, 0, sizeof(SkPaint::FontMetrics));
- if (my)
- memset(my, 0, sizeof(SkPaint::FontMetrics));
- return;
-}
-
-void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
-
- SkAutoMutexAcquire ac(gFTMutex);
-
- SkASSERT(ddc);
-
- GLYPHMETRICS gm;
- memset(&gm, 0, sizeof(gm));
-
-#if 0
- char buf[1024];
- sprintf(buf, "generateImage: id:%d, w=%d, h=%d, font:%s,fh:%d\n", glyph.fID, glyph.fWidth, glyph.fHeight, lf.lfFaceName, lf.lfHeight);
- OutputDebugString(buf);
-#endif
-
- uint32_t bytecount = 0;
- UINT glyphIndexFlag = 0; //glyph.fIsCodePoint ? 0 : GGO_GLYPH_INDEX;
- // UINT glyphIndexFlag = GGO_GLYPH_INDEX;
- uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_GRAY8_BITMAP | glyphIndexFlag, &gm, 0, NULL, &mat22);
- 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 | glyphIndexFlag, &gm, total_size, pBuff, &mat22);
-
- SkASSERT(total_size != GDI_ERROR);
-
- SkASSERT(glyph.fWidth == gm.gmBlackBoxX);
- SkASSERT(glyph.fHeight == gm.gmBlackBoxY);
-
- uint8_t* dst = (uint8_t*)glyph.fImage;
- uint32_t pitch = (gm.gmBlackBoxX + 3) & ~0x3;
- if (pitch != glyph.rowBytes()) {
- SkASSERT(false); // glyph.fImage has different rowsize!?
- }
-
- for (int32_t y = gm.gmBlackBoxY - 1; y >= 0; y--) {
- uint8_t* src = pBuff + pitch * y;
-
- for (uint32_t x = 0; x < gm.gmBlackBoxX; x++) {
- if (*src > 63) {
- *dst = 0xFF;
- }
- else {
- *dst = *src << 2; // scale to 0-255
- }
- dst++;
- src++;
- bytecount++;
- }
- memset(dst, 0, glyph.rowBytes() - glyph.fWidth);
- dst += glyph.rowBytes() - glyph.fWidth;
- }
-
- delete[] pBuff;
- }
- }
-
- SkASSERT(GDI_ERROR != total_size && total_size >= 0);
-
-}
-
-void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
-
- SkAutoMutexAcquire ac(gFTMutex);
-
- SkASSERT(&glyph && path);
- SkASSERT(ddc);
-
- path->reset();
-
-#if 0
- char buf[1024];
- sprintf(buf, "generatePath: id:%d, w=%d, h=%d, font:%s,fh:%d\n", glyph.fID, glyph.fWidth, glyph.fHeight, lf.lfFaceName, lf.lfHeight);
- OutputDebugString(buf);
-#endif
-
- GLYPHMETRICS gm;
- UINT glyphIndexFlag = 0; //glyph.fIsCodePoint ? 0 : GGO_GLYPH_INDEX;
- uint32_t total_size = GetGlyphOutlineW(ddc, glyph.fID, GGO_NATIVE | glyphIndexFlag, &gm, BUFFERSIZE, glyphbuf, &mat22);
-
- if (GDI_ERROR != total_size) {
-
- const uint8_t* cur_glyph = glyphbuf;
- const uint8_t* end_glyph = glyphbuf + total_size;
-
- while(cur_glyph < end_glyph) {
- const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
-
- const uint8_t* end_poly = cur_glyph + th->cb;
- const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
-
- path->moveTo(SkFixedToScalar(*(SkFixed*)(&th->pfxStart.x)), SkFixedToScalar(*(SkFixed*)(&th->pfxStart.y)));
-
- while(cur_poly < end_poly) {
- const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
-
- if (pc->wType == TT_PRIM_LINE) {
- for (uint16_t i = 0; i < pc->cpfx; i++) {
- path->lineTo(SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].x)), SkFixedToScalar(*(SkFixed*)(&pc->apfx[i].y)));
- }
- }
-
- if (pc->wType == TT_PRIM_QSPLINE) {
- for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
- POINTFX pnt_b = pc->apfx[u]; // B is always the current point
- POINTFX pnt_c = pc->apfx[u+1];
-
- if (u < pc->cpfx - 2) { // If not on last spline, compute C
- pnt_c.x = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.x), *(SkFixed*)(&pnt_c.x)));
- pnt_c.y = SkFixedToFIXED(SkFixedAve(*(SkFixed*)(&pnt_b.y), *(SkFixed*)(&pnt_c.y)));
- }
-
- path->quadTo(SkFixedToScalar(*(SkFixed*)(&pnt_b.x)), SkFixedToScalar(*(SkFixed*)(&pnt_b.y)), SkFixedToScalar(*(SkFixed*)(&pnt_c.x)), SkFixedToScalar(*(SkFixed*)(&pnt_c.y)));
- }
- }
- cur_poly += sizeof(uint16_t) * 2 + sizeof(POINTFX) * pc->cpfx;
- }
- cur_glyph += th->cb;
- path->close();
- }
- }
- else {
- SkASSERT(false);
- }
- //char buf[1024];
- //sprintf(buf, "generatePath: count:%d\n", count);
- //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");
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
- SkASSERT(!"SkFontHost::Deserialize unimplemented");
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
-
- //Should not be used on Windows, keep linker happy
- SkASSERT(false);
- get_default_font();
- return CreateTypeface_(gDefaultFont);
-}
-
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
- return SkNEW_ARGS(SkScalerContext_Windows, (desc));
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(const SkScalerContext::Rec& rec) {
- get_default_font();
-
- SkAutoDescriptor ad(sizeof(rec) + sizeof(gDefaultFont) + SkDescriptor::ComputeOverhead(2));
- SkDescriptor* desc = ad.getDesc();
-
- desc->init();
- SkScalerContext::Rec* newRec =
- (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
- get_default_font();
- CreateTypeface_(gDefaultFont);
- newRec->fFontID = FontFaceChecksum(gDefaultFont.lfFaceName, GetFontStyle(gDefaultFont));
- desc->computeChecksum();
-
- return SkFontHost::CreateScalerContext(desc);
-}
-
-/** Return the closest matching typeface given either an existing family
- (specified by a typeface in that family) or by a familyName, and a
- requested style.
- 1) If familyFace is null, use famillyName.
- 2) If famillyName is null, use familyFace.
- 3) If both are null, return the default font that best matches style
- This MUST not return NULL.
- */
-
-SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
- const char familyName[], SkTypeface::Style style) {
-
- SkAutoMutexAcquire ac(gFTMutex);
-
-#ifndef CAN_USE_LOGFONT_NAME
- familyName = NULL;
- familyFace = NULL;
-#endif
-
- // clip to legal style bits
- style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
- SkTypeface* tf = NULL;
- if (NULL == familyFace && NULL == familyName) {
- LOGFONT lf;
- get_default_font();
- memcpy(&lf, &gDefaultFont, sizeof(LOGFONT));
- lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
- lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
- tf = CreateTypeface_(lf);
- } else {
-#ifdef CAN_USE_LOGFONT_NAME
- LOGFONT lf;
- if (NULL != familyFace) {
- uint32_t id = familyFace->uniqueID();
- SkFaceRec* rec = find_ft_face(id);
- if (!rec) {
- SkASSERT(false);
- get_default_font();
- memcpy(&lf, &gDefaultFont, sizeof(LOGFONT));
- }
- else {
- memcpy(&lf, &(rec->fFace), sizeof(LOGFONT));
- }
- }
- else {
- memset(&lf, 0, sizeof(LOGFONT));
-
- lf.lfHeight = -11; // default
- lf.lfQuality = PROOF_QUALITY;
- lf.lfCharSet = DEFAULT_CHARSET;
-
- _tcsncpy(lf.lfFaceName, familyName, LF_FACESIZE);
- lf.lfFaceName[LF_FACESIZE-1] = '\0';
- }
-
- // use the style desired
- lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
- lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
- tf = CreateTypeface_(lf);
-#endif
- }
-
- if (NULL == tf) {
- get_default_font();
- tf = CreateTypeface_(gDefaultFont);
- }
- return tf;
-}
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
- if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
- return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
- else
- return 0; // nothing to do
-}
-
-int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
- return 0;
-}
-
-void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
- tables[0] = NULL; // black gamma (e.g. exp=1.4)
- tables[1] = NULL; // white gamma (e.g. exp= 1/1.4)
-}
-
-#endif // WIN32
-
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp
deleted file mode 100644
index 7f8b26c..0000000
--- a/src/ports/SkImageDecoder_CG.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright 2008, 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
-**
-** 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
-** limitations under the License.
-*/
-
-#include <Carbon/Carbon.h>
-#include "SkImageDecoder.h"
-#include "SkImageEncoder.h"
-#include "SkMovie.h"
-#include "SkStream.h"
-#include "SkTemplates.h"
-
-static void malloc_release_proc(void* info, const void* data, size_t size) {
- sk_free(info);
-}
-
-static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) {
- // TODO: use callbacks, so we don't have to load all the data into RAM
- size_t len = stream->getLength();
- void* data = sk_malloc_throw(len);
- stream->read(data, len);
-
- return CGDataProviderCreateWithData(data, data, len, malloc_release_proc);
-}
-
-static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) {
- CGDataProviderRef data = SkStreamToDataProvider(stream);
- CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0);
- CGDataProviderRelease(data);
- return imageSrc;
-}
-
-class SkImageDecoder_CG : public SkImageDecoder {
-protected:
- virtual bool onDecode(SkStream* stream, SkBitmap* bm,
- SkBitmap::Config pref, Mode);
-};
-
-#define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast)
-
-bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm,
- SkBitmap::Config pref, Mode mode) {
- CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream);
-
- if (NULL == imageSrc) {
- return false;
- }
- SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc);
-
- CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL);
- if (NULL == image) {
- return false;
- }
- SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image);
-
- const int width = CGImageGetWidth(image);
- const int height = CGImageGetHeight(image);
- bm->setConfig(SkBitmap::kARGB_8888_Config, width, height);
- if (SkImageDecoder::kDecodeBounds_Mode == mode) {
- return true;
- }
-
- if (!this->allocPixelRef(bm, NULL)) {
- return false;
- }
-
- bm->lockPixels();
- bm->eraseColor(0);
-
- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
- CGContextRef cg = CGBitmapContextCreate(bm->getPixels(), width, height,
- 8, bm->rowBytes(), cs, BITMAP_INFO);
- CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image);
- CGContextRelease(cg);
- CGColorSpaceRelease(cs);
-
- bm->unlockPixels();
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
- return SkNEW(SkImageDecoder_CG);
-}
-
-/////////////////////////////////////////////////////////////////////////
-
-SkMovie* SkMovie::DecodeStream(SkStream* stream) {
- return NULL;
-}
-
-/////////////////////////////////////////////////////////////////////////
-
-static size_t consumer_put(void* info, const void* buffer, size_t count) {
- SkWStream* stream = reinterpret_cast<SkWStream*>(info);
- return stream->write(buffer, count) ? count : 0;
-}
-
-static void consumer_release(void* info) {
- // we do nothing, since by design we don't "own" the stream (i.e. info)
-}
-
-static CGDataConsumerRef SkStreamToCGDataConsumer(SkWStream* stream) {
- CGDataConsumerCallbacks procs;
- procs.putBytes = consumer_put;
- procs.releaseConsumer = consumer_release;
- // we don't own/reference the stream, so it our consumer must not live
- // longer that our caller's ownership of the stream
- return CGDataConsumerCreate(stream, &procs);
-}
-
-static CGImageDestinationRef SkStreamToImageDestination(SkWStream* stream,
- CFStringRef type) {
- CGDataConsumerRef consumer = SkStreamToCGDataConsumer(stream);
- if (NULL == consumer) {
- return NULL;
- }
- SkAutoTCallVProc<const void, CFRelease> arconsumer(consumer);
-
- return CGImageDestinationCreateWithDataConsumer(consumer, type, 1, NULL);
-}
-
-class SkImageEncoder_CG : public SkImageEncoder {
-public:
- SkImageEncoder_CG(Type t) : fType(t) {}
-
-protected:
- virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);
-
-private:
- Type fType;
-};
-
-extern CGImageRef SkCreateCGImageRef(const SkBitmap&);
-
-/* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes
- to our SkWStream. Since we don't reference/own the SkWStream, our consumer
- must only live for the duration of the onEncode() method.
- */
-bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm,
- int quality) {
- CFStringRef type;
- switch (fType) {
- case kJPEG_Type:
- type = kUTTypeJPEG;
- break;
- case kPNG_Type:
- type = kUTTypePNG;
- break;
- default:
- return false;
- }
-
- CGImageDestinationRef dst = SkStreamToImageDestination(stream, type);
- if (NULL == dst) {
- return false;
- }
- SkAutoTCallVProc<const void, CFRelease> ardst(dst);
-
- CGImageRef image = SkCreateCGImageRef(bm);
- if (NULL == image) {
- return false;
- }
- SkAutoTCallVProc<CGImage, CGImageRelease> agimage(image);
-
- CGImageDestinationAddImage(dst, image, NULL);
- CGImageDestinationFinalize(dst);
- return true;
-}
-
-SkImageEncoder* SkImageEncoder::Create(Type t) {
- switch (t) {
- case kJPEG_Type:
- case kPNG_Type:
- break;
- default:
- return NULL;
- }
- return SkNEW_ARGS(SkImageEncoder_CG, (t));
-}
-