зеркало из https://github.com/mozilla/moz-skia.git
Add paging support for handle based typefaces.
http://codereview.appspot.com/5379043/ http://codereview.appspot.com/5364052/ git-svn-id: http://skia.googlecode.com/svn/trunk@2693 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
79841fe3cb
Коммит
39698b1bd7
|
@ -152,6 +152,7 @@
|
||||||
|
|
||||||
'../src/ports/SkDebug_stdio.cpp',
|
'../src/ports/SkDebug_stdio.cpp',
|
||||||
'../src/ports/SkDebug_win.cpp',
|
'../src/ports/SkDebug_win.cpp',
|
||||||
|
'../src/ports/SkFontHost_sandbox_none.cpp',
|
||||||
'../src/ports/SkFontHost_win.cpp',
|
'../src/ports/SkFontHost_win.cpp',
|
||||||
'../src/ports/SkThread_win.cpp',
|
'../src/ports/SkThread_win.cpp',
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static uint32_t GetUnitsPerEm(SkFontID fontID);
|
static uint32_t GetUnitsPerEm(SkFontID fontID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** If Skia is running in a constrained environment and the typeface
|
||||||
|
implementation is handle based, the typeface data may become
|
||||||
|
unavailable asynchronously. If a font host or scaler context method is
|
||||||
|
unable to access font data, it may call this function as a request to
|
||||||
|
make the handle contained in the typeface useable.
|
||||||
|
*/
|
||||||
|
static void EnsureTypefaceAccessible(const SkTypeface& typeface);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SkFontHost.h"
|
||||||
|
#include "SkTypeface.h"
|
||||||
|
#include "SkTypeface_win.h"
|
||||||
|
|
||||||
|
//static
|
||||||
|
void SkFontHost::EnsureTypefaceAccessible(const SkTypeface& typeface) {
|
||||||
|
//No sandbox, nothing to do.
|
||||||
|
}
|
|
@ -203,6 +203,11 @@ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ensure_typeface_accessible(SkFontID fontID) {
|
||||||
|
LogFontTypeface* face = (LogFontTypeface*)SkTypefaceCache::FindByID(fontID);
|
||||||
|
SkFontHost::EnsureTypefaceAccessible(*face);
|
||||||
|
}
|
||||||
|
|
||||||
static void GetLogFontByID(SkFontID fontID, LOGFONT* lf) {
|
static void GetLogFontByID(SkFontID fontID, LOGFONT* lf) {
|
||||||
LogFontTypeface* face = (LogFontTypeface*)SkTypefaceCache::FindByID(fontID);
|
LogFontTypeface* face = (LogFontTypeface*)SkTypefaceCache::FindByID(fontID);
|
||||||
if (face) {
|
if (face) {
|
||||||
|
@ -393,9 +398,11 @@ const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
|
||||||
SetWorldTransform(fDC, &xform);
|
SetWorldTransform(fDC, &xform);
|
||||||
|
|
||||||
uint16_t glyphID = glyph.getGlyphID();
|
uint16_t glyphID = glyph.getGlyphID();
|
||||||
ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, NULL, reinterpret_cast<LPCWSTR>(&glyphID), 1, NULL);
|
BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, NULL, reinterpret_cast<LPCWSTR>(&glyphID), 1, NULL);
|
||||||
GdiFlush();
|
GdiFlush();
|
||||||
|
if (0 == ret) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
*srcRBPtr = srcRB;
|
*srcRBPtr = srcRB;
|
||||||
// offset to the start of the image
|
// offset to the start of the image
|
||||||
return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
|
return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
|
||||||
|
@ -592,6 +599,10 @@ void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
|
||||||
// Note: need to use GGO_GRAY8_BITMAP instead of GGO_METRICS because GGO_METRICS returns a smaller
|
// 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.
|
// BlackBlox; we need the bigger one in case we need the image. fAdvance is the same.
|
||||||
uint32_t ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
|
uint32_t ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
|
||||||
|
if (GDI_ERROR == ret) {
|
||||||
|
ensure_typeface_accessible(fRec.fFontID);
|
||||||
|
ret = GetGlyphOutlineW(fDDC, glyph->getGlyphID(0), GGO_GRAY8_BITMAP | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
|
||||||
|
}
|
||||||
|
|
||||||
if (GDI_ERROR != ret) {
|
if (GDI_ERROR != ret) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -650,6 +661,10 @@ void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
|
||||||
OUTLINETEXTMETRIC otm;
|
OUTLINETEXTMETRIC otm;
|
||||||
|
|
||||||
uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
|
uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
|
||||||
|
if (GDI_ERROR == ret) {
|
||||||
|
ensure_typeface_accessible(fRec.fFontID);
|
||||||
|
ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
|
||||||
|
}
|
||||||
if (sizeof(otm) != ret) {
|
if (sizeof(otm) != ret) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -876,9 +891,13 @@ void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) {
|
||||||
|
|
||||||
size_t srcRB;
|
size_t srcRB;
|
||||||
const void* bits = fOffscreen.draw(glyph, isBW, fgColor, &srcRB);
|
const void* bits = fOffscreen.draw(glyph, isBW, fgColor, &srcRB);
|
||||||
if (!bits) {
|
if (NULL == bits) {
|
||||||
sk_bzero(glyph.fImage, glyph.computeImageSize());
|
ensure_typeface_accessible(fRec.fFontID);
|
||||||
return;
|
bits = fOffscreen.draw(glyph, isBW, fgColor, &srcRB);
|
||||||
|
if (NULL == bits) {
|
||||||
|
sk_bzero(glyph.fImage, glyph.computeImageSize());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table) {
|
if (table) {
|
||||||
|
@ -942,6 +961,10 @@ void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
|
||||||
|
|
||||||
GLYPHMETRICS gm;
|
GLYPHMETRICS gm;
|
||||||
uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &fMat22);
|
uint32_t total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &fMat22);
|
||||||
|
if (GDI_ERROR == total_size) {
|
||||||
|
ensure_typeface_accessible(fRec.fFontID);
|
||||||
|
total_size = GetGlyphOutlineW(fDDC, glyph.fID, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, BUFFERSIZE, glyphbuf, &fMat22);
|
||||||
|
}
|
||||||
|
|
||||||
if (GDI_ERROR != total_size) {
|
if (GDI_ERROR != total_size) {
|
||||||
|
|
||||||
|
@ -1033,8 +1056,12 @@ SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
|
||||||
// To request design units, create a logical font whose height is specified
|
// To request design units, create a logical font whose height is specified
|
||||||
// as unitsPerEm.
|
// as unitsPerEm.
|
||||||
OUTLINETEXTMETRIC otm;
|
OUTLINETEXTMETRIC otm;
|
||||||
if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm) ||
|
unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
|
||||||
!GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
|
if (0 == otmRet) {
|
||||||
|
ensure_typeface_accessible(fontID);
|
||||||
|
otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
|
||||||
|
}
|
||||||
|
if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
lf.lfHeight = -SkToS32(otm.otmEMSquare);
|
lf.lfHeight = -SkToS32(otm.otmEMSquare);
|
||||||
|
@ -1178,6 +1205,10 @@ SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {
|
||||||
DWORD tables[2] = {kTTCTag, 0};
|
DWORD tables[2] = {kTTCTag, 0};
|
||||||
for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) {
|
for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) {
|
||||||
size_t bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
|
size_t bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
|
||||||
|
if (bufferSize == GDI_ERROR) {
|
||||||
|
ensure_typeface_accessible(uniqueID);
|
||||||
|
bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
|
||||||
|
}
|
||||||
if (bufferSize != GDI_ERROR) {
|
if (bufferSize != GDI_ERROR) {
|
||||||
stream = new SkMemoryStream(bufferSize);
|
stream = new SkMemoryStream(bufferSize);
|
||||||
if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(),
|
if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче