aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-14 23:19:59 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-02-14 23:19:59 +0000
commit6f72d1eacd66d2a9c0059962a75c0ca6a99ff98e (patch)
treeab77ed84f87aeccd58b334279a901b07797ace18
parent97b624529c014b93cabffac5f0ef5a5842473a4b (diff)
Provide windows font host implementation needed to support TrueType text in pdf backend.
- Move AdvanceMetric template functions into new file SkAdvancedTypefaceMetrics.cpp Review URL: http://codereview.appspot.com/4174041 git-svn-id: http://skia.googlecode.com/svn/trunk@789 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkAdvancedTypefaceMetrics.h26
-rwxr-xr-xsrc/core/SkAdvancedTypefaceMetrics.cpp158
-rw-r--r--src/core/core_files.mk1
-rw-r--r--src/ports/SkFontHost_FreeType.cpp104
-rwxr-xr-x[-rw-r--r--]src/ports/SkFontHost_win.cpp151
-rw-r--r--vs/SampleApp/SampleApp.vcxproj3
6 files changed, 346 insertions, 97 deletions
diff --git a/include/core/SkAdvancedTypefaceMetrics.h b/include/core/SkAdvancedTypefaceMetrics.h
index 0c718d4f32..033e738c8a 100644
--- a/include/core/SkAdvancedTypefaceMetrics.h
+++ b/include/core/SkAdvancedTypefaceMetrics.h
@@ -107,4 +107,30 @@ public:
SkTScopedPtr<SkAutoTArray<SkString> > fGlyphNames;
};
+namespace skia_advanced_typeface_metrics_utils {
+
+template <typename Data>
+void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int startId);
+
+template <typename Data>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
+ SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
+ int startId);
+
+template <typename Data>
+void finishRange(
+ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int endId,
+ typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
+ type);
+
+template <typename Data, typename FontHandle>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
+ FontHandle fontHandle,
+ int num_glyphs,
+ bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data));
+
+} // namespace skia_advanced_typeface_metrics_utils
+
#endif
diff --git a/src/core/SkAdvancedTypefaceMetrics.cpp b/src/core/SkAdvancedTypefaceMetrics.cpp
new file mode 100755
index 0000000000..1b86fb5fac
--- /dev/null
+++ b/src/core/SkAdvancedTypefaceMetrics.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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 "SkAdvancedTypefaceMetrics.h"
+#include "SkTypes.h"
+
+#ifdef SK_BUILD_FOR_UNIX
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#endif
+
+namespace skia_advanced_typeface_metrics_utils {
+
+template <typename Data>
+void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int startId) {
+ range->fStartId = startId;
+ range->fAdvance.setCount(0);
+}
+
+template <typename Data>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
+ SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
+ int startId) {
+ nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
+ resetRange(nextSlot->get(), startId);
+ return nextSlot->get();
+}
+
+template <typename Data>
+void finishRange(
+ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
+ int endId,
+ typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
+ type) {
+ range->fEndId = endId;
+ range->fType = type;
+ int newLength;
+ if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
+ newLength = endId - range->fStartId + 1;
+ } else {
+ newLength = 1;
+ }
+ SkASSERT(range->fAdvance.count() >= newLength);
+ range->fAdvance.setCount(newLength);
+}
+
+template <typename Data, typename FontHandle>
+SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
+ FontHandle fontHandle,
+ int num_glyphs,
+ bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
+ // Assuming that an ASCII representation of a width or a glyph id is,
+ // on average, 3 characters long gives the following cut offs for
+ // using different range types:
+ // When currently in a range
+ // - Removing 4 0's is a win
+ // - Removing 5 repeats is a win
+ // When not currently in a range
+ // - Removing 1 0 is a win
+ // - Removing 3 repeats is a win
+
+ SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
+ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
+ curRange = appendRange(&result, 0);
+ Data lastAdvance = SK_MinS16;
+ int repeats = 0;
+ for (int gId = 0; gId < num_glyphs; gId++) {
+ Data advance;
+ if (!getAdvance(fontHandle, gId, &advance)) {
+ num_glyphs = (gId > 0) ? gId - 1 : 0;
+ break;
+ }
+ if (advance == lastAdvance) {
+ repeats++;
+ } else if (curRange->fAdvance.count() == repeats + 1) {
+ if (lastAdvance == 0 && repeats >= 0) {
+ resetRange(curRange, gId);
+ } else if (repeats >= 2) {
+ finishRange(curRange, gId - 1,
+ SkAdvancedTypefaceMetrics::WidthRange::kRun);
+ curRange = appendRange(&curRange->fNext, gId);
+ }
+ repeats = 0;
+ } else {
+ if (lastAdvance == 0 && repeats >= 3) {
+ finishRange(curRange, gId - repeats - 2,
+ SkAdvancedTypefaceMetrics::WidthRange::kRange);
+ curRange = appendRange(&curRange->fNext, gId);
+ } else if (repeats >= 4) {
+ finishRange(curRange, gId - repeats - 2,
+ SkAdvancedTypefaceMetrics::WidthRange::kRange);
+ curRange = appendRange(&curRange->fNext, gId - repeats - 1);
+ curRange->fAdvance.append(1, &lastAdvance);
+ finishRange(curRange, gId - 1,
+ SkAdvancedTypefaceMetrics::WidthRange::kRun);
+ curRange = appendRange(&curRange->fNext, gId);
+ }
+ repeats = 0;
+ }
+ curRange->fAdvance.append(1, &advance);
+ lastAdvance = advance;
+ }
+ finishRange(curRange, num_glyphs - 1,
+ SkAdvancedTypefaceMetrics::WidthRange::kRange);
+ return result.release();
+}
+
+// Make AdvanceMetric template functions available for linking with typename
+// WidthRange and VerticalAdvanceRange.
+#ifdef SK_BUILD_FOR_WIN
+template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
+ HDC hdc,
+ int num_glyphs,
+ bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
+#elif SK_BUILD_FOR_UNIX
+template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
+ FT_Face face,
+ int num_glyphs,
+ bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
+#endif
+template void resetRange(
+ SkAdvancedTypefaceMetrics::WidthRange* range,
+ int startId);
+template SkAdvancedTypefaceMetrics::WidthRange* appendRange(
+ SkTScopedPtr<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
+ int startId);
+template void finishRange<int16_t>(
+ SkAdvancedTypefaceMetrics::WidthRange* range,
+ int endId,
+ SkAdvancedTypefaceMetrics::WidthRange::MetricType type);
+
+template void resetRange(
+ SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
+ int startId);
+template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
+ SkTScopedPtr<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
+ nextSlot,
+ int startId);
+template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
+ SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
+ int endId,
+ SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);
+
+} // namespace skia_advanced_typeface_metrics_utils
diff --git a/src/core/core_files.mk b/src/core/core_files.mk
index 3e3436e9cc..399b1a5a65 100644
--- a/src/core/core_files.mk
+++ b/src/core/core_files.mk
@@ -1,5 +1,6 @@
SOURCE := \
Sk64.cpp \
+ SkAdvancedTypefaceMetrics.cpp \
SkAlphaRuns.cpp \
SkBitmap.cpp \
SkBitmapProcShader.cpp \
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 1b1d47b5ce..7f1e377260 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -73,6 +73,8 @@
#define SkASSERT_CONTINUE(pred)
#endif
+using namespace skia_advanced_typeface_metrics_utils;
+
//////////////////////////////////////////////////////////////////////////
struct SkFaceRec;
@@ -331,98 +333,14 @@ static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) {
return true;
}
-static int16_t getWidthAdvance(FT_Face face, int gId) {
+static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
FT_Fixed advance = 0;
- SkAssertResult(getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance) == 0);
- return advance;
-}
-
-template <typename Data>
-static void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
- int startId) {
- range->fStartId = startId;
- range->fAdvance.setCount(0);
-}
-
-template <typename Data>
-static SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
- SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
- int startId) {
- nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
- resetRange(nextSlot->get(), startId);
- return nextSlot->get();
-}
-
-template <typename Data>
-static void finishRange(
- SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
- int endId,
- typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
- type) {
- range->fEndId = endId;
- range->fType = type;
- int newLength;
- if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange)
- newLength = endId - range->fStartId + 1;
- else
- newLength = 1;
- SkASSERT(range->fAdvance.count() >= newLength);
- range->fAdvance.setCount(newLength);
-}
-
-template <typename Data>
-static SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
- FT_Face face, Data (*getAdvance)(FT_Face face, int gId)) {
- // Assuming that an ASCII representation of a width or a glyph id is,
- // on average, 3 characters long gives the following cut offs for
- // using different range types:
- // When currently in a range
- // - Removing 4 0's is a win
- // - Removing 5 repeats is a win
- // When not currently in a range
- // - Removing 1 0 is a win
- // - Removing 3 repeats is a win
-
- SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
- SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
- curRange = appendRange(&result, 0);
- Data lastAdvance = SHRT_MIN;
- int repeats = 0;
- for (int gId = 0; gId < face->num_glyphs; gId++) {
- Data advance = getAdvance(face, gId);
- if (advance == lastAdvance) {
- repeats++;
- } else if (curRange->fAdvance.count() == repeats + 1) {
- if (lastAdvance == 0 && repeats >= 0) {
- resetRange(curRange, gId);
- } else if (repeats >= 2) {
- finishRange(curRange, gId - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRun);
- curRange = appendRange(&curRange->fNext, gId);
- }
- repeats = 0;
- } else {
- if (lastAdvance == 0 && repeats >= 3) {
- finishRange(curRange, gId - repeats - 2,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- curRange = appendRange(&curRange->fNext, gId);
- } else if (repeats >= 4) {
- finishRange(curRange, gId - repeats - 2,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- curRange = appendRange(&curRange->fNext, gId - repeats - 1);
- curRange->fAdvance.append(1, &lastAdvance);
- finishRange(curRange, gId - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRun);
- curRange = appendRange(&curRange->fNext, gId);
- }
- repeats = 0;
- }
- curRange->fAdvance.append(1, &advance);
- lastAdvance = advance;
+ if (getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) {
+ return false;
}
- finishRange(curRange, face->num_glyphs - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- return result.release();
+ SkASSERT(data);
+ *data = advance;
+ return true;
}
// static
@@ -499,6 +417,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
// Figure out a good guess for StemV - Min width of i, I, !, 1.
// This probably isn't very good with an italic font.
int16_t min_width = SHRT_MAX;
+ info->fStemV = 0;
char stem_chars[] = {'i', 'I', '!', '1'};
for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
FT_BBox bbox;
@@ -550,7 +469,7 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
info->fGlyphWidths->fAdvance.append(1, &advance);
finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
- } else if(!cid) {
+ } else if (!cid) {
appendRange(&info->fGlyphWidths, 0);
// So as to not blow out the stack, get advances in batches.
for (int gID = 0; gID < face->num_glyphs; gID += 128) {
@@ -568,7 +487,8 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
finishRange(info->fGlyphWidths.get(), face->num_glyphs - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
} else {
- info->fGlyphWidths.reset(getAdvanceData(face, &getWidthAdvance));
+ info->fGlyphWidths.reset(
+ getAdvanceData(face, face->num_glyphs, &getWidthAdvance));
}
if (info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index dacabac87c..c2e43fa129 100644..100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -19,6 +19,8 @@
#include "SkFontHost.h"
#include "SkDescriptor.h"
+#include "SkAdvancedTypefaceMetrics.h"
+#include "SkStream.h"
#include "SkThread.h"
#ifdef WIN32
@@ -28,6 +30,8 @@
// client3d has to undefine this for now
#define CAN_USE_LOGFONT_NAME
+using namespace skia_advanced_typeface_metrics_utils;
+
static SkMutex gFTMutex;
static const uint16_t BUFFERSIZE = (16384 - 32);
@@ -456,11 +460,133 @@ SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
return NULL;
}
+static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
+ // Initialize the MAT2 structure to the identify transformation matrix.
+ static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),
+ SkScalarToFIXED(0), SkScalarToFIXED(1)};
+ int flags = GGO_METRICS | GGO_GLYPH_INDEX;
+ GLYPHMETRICS gm;
+ if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) {
+ return false;
+ }
+ SkASSERT(advance);
+ *advance = gm.gmCellIncX;
+ return true;
+}
+
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) {
- SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
- return NULL;
+ SkAutoMutexAcquire ac(gFTMutex);
+ LogFontTypeface* rec = LogFontTypeface::FindById(fontID);
+ LOGFONT lf = rec->logFont();
+ SkAdvancedTypefaceMetrics* info = NULL;
+
+ HDC hdc = CreateCompatibleDC(NULL);
+ HFONT font = CreateFontIndirect(&lf);
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+ HFONT designFont = NULL;
+
+ // To request design units, create a logical font whose height is specified
+ // as unitsPerEm.
+ OUTLINETEXTMETRIC otm;
+ if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm) ||
+ !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
+ goto Error;
+ }
+ lf.lfHeight = -SkToS32(otm.otmEMSquare);
+ designFont = CreateFontIndirect(&lf);
+ SelectObject(hdc, designFont);
+ if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
+ goto Error;
+ }
+
+ info = new SkAdvancedTypefaceMetrics;
+#ifdef UNICODE
+ // Get the buffer size needed first.
+ size_t str_len = WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, NULL,
+ 0, NULL, NULL);
+ // Allocate a buffer (str_len already has terminating null accounted for).
+ char *familyName = new char[str_len];
+ // Now actually convert the string.
+ WideCharToMultiByte(CP_UTF8, 0, lf.lfFaceName, -1, familyName, str_len,
+ NULL, NULL);
+ info->fFontName.set(familyName);
+ delete [] familyName;
+#else
+ info->fFontName.set(lf.lfFaceName);
+#endif
+
+ if (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE) {
+ info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
+ } else {
+ info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
+ }
+ info->fEmSize = otm.otmEMSquare;
+ info->fMultiMaster = false;
+
+ 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;
+ }
+ if (otm.otmTextMetrics.tmItalic) {
+ info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
+ }
+ // Setting symbolic style by default for now.
+ info->fStyle |= SkAdvancedTypefaceMetrics::kSymbolic_Style;
+ if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {
+ info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
+ } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {
+ info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
+ }
+
+ // The main italic angle of the font, in tenths of a degree counterclockwise
+ // from vertical.
+ info->fItalicAngle = otm.otmItalicAngle / 10;
+ info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);
+ info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);
+ // TODO(ctguil): Use alternate cap height calculation.
+ // MSDN says otmsCapEmHeight is not support but it is returning a value on
+ // my Win7 box.
+ info->fCapHeight = otm.otmsCapEmHeight;
+ info->fBBox =
+ SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,
+ otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);
+
+ // Figure out a good guess for StemV - Min width of i, I, !, 1.
+ // This probably isn't very good with an italic font.
+ int16_t min_width = SHRT_MAX;
+ info->fStemV = 0;
+ char stem_chars[] = {'i', 'I', '!', '1'};
+ for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
+ ABC abcWidths;
+ if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
+ int16_t width = abcWidths.abcB;
+ if (width > 0 && width < min_width) {
+ min_width = width;
+ info->fStemV = min_width;
+ }
+ }
+ }
+
+ // If bit 1 is set, the font may not be embedded in a document.
+ // If bit 1 is clear, the font can be embedded.
+ // If bit 2 is set, the embedding is read-only.
+ if (otm.otmfsType & 0x1) {
+ info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
+ } else if (perGlyphInfo) {
+ info->fGlyphWidths.reset(
+ getAdvanceData(hdc, SHRT_MAX, &getWidthAdvance));
+ }
+
+Error:
+ SelectObject(hdc, savefont);
+ DeleteObject(designFont);
+ DeleteObject(font);
+ DeleteDC(hdc);
+
+ return info;
}
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
@@ -471,8 +597,25 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
}
SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {
- SkASSERT(!"SkFontHost::OpenStream unimplemented");
- return NULL;
+ SkAutoMutexAcquire ac(gFTMutex);
+ LogFontTypeface* rec = LogFontTypeface::FindById(uniqueID);
+
+ HDC hdc = ::CreateCompatibleDC(NULL);
+ HFONT font = CreateFontIndirect(&rec->logFont());
+ HFONT savefont = (HFONT)SelectObject(hdc, font);
+
+ size_t bufferSize = GetFontData(hdc, 0, 0, NULL, 0);
+ SkMemoryStream* stream = new SkMemoryStream(bufferSize);
+ if (!GetFontData(hdc, 0, 0, (void*)stream->getMemoryBase(), bufferSize)) {
+ delete stream;
+ stream = NULL;
+ }
+
+ SelectObject(hdc, savefont);
+ DeleteObject(font);
+ DeleteDC(hdc);
+
+ return stream;
}
SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
diff --git a/vs/SampleApp/SampleApp.vcxproj b/vs/SampleApp/SampleApp.vcxproj
index 688e59ce6d..bf0f5fa62d 100644
--- a/vs/SampleApp/SampleApp.vcxproj
+++ b/vs/SampleApp/SampleApp.vcxproj
@@ -293,6 +293,7 @@
<ClCompile Include="..\..\samplecode\SampleVertices.cpp" />
<ClCompile Include="..\..\samplecode\SampleXfermodes.cpp" />
<ClCompile Include="..\..\src\core\Sk64.cpp" />
+ <ClCompile Include="..\..\src\core\SkAdvancedTypefaceMetrics.cpp" />
<ClCompile Include="..\..\src\core\SkAlphaRuns.cpp" />
<ClCompile Include="..\..\src\core\SkBitmap.cpp" />
<ClCompile Include="..\..\src\core\SkBitmapProcShader.cpp" />
@@ -476,4 +477,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>