本文整理汇总了C++中GlyphPage类的典型用法代码示例。如果您正苦于以下问题:C++ GlyphPage类的具体用法?C++ GlyphPage怎么用?C++ GlyphPage使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了GlyphPage类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: FS_get_ascender_descender_leading
void SimpleFontData::platformInit()
{
FS_FIXED ascender = 0;
FS_FIXED descender = 0;
FS_FIXED leading = 0;
FsAscDescLeadSource source;
FS_LONG result;
if (m_platformData.size() > 0) {
// FIXME: hack! FS_get_ascender_descender_leading() returns ERR_NO_CURRENT_SFNT when size is 0, even though we called FS_set_scale and m_platformData.font()->cur_sfnt is not 0
result = FS_get_ascender_descender_leading(m_platformData.font(), &ascender, &descender, &leading, &source);
ASSERT_UNUSED(result, result == SUCCESS);
}
m_fontMetrics.setAscent(FS_ROUND(ascender));
m_fontMetrics.setDescent(FS_ROUND(descender));
m_fontMetrics.setLineGap(iTypeFixedToFloat(leading));
m_fontMetrics.setLineSpacing(lroundf(m_fontMetrics.ascent()) + lroundf(m_fontMetrics.descent()) + lroundf(m_fontMetrics.lineGap()));
FONT_METRICS metrics;
result = FS_font_metrics(m_platformData.font(), &metrics);
ASSERT_UNUSED(result, result == SUCCESS);
// m_fontMetrics.setUnitsPerEm(FS_get_design_units(m_platformData().font()));
m_fontMetrics.setUnitsPerEm(metrics.unitsPerEm);
FS_USHORT xRange = metrics.font_bbox.xMax - metrics.font_bbox.xMin;
m_maxCharWidth = roundf((xRange * roundf(m_platformData.size())) / metrics.unitsPerEm);
TTF_OS2 os2;
if (FS_get_table_structure(m_platformData.font(), TAG_OS2, &os2) == SUCCESS && os2.sxHeight && os2.xAvgCharWidth) {
FS_USHORT yppem = m_platformData.font()->lpm;
m_fontMetrics.setXHeight(static_cast<float>(os2.sxHeight) * yppem / metrics.unitsPerEm);
m_avgCharWidth = static_cast<float>(os2.xAvgCharWidth) * yppem / metrics.unitsPerEm;
} else {
// HACK
m_fontMetrics.setXHeight(m_fontMetrics.ascent() * 0.56);
m_fontMetrics.setHasXHeight(false);
m_avgCharWidth = m_fontMetrics.xHeight();
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (glyphPageZero) {
static const UChar32 xChar = 'x';
const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(xChar).glyph;
if (xGlyph) {
// In widthForGlyph(), xGlyph will be compared with
// m_zeroWidthSpaceGlyph, which isn't initialized yet here.
// Initialize it with zero to make sure widthForGlyph() returns
// the right width.
m_zeroWidthSpaceGlyph = 0;
m_avgCharWidth = widthForGlyph(xGlyph);
}
}
}
if (m_platformData.orientation() == Vertical && !isTextOrientationFallback())
m_hasVerticalGlyphs = FS_get_table(m_platformData.font(), openTypeTag('v', 'h', 'e', 'a'), TBL_QUERY, 0)
|| FS_get_table(m_platformData.font(), openTypeTag('V', 'O', 'R', 'G'), TBL_QUERY, 0);
}
示例2: glyphDataAndPageForNonCJKCharacterWithGlyphOrientation
static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForNonCJKCharacterWithGlyphOrientation(UChar32 character, NonCJKGlyphOrientation orientation, GlyphData& data, GlyphPage* page, unsigned pageNumber)
{
if (orientation == NonCJKGlyphOrientationUpright || shouldIgnoreRotation(character)) {
RefPtr<SimpleFontData> uprightFontData = data.fontData->uprightOrientationFontData();
GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getRootChild(uprightFontData.get(), pageNumber);
GlyphPage* uprightPage = uprightNode->page();
if (uprightPage) {
GlyphData uprightData = uprightPage->glyphDataForCharacter(character);
// If the glyphs are the same, then we know we can just use the horizontal glyph rotated vertically to be upright.
if (data.glyph == uprightData.glyph)
return std::make_pair(data, page);
// The glyphs are distinct, meaning that the font has a vertical-right glyph baked into it. We can't use that
// glyph, so we fall back to the upright data and use the horizontal glyph.
if (uprightData.fontData)
return std::make_pair(uprightData, uprightPage);
}
} else if (orientation == NonCJKGlyphOrientationVerticalRight) {
RefPtr<SimpleFontData> verticalRightFontData = data.fontData->verticalRightOrientationFontData();
GlyphPageTreeNode* verticalRightNode = GlyphPageTreeNode::getRootChild(verticalRightFontData.get(), pageNumber);
GlyphPage* verticalRightPage = verticalRightNode->page();
if (verticalRightPage) {
GlyphData verticalRightData = verticalRightPage->glyphDataForCharacter(character);
// If the glyphs are distinct, we will make the assumption that the font has a vertical-right glyph baked
// into it.
if (data.glyph != verticalRightData.glyph)
return std::make_pair(data, page);
// The glyphs are identical, meaning that we should just use the horizontal glyph.
if (verticalRightData.fontData)
return std::make_pair(verticalRightData, verticalRightPage);
}
}
return std::make_pair(data, page);
}
示例3: primaryFontHasGlyphForCharacter
bool Font::primaryFontHasGlyphForCharacter(UChar32 character) const
{
unsigned pageNumber = (character / GlyphPage::size);
GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(primaryFont(), pageNumber);
GlyphPage* page = node->page();
return page && page->fontDataForCharacter(character);
}
示例4: glyphDataAndPageForCJKCharacterWithoutSyntheticItalic
static inline std::pair<GlyphData, GlyphPage*> glyphDataAndPageForCJKCharacterWithoutSyntheticItalic(UChar32 character, GlyphData& data, GlyphPage* page, unsigned pageNumber)
{
RefPtr<SimpleFontData> nonItalicFontData = data.fontData->nonSyntheticItalicFontData();
GlyphPageTreeNode* nonItalicNode = GlyphPageTreeNode::getRootChild(nonItalicFontData.get(), pageNumber);
GlyphPage* nonItalicPage = nonItalicNode->page();
if (nonItalicPage) {
GlyphData nonItalicData = nonItalicPage->glyphDataForCharacter(character);
if (nonItalicData.fontData)
return std::make_pair(nonItalicData, nonItalicPage);
}
return std::make_pair(data, page);
}
示例5: SkScalarRound
void SimpleFontData::platformInit()
{
SkPaint paint;
SkPaint::FontMetrics metrics;
m_font.setupPaint(&paint);
paint.getFontMetrics(&metrics);
// Beware those who step here: This code is designed to match Win32 font
// metrics *exactly*.
if (metrics.fVDMXMetricsValid) {
m_ascent = metrics.fVDMXAscent;
m_descent = metrics.fVDMXDescent;
} else {
m_ascent = SkScalarRound(-metrics.fAscent);
m_descent = SkScalarRound(metrics.fHeight) - m_ascent;
}
if (metrics.fXHeight)
m_xHeight = metrics.fXHeight;
else {
// hack taken from the Windows port
m_xHeight = static_cast<float>(m_ascent) * 0.56;
}
m_lineGap = SkScalarRound(metrics.fLeading);
m_lineSpacing = m_ascent + m_descent + m_lineGap;
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
m_maxCharWidth = SkScalarRound(metrics.fXRange * SkScalarRound(m_font.size()));
if (metrics.fAvgCharWidth)
m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
else {
m_avgCharWidth = m_xHeight;
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (glyphPageZero) {
static const UChar32 x_char = 'x';
const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(x_char).glyph;
if (xGlyph)
m_avgCharWidth = widthForGlyph(xGlyph);
}
}
}
示例6: m_font
FontData::FontData(const FontPlatformData& f)
: m_font(f)
, m_treatAsFixedPitch(false)
, m_smallCapsFontData(0)
{
platformInit();
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (!glyphPageZero) {
LOG_ERROR("Failed to get glyph page zero.");
m_spaceGlyph = 0;
m_spaceWidth = 0;
m_adjustedSpaceWidth = 0;
determinePitch();
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
// Nasty hack to determine if we should round or ceil space widths.
// If the font is monospace or fake monospace we ceil to ensure that
// every character and the space are the same width. Otherwise we round.
m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
float width = widthForGlyph(m_spaceGlyph);
m_spaceWidth = width;
determinePitch();
m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
// Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
// Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
// See <http://bugs.webkit.org/show_bug.cgi?id=13178>
// Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
// are mapped to the ZERO WIDTH SPACE glyph.
Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
if (zeroWidthSpaceGlyph) {
if (zeroWidthSpaceGlyph != m_spaceGlyph)
m_glyphToWidthMap.setWidthForGlyph(zeroWidthSpaceGlyph, 0);
else
LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden.");
}
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
}
示例7: platformGlyphInit
void SimpleFontData::platformGlyphInit()
{
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (!glyphPageZero) {
WTF_LOG_ERROR("Failed to get glyph page zero.");
m_spaceGlyph = 0;
m_spaceWidth = 0;
m_zeroGlyph = 0;
m_adjustedSpaceWidth = 0;
determinePitch();
m_zeroWidthSpaceGlyph = 0;
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
return;
}
m_zeroWidthSpaceGlyph = glyphPageZero->glyphForCharacter(0);
// Nasty hack to determine if we should round or ceil space widths.
// If the font is monospace or fake monospace we ceil to ensure that
// every character and the space are the same width. Otherwise we round.
m_spaceGlyph = glyphPageZero->glyphForCharacter(' ');
float width = widthForGlyph(m_spaceGlyph);
m_spaceWidth = width;
m_zeroGlyph = glyphPageZero->glyphForCharacter('0');
m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
determinePitch();
m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
// Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
// Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
// See <http://bugs.webkit.org/show_bug.cgi?id=13178>
// Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
// are mapped to the ZERO WIDTH SPACE glyph.
if (m_zeroWidthSpaceGlyph == m_spaceGlyph) {
m_zeroWidthSpaceGlyph = 0;
WTF_LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width will not be overridden.");
}
m_missingGlyphData.fontData = this;
m_missingGlyphData.glyph = 0;
}
示例8: fillGlyphPage
static bool fillGlyphPage(GlyphPage& pageToFill, UChar* buffer, unsigned bufferLength, const Font* font)
{
#if ENABLE(SVG_FONTS)
if (auto* svgData = font->svgData())
return svgData->fillSVGGlyphPage(&pageToFill, buffer, bufferLength, font);
#endif
bool hasGlyphs = pageToFill.fill(buffer, bufferLength, font);
#if ENABLE(OPENTYPE_VERTICAL)
if (hasGlyphs && font->verticalData())
font->verticalData()->substituteWithVerticalGlyphs(font, &pageToFill);
#endif
return hasGlyphs;
}
示例9: ASSERT
void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNumber)
{
ASSERT(!m_page);
ASSERT(fontData);
// This function must not be called for the root of the tree, because that
// level does not contain any glyphs.
ASSERT(m_level > 0 && m_parent);
if (m_level == 1) {
// Children of the root hold pure pages. These will cover only one
// font data's glyphs, and will have glyph index 0 if the font data does not
// contain the glyph.
initializePurePage(fontData, pageNumber);
return;
}
// The parent's page will be 0 if we are level one or the parent's font data
// did not contain any glyphs for that page.
GlyphPage* parentPage = m_parent->page();
if (parentPage && parentPage->owner() != m_parent) {
// The page we're overriding may not be owned by our parent node.
// This happens when our parent node provides no useful overrides
// and just copies the pointer to an already-existing page (see
// below).
//
// We want our override to be shared by all nodes that reference
// that page to avoid duplication, and so standardize on having the
// page's owner collect all the overrides. Call getChild on the
// page owner with the desired font data (this will populate
// the page) and then reference it.
m_page = static_cast<GlyphPageTreeNode*>(parentPage->owner())->getNormalChild(fontData, pageNumber)->page();
return;
}
initializeOverridePage(fontData, pageNumber);
}
示例10: SkSetFourByteTag
void SimpleFontData::platformInit()
{
if (!m_platformData.size()) {
m_fontMetrics.reset();
m_avgCharWidth = 0;
m_maxCharWidth = 0;
return;
}
SkPaint paint;
SkPaint::FontMetrics metrics;
m_platformData.setupPaint(&paint);
paint.getFontMetrics(&metrics);
const SkFontID fontID = m_platformData.uniqueID();
static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
int pixelSize = m_platformData.size() + 0.5;
int vdmxAscent, vdmxDescent;
bool isVDMXValid = false;
size_t vdmxSize = SkFontHost::GetTableSize(fontID, vdmxTag);
if (vdmxSize && vdmxSize < maxVDMXTableSize) {
uint8_t* vdmxTable = (uint8_t*) fastMalloc(vdmxSize);
if (vdmxTable
&& SkFontHost::GetTableData(fontID, vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize
&& parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
isVDMXValid = true;
fastFree(vdmxTable);
}
float ascent;
float descent;
// Beware those who step here: This code is designed to match Win32 font
// metrics *exactly* (except the adjustment of ascent/descent on Linux/Android).
if (isVDMXValid) {
ascent = vdmxAscent;
descent = -vdmxDescent;
} else {
SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading;
ascent = SkScalarRound(-metrics.fAscent);
descent = SkScalarRound(height) - ascent;
#if OS(LINUX) || OS(ANDROID)
// When subpixel positioning is enabled, if the descent is rounded down, the descent part
// of the glyph may be truncated when displayed in a 'overflow: hidden' container.
// To avoid that, borrow 1 unit from the ascent when possible.
// FIXME: This can be removed if sub-pixel ascent/descent is supported.
if (platformData().fontRenderStyle().useSubpixelPositioning && descent < SkScalarToFloat(metrics.fDescent) && ascent >= 1) {
++descent;
--ascent;
}
#endif
}
m_fontMetrics.setAscent(ascent);
m_fontMetrics.setDescent(descent);
float xHeight;
if (metrics.fXHeight) {
xHeight = metrics.fXHeight;
m_fontMetrics.setXHeight(xHeight);
} else {
xHeight = ascent * 0.56; // Best guess from Windows font metrics.
m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setHasXHeight(false);
}
float lineGap = SkScalarToFloat(metrics.fLeading);
m_fontMetrics.setLineGap(lineGap);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
if ((vheaSize > 0) || (vorgSize > 0))
m_hasVerticalGlyphs = true;
}
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
SkScalar xRange = metrics.fXMax - metrics.fXMin;
m_maxCharWidth = SkScalarRound(xRange * SkScalarRound(m_platformData.size()));
if (metrics.fAvgCharWidth)
m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
else {
m_avgCharWidth = xHeight;
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (glyphPageZero) {
static const UChar32 xChar = 'x';
const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(xChar).glyph;
//.........这里部分代码省略.........
示例11: ASSERT
void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNumber)
{
ASSERT(!m_page);
// This function must not be called for the root of the tree, because that
// level does not contain any glyphs.
ASSERT(m_level > 0 && m_parent);
// The parent's page will be 0 if we are level one or the parent's font data
// did not contain any glyphs for that page.
GlyphPage* parentPage = m_parent->page();
// NULL FontData means we're being asked for the system fallback font.
if (fontData) {
if (m_level == 1) {
// Children of the root hold pure pages. These will cover only one
// font data's glyphs, and will have glyph index 0 if the font data does not
// contain the glyph.
unsigned start = pageNumber * GlyphPage::size;
UChar buffer[GlyphPage::size * 2 + 2];
unsigned bufferLength;
unsigned i;
// Fill in a buffer with the entire "page" of characters that we want to look up glyphs for.
if (start < 0x10000) {
bufferLength = GlyphPage::size;
for (i = 0; i < GlyphPage::size; i++)
buffer[i] = start + i;
if (start == 0) {
// Control characters must not render at all.
for (i = 0; i < 0x20; ++i)
buffer[i] = zeroWidthSpace;
for (i = 0x7F; i < 0xA0; i++)
buffer[i] = zeroWidthSpace;
buffer[softHyphen] = zeroWidthSpace;
// \n, \t, and nonbreaking space must render as a space.
buffer[newlineCharacter] = space;
buffer[characterTabulation] = space;
buffer[noBreakSpace] = space;
} else if (start == (leftToRightMark & ~(GlyphPage::size - 1))) {
// LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all.
buffer[leftToRightMark - start] = zeroWidthSpace;
buffer[rightToLeftMark - start] = zeroWidthSpace;
buffer[leftToRightEmbed - start] = zeroWidthSpace;
buffer[rightToLeftEmbed - start] = zeroWidthSpace;
buffer[leftToRightOverride - start] = zeroWidthSpace;
buffer[rightToLeftOverride - start] = zeroWidthSpace;
buffer[zeroWidthNonJoiner - start] = zeroWidthSpace;
buffer[zeroWidthJoiner - start] = zeroWidthSpace;
buffer[popDirectionalFormatting - start] = zeroWidthSpace;
} else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) {
// Object replacement character must not render at all.
buffer[objectReplacementCharacter - start] = zeroWidthSpace;
} else if (start == (zeroWidthNoBreakSpace & ~(GlyphPage::size - 1))) {
// ZWNBS/BOM must not render at all.
buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace;
}
} else {
bufferLength = GlyphPage::size * 2;
for (i = 0; i < GlyphPage::size; i++) {
int c = i + start;
buffer[i * 2] = U16_LEAD(c);
buffer[i * 2 + 1] = U16_TRAIL(c);
}
}
// Now that we have a buffer full of characters, we want to get back an array
// of glyph indices. This part involves calling into the platform-specific
// routine of our glyph map for actually filling in the page with the glyphs.
// Success is not guaranteed. For example, Times fails to fill page 260, giving glyph data
// for only 128 out of 256 characters.
bool haveGlyphs;
if (!fontData->isSegmented()) {
m_page = GlyphPage::createForSingleFontData(this, toSimpleFontData(fontData));
haveGlyphs = fill(m_page.get(), 0, GlyphPage::size, buffer, bufferLength, toSimpleFontData(fontData));
} else {
m_page = GlyphPage::createForMixedFontData(this);
haveGlyphs = false;
const SegmentedFontData* segmentedFontData = toSegmentedFontData(fontData);
for (int i = segmentedFontData->numRanges() - 1; i >= 0; i--) {
const FontDataRange& range = segmentedFontData->rangeAt(i);
// all this casting is to ensure all the parameters to min and max have the same type,
// to avoid ambiguous template parameter errors on Windows
int from = max(0, static_cast<int>(range.from()) - static_cast<int>(start));
int to = 1 + min(static_cast<int>(range.to()) - static_cast<int>(start), static_cast<int>(GlyphPage::size) - 1);
if (from >= static_cast<int>(GlyphPage::size) || to <= 0)
continue;
// If this is a custom font needs to be loaded, do not fill
// the page so that font fallback is used while loading.
RefPtr<CustomFontData> customData = range.fontData()->customFontData();
if (customData && customData->isLoadingFallback()) {
for (int j = from; j < to; j++) {
m_page->setCustomFontToLoad(j, customData.get());
haveGlyphs = true;
}
continue;
//.........这里部分代码省略.........
示例12: initGDIFont
void SimpleFontData::platformInit()
{
m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
m_scriptCache = 0;
m_scriptFontProperties = 0;
m_isSystemFont = false;
if (m_platformData.useGDI())
return initGDIFont();
CGFontRef font = m_platformData.cgFont();
int iAscent = CGFontGetAscent(font);
int iDescent = CGFontGetDescent(font);
int iLineGap = CGFontGetLeading(font);
unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
float pointSize = m_platformData.size();
float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
if (!isCustomFont()) {
HDC dc = GetDC(0);
HGDIOBJ oldFont = SelectObject(dc, m_platformData.hfont());
int faceLength = GetTextFace(dc, 0, 0);
Vector<WCHAR> faceName(faceLength);
GetTextFace(dc, faceLength, faceName.data());
m_isSystemFont = !wcscmp(faceName.data(), L"Lucida Grande");
SelectObject(dc, oldFont);
ReleaseDC(0, dc);
if (shouldApplyMacAscentHack()) {
// This code comes from FontDataMac.mm. We only ever do this when running regression tests so that our metrics will match Mac.
// We need to adjust Times, Helvetica, and Courier to closely match the
// vertical metrics of their Microsoft counterparts that are the de facto
// web standard. The AppKit adjustment of 20% is too big and is
// incorrectly added to line spacing, so we use a 15% adjustment instead
// and add it to the ascent.
if (!wcscmp(faceName.data(), L"Times") || !wcscmp(faceName.data(), L"Helvetica") || !wcscmp(faceName.data(), L"Courier"))
fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
}
}
m_fontMetrics.setAscent(fAscent);
m_fontMetrics.setDescent(fDescent);
m_fontMetrics.setLineGap(fLineGap);
m_fontMetrics.setLineSpacing(lroundf(fAscent) + lroundf(fDescent) + lroundf(fLineGap));
// Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
// Unfortunately, NSFont will round this for us so we don't quite get the right value.
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
if (xGlyph) {
CGRect xBox;
CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
// Use the maximum of either width or height because "x" is nearly square
// and web pages that foolishly use this metric for width will be laid out
// poorly if we return an accurate height. Classic case is Times 13 point,
// which has an "x" that is 7x6 pixels.
m_fontMetrics.setXHeight(scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), unitsPerEm) * pointSize);
} else {
int iXHeight = CGFontGetXHeight(font);
m_fontMetrics.setXHeight(scaleEmToUnits(iXHeight, unitsPerEm) * pointSize);
}
m_fontMetrics.setUnitsPerEm(unitsPerEm);
}
示例13: mirroredChar
// FIXME: It is unfortunate that this function needs to be passed the original cluster.
// It is only required for the platform's FontCache::getFontDataForCharacters(), and it means
// that this function is not correct if it transforms the character to uppercase and calls
// FontCache::getFontDataForCharacters() afterwards.
const GlyphData& Font::glyphDataForCharacter(UChar32 c, const UChar* cluster, unsigned clusterLength, bool mirror, bool attemptFontSubstitution) const
{
bool smallCaps = false;
if (m_fontDescription.smallCaps() && !Unicode::isUpper(c)) {
// Convert lowercase to upper.
UChar32 upperC = Unicode::toUpper(c);
if (upperC != c) {
c = upperC;
smallCaps = true;
}
}
if (mirror)
c = mirroredChar(c);
unsigned pageNumber = (c / GlyphPage::size);
GlyphPageTreeNode* node = pageNumber ? m_pages.get(pageNumber) : m_pageZero;
if (!node) {
node = GlyphPageTreeNode::getRootChild(primaryFont(), pageNumber);
if (pageNumber)
m_pages.set(pageNumber, node);
else
m_pageZero = node;
}
if (!attemptFontSubstitution && node->level() != 1)
node = GlyphPageTreeNode::getRootChild(primaryFont(), pageNumber);
while (true) {
GlyphPage* page = node->page();
if (page) {
const GlyphData& data = page->glyphDataForCharacter(c);
if (data.glyph || !attemptFontSubstitution) {
if (!smallCaps)
return data; // We have a glyph for the character in question in the current page (or we've been told not to fall back).
const FontData* smallCapsFontData = data.fontData->smallCapsFontData(m_fontDescription);
if (!smallCapsFontData)
// This should not happen, but if it does, we will return a big cap.
return data;
GlyphPageTreeNode* smallCapsNode = GlyphPageTreeNode::getRootChild(smallCapsFontData, pageNumber);
GlyphPage* smallCapsPage = smallCapsNode->page();
if (smallCapsPage) {
const GlyphData& data = smallCapsPage->glyphDataForCharacter(c);
if (data.glyph || !attemptFontSubstitution)
return data;
}
// Not attempting system fallback off the smallCapsFontData. This is the very unlikely case that
// a font has the lowercase character but not its uppercase version.
return smallCapsFontData->missingGlyphData();
}
} else if (!attemptFontSubstitution) {
if (smallCaps) {
if (const FontData* smallCapsFontData = primaryFont()->smallCapsFontData(m_fontDescription))
return smallCapsFontData->missingGlyphData();
}
return primaryFont()->missingGlyphData();
}
if (node->isSystemFallback()) {
// System fallback is character-dependent. When we get here, we
// know that the character in question isn't in the system fallback
// font's glyph page. Try to lazily create it here.
// Convert characters that shouldn't render to zero width spaces when asking what font is
// appropriate.
const FontData* characterFontData;
if (clusterLength == 1 && Font::treatAsZeroWidthSpace(cluster[0]))
#ifdef __OWB__
characterFontData = FontCache::getFontDataForCharacters(*this, &WebCore::zeroWidthSpace, 1);
#else
characterFontData = FontCache::getFontDataForCharacters(*this, &zeroWidthSpace, 1);
#endif //__OWB__
else
characterFontData = FontCache::getFontDataForCharacters(*this, cluster, clusterLength);
if (smallCaps)
characterFontData = characterFontData->smallCapsFontData(m_fontDescription);
if (characterFontData) {
// Got the fallback font, return the glyph page associated with
// it. We also store the FontData for the glyph in the fallback
// page for future use (it's lazily populated by us).
GlyphPage* fallbackPage = GlyphPageTreeNode::getRootChild(characterFontData, pageNumber)->page();
const GlyphData& data = fallbackPage ? fallbackPage->glyphDataForCharacter(c) : characterFontData->missingGlyphData();
if (!smallCaps)
page->setGlyphDataForCharacter(c, data.glyph, characterFontData);
return data;
}
// Even system fallback can fail.
// FIXME: Should the last resort font be used?
const GlyphData& data = primaryFont()->missingGlyphData();
//.........这里部分代码省略.........
示例14: ASSERT
GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, const TextRun& run, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
{
const SimpleFontData* primaryFont = font.primaryFont();
ASSERT(primaryFont);
pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror);
GlyphData glyphData = pair.first;
// Check if we have the missing glyph data, in which case we can just return.
GlyphData missingGlyphData = primaryFont->missingGlyphData();
if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
ASSERT(glyphData.fontData);
return glyphData;
}
// Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
const SimpleFontData* originalFontData = glyphData.fontData;
if (glyphData.fontData && !glyphData.fontData->isSVGFont()) {
if (TextRun::RenderingContext* renderingContext = run.renderingContext()) {
RenderObject* renderObject = static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
ASSERT(parentRenderObject);
if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag))
glyphData.fontData = primaryFont;
}
}
}
const SimpleFontData* fontData = glyphData.fontData;
if (fontData) {
if (!fontData->isSVGFont())
return glyphData;
SVGFontElement* fontElement = 0;
SVGFontFaceElement* fontFaceElement = 0;
const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
if (!fontElement || !fontFaceElement)
return glyphData;
// If we got here, we're dealing with a glyph defined in a SVG Font.
// The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
// This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
// arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
return glyphData;
}
GlyphPage* page = pair.second;
ASSERT(page);
FontFallbackList* fontList = font.fontList();
ASSERT(fontList);
// No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.)
// Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily
// remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly.
GlyphPageTreeNode* originalGlyphPageZero = fontList->glyphPageZero();
const FontFallbackList::GlyphPages& originalGlyphPages = fontList->glyphPages();
page->setGlyphDataForCharacter(character, glyphData.glyph, 0);
// Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror);
ASSERT(fallbackGlyphData.fontData != fontData);
// Restore original state of the SVG Font glyph table and the current font fallback list,
// to assure the next lookup of the same glyph won't immediately return the fallback glyph.
page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData);
fontList->setGlyphPageZero(originalGlyphPageZero);
fontList->setGlyphPages(originalGlyphPages);
ASSERT(fallbackGlyphData.fontData);
return fallbackGlyphData;
}
示例15: SkSetFourByteTag
void SimpleFontData::platformInit()
{
if (!m_platformData.size()) {
m_fontMetrics.reset();
m_avgCharWidth = 0;
m_maxCharWidth = 0;
return;
}
SkPaint paint;
SkPaint::FontMetrics metrics;
m_platformData.setupPaint(&paint);
paint.getFontMetrics(&metrics);
const SkFontID fontID = m_platformData.uniqueID();
static const uint32_t vdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
int pixelSize = m_platformData.size() + 0.5;
int vdmxAscent, vdmxDescent;
bool isVDMXValid = false;
size_t vdmxSize = SkFontHost::GetTableSize(fontID, vdmxTag);
if (vdmxSize && vdmxSize < maxVDMXTableSize) {
uint8_t* vdmxTable = (uint8_t*) fastMalloc(vdmxSize);
if (vdmxTable
&& SkFontHost::GetTableData(fontID, vdmxTag, 0, vdmxSize, vdmxTable) == vdmxSize
&& parseVDMX(&vdmxAscent, &vdmxDescent, vdmxTable, vdmxSize, pixelSize))
isVDMXValid = true;
fastFree(vdmxTable);
}
float ascent;
float descent;
// Beware those who step here: This code is designed to match Win32 font
// metrics *exactly*.
if (isVDMXValid) {
ascent = vdmxAscent;
descent = -vdmxDescent;
} else {
SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading;
ascent = SkScalarRound(-metrics.fAscent);
descent = SkScalarRound(height) - ascent;
}
m_fontMetrics.setAscent(ascent);
m_fontMetrics.setDescent(descent);
float xHeight;
if (metrics.fXHeight)
xHeight = metrics.fXHeight;
else {
// hack taken from the Windows port
xHeight = ascent * 0.56f;
}
float lineGap = SkScalarToFloat(metrics.fLeading);
m_fontMetrics.setLineGap(lineGap);
m_fontMetrics.setXHeight(xHeight);
m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
if ((vheaSize > 0) || (vorgSize > 0))
m_hasVerticalGlyphs = true;
}
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
SkScalar xRange = metrics.fXMax - metrics.fXMin;
m_maxCharWidth = SkScalarRound(xRange * SkScalarRound(m_platformData.size()));
if (metrics.fAvgCharWidth)
m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
else {
m_avgCharWidth = xHeight;
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (glyphPageZero) {
static const UChar32 x_char = 'x';
const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(x_char).glyph;
if (xGlyph)
m_avgCharWidth = widthForGlyph(xGlyph);
}
}
}