Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(657)

Side by Side Diff: src/ports/SkFontHost_win.cpp

Issue 19231003: Implement onCountGlyphs and onGetUPEM on Windows. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/core/SkTypeface.cpp ('k') | src/ports/SkFontHost_win_dw.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkAdvancedTypefaceMetrics.h" 9 #include "SkAdvancedTypefaceMetrics.h"
10 #include "SkBase64.h" 10 #include "SkBase64.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkData.h" 12 #include "SkData.h"
13 #include "SkDescriptor.h" 13 #include "SkDescriptor.h"
14 #include "SkFontDescriptor.h" 14 #include "SkFontDescriptor.h"
15 #include "SkFontHost.h" 15 #include "SkFontHost.h"
16 #include "SkGlyph.h" 16 #include "SkGlyph.h"
17 #include "SkMaskGamma.h" 17 #include "SkMaskGamma.h"
18 #include "SkOTTable_maxp.h"
18 #include "SkOTUtils.h" 19 #include "SkOTUtils.h"
19 #include "SkPath.h" 20 #include "SkPath.h"
20 #include "SkStream.h" 21 #include "SkStream.h"
21 #include "SkString.h" 22 #include "SkString.h"
22 #include "SkTemplates.h" 23 #include "SkTemplates.h"
23 #include "SkThread.h" 24 #include "SkThread.h"
24 #include "SkTypeface_win.h" 25 #include "SkTypeface_win.h"
25 #include "SkTypefaceCache.h" 26 #include "SkTypefaceCache.h"
26 #include "SkUtils.h" 27 #include "SkUtils.h"
27 28
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return *(FIXED*)(&x); 134 return *(FIXED*)(&x);
134 } 135 }
135 static inline SkFixed SkFIXEDToFixed(FIXED x) { 136 static inline SkFixed SkFIXEDToFixed(FIXED x) {
136 return *(SkFixed*)(&x); 137 return *(SkFixed*)(&x);
137 } 138 }
138 139
139 static inline FIXED SkScalarToFIXED(SkScalar x) { 140 static inline FIXED SkScalarToFIXED(SkScalar x) {
140 return SkFixedToFIXED(SkScalarToFixed(x)); 141 return SkFixedToFIXED(SkScalarToFixed(x));
141 } 142 }
142 143
143 static unsigned calculateOutlineGlyphCount(HDC hdc) { 144 static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
145 TEXTMETRIC textMetric;
146 if (0 == GetTextMetrics(hdc, &textMetric)) {
147 textMetric.tmPitchAndFamily = TMPF_VECTOR;
148 call_ensure_accessible(lf);
149 GetTextMetrics(hdc, &textMetric);
150 }
151
152 if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
153 return textMetric.tmLastChar;
154 }
155
144 // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes. 156 // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
145 const DWORD maxpTag =
146 SkEndian_SwapBE32(SkSetFourByteTag('m', 'a', 'x', 'p'));
147 uint16_t glyphs; 157 uint16_t glyphs;
148 if (GetFontData(hdc, maxpTag, 4, &glyphs, sizeof(glyphs)) != GDI_ERROR) { 158 if (GDI_ERROR != GetFontData(hdc, SkOTTableMaximumProfile::TAG, 4, &glyphs, sizeof(glyphs))) {
149 return SkEndian_SwapBE16(glyphs); 159 return SkEndian_SwapBE16(glyphs);
150 } 160 }
151 161
152 // Binary search for glyph count. 162 // Binary search for glyph count.
153 static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; 163 static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
154 int32_t max = SK_MaxU16 + 1; 164 int32_t max = SK_MaxU16 + 1;
155 int32_t min = 0; 165 int32_t min = 0;
156 GLYPHMETRICS gm; 166 GLYPHMETRICS gm;
157 while (min < max) { 167 while (min < max) {
158 int32_t mid = min + ((max - min) / 2); 168 int32_t mid = min + ((max - min) / 2);
159 if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, 169 if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
160 NULL, &mat2) == GDI_ERROR) { 170 NULL, &mat2) == GDI_ERROR) {
161 max = mid; 171 max = mid;
162 } else { 172 } else {
163 min = mid + 1; 173 min = mid + 1;
164 } 174 }
165 } 175 }
166 SkASSERT(min == max); 176 SkASSERT(min == max);
167 return min; 177 return min;
168 } 178 }
169 179
180 static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) {
181 TEXTMETRIC textMetric;
182 if (0 == GetTextMetrics(hdc, &textMetric)) {
183 textMetric.tmPitchAndFamily = TMPF_VECTOR;
184 call_ensure_accessible(lf);
185 GetTextMetrics(hdc, &textMetric);
186 }
187
188 if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
189 return textMetric.tmMaxCharWidth;
190 }
191
192 OUTLINETEXTMETRIC otm;
193 unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
194 if (0 == otmRet) {
195 call_ensure_accessible(lf);
196 otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
197 }
198
199 return (0 == otmRet) ? 0 : otm.otmEMSquare;
200 }
201
170 class LogFontTypeface : public SkTypeface { 202 class LogFontTypeface : public SkTypeface {
171 public: 203 public:
172 LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, bool serializeAsStream = false) : 204 LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, bool serializeAsStream = false) :
173 SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(seria lizeAsStream) { 205 SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(seria lizeAsStream) {
174 206
175 // If the font has cubic outlines, it will not be rendered with ClearTyp e. 207 // If the font has cubic outlines, it will not be rendered with ClearTyp e.
176 HFONT font = CreateFontIndirect(&lf); 208 HFONT font = CreateFontIndirect(&lf);
177 209
178 HDC deviceContext = ::CreateCompatibleDC(NULL); 210 HDC deviceContext = ::CreateCompatibleDC(NULL);
179 HFONT savefont = (HFONT)SelectObject(deviceContext, font); 211 HFONT savefont = (HFONT)SelectObject(deviceContext, font);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 253 }
222 254
223 protected: 255 protected:
224 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; 256 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
225 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE; 257 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE;
226 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; 258 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
227 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 259 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
228 SkAdvancedTypefaceMetrics::PerGlyphInfo, 260 SkAdvancedTypefaceMetrics::PerGlyphInfo,
229 const uint32_t*, uint32_t) const SK_OVERRIDE; 261 const uint32_t*, uint32_t) const SK_OVERRIDE;
230 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ; 262 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ;
263 virtual int onCountGlyphs() const SK_OVERRIDE;
264 virtual int onGetUPEM() const SK_OVERRIDE;
231 }; 265 };
232 266
233 class FontMemResourceTypeface : public LogFontTypeface { 267 class FontMemResourceTypeface : public LogFontTypeface {
234 public: 268 public:
235 /** 269 /**
236 * Takes ownership of fontMemResource. 270 * Takes ownership of fontMemResource.
237 */ 271 */
238 FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGF ONT& lf, HANDLE fontMemResource) : 272 FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGF ONT& lf, HANDLE fontMemResource) :
239 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour ce) { 273 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour ce) {
240 } 274 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 ::ScriptFreeCache(&fSC); 751 ::ScriptFreeCache(&fSC);
718 } 752 }
719 } 753 }
720 754
721 bool SkScalerContext_Windows::isValid() const { 755 bool SkScalerContext_Windows::isValid() const {
722 return fDDC && fFont; 756 return fDDC && fFont;
723 } 757 }
724 758
725 unsigned SkScalerContext_Windows::generateGlyphCount() { 759 unsigned SkScalerContext_Windows::generateGlyphCount() {
726 if (fGlyphCount < 0) { 760 if (fGlyphCount < 0) {
727 if (fType == SkScalerContext_Windows::kBitmap_Type) { 761 fGlyphCount = calculateGlyphCount(
728 return fTM.tmLastChar; 762 fDDC, static_cast<const LogFontTypeface*>(this->getTyp eface())->fLogFont);
729 }
730 fGlyphCount = calculateOutlineGlyphCount(fDDC);
731 } 763 }
732 return fGlyphCount; 764 return fGlyphCount;
733 } 765 }
734 766
735 uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) { 767 uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
736 uint16_t index = 0; 768 uint16_t index = 0;
737 WCHAR c[2]; 769 WCHAR c[2];
738 // TODO(ctguil): Support characters that generate more than one glyph. 770 // TODO(ctguil): Support characters that generate more than one glyph.
739 if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) { 771 if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) {
740 // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0. 772 // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 } 1471 }
1440 if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) { 1472 if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
1441 goto Error; 1473 goto Error;
1442 } 1474 }
1443 lf.lfHeight = -SkToS32(otm.otmEMSquare); 1475 lf.lfHeight = -SkToS32(otm.otmEMSquare);
1444 designFont = CreateFontIndirect(&lf); 1476 designFont = CreateFontIndirect(&lf);
1445 SelectObject(hdc, designFont); 1477 SelectObject(hdc, designFont);
1446 if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) { 1478 if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
1447 goto Error; 1479 goto Error;
1448 } 1480 }
1449 glyphCount = calculateOutlineGlyphCount(hdc); 1481 glyphCount = calculateGlyphCount(hdc, fLogFont);
1450 1482
1451 info = new SkAdvancedTypefaceMetrics; 1483 info = new SkAdvancedTypefaceMetrics;
1452 info->fEmSize = otm.otmEMSquare; 1484 info->fEmSize = otm.otmEMSquare;
1453 info->fMultiMaster = false; 1485 info->fMultiMaster = false;
1454 info->fLastGlyphID = SkToU16(glyphCount - 1); 1486 info->fLastGlyphID = SkToU16(glyphCount - 1);
1455 info->fStyle = 0; 1487 info->fStyle = 0;
1456 tchar_to_skstring(lf.lfFaceName, &info->fFontName); 1488 tchar_to_skstring(lf.lfFaceName, &info->fFontName);
1457 1489
1458 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { 1490 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
1459 populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode)); 1491 populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode));
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 } 1709 }
1678 } 1710 }
1679 1711
1680 SelectObject(hdc, savefont); 1712 SelectObject(hdc, savefont);
1681 DeleteObject(font); 1713 DeleteObject(font);
1682 DeleteDC(hdc); 1714 DeleteDC(hdc);
1683 1715
1684 return stream; 1716 return stream;
1685 } 1717 }
1686 1718
1719 int LogFontTypeface::onCountGlyphs() const {
1720 HDC hdc = ::CreateCompatibleDC(NULL);
1721 HFONT font = CreateFontIndirect(&fLogFont);
1722 HFONT savefont = (HFONT)SelectObject(hdc, font);
1723
1724 unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
1725
1726 SelectObject(hdc, savefont);
1727 DeleteObject(font);
1728 DeleteDC(hdc);
1729
1730 return glyphCount;
1731 }
1732
1733 int LogFontTypeface::onGetUPEM() const {
1734 HDC hdc = ::CreateCompatibleDC(NULL);
1735 HFONT font = CreateFontIndirect(&fLogFont);
1736 HFONT savefont = (HFONT)SelectObject(hdc, font);
1737
1738 unsigned int upem = calculateUPEM(hdc, fLogFont);
1739
1740 SelectObject(hdc, savefont);
1741 DeleteObject(font);
1742 DeleteDC(hdc);
1743
1744 return upem;
1745 }
1746
1687 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc ) const { 1747 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc ) const {
1688 SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows, 1748 SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows,
1689 (const_cast<LogFontTypeface*>(th is), desc)); 1749 (const_cast<LogFontTypeface*>(th is), desc));
1690 if (!ctx->isValid()) { 1750 if (!ctx->isValid()) {
1691 SkDELETE(ctx); 1751 SkDELETE(ctx);
1692 ctx = NULL; 1752 ctx = NULL;
1693 } 1753 }
1694 return ctx; 1754 return ctx;
1695 } 1755 }
1696 1756
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 return this->createFromStream(stream); 2004 return this->createFromStream(stream);
1945 } 2005 }
1946 2006
1947 private: 2007 private:
1948 SkTDArray<ENUMLOGFONTEX> fLogFontArray; 2008 SkTDArray<ENUMLOGFONTEX> fLogFontArray;
1949 }; 2009 };
1950 2010
1951 SkFontMgr* SkFontMgr::Factory() { 2011 SkFontMgr* SkFontMgr::Factory() {
1952 return SkNEW(SkFontMgrGDI); 2012 return SkNEW(SkFontMgrGDI);
1953 } 2013 }
OLDNEW
« no previous file with comments | « src/core/SkTypeface.cpp ('k') | src/ports/SkFontHost_win_dw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698