}
bool defaultPositioning = (positioning == SkTextBlob::kDefault_Positioning);
paint.setHinting(SkPaint::kNo_Hinting);
- SkAutoGlyphCache glyphCache(paint, nullptr, nullptr);
+
+ int emSize;
+ SkAutoGlyphCache glyphCache = SkPDFFont::MakeVectorCache(typeface, &emSize);
+
+ SkScalar textSize = paint.getTextSize();
+ SkScalar advanceScale = textSize * paint.getTextScaleX() / emSize;
SkPaint::Align alignment = paint.getTextAlign();
float alignmentFactor = SkPaint::kLeft_Align == alignment ? 0.0f :
if (defaultPositioning && alignment != SkPaint::kLeft_Align) {
SkScalar advance = 0;
for (int i = 0; i < glyphCount; ++i) {
- advance += glyphCache->getGlyphIDAdvance(glyphs[i]).fAdvanceX;
+ advance += advanceScale * glyphCache->getGlyphIDAdvance(glyphs[i]).fAdvanceX;
}
offset.offset(alignmentFactor * advance, 0);
}
return;
}
SkDynamicMemoryWStream* out = &content.entry()->fContent;
- SkScalar textSize = paint.getTextSize();
const SkTDArray<SkUnichar>& glyphToUnicode = metrics->fGlyphToUnicode;
out->writeText("BT\n");
SK_AT_SCOPE_EXIT(out->writeText("ET\n"));
- const SkGlyphID maxGlyphID = metrics->fLastGlyphID;
+ const SkGlyphID maxGlyphID = SkToU16(typeface->countGlyphs() - 1);
+
bool multiByteGlyphs = SkPDFFont::IsMultiByte(SkPDFFont::FontType(*metrics));
if (clusterator.reversedChars()) {
out->writeText("/ReversedChars BMC\n");
SkPoint xy{0, 0};
SkScalar advance{0};
if (!defaultPositioning) {
- advance = glyphCache->getGlyphIDAdvance(gid).fAdvanceX;
+ advance = advanceScale * glyphCache->getGlyphIDAdvance(gid).fAdvanceX;
xy = SkTextBlob::kFull_Positioning == positioning
? SkPoint{pos[2 * index], pos[2 * index + 1]}
: SkPoint{pos[index], 0};
#include "sample/chromium/font_subsetter.h"
#endif
+SkAutoGlyphCache SkPDFFont::MakeVectorCache(SkTypeface* face, int* size) {
+ SkPaint tmpPaint;
+ tmpPaint.setHinting(SkPaint::kNo_Hinting);
+ tmpPaint.setTypeface(sk_ref_sp(face));
+ int unitsPerEm = face->getUnitsPerEm();
+ if (unitsPerEm <= 0) {
+ unitsPerEm = 1024;
+ }
+ if (size) {
+ *size = unitsPerEm;
+ }
+ tmpPaint.setTextSize((SkScalar)unitsPerEm);
+ const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+ SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
+ SkASSERT(glyphCache.get());
+ return glyphCache;
+}
+
namespace {
// PDF's notion of symbolic vs non-symbolic is related to the character set, not
// symbols vs. characters. Rarely is a font the right character set to call it
// File-Local Functions
///////////////////////////////////////////////////////////////////////////////
-static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) {
- SkPaint tmpPaint;
- tmpPaint.setHinting(SkPaint::kNo_Hinting);
- tmpPaint.setTypeface(sk_ref_sp(face));
- if (0 == size) {
- SkASSERT(face);
- tmpPaint.setTextSize((SkScalar)face->getUnitsPerEm());
- } else {
- tmpPaint.setTextSize(size);
- }
- const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
- SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
- SkASSERT(glyphCache.get());
- return glyphCache;
-}
-
// scale from em-units to base-1000, returning as a SkScalar
SkScalar from_font_units(SkScalar scaled, uint16_t emSize) {
if (emSize == 1000) {
nullptr, 0));
if (!metrics) {
metrics = sk_make_sp<SkAdvancedTypefaceMetrics>();
- metrics->fLastGlyphID = SkToU16(count - 1);
}
- SkASSERT(metrics->fLastGlyphID == SkToU16(count - 1));
return *canon->fTypefaceMetrics.set(id, metrics.release());
}
sk_sp<SkTypeface> typeface(sk_ref_sp(face));
SkASSERT(typeface);
- SkGlyphID lastGlyph = metrics.fLastGlyphID;
- SkASSERT(typeface->countGlyphs() == SkToInt(1 + metrics.fLastGlyphID));
+ SkGlyphID lastGlyph = SkToU16(typeface->countGlyphs() - 1);
// should be caught by SkPDFDevice::internalDrawText
SkASSERT(glyphID <= lastGlyph);
static void add_common_font_descriptor_entries(SkPDFDict* descriptor,
const SkAdvancedTypefaceMetrics& metrics,
+ uint16_t emSize,
int16_t defaultWidth) {
- const uint16_t emSize = metrics.fEmSize;
descriptor->insertName("FontName", metrics.fFontName);
descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic));
descriptor->insertScalar("Ascent",
scaleFromFontUnits(metrics.fCapHeight, emSize));
descriptor->insertInt("ItalicAngle", metrics.fItalicAngle);
descriptor->insertObject(
- "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize));
+ "FontBBox", makeFontBBox(metrics.fBBox, emSize));
if (defaultWidth > 0) {
descriptor->insertScalar("MissingWidth",
scaleFromFontUnits(defaultWidth, emSize));
SkASSERT(face);
auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
- add_common_font_descriptor_entries(descriptor.get(), metrics, 0);
+ uint16_t emSize = SkToU16(this->typeface()->getUnitsPerEm());
+ add_common_font_descriptor_entries(descriptor.get(), metrics, emSize , 0);
int ttcIndex;
std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex));
sysInfo->insertInt("Supplement", 0);
newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
- uint16_t emSize = metrics.fEmSize;
int16_t defaultWidth = 0;
{
- SkAutoGlyphCache glyphCache = vector_cache(face);
+ int emSize;
+ SkAutoGlyphCache glyphCache = SkPDFFont::MakeVectorCache(face, &emSize);
sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
- glyphCache.get(), &this->glyphUsage(), emSize, &defaultWidth);
+ glyphCache.get(), &this->glyphUsage(), SkToS16(emSize), &defaultWidth);
if (widths && widths->size() > 0) {
newCIDFont->insertObject("W", std::move(widths));
}
newCIDFont->insertScalar(
- "DW", scaleFromFontUnits(defaultWidth, emSize));
+ "DW", scaleFromFontUnits(defaultWidth, SkToS16(emSize)));
}
////////////////////////////////////////////////////////////////////////////
SkTypeface* typeface,
const SkAdvancedTypefaceMetrics& info) {
auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
- add_common_font_descriptor_entries(descriptor.get(), info, 0);
+ uint16_t emSize = SkToU16(typeface->getUnitsPerEm());
+ add_common_font_descriptor_entries(descriptor.get(), info, emSize, 0);
if (!can_embed(info)) {
return descriptor;
}
font->insertInt("FirstChar", (size_t)0);
font->insertInt("LastChar", (size_t)glyphCount);
{
- SkAutoGlyphCache glyphCache = vector_cache(typeface);
+ int emSize;
+ SkAutoGlyphCache glyphCache = SkPDFFont::MakeVectorCache(typeface, &emSize);
auto widths = sk_make_sp<SkPDFArray>();
SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
- const uint16_t emSize = info.fEmSize;
- widths->appendScalar(from_font_units(advance, emSize));
+ widths->appendScalar(from_font_units(advance, SkToU16(emSize)));
for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) {
advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX;
- widths->appendScalar(from_font_units(advance, emSize));
+ widths->appendScalar(from_font_units(advance, SkToU16(emSize)));
}
font->insertObject("Widths", std::move(widths));
}
static void add_type3_font_info(SkPDFCanon* canon,
SkPDFDict* font,
SkTypeface* typeface,
- SkScalar emSize,
const SkBitSet& subset,
SkGlyphID firstGlyphID,
SkGlyphID lastGlyphID) {
while (lastGlyphID > firstGlyphID && !subset.has(lastGlyphID)) {
--lastGlyphID;
}
- SkASSERT(emSize > 0.0f);
- SkAutoGlyphCache cache = vector_cache(typeface, emSize);
+ int unitsPerEm;
+ SkAutoGlyphCache cache = SkPDFFont::MakeVectorCache(typeface, &unitsPerEm);
+ SkScalar emSize = (SkScalar)unitsPerEm;
font->insertName("Subtype", "Type3");
// Flip about the x-axis and scale by 1/emSize.
SkMatrix fontMatrix;
: SkPDFFont(std::move(info)) {}
void SkPDFType3Font::getFontSubset(SkPDFCanon* canon) {
- const SkAdvancedTypefaceMetrics* info =
- SkPDFFont::GetMetrics(this->typeface(), canon);
- SkASSERT(info);
- uint16_t emSize = info->fEmSize > 0 ? info->fEmSize : 1000;
- add_type3_font_info(canon, this, this->typeface(), (SkScalar)emSize,
- this->glyphUsage(),
+ add_type3_font_info(canon, this, this->typeface(), this->glyphUsage(),
this->firstGlyphID(), this->lastGlyphID());
}