Basic changes to get XPS drawing text. Basic maintenance to get basic things working. Most of the motivation is to use better ownership and iteration patterns. Change-Id: If8ffe0c7b2bddd55259ac8fa119fc9e233b9249d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/236616 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Hal Canary <halcanary@google.com>
diff --git a/src/ports/SkImageGeneratorWIC.cpp b/src/ports/SkImageGeneratorWIC.cpp index 16ecffb..cea31ad 100644 --- a/src/ports/SkImageGeneratorWIC.cpp +++ b/src/ports/SkImageGeneratorWIC.cpp
@@ -8,6 +8,7 @@ #include "include/core/SkStream.h" #include "include/ports/SkImageGeneratorWIC.h" #include "include/private/SkTemplates.h" +#include "src/core/SkMakeUnique.h" #include "src/utils/win/SkIStream.h" #include "src/utils/win/SkTScopedComPtr.h" @@ -59,7 +60,7 @@ SkTScopedComPtr<IStream> iStream; // Note that iStream will take ownership of the new memory stream because // we set |deleteOnRelease| to true. - hr = SkIStream::CreateFromSkStream(new SkMemoryStream(data), true, &iStream); + hr = SkIStream::CreateFromSkStream(skstd::make_unique<SkMemoryStream>(data), &iStream); if (FAILED(hr)) { return nullptr; }
diff --git a/src/utils/win/SkIStream.cpp b/src/utils/win/SkIStream.cpp index e19128b..93b483b 100644 --- a/src/utils/win/SkIStream.cpp +++ b/src/utils/win/SkIStream.cpp
@@ -87,26 +87,21 @@ /** * SkIStream */ -SkIStream::SkIStream(SkStream* stream, bool deleteOnRelease) +SkIStream::SkIStream(std::unique_ptr<SkStreamAsset> stream) : SkBaseIStream() - , fSkStream(stream) - , fDeleteOnRelease(deleteOnRelease) + , fSkStream(std::move(stream)) , fLocation() { this->fSkStream->rewind(); } -SkIStream::~SkIStream() { - if (fDeleteOnRelease) { - delete this->fSkStream; - } -} +SkIStream::~SkIStream() {} -HRESULT SkIStream::CreateFromSkStream(SkStream* stream, bool deleteOnRelease, IStream ** ppStream) { +HRESULT SkIStream::CreateFromSkStream(std::unique_ptr<SkStreamAsset> stream, IStream** ppStream) { if (nullptr == stream) { return E_INVALIDARG; } - *ppStream = new SkIStream(stream, deleteOnRelease); + *ppStream = new SkIStream(std::move(stream)); return S_OK; } @@ -155,8 +150,6 @@ if (!this->fSkStream->rewind()) { hr = E_FAIL; } else { - // FIXME: Should not depend on getLength. - // See https://code.google.com/p/skia/issues/detail?id=1570 size_t skip = static_cast<size_t>(this->fSkStream->getLength() + liDistanceToMove.QuadPart); size_t skipped = this->fSkStream->skip(skip); @@ -183,8 +176,6 @@ return STG_E_INVALIDFLAG; } pStatstg->pwcsName = nullptr; - // FIXME: Should not depend on getLength - // See https://code.google.com/p/skia/issues/detail?id=1570 pStatstg->cbSize.QuadPart = this->fSkStream->getLength(); pStatstg->clsid = CLSID_NULL; pStatstg->type = STGTY_STREAM;
diff --git a/src/utils/win/SkIStream.h b/src/utils/win/SkIStream.h index a8a3ee7..3c1af96 100644 --- a/src/utils/win/SkIStream.h +++ b/src/utils/win/SkIStream.h
@@ -62,7 +62,7 @@ */ class SkIStream : public SkBaseIStream { public: - HRESULT static CreateFromSkStream(SkStream* stream, bool fDeleteOnRelease, IStream** ppStream); + HRESULT static CreateFromSkStream(std::unique_ptr<SkStreamAsset>, IStream** ppStream); SK_STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead) override; SK_STDMETHODIMP Write(void const* pv, ULONG cb, ULONG* pcbWritten) override; @@ -72,11 +72,10 @@ SK_STDMETHODIMP Stat(STATSTG* pStatstg, DWORD grfStatFlag) override; private: - SkStream *fSkStream; - const bool fDeleteOnRelease; + const std::unique_ptr<SkStream> fSkStream; ULARGE_INTEGER fLocation; - SkIStream(SkStream* stream, bool fDeleteOnRelease); + explicit SkIStream(std::unique_ptr<SkStreamAsset>); ~SkIStream() override; };
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp index 46bf6c1..cebf60d 100644 --- a/src/xps/SkXPSDevice.cpp +++ b/src/xps/SkXPSDevice.cpp
@@ -40,6 +40,7 @@ #include "src/core/SkEndian.h" #include "src/core/SkGeometry.h" #include "src/core/SkImagePriv.h" +#include "src/core/SkMakeUnique.h" #include "src/core/SkMaskFilterBase.h" #include "src/core/SkRasterClip.h" #include "src/core/SkStrikeCache.h" @@ -119,18 +120,6 @@ SkXPSDevice::~SkXPSDevice() {} -SkXPSDevice::TypefaceUse::TypefaceUse() - : typefaceId(0xffffffff) - , fontData(nullptr) - , xpsFont(nullptr) - , glyphsUsed(nullptr) {} - -SkXPSDevice::TypefaceUse::~TypefaceUse() { - //xpsFont owns fontData ref - this->xpsFont->Release(); - delete this->glyphsUsed; -} - bool SkXPSDevice::beginPortfolio(SkWStream* outputStream, IXpsOMObjectFactory* factory) { SkASSERT(factory); fXpsFactory.reset(SkRefComPtr(factory)); @@ -328,28 +317,28 @@ return true; } -static HRESULT subset_typeface(SkXPSDevice::TypefaceUse* current) { +static HRESULT subset_typeface(const SkXPSDevice::TypefaceUse& current) { //CreateFontPackage wants unsigned short. //Microsoft, Y U NO stdint.h? std::vector<unsigned short> keepList; - current->glyphsUsed->getSetValues([&keepList](unsigned v) { + current.glyphsUsed.getSetValues([&keepList](unsigned v) { keepList.push_back((unsigned short)v); }); - int ttcCount = (current->ttcIndex + 1); + int ttcCount = (current.ttcIndex + 1); //The following are declared with the types required by CreateFontPackage. unsigned char *fontPackageBufferRaw = nullptr; unsigned long fontPackageBufferSize; unsigned long bytesWritten; unsigned long result = CreateFontPackage( - (unsigned char *) current->fontData->getMemoryBase(), - (unsigned long) current->fontData->getLength(), + (unsigned char *) current.fontData->getMemoryBase(), + (unsigned long) current.fontData->getLength(), &fontPackageBufferRaw, &fontPackageBufferSize, &bytesWritten, TTFCFP_FLAGS_SUBSET | TTFCFP_FLAGS_GLYPHLIST | (ttcCount > 0 ? TTFCFP_FLAGS_TTC : 0), - current->ttcIndex, + current.ttcIndex, TTFCFP_SUBSET, 0, 0, @@ -404,17 +393,17 @@ newStream->setMemoryOwned(fontPackageBuffer.release(), bytesWritten + extra); SkTScopedComPtr<IStream> newIStream; - SkIStream::CreateFromSkStream(newStream.release(), true, &newIStream); + SkIStream::CreateFromSkStream(std::move(newStream), &newIStream); XPS_FONT_EMBEDDING embedding; - HRM(current->xpsFont->GetEmbeddingOption(&embedding), + HRM(current.xpsFont->GetEmbeddingOption(&embedding), "Could not get embedding option from font."); SkTScopedComPtr<IOpcPartUri> partUri; - HRM(current->xpsFont->GetPartName(&partUri), + HRM(current.xpsFont->GetPartName(&partUri), "Could not get part uri from font."); - HRM(current->xpsFont->SetContent( + HRM(current.xpsFont->SetContent( newIStream.get(), embedding, partUri.get()), @@ -425,16 +414,14 @@ bool SkXPSDevice::endPortfolio() { //Subset fonts - if (!this->fTypefaces.empty()) { - SkXPSDevice::TypefaceUse* current = &this->fTypefaces.front(); - const TypefaceUse* last = &this->fTypefaces.back(); - for (; current <= last; ++current) { - //Ignore return for now, if it didn't subset, let it be. - subset_typeface(current); - } + for (const TypefaceUse& current : this->fTypefaces) { + //Ignore return for now, if it didn't subset, let it be. + subset_typeface(current); } - HRBM(this->fPackageWriter->Close(), "Could not close writer."); + if (this->fPackageWriter) { + HRBM(this->fPackageWriter->Close(), "Could not close writer."); + } return true; } @@ -473,6 +460,9 @@ return XPS_SPREAD_METHOD_REPEAT; case SkTileMode::kMirror: return XPS_SPREAD_METHOD_REFLECT; + case SkTileMode::kDecal: + // TODO: fake + return XPS_SPREAD_METHOD_PAD; default: SkDEBUGFAIL("Unknown tile mode."); } @@ -637,10 +627,8 @@ if (!SkEncodeImage(&write, bitmap, SkEncodedImageFormat::kPNG, 100)) { HRM(E_FAIL, "Unable to encode bitmap as png."); } - SkMemoryStream* read = new SkMemoryStream; - read->setData(write.detachAsData()); - SkTScopedComPtr<IStream> readWrapper; - HRM(SkIStream::CreateFromSkStream(read, true, &readWrapper), + SkTScopedComPtr<IStream> read; + HRM(SkIStream::CreateFromSkStream(write.detachAsStream(), &read), "Could not create stream from png data."); const size_t size = @@ -656,7 +644,7 @@ SkTScopedComPtr<IXpsOMImageResource> imageResource; HRM(this->fXpsFactory->CreateImageResource( - readWrapper.get(), + read.get(), XPS_IMAGE_TYPE_PNG, imagePartUri.get(), &imageResource), @@ -1143,29 +1131,15 @@ return S_OK; } -template <typename F, typename... Args> -void draw(SkClipStackDevice* dev, F f, Args&&... args) { - SkIRect r = dev->devClipBounds(); - SkRasterClip rc(r); - SkDraw draw; - draw.fMatrix = &dev->ctm(); - draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0); - draw.fRC = &rc; - (draw.*f)(std::forward<Args>(args)...); -} - - void SkXPSDevice::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[], const SkPaint& paint) { - draw(this, &SkDraw::drawPoints, mode, count, points, paint, this); + //TODO } void SkXPSDevice::drawVertices(const SkVertices* v, const SkVertices::Bone bones[], int boneCount, SkBlendMode blendMode, const SkPaint& paint) { - draw(this, &SkDraw::drawVertices, v->mode(), v->vertexCount(), v->positions(), v->texCoords(), - v->colors(), v->boneIndices(), v->boneWeights(), blendMode, v->indices(), v->indexCount(), - paint, bones, boneCount); + //TODO } void SkXPSDevice::drawPaint(const SkPaint& origPaint) { @@ -1651,7 +1625,7 @@ return; } } - // The xpsCompatiblePath is noW inverse even odd, so fall through. + // The xpsCompatiblePath is now inverse even odd, so fall through. case SkPath::kInverseEvenOdd_FillType: { const SkRect universe = SkRect::MakeLTRB( 0, 0, @@ -1704,9 +1678,13 @@ } HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) { + if (this->cs().isWideOpen()) { + return S_OK; + } SkPath clipPath; // clipPath.addRect(this->cs().bounds(size(*this))); (void)this->cs().asPath(&clipPath); + // TODO: handle all the kinds of paths, like drawPath does return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD); } HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual, @@ -1740,22 +1718,16 @@ SkDEBUGF("XPS drawSprite not yet implemented."); } -#if 0 - -HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint, +HRESULT SkXPSDevice::CreateTypefaceUse(const SkFont& font, TypefaceUse** typefaceUse) { - SkAutoResolveDefaultTypeface typeface(paint.getTypeface()); + SkAutoResolveDefaultTypeface typeface(font.getTypeface()); //Check cache. const SkFontID typefaceID = typeface->uniqueID(); - if (!this->fTypefaces.empty()) { - TypefaceUse* current = &this->fTypefaces.front(); - const TypefaceUse* last = &this->fTypefaces.back(); - for (; current <= last; ++current) { - if (current->typefaceId == typefaceID) { - *typefaceUse = current; - return S_OK; - } + for (TypefaceUse& current : this->fTypefaces) { + if (current.typefaceId == typefaceID) { + *typefaceUse = ¤t; + return S_OK; } } @@ -1766,8 +1738,11 @@ SkTScopedComPtr<IStream> fontStream; int ttcIndex; std::unique_ptr<SkStreamAsset> fontData = typeface->openStream(&ttcIndex); + if (!fontData) { + return E_NOTIMPL; + } //TODO: cannot handle FON fonts. - HRM(SkIStream::CreateFromSkStream(fontData.release(), true, &fontStream), + HRM(SkIStream::CreateFromSkStream(fontData->duplicate(), &fontStream), "Could not create font stream."); const size_t size = @@ -1795,17 +1770,14 @@ fontData->getLength() >= sizeof(SkTTCFHeader) && ((SkTTCFHeader*)data)->ttcTag == SkTTCFHeader::TAG); - TypefaceUse& newTypefaceUse = this->fTypefaces.push_back(); - newTypefaceUse.typefaceId = typefaceID; - newTypefaceUse.ttcIndex = isTTC ? ttcIndex : -1; - newTypefaceUse.fontData = fontData; - newTypefaceUse.xpsFont = xpsFontResource.release(); - auto glyphCache = - SkStrikeCache::FindOrCreateStrikeExclusive( - paint, this->surfaceProps(), - SkScalerContextFlags::kNone, SkMatrix::I()); - unsigned int glyphCount = glyphCache->getGlyphCount(); - newTypefaceUse.glyphsUsed = new SkBitSet(glyphCount); + int glyphCount = typeface->countGlyphs(); + + TypefaceUse& newTypefaceUse = this->fTypefaces.emplace_back( + typefaceID, + isTTC ? ttcIndex : -1, + std::move(fontData), + std::move(xpsFontResource), + glyphCount); *typefaceUse = &newTypefaceUse; return S_OK; @@ -1813,7 +1785,7 @@ HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory, IXpsOMCanvas* canvas, - TypefaceUse* font, + const TypefaceUse* font, LPCWSTR text, XPS_GLYPH_INDEX* xpsGlyphs, UINT32 xpsGlyphsLen, @@ -1823,13 +1795,13 @@ const SkMatrix& transform, const SkPaint& paint) { SkTScopedComPtr<IXpsOMGlyphs> glyphs; - HRM(xpsFactory->CreateGlyphs(font->xpsFont, &glyphs), "Could not create glyphs."); + HRM(xpsFactory->CreateGlyphs(font->xpsFont.get(), &glyphs), "Could not create glyphs."); HRM(glyphs->SetFontFaceIndex(font->ttcIndex), "Could not set glyph font face index."); //XPS uses affine transformations for everything... //...except positioning text. bool useCanvasForClip; - if ((transform.getType() & ~SkMatrix::kTranslate_Mask) == 0) { + if (transform.isTranslate()) { origin->x += SkScalarToFLOAT(transform.getTranslateX()); origin->y += SkScalarToFLOAT(transform.getTranslateY()); useCanvasForClip = false; @@ -1904,16 +1876,6 @@ return S_OK; } -static int num_glyph_guess(SkTextEncoding encoding, const void* text, size_t byteLength) { - static_assert((int)SkTypeface::kUTF8_Encoding == (int)SkTextEncoding::kUTF8, ""); - static_assert((int)SkTypeface::kUTF16_Encoding == (int)SkTextEncoding::kUTF16, ""); - static_assert((int)SkTypeface::kUTF32_Encoding == (int)SkTextEncoding::kUTF32, ""); - if (encoding == SkTextEncoding::kGlyphID) { - return SkToInt(byteLength / 2); - } - return SkUTFN_CountUnichars((SkTypeface::Encoding)encoding, text, byteLength); -} - static bool text_must_be_pathed(const SkPaint& paint, const SkMatrix& matrix) { const SkPaint::Style style = paint.getStyle(); return matrix.hasPerspective() @@ -1923,108 +1885,63 @@ ; } -typedef SkTDArray<XPS_GLYPH_INDEX> GlyphRun; +void SkXPSDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList) { -class ProcessOneGlyph { -public: - ProcessOneGlyph(FLOAT centemPerUnit, SkBitSet* glyphUse, GlyphRun* xpsGlyphs) - : fCentemPerUnit(centemPerUnit) - , fGlyphUse(glyphUse) - , fXpsGlyphs(xpsGlyphs) { } + const SkPaint& paint = glyphRunList.paint(); + for (const auto& run : glyphRunList) { + const SkGlyphID* glyphIDs = run.glyphsIDs().data(); + size_t glyphCount = run.glyphsIDs().size(); + const SkFont& font = run.font(); - void operator()(const SkGlyph& glyph, SkPoint position, SkPoint) { - SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0); - - SkScalar x = position.fX; - SkScalar y = position.fY; - - XPS_GLYPH_INDEX* xpsGlyph = fXpsGlyphs->append(); - uint16_t glyphID = glyph.getGlyphID(); - fGlyphUse->set(glyphID); - xpsGlyph->index = glyphID; - if (1 == fXpsGlyphs->count()) { - xpsGlyph->advanceWidth = 0.0f; - xpsGlyph->horizontalOffset = SkScalarToFloat(x) * fCentemPerUnit; - xpsGlyph->verticalOffset = SkScalarToFloat(y) * -fCentemPerUnit; + if (!glyphCount || !glyphIDs || font.getSize() <= 0) { + continue; } - else { - const XPS_GLYPH_INDEX& first = (*fXpsGlyphs)[0]; - xpsGlyph->advanceWidth = 0.0f; - xpsGlyph->horizontalOffset = (SkScalarToFloat(x) * fCentemPerUnit) - - first.horizontalOffset; - xpsGlyph->verticalOffset = (SkScalarToFloat(y) * -fCentemPerUnit) - - first.verticalOffset; + + TypefaceUse* typeface; + if (FAILED(CreateTypefaceUse(font, &typeface)) || text_must_be_pathed(paint, this->ctm())) { + SkPath path; + //TODO: make this work, Draw currently does not handle as well. + //paint.getTextPath(text, byteLength, x, y, &path); + //this->drawPath(path, paint, nullptr, true); + //TODO: add automation "text" + continue; } + + //TODO: handle font scale and skew in x (text_scale_skew) + + // Advance width and offsets for glyphs measured in hundredths of the font em size + // (XPS Spec 5.1.3). + FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(font.getSize()); + SkAutoSTMalloc<32, XPS_GLYPH_INDEX> xpsGlyphs(glyphCount); + + for (size_t i = 0; i < glyphCount; ++i) { + const SkPoint& position = run.positions()[i]; + XPS_GLYPH_INDEX& xpsGlyph = xpsGlyphs[i]; + xpsGlyph.index = glyphIDs[i]; + xpsGlyph.advanceWidth = 0.0f; + xpsGlyph.horizontalOffset = (SkScalarToFloat(position.fX) * centemPerUnit); + xpsGlyph.verticalOffset = (SkScalarToFloat(position.fY) * -centemPerUnit); + typeface->glyphsUsed.set(xpsGlyph.index); + } + + XPS_POINT origin = { + glyphRunList.origin().x(), + glyphRunList.origin().y(), + }; + + HRV(AddGlyphs(this->fXpsFactory.get(), + this->fCurrentXpsCanvas.get(), + typeface, + nullptr, + xpsGlyphs.get(), glyphCount, + &origin, + SkScalarToFLOAT(font.getSize()), + XPS_STYLE_SIMULATION_NONE, + this->ctm(), + paint)); } - -private: - /** [in] Advance width and offsets for glyphs measured in - hundredths of the font em size (XPS Spec 5.1.3). */ - const FLOAT fCentemPerUnit; - /** [in,out] The accumulated glyphs used in the current typeface. */ - SkBitSet* const fGlyphUse; - /** [out] The glyphs to draw. */ - GlyphRun* const fXpsGlyphs; -}; - -void SkXPSDevice::drawPosText(const void* text, size_t byteLen, - const SkScalar pos[], int scalarsPerPos, - const SkPoint& offset, const SkPaint& paint) { - if (byteLen < 1) return; - - if (text_must_be_pathed(paint, this->ctm())) { - SkPath path; - //TODO: make this work, Draw currently does not handle as well. - //paint.getTextPath(text, byteLength, x, y, &path); - //this->drawPath(path, paint, nullptr, true); - //TODO: add automation "text" - return; - } - - TypefaceUse* typeface; - HRV(CreateTypefaceUse(paint, &typeface)); - - auto cache = - SkStrikeCache::FindOrCreateStrikeExclusive( - paint, this->surfaceProps(), - SkScalerContextFlags::kNone, SkMatrix::I()); - - // Advance width and offsets for glyphs measured in hundredths of the font em size - // (XPS Spec 5.1.3). - FLOAT centemPerUnit = 100.0f / SkScalarToFLOAT(paint.getTextSize()); - GlyphRun xpsGlyphs; - xpsGlyphs.setReserve(num_glyph_guess(paint.getTextEncoding(), - static_cast<const char*>(text), byteLen)); - - ProcessOneGlyph processOneGlyph(centemPerUnit, typeface->glyphsUsed, &xpsGlyphs); - - SkFindAndPlaceGlyph::ProcessPosText( - paint.getTextEncoding(), static_cast<const char*>(text), byteLen, - offset, SkMatrix::I(), pos, scalarsPerPos, cache.get(), processOneGlyph); - - if (xpsGlyphs.count() == 0) { - return; - } - - XPS_POINT origin = { - xpsGlyphs[0].horizontalOffset / centemPerUnit, - xpsGlyphs[0].verticalOffset / -centemPerUnit, - }; - xpsGlyphs[0].horizontalOffset = 0.0f; - xpsGlyphs[0].verticalOffset = 0.0f; - - HRV(AddGlyphs(this->fXpsFactory.get(), - this->fCurrentXpsCanvas.get(), - typeface, - nullptr, - xpsGlyphs.begin(), xpsGlyphs.count(), - &origin, - SkScalarToFLOAT(paint.getTextSize()), - XPS_STYLE_SIMULATION_NONE, - this->ctm(), - paint)); } -#endif + void SkXPSDevice::drawDevice( SkBaseDevice* dev, int x, int y, const SkPaint&) {
diff --git a/src/xps/SkXPSDevice.h b/src/xps/SkXPSDevice.h index d9b7bab..f37bb2b 100644 --- a/src/xps/SkXPSDevice.h +++ b/src/xps/SkXPSDevice.h
@@ -94,27 +94,26 @@ const SkRect* srcOrNull, const SkRect& dst, const SkPaint& paint, SkCanvas::SrcRectConstraint) override; - void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override { - SK_ABORT("Needs an implementation"); - } + void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override; void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode, const SkPaint&) override; void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override; private: - class TypefaceUse : ::SkNoncopyable { + class TypefaceUse { public: - SkFontID typefaceId; - int ttcIndex; - SkStream* fontData; - IXpsOMFontResource* xpsFont; - SkBitSet* glyphsUsed; - - explicit TypefaceUse(); - ~TypefaceUse(); + TypefaceUse(SkFontID id, int index, std::unique_ptr<SkStream> data, + SkTScopedComPtr<IXpsOMFontResource> xps, size_t numGlyphs) + : typefaceId(id), ttcIndex(index), fontData(std::move(data)) + , xpsFont(std::move(xps)), glyphsUsed(numGlyphs) {} + const SkFontID typefaceId; + const int ttcIndex; + const std::unique_ptr<SkStream> fontData; + const SkTScopedComPtr<IXpsOMFontResource> xpsFont; + SkBitSet glyphsUsed; }; - friend HRESULT subset_typeface(TypefaceUse* current); + friend HRESULT subset_typeface(const TypefaceUse& current); bool createCanvasForLayer(); @@ -207,13 +206,13 @@ IXpsOMGeometryFigure** xpsQuad); HRESULT CreateTypefaceUse( - const SkPaint& paint, + const SkFont& font, TypefaceUse** fontResource); HRESULT AddGlyphs( IXpsOMObjectFactory* xpsFactory, IXpsOMCanvas* canvas, - TypefaceUse* font, + const TypefaceUse* font, LPCWSTR text, XPS_GLYPH_INDEX* xpsGlyphs, UINT32 xpsGlyphsLen,